├── .gitignore
├── graphics
├── homekit.png
├── ustawienia.png
├── envoy_topbar.png
└── homebridge-enphase-envoy.png
├── .github
└── workflows
│ └── stale.yml
├── LICENSE
├── src
├── impulsegenerator.js
├── digestauth.js
├── passwdcalc.js
├── envoytoken.js
├── mqtt.js
├── restful.js
├── functions.js
└── constants.js
├── package.json
├── index.js
├── enphase_envoy.15s.rb
├── sample-config.json
├── README.md
└── CHANGELOG.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/graphics/homekit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grzegorz914/homebridge-enphase-envoy/HEAD/graphics/homekit.png
--------------------------------------------------------------------------------
/graphics/ustawienia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grzegorz914/homebridge-enphase-envoy/HEAD/graphics/ustawienia.png
--------------------------------------------------------------------------------
/graphics/envoy_topbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grzegorz914/homebridge-enphase-envoy/HEAD/graphics/envoy_topbar.png
--------------------------------------------------------------------------------
/graphics/homebridge-enphase-envoy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grzegorz914/homebridge-enphase-envoy/HEAD/graphics/homebridge-enphase-envoy.png
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues and pull requests
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *' # Runs daily at midnight (UTC)
6 | workflow_dispatch: # Allows you to manually trigger the workflow
7 |
8 | jobs:
9 | stale:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/stale@v8
13 | with:
14 | repo-token: ${{ secrets.GITHUB_TOKEN }}
15 | stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.'
16 | days-before-stale: 30
17 | days-before-close: 7
18 | stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.'
19 | stale-issue-label: 'stale'
20 | exempt-issue-labels: 'pinned,security'
21 | close-issue-message: 'Closing this issue due to inactivity.'
22 | close-pr-message: 'Closing this pull request due to inactivity.'
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2022 Grzegorz Kaczor
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/impulsegenerator.js:
--------------------------------------------------------------------------------
1 | import EventEmitter from 'events';
2 |
3 | class ImpulseGenerator extends EventEmitter {
4 | constructor() {
5 | super();
6 | this.timersState = false;
7 | this.timers = [];
8 | }
9 |
10 | async state(state, timers = [], runOnStart = true) {
11 | // Stop current timers before new start
12 | if (this.timersState && state) {
13 | await this.state(false);
14 | }
15 |
16 | if (state) {
17 | if (!Array.isArray(timers)) throw new Error('Timers must be an array');
18 |
19 | for (const { name, sampling } of timers) {
20 | if (!name || !sampling) continue;
21 |
22 | if (runOnStart) this.emit(name);
23 |
24 | const interval = setInterval(() => {
25 | this.emit(name);
26 | }, sampling);
27 |
28 | this.timers.push(interval);
29 | }
30 | } else {
31 | this.timers.forEach(clearInterval);
32 | this.timers = [];
33 | }
34 |
35 | this.timersState = state;
36 | this.emit('state', state);
37 | return true;
38 | }
39 | }
40 |
41 | export default ImpulseGenerator;
42 |
43 |
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": false,
3 | "displayName": "Enphase Envoy",
4 | "name": "homebridge-enphase-envoy",
5 | "version": "10.3.8",
6 | "description": "Homebridge p7ugin for Photovoltaic Energy System manufactured by Enphase.",
7 | "license": "MIT",
8 | "author": "grzegorz914",
9 | "maintainers": [
10 | "grzegorz914"
11 | ],
12 | "homepage": "https://github.com/grzegorz914/homebridge-enphase-envoy#readme",
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/grzegorz914/homebridge-enphase-envoy.git"
16 | },
17 | "bugs": {
18 | "url": "https://github.com/grzegorz914/homebridge-enphase-envoy/issues"
19 | },
20 | "type": "module",
21 | "exports": {
22 | ".": "./index.js"
23 | },
24 | "files": [
25 | "src",
26 | "index.js",
27 | "config.schema.json",
28 | "package.json",
29 | "CHANGELOG.md",
30 | "README.md",
31 | "LICENSE"
32 | ],
33 | "engines": {
34 | "homebridge": "^1.8.0 || ^2.0.0 || ^2.0.0-beta.40 || ^2.0.0-alpha.60",
35 | "node": "^20 || ^22 || ^24 || ^25"
36 | },
37 | "dependencies": {
38 | "mqtt": "^5.14.1",
39 | "axios": "^1.13.2",
40 | "express": "^5.2.1",
41 | "fast-xml-parser": "^5.3.3",
42 | "fakegato-history": "^0.6.7"
43 | },
44 | "keywords": [
45 | "homebridge",
46 | "homebridge-plugin",
47 | "envoy",
48 | "enphase",
49 | "ensemble",
50 | "enpower",
51 | "encharge",
52 | "photovoltaic",
53 | "solar",
54 | "mqtt",
55 | "restful"
56 | ],
57 | "contributors": [],
58 | "scripts": {
59 | "test": "echo \"Error: no test specified\" && exit 1"
60 | }
61 | }
--------------------------------------------------------------------------------
/src/digestauth.js:
--------------------------------------------------------------------------------
1 | import crypto from 'crypto';
2 | import axios from 'axios';
3 |
4 | class DigestAuth {
5 | constructor(config) {
6 | this.user = config.user;
7 | this.passwd = config.passwd;
8 | this.count = 0;
9 | }
10 |
11 | async request(path, options) {
12 | const url = `${options.baseURL}${path}`;
13 | options.headers = options.headers || {};
14 |
15 | try {
16 | return await axios.request(url, options);
17 | } catch (error) {
18 | const resError = error.response;
19 | if (!resError || resError.status !== 401) throw new Error(`Digest authentication response error: ${resError ? resError.status : 'Unknown error'}`);
20 |
21 | const resHeaders = resError.headers["www-authenticate"];
22 | if (!resHeaders || !resHeaders.includes('nonce')) throw new Error(`Digest authentication headers error: ${resHeaders || 'Header not found'}`);
23 |
24 | try {
25 | const authDetails = {};
26 | resHeaders.match(/(\w+)=("([^"]+)"|([^,]+))/g).forEach(part => {
27 | const match = part.match(/(\w+)=("([^"]+)"|([^,]+))/);
28 | authDetails[match[1]] = match[3] || match[4];
29 | });
30 |
31 | const realm = authDetails.realm;
32 | const nonce = authDetails.nonce;
33 | const nonceCount = (`00000000${this.count++}`).slice(-8);
34 | const cnonce = crypto.randomBytes(24).toString('hex');
35 |
36 | const md5 = str => crypto.createHash('md5').update(str).digest('hex');
37 | const HA1 = md5(`${this.user}:${realm}:${this.passwd}`);
38 | const HA2 = md5(`${options.method}:${path}`);
39 | const response = md5(`${HA1}:${nonce}:${nonceCount}:${cnonce}:auth:${HA2}`);
40 | const authHeader = `Digest username="${this.user}", realm="${realm}", nonce="${nonce}", uri="${path}", qop=auth, algorithm=MD5, response="${response}", nc=${nonceCount}, cnonce="${cnonce}"`;
41 | options.headers["authorization"] = authHeader;
42 |
43 | return await axios.request(url, options);
44 | } catch (error) {
45 | throw new Error(`Digest authentication error: ${error}`);
46 | }
47 | }
48 | }
49 | }
50 |
51 | export default DigestAuth;
52 |
53 |
--------------------------------------------------------------------------------
/src/passwdcalc.js:
--------------------------------------------------------------------------------
1 | import crypto from 'crypto';
2 |
3 | class PasswdCalc {
4 | constructor(config) {
5 | this.user = config.user;
6 | this.realm = config.realm;
7 | this.serialNumber = config.serialNumber;
8 | }
9 |
10 | async getPasswd() {
11 | try {
12 | const hashString = `[e]${this.user}@${this.realm}#${this.serialNumber} EnPhAsE eNeRgY `;
13 | const inputString = crypto.createHash('md5').update(hashString).digest('hex');
14 | const digestIterator = this.digestSnippet(inputString);
15 |
16 | const counters = inputString.split("").reduce((acc, val) => {
17 | if (val === "0") acc[0]++;
18 | else if (val === "1") acc[1]++;
19 | return acc;
20 | }, [0, 0]);
21 |
22 | let [countZero, countOne] = counters;
23 | let password = '';
24 |
25 | const MAX_ZERO = 20;
26 | const MAX_ONE = 26;
27 | const SKIP_ZERO = [3, 6, 9];
28 | const SKIP_ONE = [9, 15];
29 |
30 | for (const cc of digestIterator) {
31 | if (SKIP_ZERO.includes(countZero)) countZero--;
32 | if (countZero > MAX_ZERO) countZero = MAX_ZERO;
33 | if (countZero < 0) countZero = 0;
34 |
35 | if (SKIP_ONE.includes(countOne)) countOne--;
36 | if (countOne > MAX_ONE) countOne = MAX_ONE;
37 | if (countOne < 0) countOne = 0;
38 |
39 | switch (cc) {
40 | case "0":
41 | password += String.fromCharCode('f'.charCodeAt(0) + countZero);
42 | countZero--;
43 | break;
44 | case "1":
45 | password += String.fromCharCode('@'.charCodeAt(0) + countOne);
46 | countOne--;
47 | break;
48 | default:
49 | password += cc;
50 | break;
51 | }
52 | }
53 |
54 | return password;
55 | } catch (error) {
56 | throw new Error(`Generate password error: ${error}`);
57 | }
58 | }
59 |
60 | *digestSnippet(inputString) {
61 | for (let i = inputString.length - 1; i > inputString.length - 9; i--) {
62 | yield inputString[i];
63 | }
64 | }
65 | }
66 |
67 | export default PasswdCalc;
--------------------------------------------------------------------------------
/src/envoytoken.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import { URLSearchParams } from 'url';
3 | import EventEmitter from 'events';
4 | import { EnphaseUrls } from './constants.js';
5 |
6 | class EnvoyToken extends EventEmitter {
7 | constructor(config) {
8 | super();
9 | this.user = config.user;
10 | this.passwd = config.passwd;
11 | this.serialNumber = config.serialNumber;
12 | this.logWarn = config.logWarn;
13 | this.logError = config.logError;
14 | }
15 |
16 | async refreshToken() {
17 | try {
18 | const cookie = await this.loginToEnlighten();
19 | if (!cookie) return null;
20 |
21 | const tokenData = await this.getToken(cookie);
22 | if (!tokenData) return null;
23 |
24 | // Determine if token is installer or user (12h = 43200 seconds)
25 | const installerToken = (tokenData.expires_at - tokenData.generation_time) === 43200;
26 | tokenData.installer = installerToken;
27 |
28 | this.emit('success', `Token ${installerToken ? 'installer' : 'user'}, expires at: ${new Date(tokenData.expires_at * 1000).toLocaleString()}`);
29 |
30 | return tokenData;
31 | } catch (error) {
32 | throw new Error(`Refresh token error: ${error}`);
33 | }
34 | }
35 |
36 | async loginToEnlighten() {
37 | try {
38 | const form = new URLSearchParams();
39 | form.append('user[email]', this.user);
40 | form.append('user[password]', this.passwd);
41 |
42 | const response = await axios({
43 | method: 'POST',
44 | baseURL: EnphaseUrls.BaseUrl,
45 | url: EnphaseUrls.Login,
46 | headers: {
47 | 'Content-Type': 'application/x-www-form-urlencoded'
48 | },
49 | data: form,
50 | timeout: 10000
51 | });
52 |
53 | if (response.status !== 200) {
54 | if (this.logError) this.emit('error', `Login failed with status code: ${response.status}`);
55 | return null;
56 | }
57 |
58 | const cookie = response.headers['set-cookie'];
59 | if (!cookie) {
60 | if (this.logWarn) this.emit('warn', `No cookie returned from login. Response headers: ${JSON.stringify(response.headers)}`);
61 | return null;
62 | }
63 |
64 | return cookie;
65 | } catch (error) {
66 | throw new Error(`Login to Enlighten error: ${error}`);
67 | }
68 | }
69 |
70 | async getToken(cookie) {
71 | try {
72 | const response = await axios({
73 | method: 'GET',
74 | baseURL: EnphaseUrls.BaseUrl,
75 | url: EnphaseUrls.EntrezAuthToken,
76 | params: {
77 | serial_num: this.serialNumber
78 | },
79 | headers: {
80 | Accept: 'application/json',
81 | Cookie: cookie
82 | },
83 | timeout: 10000
84 | });
85 |
86 | const tokenData = response.data;
87 |
88 | if (!tokenData.token || !tokenData.expires_at || !tokenData.generation_time) {
89 | if (this.logWarn) this.emit('warn', `Incomplete token data: ${JSON.stringify(tokenData)}`);
90 | return null;
91 | }
92 |
93 | return tokenData;
94 | } catch (error) {
95 | throw new Error(`Get token error: ${error}`);
96 | }
97 | }
98 | }
99 |
100 | export default EnvoyToken;
101 |
102 |
103 |
--------------------------------------------------------------------------------
/src/mqtt.js:
--------------------------------------------------------------------------------
1 | import { connect } from 'mqtt';
2 | import EventEmitter from 'events';
3 |
4 | class Mqtt extends EventEmitter {
5 | constructor(config) {
6 | super();
7 |
8 | const url = `mqtt://${config.host}:${config.port}`;
9 | const subscribeTopic = `${config.prefix}/Set`;
10 |
11 | const options = {
12 | clientId: config.clientId,
13 | username: config.user,
14 | password: config.passwd,
15 | protocolVersion: 5,
16 | clean: false,
17 | properties: {
18 | sessionExpiryInterval: 60 * 60, // 1 hour
19 | userProperties: {
20 | source: 'node-client'
21 | }
22 | }
23 | };
24 |
25 | this.mqttClient = connect(url, options);
26 |
27 | // === CONNECTED ===
28 | this.mqttClient.on('connect', async (packet) => {
29 | this.emit('connected', 'MQTT v5 connected.');
30 |
31 | try {
32 | const result = await this.mqttClient.subscribeAsync(subscribeTopic, {
33 | qos: 1,
34 | properties: {
35 | userProperties: {
36 | type: 'subscription'
37 | }
38 | }
39 | });
40 |
41 | // MQTT v5 subscription results contain reason codes
42 | if (config.logDebug) this.emit('debug', `Subscribed to ${subscribeTopic}, reason codes: ${JSON.stringify(result)}`);
43 | this.emit('subscribed', `MQTT Subscribe topic: ${subscribeTopic}`);
44 |
45 | } catch (error) {
46 | if (config.logWarn) this.emit('warn', `MQTT Subscribe error: ${error}`);
47 | }
48 | });
49 |
50 | // === MESSAGE ===
51 | this.mqttClient.on('message', (topic, payload, packet) => {
52 | try {
53 | const obj = JSON.parse(payload.toString());
54 | if (config.logDebug) this.emit('debug', `MQTT Received:\nTopic: ${topic}\nPayload: ${JSON.stringify(obj, null, 2)}\nProperties: ${JSON.stringify(packet.properties, null, 2)}`);
55 |
56 | const key = Object.keys(obj)[0];
57 | const value = Object.values(obj)[0];
58 | this.emit('set', key, value);
59 |
60 | } catch (error) {
61 | if (config.logWarn) this.emit('warn', `MQTT Parse error: ${error}`);
62 | }
63 | });
64 |
65 | // === PUBLISH EVENT ===
66 | this.on('publish', async (topic, message) => {
67 | try {
68 | const fullTopic = `${config.prefix}/${topic}`;
69 | const publishMessage = JSON.stringify(message);
70 |
71 | await this.mqttClient.publishAsync(fullTopic, publishMessage, {
72 | qos: 1,
73 | properties: {
74 | contentType: 'application/json',
75 | userProperties: {
76 | source: 'node',
77 | action: 'set'
78 | }
79 | }
80 | });
81 |
82 | if (config.logDebug) this.emit('debug', `MQTT Publish:\nTopic: ${fullTopic}\nPayload: ${publishMessage}`);
83 | } catch (error) {
84 | if (config.logWarn) this.emit('warn', `MQTT Publish error: ${error}`);
85 | }
86 | });
87 |
88 | // === ERRORS / STATE ===
89 | this.mqttClient.on('error', (err) => {
90 | this.emit('warn', `MQTT Error: ${err.message}`);
91 | });
92 |
93 | this.mqttClient.on('reconnect', () => {
94 | if (config.logDebug) this.emit('debug', 'MQTT Reconnecting...');
95 | });
96 |
97 | this.mqttClient.on('close', () => {
98 | if (config.logDebug) this.emit('debug', 'MQTT Connection closed.');
99 | });
100 | }
101 | }
102 |
103 | export default Mqtt;
--------------------------------------------------------------------------------
/src/restful.js:
--------------------------------------------------------------------------------
1 | import express, { json } from 'express';
2 | import EventEmitter from 'events';
3 |
4 | const DEFAULT_MESSAGE = 'This data is not available in your system.';
5 |
6 | class RestFul extends EventEmitter {
7 | constructor(config) {
8 | super();
9 | this.port = config.port;
10 | this.logWarn = config.logWarn;
11 | this.logDebug = config.logDebug;
12 |
13 | this.restFulData = {
14 | token: DEFAULT_MESSAGE,
15 | info: DEFAULT_MESSAGE,
16 | home: DEFAULT_MESSAGE,
17 | inventory: DEFAULT_MESSAGE,
18 | microinvertersstatus: DEFAULT_MESSAGE,
19 | meters: DEFAULT_MESSAGE,
20 | metersreading: DEFAULT_MESSAGE,
21 | metersreports: DEFAULT_MESSAGE,
22 | detaileddevicesdata: DEFAULT_MESSAGE,
23 | microinvertersdata: DEFAULT_MESSAGE,
24 | qrelaysdata: DEFAULT_MESSAGE,
25 | homedata: DEFAULT_MESSAGE,
26 | metersdata: DEFAULT_MESSAGE,
27 | production: DEFAULT_MESSAGE,
28 | productionpdm: DEFAULT_MESSAGE,
29 | energypdm: DEFAULT_MESSAGE,
30 | productionct: DEFAULT_MESSAGE,
31 | powerandenergydata: DEFAULT_MESSAGE,
32 | acbatterydata: DEFAULT_MESSAGE,
33 | ensembleinventory: DEFAULT_MESSAGE,
34 | ensemblestatus: DEFAULT_MESSAGE,
35 | ensemblepower: DEFAULT_MESSAGE,
36 | enchargesettings: DEFAULT_MESSAGE,
37 | tariff: DEFAULT_MESSAGE,
38 | drycontacts: DEFAULT_MESSAGE,
39 | drycontactssettings: DEFAULT_MESSAGE,
40 | generator: DEFAULT_MESSAGE,
41 | generatorsettings: DEFAULT_MESSAGE,
42 | ensembledata: DEFAULT_MESSAGE,
43 | gridprofile: DEFAULT_MESSAGE,
44 | livedata: DEFAULT_MESSAGE,
45 | livedatadata: DEFAULT_MESSAGE,
46 | productionstate: DEFAULT_MESSAGE,
47 | plclevel: DEFAULT_MESSAGE,
48 | datasampling: DEFAULT_MESSAGE
49 | };
50 |
51 | this.connect();
52 | }
53 |
54 | connect() {
55 | try {
56 | const app = express();
57 | app.set('json spaces', 2);
58 | app.use(json());
59 |
60 | // Create GET routes directly from field names
61 | for (const key of Object.keys(this.restFulData)) {
62 | app.get(`/${key}`, (req, res) => {
63 | res.json(this.restFulData[key]);
64 | });
65 | }
66 |
67 | // Health check route
68 | app.get('/status', (req, res) => {
69 | res.json({
70 | status: 'online',
71 | uptime: process.uptime(),
72 | available_paths: Object.keys(this.restFulData).map(k => `/${k}`)
73 | });
74 | });
75 |
76 | // POST route
77 | app.post('/', (req, res) => {
78 | try {
79 | const obj = req.body;
80 | if (!obj || typeof obj !== 'object' || Object.keys(obj).length === 0) {
81 | if (this.logWarn) this.emit('warn', 'RESTFul Invalid JSON payload');
82 | return res.status(400).json({ error: 'RESTFul Invalid JSON payload' });
83 | }
84 |
85 | const key = Object.keys(obj)[0];
86 | const value = obj[key];
87 | this.emit('set', key, value);
88 | this.update(key, value);
89 |
90 | if (this.logDebug) this.emit('debug', `RESTFul post data: ${JSON.stringify(obj, null, 2)}`);
91 |
92 | res.json({ success: true, received: obj });
93 | } catch (error) {
94 | if (this.logWarn) this.emit('warn', `RESTFul Parse error: ${error}`);
95 | res.status(500).json({ error: 'RESTFul Internal Server Error' });
96 | }
97 | });
98 |
99 | app.listen(this.port, () => {
100 | this.emit('connected', `RESTful started on port: ${this.port}`);
101 | });
102 | } catch (error) {
103 | if (this.logWarn) this.emit('warn', `RESTful Connect error: ${error}`);
104 | }
105 | }
106 |
107 | update(path, data) {
108 | if (this.restFulData.hasOwnProperty(path)) {
109 | this.restFulData[path] = data;
110 | if (this.logDebug) this.emit('debug', `RESTFul update path: ${path}, data: ${JSON.stringify(data, null, 2)}`);
111 | } else {
112 | if (this.logWarn) this.emit('warn', `RESTFul update failed. Unknown path: "${path}". Valid paths: ${Object.keys(this.restFulData).join(', ')}`);
113 | }
114 | }
115 | }
116 |
117 | export default RestFul;
118 |
119 |
--------------------------------------------------------------------------------
/src/functions.js:
--------------------------------------------------------------------------------
1 | import { promises as fsPromises } from 'fs';
2 | import axios from 'axios';
3 | import { Agent } from 'https';
4 | import { ApiCodes, TimezoneLocaleMap } from './constants.js';
5 |
6 | class Functions {
7 | constructor() {
8 | }
9 |
10 | async saveData(path, data, stringify = true) {
11 | try {
12 | data = stringify ? JSON.stringify(data, null, 2) : data;
13 | await fsPromises.writeFile(path, data);
14 | return true;
15 | } catch (error) {
16 | throw new Error(`Save data error: ${error}`);
17 | }
18 | }
19 |
20 | async readData(path, parseJson = false) {
21 | try {
22 | const data = await fsPromises.readFile(path, 'utf8');
23 |
24 | if (parseJson) {
25 | if (!data.trim()) {
26 | // Empty file when expecting JSON
27 | return null;
28 | }
29 | try {
30 | return JSON.parse(data);
31 | } catch (jsonError) {
32 | throw new Error(`JSON parse error in file "${path}": ${jsonError.message}`);
33 | }
34 | }
35 |
36 | // For non-JSON, just return file content (can be empty string)
37 | return data;
38 | } catch (error) {
39 | if (error.code === 'ENOENT') {
40 | // File does not exist
41 | return null;
42 | }
43 | // Preserve original error details
44 | const wrappedError = new Error(`Read data error for "${path}": ${error.message}`);
45 | wrappedError.original = error;
46 | throw wrappedError;
47 | }
48 | }
49 |
50 | async getStatus(status) {
51 | if (!Array.isArray(status) || status.length === 0) {
52 | return 'OK';
53 | }
54 |
55 | const mapped = status.map(a => {
56 | const value = ApiCodes[a];
57 | return (typeof value === 'string' && value.trim() !== '') ? value.trim() : a;
58 | }).filter(Boolean); // Remove any empty/null/undefined values
59 |
60 | if (mapped.length === 0) {
61 | return 'OK';
62 | }
63 |
64 | const result = mapped.join(', ');
65 |
66 | // Add ellipsis only if result is actually truncated
67 | return result.length > 64 ? result.slice(0, 61) + '…' : result;
68 | }
69 |
70 | isValidValue(v) {
71 | return v !== undefined && v !== null && !(typeof v === 'number' && Number.isNaN(v));
72 | }
73 |
74 | scaleValue(value, inMin, inMax, outMin, outMax) {
75 | if (!this.isValidValue(value) || !this.isValidValue(inMin) || !this.isValidValue(inMax) || !this.isValidValue(outMin) || !this.isValidValue(outMax)) return null;
76 |
77 | if (inMax === inMin) return outMin;
78 | if (value <= inMin) return outMin;
79 | if (value >= inMax) return outMax;
80 |
81 | const scaled = ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
82 | if (scaled > outMax) return outMax;
83 |
84 | return scaled < 0.5 ? outMin : Math.round(scaled);
85 | }
86 |
87 | evaluateCompareMode(value, threshold, mode) {
88 | switch (mode) {
89 | case 0: return value > threshold;
90 | case 1: return value >= threshold;
91 | case 2: return value === threshold;
92 | case 3: return value < threshold;
93 | case 4: return value <= threshold;
94 | case 5: return value !== threshold;
95 | default: return false;
96 | }
97 | }
98 |
99 | formatTimestamp(ts, timezone) {
100 | const locale = TimezoneLocaleMap[timezone] || 'en-US';
101 | const options = {
102 | timeZone: timezone,
103 | year: 'numeric',
104 | month: '2-digit',
105 | day: '2-digit',
106 | hour: '2-digit',
107 | minute: '2-digit',
108 | second: '2-digit',
109 | };
110 |
111 | if (!ts) {
112 | return new Date().toLocaleString(locale, options);
113 | }
114 |
115 | const numeric = Number(ts);
116 | if (Number.isInteger(numeric)) {
117 | const ms = numeric < 1e12 ? numeric * 1000 : numeric;
118 | return new Date(ms).toLocaleString(locale, options);
119 | }
120 |
121 | return ts;
122 | }
123 |
124 | powerPeak(power, powerPeakStored) {
125 | if (!this.isValidValue(power) && !this.isValidValue(powerPeakStored)) return null;
126 | if (!this.isValidValue(power)) return powerPeakStored;
127 | if (!this.isValidValue(powerPeakStored)) return power;
128 |
129 | // dodatnie — szczyt rośnie w górę
130 | if (power >= 0 && power > powerPeakStored) return power;
131 |
132 | // ujemne — szczyt rośnie w dół
133 | if (power < 0 && power < powerPeakStored) return power;
134 |
135 | return powerPeakStored;
136 | }
137 |
138 | createAxiosInstance(url, authHeader = null, cookie = null) {
139 | return axios.create({
140 | baseURL: url,
141 | headers: {
142 | Accept: 'application/json',
143 | ...(authHeader ? { Authorization: authHeader } : {}),
144 | ...(cookie ? { Cookie: cookie } : {}),
145 | },
146 | withCredentials: true,
147 | httpsAgent: new Agent({
148 | keepAlive: false,
149 | rejectUnauthorized: false
150 | }),
151 | timeout: 60000
152 | });
153 | }
154 |
155 | }
156 | export default Functions
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import { mkdirSync, existsSync, writeFileSync } from 'fs';
3 | import EnvoyDevice from './src/envoydevice.js';
4 | import ImpulseGenerator from './src/impulsegenerator.js';
5 | import { PluginName, PlatformName } from './src/constants.js';
6 | import CustomCharacteristics from './src/customcharacteristics.js';
7 |
8 | class EnvoyPlatform {
9 | constructor(log, config, api) {
10 | if (!config || !Array.isArray(config.devices)) {
11 | log.warn(`No configuration found for ${PluginName}.`);
12 | return;
13 | }
14 |
15 | this.log = log;
16 | this.accessories = [];
17 |
18 | const prefDir = join(api.user.storagePath(), 'enphaseEnvoy');
19 | try {
20 | mkdirSync(prefDir, { recursive: true });
21 | } catch (error) {
22 | log.error(`Prepare directory error: ${error}.`);
23 | return;
24 | }
25 |
26 | api.on('didFinishLaunching', async () => {
27 | for (let i = 0; i < config.devices.length; i++) {
28 | const device = config.devices[i];
29 | const displayType = device.displayType || 0;
30 | if (displayType === 0) continue;
31 |
32 | const deviceName = device.name;
33 | const host = device.host || (i === 0 ? 'envoy.local' : `envoy-${i + 1}.local`);
34 | const { envoyFirmware7xxTokenGenerationMode = 0, envoyToken, enlightenUser, enlightenPasswd } = device;
35 |
36 | const logLevel = {
37 | devInfo: device.log?.deviceInfo || true,
38 | success: device.log?.success || true,
39 | info: device.log?.info || false,
40 | warn: device.log?.warn || true,
41 | error: device.log?.error || true,
42 | debug: device.log?.debug || false
43 | };
44 |
45 | if (!deviceName) {
46 | log.warn(`Device: ${host}, Name missing.`);
47 | continue;
48 | }
49 |
50 | if (envoyFirmware7xxTokenGenerationMode === 1 && (!enlightenUser || !enlightenPasswd)) {
51 | log.warn(`Device: ${host} ${deviceName}, missing Enlighten credentials.`);
52 | continue;
53 | }
54 |
55 | if (envoyFirmware7xxTokenGenerationMode === 2 && !envoyToken) {
56 | log.warn(`Device: ${host} ${deviceName}, missing Envoy token.`);
57 | continue;
58 | }
59 |
60 | if (logLevel.debug) {
61 | log.info(`Device: ${host} ${deviceName}, did finish launching.`);
62 | const redactedConfig = JSON.stringify({
63 | ...device,
64 | envoyPasswd: 'removed',
65 | envoyToken: 'removed',
66 | enlightenPasswd: 'removed',
67 | mqtt: {
68 | auth: {
69 | ...device.mqtt?.auth,
70 | passwd: 'removed',
71 | }
72 | },
73 | }, null, 2);
74 | log.info(`Device: ${host} ${deviceName}, Config: ${redactedConfig}`);
75 | }
76 |
77 | const postFix = host.split('.').join('');
78 | const envoyIdFile = join(prefDir, `envoyId_${postFix}`);
79 | const envoyTokenFile = join(prefDir, `envoyToken_${postFix}`);
80 | const energyMeterHistoryFileName = `energyMeterHistory_${postFix}`;
81 |
82 | try {
83 | [envoyIdFile, envoyTokenFile].forEach(file => {
84 | if (!existsSync(file)) writeFileSync(file, '0');
85 | });
86 | } catch (error) {
87 | if (logLevel.error) log.error(`Device: ${host} ${deviceName}, File init error: ${error}`);
88 | continue;
89 | }
90 |
91 | try {
92 | const url = envoyFirmware7xxTokenGenerationMode > 0 ? `https://${host}` : `http://${host}`;
93 |
94 | // create impulse generator
95 | const impulseGenerator = new ImpulseGenerator()
96 | .on('start', async () => {
97 | try {
98 | const envoyDevice = new EnvoyDevice(api, log, url, deviceName, device, envoyIdFile, envoyTokenFile, prefDir, energyMeterHistoryFileName)
99 | .on('devInfo', (info) => log.info(info))
100 | .on('success', (msg) => log.success(`Device: ${host} ${deviceName}, ${msg}`))
101 | .on('info', (msg) => log.info(`Device: ${host} ${deviceName}, ${msg}`))
102 | .on('debug', (msg, data) => log.info(`Device: ${host} ${deviceName}, debug: ${data ? `${msg} ${JSON.stringify(data, null, 2)}` : msg}`))
103 | .on('warn', (msg) => log.warn(`Device: ${host} ${deviceName}, ${msg}`))
104 | .on('error', (msg) => log.error(`Device: ${host} ${deviceName}, ${msg}`));
105 |
106 | const accessories = await envoyDevice.start();
107 | if (accessories) {
108 | api.publishExternalAccessories(PluginName, accessories);
109 | if (logLevel.success) log.success(`Device: ${host} ${deviceName}, Published as external accessory.`);
110 |
111 | await impulseGenerator.state(false);
112 | await envoyDevice.startStopImpulseGenerator(true);
113 | }
114 | } catch (error) {
115 | if (logLevel.error) log.error(`Device: ${host} ${deviceName}, Start impulse generator error: ${error}, retrying.`);
116 | }
117 | })
118 | .on('state', state => {
119 | if (logLevel.debug) log.info(`Device: ${host} ${deviceName}, Start impulse generator ${state ? 'started' : 'stopped'}.`);
120 | });
121 |
122 | // start impulse generator
123 | await impulseGenerator.state(true, [{ name: 'start', sampling: 120000 }]);
124 | } catch (error) {
125 | if (logLevel.error) log.error(`Device: ${host} ${deviceName}, Did finish launching error: ${error}`);
126 | }
127 | }
128 | });
129 | }
130 |
131 | configureAccessory(accessory) {
132 | this.accessories.push(accessory);
133 | }
134 | }
135 |
136 | export default (api) => {
137 | CustomCharacteristics(api);
138 | api.registerPlatform(PluginName, PlatformName, EnvoyPlatform);
139 | };
140 |
141 |
--------------------------------------------------------------------------------
/enphase_envoy.15s.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | # By grzegorz914@icloud.com
4 | # see https://github.com/grzegorz914/homebridge-enphase-envoy
5 |
6 | # Enphase Envoy
7 | # v1.0
8 | # Grzegorz
9 | # grzegorz914
10 | # Display the power and energy of Enphase solar system.
11 | # ruby
12 | # http://url-to-about.com/
13 |
14 | require 'net/http'
15 | require 'net/http/digest_auth'
16 | require 'json'
17 |
18 | ENVOY_IP = 'envoy.local'
19 | MICROINVERTERS_SUM_WATTS = 5400 # Set the summary power of microinverters
20 |
21 | def autoFormatPower(val)
22 | if (val < 1000 && val > -1000)
23 | return val.round(1).to_s + ' W'
24 | end
25 | if ((val >= 1000 && val < 1000000) || (val > -1000000 && val <= -1000))
26 | return (val/1000).round(3).to_s + ' kW'
27 | end
28 | if (val <= -1000000 || val >= 1000000)
29 | return (val/1000000).round(3).to_s + ' MW'
30 | end
31 | end
32 |
33 | def autoFormatEnergy(val)
34 | if (val < 1000 && val > -1000)
35 | return val.round(1).to_s + ' Wh'
36 | end
37 | if ((val >= 1000 && val < 1000000) || (val > -1000000 && val <= -1000))
38 | return (val/1000).round(3).to_s + ' kWh'
39 | end
40 | if (val <= -1000000 || val >= 1000000)
41 | return (val/1000000).round(3).to_s + ' MWh'
42 | end
43 | end
44 |
45 | begin
46 | raise "Not a valid IP address. Update ENVOY_IP in script" unless ENVOY_IP.match(/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/)
47 | http = Net::HTTP.new(ENVOY_IP)
48 |
49 | # Check installed meters
50 | uri = URI("http://" + ENVOY_IP + "/ivp/meters")
51 | req = Net::HTTP::Get.new(uri.request_uri)
52 | res = http.request(req)
53 | raise "Error on meters response: " + res.message unless res.is_a?(Net::HTTPSuccess)
54 | meters = JSON.parse(res.body)
55 |
56 | # Check enabled meters
57 | ctmeters = meters.length
58 | if ctmeters > 0
59 | ctmeterProduction = (meters[0]["state"] == "enabled")
60 | ctmeterConsumption = (meters[1]["state"] == "enabled")
61 | else
62 | ctmeterProduction = false
63 | ctmeterConsumption = false
64 | end
65 |
66 | # Get production misroinverters
67 | uri = URI("http://" + ENVOY_IP + "/api/v1/production")
68 | req = Net::HTTP::Get.new(uri.request_uri)
69 | res = http.request(req)
70 | raise "Error on production response: " + res.message unless res.is_a?(Net::HTTPSuccess)
71 | production = JSON.parse(res.body)
72 |
73 | productionMicroSummarywhToday = production["attHoursToday"]
74 | productionMicroSummarywhLastSevenDays = production["wattHoursSevenDays"]
75 | productionMicroSummarywhLifeTime = production["wattHoursLifetime"]
76 | productionMicroSummaryWattsNow = production["wattsNow"]
77 |
78 | # Get production cureent meters
79 | uri = URI("http://" + ENVOY_IP + "/production.json?details=1")
80 | req = Net::HTTP::Get.new(uri.request_uri)
81 | res = http.request(req)
82 | raise "Error on productionct response: " + res.message unless res.is_a?(Net::HTTPSuccess)
83 | productionct = JSON.parse(res.body)
84 |
85 | if ctmeterProduction == true
86 | productionPower = productionct["production"][1]["wNow"]
87 | productionEnergyToday = productionct["production"][1]["whToday"]
88 | productionEnergyLastSevenDays = productionct["production"][1]["whLastSevenDays"]
89 | productionEnergyLifeTime = productionct["production"][1]["whLifetime"]
90 | end
91 |
92 | if ctmeterConsumption == true
93 | consumptionTotalPower = productionct["consumption"][0]["wNow"]
94 | consumptionTotalEnergyToday = productionct["consumption"][0]["whToday"]
95 | consumptionTotalEnergyLastSevenDays = productionct["consumption"][0]["whLastSevenDays"]
96 | consumptionTotalEnergyLifeTime = productionct["consumption"][0]["whLifetime"]
97 | consumptionNetPower = productionct["consumption"][1]["wNow"]
98 | consumptionNetEnergyLifeTime = productionct["consumption"][1]["whLifetime"]
99 | end
100 |
101 | if ctmeterConsumption == true
102 | case
103 | when consumptionNetPower > 0
104 | icon = "🔌" # Power plug
105 | power = consumptionNetPower
106 | when (ctmeterProduction ? productionPower : productionMicroSummaryWattsNow) < (MICROINVERTERS_SUM_WATTS / 2)
107 | icon = "⛅" # Cloudy
108 | power = ctmeterProduction ? productionPower : productionMicroSummaryWattsNow
109 | else
110 | icon = "☀️" # Sun
111 | power = ctmeterProduction ? productionPower : productionMicroSummaryWattsNow
112 | end
113 | else
114 | case
115 | when (ctmeterProduction ? productionPower : productionMicroSummaryWattsNow) < (MICROINVERTERS_SUM_WATTS / 2)
116 | icon = "⛅" # Cloudy
117 | power = ctmeterProduction ? productionPower : productionMicroSummaryWattsNow
118 | else
119 | icon = "☀️" # Sun
120 | power = ctmeterProduction ? productionPower : productionMicroSummaryWattsNow
121 | end
122 | end
123 |
124 | puts "#{icon} #{autoFormatPower(power)}| color=#{power > 0 ? "red":"white"} size=12"
125 | puts "---"
126 | puts "Production"
127 | puts "Power #{autoFormatPower(ctmeterProduction ? productionPower : productionMicroSummaryWattsNow)}| size=12"
128 | puts "Energy #{autoFormatEnergy(ctmeterProduction ? productionEnergyToday : productionMicroSummarywhToday)}| size=12"
129 | puts "Energy 7 days #{autoFormatEnergy(ctmeterProduction ? productionEnergyLastSevenDays : productionMicroSummarywhLastSevenDays)}| size=12"
130 | puts "Energy lifetime #{autoFormatEnergy(ctmeterProduction ? productionEnergyLifeTime : productionMicroSummarywhLifeTime)}| size=12"
131 | puts "---"
132 | if ctmeterConsumption == true
133 | puts "Consumption total"
134 | puts "Power #{autoFormatPower(consumptionTotalPower)}| size=12"
135 | puts "Energy #{autoFormatEnergy(consumptionTotalEnergyToday)}| size=12"
136 | puts "Energy 7 days #{autoFormatEnergy(consumptionTotalEnergyLastSevenDays)}| size=12"
137 | puts "Energy lifetime #{autoFormatEnergy(consumptionTotalEnergyLifeTime)}| size=12"
138 | puts "---"
139 | puts "Consumption net"
140 | puts "Power #{autoFormatPower(consumptionNetPower)}| size=12"
141 | puts "Energy lifetime #{autoFormatEnergy(consumptionNetEnergyLifeTime)}| size=12"
142 | puts "---"
143 | end
144 |
145 | # Get installed and active devices
146 | uri = URI("http://" + ENVOY_IP + "/inventory.json")
147 | req = Net::HTTP::Get.new(uri.request_uri)
148 | res = http.request(req)
149 | raise "Error on inventory response: " + res.message unless res.is_a?(Net::HTTPSuccess)
150 | inventory = JSON.parse(res.body)
151 |
152 | # Get the serial number of the envoy
153 | uri = URI("http://" + ENVOY_IP + "/info.xml")
154 | req = Net::HTTP::Get.new(uri.request_uri)
155 | res = http.request(req)
156 | raise "Error on envoy serial response: " + res.message unless res.is_a?(Net::HTTPSuccess)
157 | envoySerial = res.body.scan(/sn>(\d*)<\/sn>/).first.first
158 |
159 | # Now lets see how much the every microinverter producing.
160 | uri = URI("http://" + ENVOY_IP + "/api/v1/production/inverters")
161 | uri.user = "envoy"
162 | uri.password = envoySerial[-6,6]
163 |
164 | # Make the first request to get the auth
165 | req = Net::HTTP::Get.new(uri.request_uri)
166 | res = http.request(req)
167 |
168 | # Aauthentication digest
169 | digest_auth = Net::HTTP::DigestAuth.new
170 | auth = digest_auth.auth_header(uri, res['www-authenticate'], 'GET')
171 | req = Net::HTTP::Get.new(uri.request_uri)
172 | req.add_field('Authorization', auth)
173 | res = http.request(req)
174 |
175 | # Get serial number and power of every microinverter
176 | case res
177 | when Net::HTTPSuccess
178 | allInverters = JSON.parse(res.body)
179 | puts "Mikroinwerter"
180 | j = 0
181 | arr = Array.new
182 | arr1 = Array.new
183 | loop do
184 | serialNumber = allInverters[j]["serialNumber"]
185 | power = allInverters[j]["lastReportWatts"]
186 | arr.push(serialNumber)
187 | arr1.push(power)
188 | j += 1
189 | if j == allInverters.length
190 | break
191 | end
192 | end
193 |
194 | i = 0
195 | loop do
196 | serial = inventory[0]["devices"][i]["serial_num"]
197 | index = arr.find_index(serial)
198 | puts "Nr. #{arr[index]} moc: #{autoFormatPower(arr1[index])}| size=12"
199 | i += 1
200 | if i == inventory[0]["devices"].length
201 | break
202 | puts "---"
203 | end
204 | end
205 | when Net::HTTPUnauthorized
206 | {'error' => "#{res.message}: username and password set and correct?"}
207 | when Net::HTTPServerError
208 | {'error' => "#{res.message}: try again later?"}
209 | else
210 | {'error' => res.message}
211 | end
212 |
213 | rescue StandardError => e
214 | puts ":warning: Error| size=12"
215 | puts "---"
216 | puts e.message
217 | end
218 |
--------------------------------------------------------------------------------
/sample-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "bridge": {
3 | "name": "Homebridge",
4 | "username": "AA:BB:CC:DD:EE:FF",
5 | "manufacturer": "homebridge.io",
6 | "model": "homebridge",
7 | "port": 9100,
8 | "pin": "123-45-678"
9 | },
10 | "description": "HomeKit Bridge",
11 | "ports": {
12 | "start": 9101,
13 | "end": 9150,
14 | "comment": "In this section set the port for Homebridge accessories."
15 | },
16 | "accessories": [],
17 | "platforms": [
18 | {
19 | "platform": "enphaseEnvoy",
20 | "devices": [
21 | {
22 | "name": "Envoy",
23 | "host": "192.168.1.35",
24 | "displayType": 1,
25 | "envoyFirmware7xxTokenGenerationMode": 0,
26 | "envoyPasswd": "",
27 | "enlightenUser": "",
28 | "enlightenPasswd": "",
29 | "envoyToken": "",
30 | "envoyTokenInstaller": false,
31 | "lockControl": {
32 | "enable": true,
33 | "time": 30,
34 | "namePrefix": false
35 | },
36 | "productionStateSensor": {
37 | "name": "Sensor name",
38 | "displayType": 0,
39 | "namePrefix": false
40 | },
41 | "plcLevelControl": {
42 | "name": "Control name",
43 | "displayType": 0,
44 | "namePrefix": false
45 | },
46 | "powerProductionSummary": 7200,
47 | "powerProductionLevelSensors": [
48 | {
49 | "name": "Production > 7500W",
50 | "compareMode": 0,
51 | "powerLevel": 7500,
52 | "displayType": 0,
53 | "namePrefix": false
54 | }
55 | ],
56 | "energyProductionLifetimeOffset": 0,
57 | "energyProductionLevelSensors": [
58 | {
59 | "name": "Production energy level > 5000Wh",
60 | "compareMode": 0,
61 | "energyLevel": 5000,
62 | "displayType": 0,
63 | "namePrefix": false
64 | }
65 | ],
66 | "gridProductionQualitySensors": [
67 | {
68 | "displayType": 0,
69 | "name": "Cyrrent > 5A",
70 | "compareMode": 0,
71 | "compareType": 0,
72 | "compareevel": 5,
73 | "namePrefix": false
74 | }
75 | ],
76 | "powerConsumptionTotalLevelSensors": [
77 | {
78 | "name": "Consumption Total > 5500W",
79 | "compareMode": 0,
80 | "powerLevel": 5500,
81 | "displayType": 0,
82 | "namePrefix": false
83 | }
84 | ],
85 | "energyConsumptionTotalLifetimeOffset": 0,
86 | "energyConsumptionTotalLevelSensors": [
87 | {
88 | "name": "Consumption Total energy level > 5000Wh",
89 | "compareMode": 0,
90 | "energyLevel": 5000,
91 | "displayType": 0,
92 | "namePrefix": false
93 | }
94 | ],
95 | "gridConsumptionTotalQualitySensors": [
96 | {
97 | "displayType": 0,
98 | "name": "Cyrrent > 5A",
99 | "compareMode": 0,
100 | "compareType": 0,
101 | "compareevel": 5,
102 | "namePrefix": false
103 | }
104 | ],
105 | "powerConsumptionNetLevelSensors": [
106 | {
107 | "name": "Import from Net > 5500W",
108 | "compareMode": 0,
109 | "powerLevel": 5500,
110 | "displayType": 0,
111 | "namePrefix": false
112 | },
113 | {
114 | "name": "Export to Net = 5500W",
115 | "compareMode": 2,
116 | "powerLevel": -5500,
117 | "displayType": 0,
118 | "namePrefix": false
119 | }
120 | ],
121 | "energyConsumptionNetLifetimeOffset": 0,
122 | "energyConsumptionNetLevelSensors": [
123 | {
124 | "name": "Consumption Net energy level >= 5000Wh",
125 | "compareMode": 0,
126 | "energyLevel": 5000,
127 | "displayType": 0,
128 | "namePrefix": false
129 | }
130 | ],
131 | "gridConsumptionNetQualitySensors": [
132 | {
133 | "displayType": 0,
134 | "name": "Cyrrent > 5A",
135 | "compareMode": 0,
136 | "compareType": 0,
137 | "compareevel": 5,
138 | "namePrefix": false
139 | }
140 | ],
141 | "qRelayStateSensor": {
142 | "name": "Sensor name",
143 | "displayType": 0,
144 | "namePrefix": false,
145 | "multiphase": false
146 | },
147 | "acBatterieName": "AC batterie name",
148 | "acBatterieBackupLevelSummaryAccessory": {
149 | "displayType": 0,
150 | "minSoc": 0
151 | },
152 | "acBatterieBackupLevelAccessory": {
153 | "displayType": 0,
154 | "minSoc": 0
155 | },
156 | "enpowerGridStateControl": {
157 | "name": "Control name",
158 | "displayType": 0,
159 | "namePrefix": false
160 | },
161 | "enpowerGridStateSensor": {
162 | "name": "Sensor name",
163 | "displayType": 0,
164 | "namePrefix": false
165 | },
166 | "enpowerGridModeSensors": [
167 | {
168 | "name": "Sensor name",
169 | "mode": "On",
170 | "displayType": 0,
171 | "namePrefix": false
172 | }
173 | ],
174 | "enchargeName": "Encharge name",
175 | "enchargeBackupLevelSummaryAccessory": {
176 | "displayType": 0,
177 | "minSoc": 0
178 | },
179 | "enchargeBackupLevelAccessory": {
180 | "displayType": 0,
181 | "minSoc": 0
182 | },
183 | "enchargeStateSensor": {
184 | "name": "Sensor name",
185 | "displayType": 0,
186 | "namePrefix": false
187 | },
188 | "enchargeProfileControls": [
189 | {
190 | "name": "Tile name",
191 | "profile": "self-consumption",
192 | "displayType": 0,
193 | "namePrefix": false
194 | }
195 | ],
196 | "enchargeProfileSensors": [
197 | {
198 | "name": "Sensor name",
199 | "profile": "self-consumption",
200 | "displayType": 0,
201 | "namePrefix": false
202 | }
203 | ],
204 | "enchargeGridStateSensor": {
205 | "name": "Sensor name",
206 | "displayType": 0,
207 | "namePrefix": false
208 | },
209 | "enchargeGridModeSensors": [
210 | {
211 | "name": "Sensor name",
212 | "gridMode": "grid-on",
213 | "displayType": 0,
214 | "namePrefix": false
215 | }
216 | ],
217 | "enchargeBackupLevelSensors": [
218 | {
219 | "name": "Backup > 50%",
220 | "compareMode": 0,
221 | "backupLevel": 100,
222 | "displayType": 0,
223 | "namePrefix": false
224 | }
225 | ],
226 | "solarGridStateSensor": {
227 | "name": "Sensor name",
228 | "displayType": 0,
229 | "namePrefix": false
230 | },
231 | "solarGridModeSensors": [
232 | {
233 | "name": "Sensor name",
234 | "gridMode": "grid-on",
235 | "displayType": 0,
236 | "namePrefix": false
237 | }
238 | ],
239 | "enpowerDryContactsControl": false,
240 | "enpowerDryContactsSensor": false,
241 | "generatorStateControl": {
242 | "name": "Control name",
243 | "displayType": 0,
244 | "namePrefix": false
245 | },
246 | "generatorStateSensor": {
247 | "name": "Sensor name",
248 | "displayType": 0,
249 | "namePrefix": false
250 | },
251 | "generatordModeContol": [
252 | {
253 | "name": "Tile name",
254 | "mode": "auto",
255 | "displayType": 0,
256 | "namePrefix": false
257 | }
258 | ],
259 | "generatordModeSensors": [
260 | {
261 | "name": "Sensor name",
262 | "mode": "off",
263 | "displayType": 0,
264 | "namePrefix": false
265 | }
266 | ],
267 | "dataRefreshControl": {
268 | "name": "Control name",
269 | "displayType": 0,
270 | "namePrefix": false
271 | },
272 | "dataRefreshSensor": {
273 | "name": "Sensor name",
274 | "displayType": 0,
275 | "namePrefix": false
276 | },
277 | "metersDataRefreshTime": 3.0,
278 | "productionDataRefreshTime": 5.0,
279 | "liveDataRefreshTime": 3.0,
280 | "ensembleDataRefreshTime": 15.0,
281 | "log": {
282 | "deviceInfo": true,
283 | "success": true,
284 | "info": false,
285 | "warn": true,
286 | "error": true,
287 | "debug": false
288 | },
289 | "restFul": {
290 | "enable": false,
291 | "port": 3000
292 | },
293 | "mqtt": {
294 | "enable": false,
295 | "host": "",
296 | "port": 1883,
297 | "clientId": "",
298 | "prefix": "",
299 | "auth": {
300 | "enable": false,
301 | "user": "",
302 | "passwd": ""
303 | }
304 | }
305 | }
306 | ]
307 | }
308 | ]
309 | }
--------------------------------------------------------------------------------
/src/constants.js:
--------------------------------------------------------------------------------
1 | export const PlatformName = "enphaseEnvoy";
2 | export const PluginName = "homebridge-enphase-envoy";
3 | export const DisplayName = "Enphase Envoy";
4 | export const Authorization = {
5 | "EnvoyUser": "envoy",
6 | "InstallerUser": "installer",
7 | "Realm": "enphaseenergy.com"
8 | };
9 |
10 | export const EnphaseUrls = {
11 | "BaseUrl": "https://enlighten.enphaseenergy.com",
12 | "Login": "/login/login.json",
13 | "EntrezAuthToken": "/entrez-auth-token"
14 | };
15 |
16 | export const EntrezUrls = {
17 | "BaseUrl": "https://entrez.enphaseenergy.com",
18 | "Login": "/login",
19 | "Tokens": "/tokens"
20 | };
21 |
22 | export const ApiUrls = {
23 | "AcbSleepModeGetSetCancel": "/admin/lib/acb_config.json",
24 | "AddLoadKontrolKit": "/ivp/ss/load_control",
25 | "AgfProfileIndex": "/installer/agf/index.json?simplified=true",
26 | "AgfProfileDetails": "/installer/agf/details.json",
27 | "AgfProfileInverterStatus": "/installer/agf/inverters_status.json",
28 | "AgfProfileSetProfile": "/installer/agf/set_profile.json",
29 | "BackboneApplication": "/backbone/application.js",
30 | "CellularConfig": "/admin/lib/network_display.json?cellular=1",
31 | "CheckJwt": "/auth/check_jwt",
32 | "ClearGFIPost": "/admin/lib/admin_dcc_display.json",
33 | "DerSettings": "/ivp/ss/der_settings",
34 | "DevStatus": "/ivp/peb/devstatus",
35 | "DevicesData": "/ivp/pdm/device_data",
36 | "DryContacts": "/ivp/ensemble/dry_contacts",
37 | "DryContactsSettings": "/ivp/ss/dry_contact_settings",
38 | "EnchargeBattery": "/ivp/ensemble/power",
39 | "EnchargeChargingDischargingStatus": "/ivp/sc/sched",
40 | "EnchargeRelay": "/ivp/ensemble/relay",
41 | "EnchargeGetSetCancelSleepMode": "/ivp/ensemble/sleep",
42 | "EnchargeSettings": "/ivp/ss/enc_settings",
43 | "EnchrgeStatus": "/ivp/sc/status",
44 | "EnsembleAgfProfileStatus": "/ivp/ensemble/profile_status",
45 | "EnsembleComm": "/ivp/ensemble/comm_check",
46 | "EnsembleDeletePut": "/ivp/zb/provision",
47 | "EnsembleInventory": "/ivp/ensemble/inventory",
48 | "EnsembleSecctrl": "/ivp/ensemble/secctrl",
49 | "EnsembleStatus": "/ivp/ensemble/status",
50 | "EnsemblePower": "/ivp/ensemble/power",
51 | "EthernetConfigCheckNewIpGetPut": "/admin/lib/network_display.json",
52 | "EventsGet": "/datatab/event_dt.rb",
53 | "Generator": "/ivp/ensemble/generator",
54 | "GeneratorDelete": "/ivp/ss/gen_delete",
55 | "GeneratorMeterStateSet": "/ivp/ss/generator_meter_enable",
56 | "GeneratorModeGetSet": "/ivp/ss/gen_mode",
57 | "GeneratorProfileGetSet": "/ivp/ss/gen_profile",
58 | "GeneratorScheduleGetSet": "/ivp/ss/gen_schedule",
59 | "GeneratorSettingsGetSet": "/ivp/ss/gen_config",
60 | "GetInfo": "/info.xml",
61 | "GetTimezones": "/admin/lib/date_time_display.json?tzlist=1",
62 | "Home": "/home.json",
63 | "InternalMeterCurrentCtSettings": "/ivp/meters/cts",
64 | "InternalMeterCurrentCtSettingsEid": "/ivp/meters/cts/EID",
65 | "InternalMeterInfo": "/ivp/meters",
66 | "InternalMeterInfoEid": "/ivp/meters/EID",
67 | "InternalMeterInfoStorage": "/ivp/meters/storage_settings",
68 | "InternalMeterRevelsalEid": "/ivp/meters/ctreversal/EID",
69 | "InternalMeterReadings": "/ivp/meters/readings",
70 | "InternalMeterReadingsEid": "/ivp/meters/readings/EID",
71 | "InternalMeterStream": "/stream/meter",
72 | "InternalMetersReports": "/ivp/meters/reports/",
73 | "InternalMetersReportsProduction": "/ivp/meters/reports/production",
74 | "InternalMetersReportsConsumption": "/ivp/meters/reports/consumption",
75 | "InverterComm": "/installer/pcu_comm_check",
76 | "InverterDelete": "/prov",
77 | "InverterProduction": "/api/v1/production/inverters",
78 | "InverterPut": "/prov",
79 | "Inventory": "/inventory.json",
80 | "InventoryDeleted": "/inventory.json?deleted=1",
81 | "LiveDataStatus": "/ivp/livedata/status",
82 | "LiveDataStream": "/ivp/livedata/stream",
83 | "NewScanGetPD": "/ivp/peb/newscan",
84 | "ProductionPdm": "/ivp/pdm/production",
85 | "EnergyPdm": "/ivp/pdm/energy",
86 | "Production": "/api/v1/production",
87 | "Energy": "/api/v1/energy",
88 | "PMUGetPost": "/admin/lib/admin_pmu_display.json",
89 | "PowerControlSystemGetSet": "/ivp/ss/pcs_settings",
90 | "PowerExportLimitGet": "/ivp/ss/pel_settings",
91 | "PowerForcedModeGetPut": "/ivp/mod/EID/mode/power",
92 | "Profile": "/ivp/arf/profile",
93 | "Pvlimit": "/ivp/sc/pvlimit",
94 | "RedeterminePhase": "/ivp/grest/local/gs/redeterminephase",
95 | "ReportSettingsGetPut": "/ivp/peb/reportsettings",
96 | "SendPhaseInformation": "/ivp/ss/sys_phase_balance",
97 | "SetTimezone": "/admin/lib/date_time_display.json",
98 | "SystemReadingStats": "/production.json?details=1",
99 | "TariffSettingsGetPut": "/admin/lib/tariff",
100 | "TunnelStateGetPut": "/admin/lib/dba.json",
101 | "UpdateMeterConfig": "/ivp/meters/EID",
102 | "UpdateMeterCurrentCTConfig": "/ivp/meters/cts/EID",
103 | "UpdatePassword": "/admin/lib/security_display.json",
104 | "WifiSettingsGetJoin": "/admin/lib/wireless_display.json"
105 | };
106 |
107 | export const PartNumbers = {
108 | "800-00551-r03": "X-IQ-AM1-120-B-M",
109 | "800-00553-r03": "X-IQ-AM1-240-B",
110 | "800-00557-r03": "X-IQ-AM1-240-BM",
111 | "800-00554-r04": "X-IQ-AM1-240-2",
112 | "800-00554-r05": "X-IQ-AM1-240-2-M",
113 | "800-00555-r03": "X-IQ-AM1-240-3",
114 | "800-00655-r09": "X-IQ-AM1-240-3-ES",
115 | "800-00556-r03": "X-IQ-AM1-240-3C",
116 | "800-00554-r07": "X-IQ-AM1-240-3C-ES",
117 | "880-00122-r02": "ENV-S-AB-120-A",
118 | "880-00210-r02": "ENV-S-AM1-120",
119 | "800-00552-r01": "ENV-S-WM-230",
120 | "800-00553-r01": "ENV-S-WB-230",
121 | "800-00553-r02": "ENV-S-WB-230-F",
122 | "800-00554-r03": "ENV-S-WM-230",
123 | "800-00654-r06": "ENV-S-WM-230",
124 | "800-00654-r08": "ENV-S-WM-230",
125 | "800-00664-r05": "ENV-S-WM-230",
126 | "880-00208-r02": "ENV-IQ-AM1-240",
127 | "880-00208-r03": "ENV-IQ-AM1-240",
128 | "880-00231-r02": "ENV-IQ-AM1-240",
129 | "880-00209-r03": "ENV-IQ-AM3-3P",
130 | "880-00557-r02": "ENV-IQ-AM3-3P",
131 | "860-00152-r02": "Q-RELAY-1P-INT",
132 | "800-00598-r04": "Q-RELAY-1P-INT",
133 | "800-00597-r02": "Q-RELAY-3P-INT",
134 | "800-00630-r02": "IQ7-60-2-INT",
135 | "800-00637-r02": "IQ7-60-2-US",
136 | "800-00641-r02": "IQ7-60-B-US",
137 | "800-00633-r02": "IQ7A-72-2-INT",
138 | "800-00634-r02": "IQ7A-72-2-US",
139 | "800-00638-r02": "IQ7A-72-B-US",
140 | "800-00632-r02": "IQ7X-96-2-INT",
141 | "800-00635-r02": "IQ7X-96-2-US",
142 | "800-00639-r02": "IQ7X-96-B-US",
143 | "800-00631-r02": "IQ7PLUS-72-2-INT",
144 | "880-01736-r02": "IQ7PLUS-72-M-INT",
145 | "800-00636-r02": "IQ7PLUS-72-2-US",
146 | "800-00640-r02": "IQ7PLUS-72-B-US",
147 | "883-00852-r09": "IQ7PLUS-72-2-US",
148 | "800-01131-r02": "IQ8",
149 | "800-01395-r03": "IQ8AC-72-M-INT",
150 | "860-00276-r48": "EP200G101-M240US00",
151 | "830-00703-r75": "B03-A01-US00-1-3",
152 | "830-00703-r84": "B03-A01-US00-1-3",
153 | "836-01890-r24": "ENCHARGE-IQ-5P",
154 | "836-00750-r27": "ENCHARGE-10-1P-NA",
155 | "860-00376-r38": "ENPOWER",
156 | "860-00276-r59": "ENPOWER",
157 | "800-01612-r04": "ENSEMBLE",
158 | "865-00400-r22": "IQ Meter Collar",
159 | "800-02403-r08": "IQ Combiner C6",
160 | "836-01250-r00": "IQ Battery 10C",
161 | "xxx-xxxxx-xx3": "COMMS-KIT-01",
162 | "834-01927-r03": "COMMS-KIT-02"
163 | };
164 |
165 | export const ApiCodes = {
166 | "ACB": "AC Batterie",
167 | "BLE": "BLE",
168 | "CAN": "CAN",
169 | "COLLAR": "Collar",
170 | "C6 COMBINER CONTROLER": "C6 Combiner Controller",
171 | "C6 RGM": "C6 Revenue Grade Meter",
172 | "ENCHARGE": "Encharge",
173 | "ENCHG_STATE_CHARGING": "Encharge state charging",
174 | "ENCHG_STATE_DISCHARGING": "Encharge state discharging",
175 | "ENCHG_STATE_IDLE": "Encharge state idle",
176 | "ENCHG_STATE_READY": "Encharge state ready",
177 | "ENCMN_MDE_ENCHARGE_READY": "Encharge mode ready",
178 | "ENCMN_MDE_ON_GRID": "Encharge mode on grid",
179 | "ENCMN_MDE_OFF_GRID": "Encharge mode off grid",
180 | "ENCMN_C6_CC_READY": "C6 Combiner Controller ready",
181 | "ENPOWER": "Enpower",
182 | "ENS_DEVICE_STATE_READY": "Ensemble state ready",
183 | "ENPWR_STATE_GRIDMODE_CONFIRM": "Enpower state grid mode confirm",
184 | "ENPWR_STATE_GRIDMODE_WAIT": "Enpower state grid mode wait",
185 | "ENPWR_STATE_OPER_CLOSED": "Enpower state closed",
186 | "ENPWR_STATE_OPER_NO_GRID": "Enpower state no grid",
187 | "ENPWR_STATE_OPER_OPEN": "Enpower state open",
188 | "ENPWR_STATE_OPER_SYNC_READY": "Enpower state sync ready",
189 | "ESUB": "Ensemble",
190 | "NSRB": "Q-Relay",
191 | "PCU": "Microinverter",
192 | "StorageTouMode_DEFAULT_TOU_MODE": "Default tou mode",
193 | "USB": "USB",
194 | "Unknown": "Unknown",
195 | "always_on": "Always On",
196 | "apply": "Apply",
197 | "auto": "Auto",
198 | "backup": "Full backup",
199 | "backfeed": "Back Feed",
200 | "cellular": "Cellular",
201 | "charging": "Charging",
202 | "check-wiring": "Check Wiring",
203 | "close": "Close",
204 | "closed": "Closed",
205 | "connected": "Connected",
206 | "consumption": "Consumption Net",
207 | "discharging": "Discharging",
208 | "disabled": "Disabled",
209 | "disconnected": "Disconnected",
210 | "economy": "Economy",
211 | "eim": "Current Meter",
212 | "enabled": "Enabled",
213 | "encharge": "Encharge",
214 | "enpower": "Enpower",
215 | "esub": "Ensemble",
216 | "eth0": "Ethernet",
217 | "ethernet": "Ethernet",
218 | "evse": "EV Charger",
219 | "flat": "Flat",
220 | "full": "Full",
221 | "gen": "Generstor",
222 | "grid-forming": "Grid Forming",
223 | "grid-interactive": "Grid Interactive",
224 | "grid-tied": "Grid Tied",
225 | "idle": "Idle",
226 | "inverters": "Microinverters",
227 | "load": "Load",
228 | "manual": "Manual",
229 | "multimode-offgrid": "Multimode Grid OFF",
230 | "multimode-ongrid": "Multimode Grid ON",
231 | "net-consumption": "Consumption Net",
232 | "negative-production": "Negative production",
233 | "negative-total-consumption": "Negative total consumption",
234 | "none": "None",
235 | "normal": "Normal",
236 | "not-metering": "Not metering",
237 | "not-satisfied": "Not satisfied",
238 | "not_set": "Not set",
239 | "nsrb": "Q-Relay",
240 | "off": "Off",
241 | "off-grid": "Grid OFF",
242 | "off_grid": "Grid OFF",
243 | "on": "On",
244 | "on-grid": "Grid ON",
245 | "on_grid": "Grid ON",
246 | "one": "One",
247 | "open": "Open",
248 | "open synchronized": "Open Synchronized",
249 | "open synchronizing": "Open Synchronizing",
250 | "pcu": "Microinverter",
251 | "ph-a": "L1",
252 | "ph-b": "L2",
253 | "ph-c": "L3",
254 | "ph-all": "All",
255 | "ph-unk": "Unknown",
256 | "pmu": "Power Meter Unit",
257 | "power-on-unused-phase": "Powwr on unused phase",
258 | "production": "Production",
259 | "production-imbalance": "Production imbalance",
260 | "prop.done": "Prop done",
261 | "prop.not.done": "Prop not done",
262 | "pv": "PV",
263 | "pv3p": "PV 3 Phase",
264 | "ready": "Ready",
265 | "rgm": "Revenue Grade Meter",
266 | "satisfied": "Satisfied",
267 | "savings-mode": "Savings",
268 | "self-consumption": "Self consumption",
269 | "shed": "Shed",
270 | "shedule": "Shedule",
271 | "single": "Single",
272 | "single_rate": "Single rate",
273 | "soc": "State oF Charge",
274 | "split": "Split",
275 | "storage": "Storage",
276 | "subghz": "Sub GHz",
277 | "synchronizing-to-grid": "Synchronizing to grid",
278 | "three": "Three",
279 | "tiered": "Tiered",
280 | "time_of_use": "Time of use",
281 | "time_to_use": "Time to use",
282 | "total-consumption": "Consumption Total",
283 | "two": "Two",
284 | "unknown": "Unknown",
285 | "utility-interactive": "Utility Interactive",
286 | "wifi": "WiFi",
287 | "wlan0": "WiFi",
288 | "zigbee": "ZigBee",
289 | "envoy.cond_flags.acb_ctrl.bmudatabounds": "BMU Data Bounds Error",
290 | "envoy.cond_flags.acb_ctrl.bmuhardwareerror": "BMU Hardware Error",
291 | "envoy.cond_flags.acb_ctrl.bmuimageerror": "BMU Image Error",
292 | "envoy.cond_flags.acb_ctrl.bmumaxcurrentwarning": "BMU Max Current Warning",
293 | "envoy.cond_flags.acb_ctrl.bmusenseerror": "BMU Sense Error",
294 | "envoy.cond_flags.acb_ctrl.cellmaxtemperror": "Cell Max Temperature Error",
295 | "envoy.cond_flags.acb_ctrl.cellmaxtempwarning": "Cell Max Temperature Warning",
296 | "envoy.cond_flags.acb_ctrl.cellmaxvoltageerror": "Cell Max Voltage Error",
297 | "envoy.cond_flags.acb_ctrl.cellmaxvoltagewarning": "Cell Max Voltage Warning",
298 | "envoy.cond_flags.acb_ctrl.cellmintemperror": "Cell Min Temperature Error",
299 | "envoy.cond_flags.acb_ctrl.cellmintempwarning": "Cell Min Temperature Warning",
300 | "envoy.cond_flags.acb_ctrl.cellminvoltageerror": "Cell Min Voltage Error",
301 | "envoy.cond_flags.acb_ctrl.cellminvoltagewarning": "Cell Min Voltage Warning",
302 | "envoy.cond_flags.acb_ctrl.cibcanerror": "CIB CAN Error",
303 | "envoy.cond_flags.acb_ctrl.cibimageerror": "CIB Image Error",
304 | "envoy.cond_flags.acb_ctrl.cibspierror": "CIB SPI Error",
305 | "envoy.cond_flags.nsrb_ctrl.acfreqhigh": "AC Frequency High",
306 | "envoy.cond_flags.nsrb_ctrl.acfreqlow": "AC Frequency Low",
307 | "envoy.cond_flags.nsrb_ctrl.acfrequencyoor": "AC Frequency Out Of Range",
308 | "envoy.cond_flags.nsrb_ctrl.acvoltageavgline1": "AC Voltage Avg Out Of Range - Phase 1",
309 | "envoy.cond_flags.nsrb_ctrl.acvoltageavgline2": "AC Voltage Avg Out Of Range - Phase 2",
310 | "envoy.cond_flags.nsrb_ctrl.acvoltageavgline3": "AC Voltage Avg Out Of Range - Phase 3",
311 | "envoy.cond_flags.nsrb_ctrl.acvoltagehighline1": "AC Voltage High - Phase 1",
312 | "envoy.cond_flags.nsrb_ctrl.acvoltagehighline2": "AC Voltage Out Of Range - Phase 2",
313 | "envoy.cond_flags.nsrb_ctrl.acvoltagehighline3": "AC Voltage High - Phase 3",
314 | "envoy.cond_flags.nsrb_ctrl.acvoltagelowline1": "AC Voltage Low - Phase 1",
315 | "envoy.cond_flags.nsrb_ctrl.acvoltagelowline2": "AC Voltage Out Of Range - Phase 2",
316 | "envoy.cond_flags.nsrb_ctrl.acvoltagelowline3": "AC Voltage Low - Phase 3",
317 | "envoy.cond_flags.nsrb_ctrl.acvoltageoorline1": "AC Voltage Out Of Range - Phase 1",
318 | "envoy.cond_flags.nsrb_ctrl.acvoltageoorline2": "AC Voltage Out Of Range - Phase 2",
319 | "envoy.cond_flags.nsrb_ctrl.acvoltageoorline3": "AC Voltage Out Of Range - Phase 3",
320 | "envoy.cond_flags.nsrb_ctrl.buttonpress": "Button Pressed",
321 | "envoy.cond_flags.nsrb_ctrl.dcgriderror": "DC Grid Current Error",
322 | "envoy.cond_flags.nsrb_ctrl.dcgridhigh": "DC Grid Current High",
323 | "envoy.cond_flags.nsrb_ctrl.dcgridlow": "DC Grid Current Low",
324 | "envoy.cond_flags.nsrb_ctrl.relayforced": "Relay Forced",
325 | "envoy.cond_flags.nsrb_ctrl.relayopen": "Relay Open",
326 | "envoy.cond_flags.nsrb_ctrl.rocof": "Rate of Change of Frequency Error",
327 | "envoy.cond_flags.obs_strs.discovering": "Discovering",
328 | "envoy.cond_flags.obs_strs.failure": "Failure to report",
329 | "envoy.cond_flags.obs_strs.flasherror": "Flash Error",
330 | "envoy.cond_flags.obs_strs.notmonitored": "Not Monitored",
331 | "envoy.cond_flags.obs_strs.ok": "Normal",
332 | "envoy.cond_flags.obs_strs.plmerror": "PLM Error",
333 | "envoy.cond_flags.obs_strs.secmodeenterfailure": "Secure mode enter failure",
334 | "envoy.cond_flags.obs_strs.secmodeexitfailure": "Secure mode exit failure",
335 | "envoy.cond_flags.obs_strs.sleeping": "Sleep Mode On",
336 | "envoy.cond_flags.obs_strs.verifing": "Verifying Device",
337 | "envoy.cond_flags.pcu_chan.acMonitorError": "AC Monitor Error",
338 | "envoy.cond_flags.pcu_chan.acfrequencyhigh": "AC Frequency High",
339 | "envoy.cond_flags.pcu_chan.acfrequencylow": "AC Frequency Low",
340 | "envoy.cond_flags.pcu_chan.acfrequencyoor": "AC Frequency Out Of Range",
341 | "envoy.cond_flags.pcu_chan.acvoltage_avg_hi": "AC Voltage Average High",
342 | "envoy.cond_flags.pcu_chan.acvoltagehigh": "AC Voltage High",
343 | "envoy.cond_flags.pcu_chan.acvoltagelow": "AC Voltage Low",
344 | "envoy.cond_flags.pcu_chan.acvoltageoor": "AC Voltage Out Of Range",
345 | "envoy.cond_flags.pcu_chan.acvoltageoosp1": "AC Voltage Out Of Range - Phase 1",
346 | "envoy.cond_flags.pcu_chan.acvoltageoosp2": "AC Voltage Out Of Range - Phase 2",
347 | "envoy.cond_flags.pcu_chan.acvoltageoosp3": "AC Voltage Out Of Range - Phase 3",
348 | "envoy.cond_flags.pcu_chan.agfpowerlimiting": "AGF Power Limiting",
349 | "envoy.cond_flags.pcu_chan.dcresistancelow": "DC Resistance Low",
350 | "envoy.cond_flags.pcu_chan.dcresistancelowpoweroff": "DC Resistance Low - Power Off",
351 | "envoy.cond_flags.pcu_chan.dcvoltagetoohigh": "DC Voltage Too High",
352 | "envoy.cond_flags.pcu_chan.dcvoltagetoolow": "DC Voltage Too Low",
353 | "envoy.cond_flags.pcu_chan.dfdt": "AC Frequency Changing too Fast",
354 | "envoy.cond_flags.pcu_chan.gfitripped": "GFI Tripped",
355 | "envoy.cond_flags.pcu_chan.gridgone": "Grid Gone",
356 | "envoy.cond_flags.pcu_chan.gridinstability": "Grid Instability",
357 | "envoy.cond_flags.pcu_chan.gridoffsethi": "Grid Offset Hi",
358 | "envoy.cond_flags.pcu_chan.gridoffsetlow": "Grid Offset Low",
359 | "envoy.cond_flags.pcu_chan.hardwareError": "Hardware Error",
360 | "envoy.cond_flags.pcu_chan.hardwareWarning": "Hardware Warning",
361 | "envoy.cond_flags.pcu_chan.highskiprate": "High Skip Rate",
362 | "envoy.cond_flags.pcu_chan.invalidinterval": "Invalid Interval",
363 | "envoy.cond_flags.pcu_chan.pwrgenoffbycmd": "Power generation off by command",
364 | "envoy.cond_flags.pcu_chan.skippedcycles": "Skipped Cycles",
365 | "envoy.cond_flags.pcu_chan.vreferror": "Voltage Ref Error",
366 | "envoy.cond_flags.pcu_ctrl.altpwrgenmode": "Alternate Power Generation Mode",
367 | "envoy.cond_flags.pcu_ctrl.altvfsettings": "Alternate Voltage and Frequency Settings",
368 | "envoy.cond_flags.pcu_ctrl.badflashimage": "Bad Flash Image",
369 | "envoy.cond_flags.pcu_ctrl.bricked": "No Grid Profile",
370 | "envoy.cond_flags.pcu_ctrl.commandedreset": "Commanded Reset",
371 | "envoy.cond_flags.pcu_ctrl.criticaltemperature": "Critical Temperature",
372 | "envoy.cond_flags.pcu_ctrl.dc-pwr-low": "DC Power Too Low",
373 | "envoy.cond_flags.pcu_ctrl.iuplinkproblem": "IUP Link Problem",
374 | "envoy.cond_flags.pcu_ctrl.lertactive": "Alert Active",
375 | "envoy.cond_flags.pcu_ctrl.manutestmode": "In Manu Test Mode",
376 | "envoy.cond_flags.pcu_ctrl.nsync": "Grid Perturbation Unsynchronized",
377 | "envoy.cond_flags.pcu_ctrl.overtemperature": "Over Temperature",
378 | "envoy.cond_flags.pcu_ctrl.poweronreset": "Power On Reset",
379 | "envoy.cond_flags.pcu_ctrl.pwrgenoffbycmd": "Power generation off by command",
380 | "envoy.cond_flags.pcu_ctrl.runningonac": "Running on AC",
381 | "envoy.cond_flags.pcu_ctrl.sleep-mode": "Sleep Mode On",
382 | "envoy.cond_flags.pcu_ctrl.tpmtest": "Transient Grid Profile",
383 | "envoy.cond_flags.pcu_ctrl.unexpectedreset": "Unexpected Reset",
384 | "envoy.cond_flags.pcu_ctrl.watchdogreset": "Watchdog Reset",
385 | "envoy.cond_flags.rgm_chan.check_meter": "Meter Error",
386 | "envoy.cond_flags.rgm_chan.power_quality": "Poor Power Quality",
387 | "envoy.cond_flags.undef-0x00020000": "Status 0x00020000",
388 | "envoy.global.ok": "Normal"
389 | };
390 |
391 | export const MetersKeyMap = {
392 | "production": "production",
393 | "net-consumption": "consumptionNet",
394 | "total-consumption": "consumptionTotal",
395 | "storage": "storage",
396 | "gen": "gen",
397 | "backfeed": "backfeed",
398 | "evse": "evse",
399 | "load": "load",
400 | "pv3p": "pv3p"
401 | };
402 |
403 | export const MetersKeyMap1 = {
404 | "Production": "production",
405 | "Consumption Net": "consumptionNet",
406 | "Consumption Total": "consumptionTotal",
407 | "Storage": "storage",
408 | "Generator": "generator",
409 | };
410 |
411 | export const DeviceTypeMap = {
412 | 1: "Microinverter",
413 | 12: "Q-Relay",
414 | 13: "Encharge",
415 | 14: "Encharge Sub Module",
416 | 15: "Encharge Control Module",
417 | 17: "Enpower",
418 | 18: "Enpower Sub Module",
419 | 20: "Enpower Control Module",
420 | 19: "Ensemble",
421 | 22: "Ensemble Comm Module",
422 | 24: "Ensemble Comm Control Module",
423 | };
424 |
425 | export const LedStatus = {
426 | "0": "Off",
427 | "1": "Standby",
428 | "2": "Booting",
429 | "3": "Initializing",
430 | "4": "Connected",
431 | "5": "Firmware Update",
432 | "7": "Warning",
433 | "8": "Error",
434 | "9": "Critical Error",
435 | "10": "Maintenance",
436 | "11": "Testing",
437 | "12": "Charging",
438 | "13": "Discharging",
439 | "14": "Idle",
440 | "15": "Reserved",
441 | "16": "Reserved",
442 | "17": "Reserved",
443 | "18": "Unknown",
444 | "19": "Unknown",
445 | "20": "Unknown"
446 | };
447 |
448 | export const TimezoneLocaleMap = {
449 | // US / North America
450 | "America/Los_Angeles": "en-US", // Pacific Time
451 | "US/Pacific": "en-US",
452 | "America/Denver": "en-US", // Mountain Time
453 | "US/Mountain": "en-US",
454 | "America/Chicago": "en-US", // Central Time
455 | "US/Central": "en-US",
456 | "America/New_York": "en-US", // Eastern Time
457 | "US/Eastern": "en-US",
458 | "America/Anchorage": "en-US",
459 | "Pacific/Honolulu": "en-US",
460 |
461 | "America/Vancouver": "en-CA",
462 | "Canada/Pacific": "en-CA",
463 | "America/Toronto": "en-CA",
464 | "Canada/Eastern": "en-CA",
465 | "America/Halifax": "en-CA",
466 | "Canada/Atlantic": "en-CA",
467 |
468 | "Mexico/BajaNorte": "en-US",
469 | "Mexico/BajaSur": "en-US",
470 |
471 | // Europe
472 | "Europe/London": "en-GB",
473 | "Europe/Dublin": "en-IE",
474 | "Europe/Paris": "fr-FR",
475 | "Europe/Berlin": "de-DE",
476 | "Europe/Madrid": "es-ES",
477 | "Europe/Rome": "it-IT",
478 | "Europe/Warsaw": "pl-PL",
479 | "Europe/Amsterdam": "nl-NL",
480 | "Europe/Brussels": "fr-BE",
481 | "Europe/Zurich": "de-CH",
482 | "Europe/Vienna": "de-AT",
483 | "Europe/Stockholm": "sv-SE",
484 | "Europe/Helsinki": "fi-FI",
485 | "Europe/Athens": "el-GR",
486 | "Europe/Moscow": "ru-RU",
487 |
488 | // Asia
489 | "Asia/Tokyo": "ja-JP",
490 | "Asia/Shanghai": "zh-CN",
491 | "Asia/Hong_Kong": "zh-HK",
492 | "Asia/Singapore": "en-SG",
493 | "Asia/Kolkata": "hi-IN",
494 | "Asia/Seoul": "ko-KR",
495 | "Asia/Bangkok": "th-TH",
496 | "Asia/Jakarta": "id-ID",
497 | "Asia/Dubai": "ar-AE",
498 | "Asia/Taipei": "zh-TW",
499 |
500 | // Australia & Oceania
501 | "Australia/Sydney": "en-AU",
502 | "Australia/Melbourne": "en-AU",
503 | "Australia/Perth": "en-AU",
504 | "Pacific/Auckland": "en-NZ",
505 |
506 | // South America
507 | "America/Sao_Paulo": "pt-BR",
508 | "America/Buenos_Aires": "es-AR",
509 | "America/Bogota": "es-CO",
510 | "America/Mexico_City": "es-MX",
511 |
512 | // Africa
513 | "Africa/Johannesburg": "en-ZA",
514 | "Africa/Cairo": "ar-EG",
515 | "Africa/Nairobi": "en-KE",
516 |
517 | // Middle East
518 | "Asia/Riyadh": "ar-SA",
519 | "Asia/Tehran": "fa-IR",
520 | "Asia/Jerusalem": "he-IL",
521 |
522 | // Aliases (some European and Pacific examples)
523 | "Europe/Belfast": "en-GB",
524 | "Europe/Guernsey": "en-GB",
525 | "Europe/Isle_of_Man": "en-GB",
526 | "Europe/Jersey": "en-GB",
527 |
528 | "Pacific/Johnston": "en-US",
529 | "Pacific/Samoa": "en-US",
530 |
531 | // UTC fallback
532 | "UTC": "en-US",
533 | };
534 |
535 |
536 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # Homebridge Enphase Envoy
8 |
9 | [](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
10 | [](https://www.npmjs.com/package/homebridge-enphase-envoy)
11 | [](https://www.npmjs.com/package/homebridge-enphase-envoy)
12 | [](https://www.npmjs.com/package/homebridge-enphase-envoy)
13 | [](https://github.com/grzegorz914/homebridge-enphase-envoy/pulls)
14 | [](https://github.com/grzegorz914/homebridge-enphase-envoy/issues)
15 |
16 |
17 |
18 | ## About The Plugin
19 |
20 | The `homebridge-enphase-envoy` plugin integrates Enphase Envoy solar energy monitoring systems with Homebridge, allowing HomeKit users to track solar production, consumption, and battery status directly in the Apple Home app. With real-time energy insights, automation possibilities, and Siri voice control, this plugin enhances smart home energy management by seamlessly connecting your Enphase Envoy system to the HomeKit ecosystem.
21 |
22 | ## Requirements
23 |
24 | | Package | Installation | Role | Required |
25 | | --- | --- | --- | --- |
26 | | [Homebridge v2.0.0](https://github.com/homebridge/homebridge) | [Homebridge Wiki](https://github.com/homebridge/homebridge/wiki) | HomeKit Bridge | Required |
27 | | [Homebridge UI <= v5.5.0](https://github.com/homebridge/homebridge-config-ui-x) | [Homebridge UI Wiki](https://github.com/homebridge/homebridge-config-ui-x/wiki) | Homebridge Web User Interface | Required |
28 | | [Enphase Envoy](https://www.npmjs.com/package/homebridge-enphase-envoy) | [Plug-In Wiki](https://github.com/grzegorz914/homebridge-enphase-envoy/wiki) | Homebridge Plug-In | Required |
29 |
30 | ## Supported hardware
31 |
32 | * Firmware v5 through v8
33 | * System/Enpower `Envoy S`, `IQ Gateway`, `IQ Load Controller`, `IQ Combiner Controller`
34 | * Q-Relays `Q-Relay 1P` `Q-Relay 3P`
35 | * AC Batteries `AC Battery`
36 | * Meters `Production`, `Consumption`, `Storage`, `Back Feed`, `EV Charger`, `PV 3P`, `Load`
37 | * Microinverters `M215`, `M250`, `IQ6`, `IQ7`, `IQ8`
38 | * Encharges `IQ Battery 3`, `IQ Battery 10`, `IQ Battery 5P`, `IQ Battery 3T`, `IQ Battery 10T`, `IQ Battery 10C`
39 | * WirelessKit `Communications Kit 1/2`
40 | * Generator
41 |
42 | ## Exposed accessories in the Apple Home app
43 |
44 | ### Monitoring Sensors
45 |
46 | * System `Data Refresh`
47 | * Production `State`, `Power State`, `Power Level`, `Energy State`, `Energy Level`, `Current`, `Voltage`, `Frequency`, `Power Factor`
48 | * Consumption `Power State`, `Power Level`, `Energy State`, `Energy Level`, `Current`, `Voltage`, `Frequency`, `Power Factor`
49 | * Q-Relay `State`
50 | * Enpower `Grid State`
51 | * Encharge: `State`, `Grid State`, `Backup Level`, `Dry Contacts`
52 | * Solar `Grid State`
53 | * Encharge Profile: `Self Consumption`, `Savings`, `Economy`, `Full Backup`
54 | * Grid:
55 | * Mode:
56 | * Enpower `Grid On`, `Grid Off`, `Multimode Grid On`, `Multimode Grid Off`, `Grid Tied`, `Grid Forming`
57 | * Encharge `Grid On`, `Grid Off`, `Multimode Grid On`, `Multimode Grid Off`, `Grid Tied`, `Grid Forming`
58 | * Solar `Grid On`, `Grid Off`, `Multimode Grid On`, `Multimode Grid Off`, `Grid Tied`, `Grid Forming`
59 | * Quality:
60 | * Production `Current (A)`, `Voltage (V)`, `Power Factor (cos Fi)`, `Frequency (Hz)`
61 | * Consumption Total `Current (A)`, `Voltage (V)`, `Power Factor (cos Fi)`, `Frequency (Hz)`,
62 | * Consumption Net `Current (A)`, `Voltage (V)`, `Power Factor (cos Fi)`, `Frequency (Hz)`,
63 | * Generator `State`, `Mode`
64 |
65 | ### Control Switches, Outlets, Lightbulbs
66 |
67 | * System `Data Refresh`, `Lock Control`
68 | * Production `State`, `Power Mode`, `Power State`, `Power Level`
69 | * AC Battery `Energy State`, `Backup Level Summary`, `Backup Level`
70 | * Enpower `Grid State`, `Dry Contacts`
71 | * Encharge `Energy State Summary`, `Backup Level Summary`, `Energy State`, `Backup Level`
72 | * Encharge Profile
73 | * Self Consumption `Activate`, `Set Reserve`
74 | * Savings `Activate`, `Set Reserve`
75 | * Economy `Activate`, `Set Reserve`
76 | * Full Backup `Activate`
77 | * Generator `State`, `Mode`
78 | * PLC Level `State`
79 |
80 | ## Notes
81 |
82 | * Token authentication (v7.0+) - Tokens can be generated automatically with the Enlighten username (email address) and password or external tools. Tokens generated with Enlighten credentials are automatically refreshed while those generated with external tools are not.
83 | * Envoy `password` is detected automatically or can be added in the configuration if already changed by user.
84 | * Installer `password` is generated automatically (firmware < v7.0+).
85 | * Envoy `device ID` is detected automatically.
86 | * Supports [Production State Conrol](https://github.com/grzegorz914/homebridge-enphase-envoy/wiki#power-production-control) and `PLC Level Check` (firmware v7.0+ requires installer credentials).
87 | * For the best experience and to display all data, please use the `Controller` or `Eve` apps.
88 | * External integrations include: [REST](https://github.com/grzegorz914/homebridge-enphase-envoy?tab=readme-ov-file#restful-integration) and [MQTT](https://github.com/grzegorz914/homebridge-enphase-envoy?tab=readme-ov-file#mqtt-integration).
89 |
90 | ### Configuration
91 |
92 | * Running this plugin as a [Child Bridge](https://github.com/homebridge/homebridge/wiki/Child-Bridges) is **highly recommended**. This prevents Homebridge from crashing if the plugin crashes.
93 | * Installation and use of [Homebridge UI <= v5.5.0](https://github.com/homebridge/homebridge-config-ui-x) to configure this plugin.
94 | * The `sample-config.json` can be edited and used as an alternative for advanced users.
95 |
96 |
97 |
98 |
99 |
100 | | Key | Subkey | Type | Description |
101 | | --- | --- | --- | --- |
102 | | `name` | | string | Envoy Enphase Gateway accessory name to be displayed in Home app |
103 | | `host` | | string | The Envoy Enphase Gateway `IP Address` or `Hostname`. If not supplied, defaults to `envoy.local`. For firmware v7.0+, please set the `IP Address`. |
104 | | `displayType` | | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Light Bulb, `2` - Fan, `3` - Humidity Sensor, `4` - Carbon Monoxide Sensor |
105 | | `envoyFirmware7xxTokenGenerationMode` | | number | How you will obtain the token: `0` - Envoy Password (firmware < v7.0), `1` - Enlighten Credentials, `2` - Your Own Generated Token |
106 | | `envoyPasswd` | | string | Envoy password (only if U already changed the default password) ||
107 | | `enlightenUser` | | string | Enlighten username |
108 | | `enlightenPasswd` | | string | Enlighten password |
109 | | `envoyToken` | | string | Token if you selected `2 - Your Own Generated Token` for envoyFirmware7xxTokenGenerationMode |
110 | | `envoyTokenInstaller` | | boolean | Enable if you are using the installer token |
111 | | `lockControl` | | key | `Lock Control` for enable?disable system control |
112 | | | `lockControl.enable` | boolean | Enables system control auto lock accessory |
113 | | | `lockControl.time` | number | `System Auto Lock Control` time (seconds) |
114 | | | `lockControl.namePrefix` | boolean | Use accessory name for prefix |
115 | | `energyMeter` | | boolean | Enables energy meter as a axtra accessory to display charts in EVE app |
116 | | `productionStateSensor` | | key | `Production State Sensor` for production state monitoring |
117 | | | `name` | string | Accessory name for Home app |
118 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
119 | | | `namePrefix` | boolean | Use accessory name for prefix |
120 | | `plcLevelControl` | | key | `PLC Level Control` for PLC level check (firmware v7.0+ require installer credentials) |
121 | | | `name` | string | Accessory name for Home app |
122 | | | `displayType` | number | Accessory type for Home app: `0` - None/Disabled, `1` - Switch, `2` - Outlet, `3` - Lightbulb |
123 | | | `namePrefix` | boolean | Use accessory name for prefix |
124 | | `powerProductionSummary` | | number | `Power Summary`, in `W`, of all microinverters. This will be used to calculate the display power level in the Home app `0-100 %` |
125 | | `powerProductionLevelSensors` | | key | `Power Level Sensor` for production monitoring |
126 | | | `name` | string | Accessory name for Home app |
127 | | | `compareMode` | string | Comparison mode: `<`, `<=`, `==`, `>`, `>=`, `!=` |
128 | | | `powerLevel` | number | Power production level in `W` to compare to sensor that was triggered |
129 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
130 | | | `namePrefix` | boolean | Use accessory name for prefix |
131 | | `energyProductionLifetimeOffset` | | number | `Energy Offset` in `Wh` for production (if needed) `+/-` |
132 | | `energyProductionLevelSensors` | | key | `Energy Level Sensor` for production monitoring |
133 | | | `name` | string | Accessory name for Home app |
134 | | | `compareMode` | string | Comparison mode: `<`, `<=`, `==`, `>`, `>=`, `!=` |
135 | | | `energyLevel` | number | Energy production level in `Wh` to compare to sensor that was triggered |
136 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
137 | | | `namePrefix` | boolean | Use accessory name for prefix |
138 | | `gridProductionQualitySensors` | | key | `Power Level Sensor` for production monitoring |
139 | | | `name` | string | Accessory name for Home app |
140 | | | `compareMode` | string | Comparison mode: `<`, `<=`, `==`, `>`, `>=`, `!=` |
141 | | | `compareType` | string | Comparison type: `Current`, `Voltage`, `Frequency`, `Power Factor` |
142 | | | `compareLevel` | number | Level to compare to sensor that was triggered |
143 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
144 | | | `namePrefix` | boolean | Use accessory name for prefix |
145 | | `powerConsumptionTotalLevelSensors` | | key | `Power Level Sensor` for total consumption monitoring |
146 | | | `name` | string | Accessory name for Home app |
147 | | | `compareMode` | string | Comparison mode `<`, `<=`, `==`, `>`, `>=`, `!=` |
148 | | | `powerLevel` | number | Total power consumption level in `W` to compare to power level sensor that was triggered |
149 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
150 | | | `namePrefix` | boolean | Use accessory name for prefix |
151 | | `energyConsumptionTotalLifetimeOffset` | | number | `Energy Offset` in `Wh` for total consumption (if needed) `+/-` |
152 | | `energyConsumptionTotalLevelSensors` | | key | `Energy Level Sensor` for total consumption monitoring |
153 | | | `name` | string | Accessory name for Home app |
154 | | | `compareMode` | string | Comparison mode `<`, `<=`, `==`, `>`, `>=`, `!=` |
155 | | | `energyLevel` | number | Energy level total in `Wh` to compare to sensor that was triggered |
156 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
157 | | | `namePrefix` | boolean | Use accessory name for prefix |
158 | | `gridConsumptionTotalQualitySensors` | | key | `Power Level Sensor` for production monitoring |
159 | | | `name` | string | Accessory name for Home app |
160 | | | `compareMode` | string | Comparison mode: `<`, `<=`, `==`, `>`, `>=`, `!=` |
161 | | | `compareType` | string | Comparison type: `Current`, `Voltage`, `Frequency`, `Power Factor` |
162 | | | `compareLevel` | number | Level to compare to sensor that was triggered |
163 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
164 | | | `namePrefix` | boolean | Use accessory name for prefix |
165 | | `powerConsumptionNetLevelSensors` | | key | `Power Level Sensor` for net power consumption level monitoring |
166 | | | `name` | string | Accessory name for Home app |
167 | | | `compareMode` | string | Comparison mode `<`, `<=`, `==`, `>`, `>=`, `!=` |
168 | | | `powerLevel` | number | Net power consumption power level in `W` to compare for the sensor that was triggered |
169 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
170 | | | `namePrefix` | boolean | Use accessory name for prefix |
171 | | `energyConsumptionNetLifetimeOffset` | | number | `Energy Offset` in `Wh` for consumption `Net` (if needed) `+/-` |
172 | | `energyConsumptionNetLevelSensors` | | key | `Energy Level Sensor` for net consumption monitoring |
173 | | | `name` | string | Accessory name for Home app |
174 | | | `compareMode` | string | Comparison mode `<`, `<=`, `==`, `>`, `>=`, `!=` |
175 | | | `energyLevel` | number | Net energy comsumption level in `Wh` to compare to sensor that was triggered |
176 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
177 | | | `namePrefix` | boolean | Use accessory name for prefix |
178 | | `gridConsumptionNetQualitySensors` | | key | `Power Level Sensor` for production monitoring |
179 | | | `name` | string | Accessory name for Home app |
180 | | | `compareMode` | string | Comparison mode: `<`, `<=`, `==`, `>`, `>=`, `!=` |
181 | | | `compareType` | string | Comparison type: `Current`, `Voltage`, `Frequency`, `Power Factor` |
182 | | | `compareLevel` | number | Level to compare to sensor that was triggered |
183 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
184 | | | `namePrefix` | boolean | Use accessory name for prefix |
185 | | `qRelayStateSensor` | | key | `Q-Relay State Sensor` for monitoring. If `State ON`, the contact was opened. |
186 | | | `name` | string | Accessory name for Home app |
187 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
188 | | | `namePrefix` | boolean | Use accessory name for prefix |
189 | | | `multiphase` | boolean | Enables multiphase support, if present |
190 | | `acBatterieName` | | string | AC Bettery Accessory name for Home app, if not set will use default name |
191 | | `acBatterieBackupLevelSummaryAccessory` | | key | `AC Batteries Backup Level Summary Accessory` in Home app, if present |
192 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Light Bulb, `2` - Fan, `3` - Humidity Sensor, `4` - Carbon Monoxide Sensor, `5` - Battery |
193 | | | `minSoc` | boolean | Minimum SoC level in (%) for ac batteries backup level summary |
194 | | `acBatterieBackupLevelAccessory` | | key | `AC Battery Backup Level Accessory` in Home app, if present |
195 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Light Bulb, `2` - Fan, `3` - Humidity Sensor, `4` - Carbon Monoxide Sensor, `5` - Battery |
196 | | | `minSoc` | boolean | Minimum SoC level in (%) for ac battery backup level |
197 | | `enpowerGridStateControl` | | key | `Enpower Grid State Control` for `Grid ON/OFF` control from HomeKit |
198 | | | `name` | string | Accessory name for Home app |
199 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Switch, `2` - Outlet, `3` - Lightbulb |
200 | | | `namePrefix` | boolean | Use accessory name for prefix |
201 | | `enepowerGridStateSensor` | | key | `Enpower Grid State Sensor` for monitoring. If `Grid ON`, the contact was opened. |
202 | | | `name` | string | Accessory name for Home app |
203 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
204 | | | `namePrefix` | boolean | Use accessory name for prefix |
205 | | `enpowerGridModeSensors` | | key | `Enpower Grid Mode Sensors` for monitoring. If the `Mode` matches, the contact was opened. |
206 | | | `name` | string | Accessory name for Home app |
207 | | | `gridMode` | string | Grid mode: `Grid On`, `Grid Off`, `Multimode Grid On`, `Multimode Grid Off`, `Grid Tied`, `Grid Forming` |
208 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
209 | | | `namePrefix` | boolean | Use accessory name for prefix |
210 | | `enchargeName` | | string | Encharge Accessory name for Home app, if not set will use default name |
211 | | `enchargeBackupLevelSummaryAccessory` | | key | `Encharge Backup Level Summary Accessory` in Home app, if present |
212 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Light Bulb, `2` - Fan, `3` - Humidity Sensor, `4` - Carbon Monoxide Sensor, `5` - Battery |
213 | | | `minSoc` | boolean | Minimum SoC level in (%) for encharges backup level summary |
214 | | `enchargeBackupLevelAccessory` | | key | `Encharge Backup Level Accessory` in Home app, if present |
215 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, , `1` - Battery |
216 | | | `minSoc` | boolean | Minimum SoC level in (%) for encharges backup level summary |
217 | | `enchargeStateSensor` | | key | `Encharge State Sensor` for monitoring. If `State ON`, the contact was opened. |
218 | | | `name` | string | Accessory name for Home app |
219 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
220 | | | `namePrefix` | boolean | Use accessory name for prefix |
221 | | `enchargeProfileControls` | | key | `Encharge Profile Controls` for `Profile` control from HomeKit |
222 | | | `name` | string | Accessory name for Home app |
223 | | | `profile` | string | Profile: `Savings`, `Economy`, `Full Backup`, `Self Consumption` |
224 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Lightbulb |
225 | | | `chargeFromGrid` | boolean | Allow charge from grid |
226 | | | `namePrefix` | boolean | Use accessory name for prefix |
227 | | `enchargeProfileSensors` | | key | `Encharge Profile Sensors` for monitoring. If the `Profile` matches, the contact was opened. |
228 | | | `name` | string | Accessory name for Home app |
229 | | | `profile` | string | Profile: `Savings`, `Economy`, `Full Backup`, `Self Consumption` |
230 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
231 | | | `namePrefix` | boolean | Use accessory name for prefix |
232 | | `enechargeGridStateSensor` | | key | `Encharge Grid State Sensor` for monitoring. If `Grid ON`, the contact was opened. |
233 | | | `name` | string | Accessory name for Home app |
234 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
235 | | | `namePrefix` | boolean | Use accessory name for prefix |
236 | | `enchargeGridModeSensors` | | key | `Encharge Grid Mode Sensors` for monitoring. If the `Mode` matches, the contact was opened. |
237 | | | `name` | string | Accessory name for Home app |
238 | | | `gridMode` | string | Grid mode: `Multimode Grid On`, `Multimode Grid Off` |
239 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
240 | | | `namePrefix` | boolean | Use accessory name for prefix |
241 | | `enchargeBackupLevelSensors` | | key | `Encharge Backup Level Sensors` for monitoring. If the `Level` matches, the contact was opened. |
242 | | | `name` | string | Accessory name for Home app |
243 | | | `compareMode` | string | Comparison mode: `<`, `<=`, `==`, `>`, `>=` |
244 | | | `backupLevel` | number | Backup level in `%` to compare to sensor that was triggered |
245 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
246 | | | `namePrefix` | boolean | Use accessory name for prefix |
247 | | `solarGridStateSensor` | | key | `Solar Grid State Sensor` for monitoring. If `Grid ON`, the contact was opened. |
248 | | | `name` | string | Accessory name for Home app |
249 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
250 | | | `namePrefix` | boolean | Use accessory name for prefix |
251 | | `solarGridModeSensors` | | key | `Solar Grid Mode Sensors` for monitoring. If the `Mode` matches, the contact was opened. |
252 | | | `name` | string | Accessory name for Home app |
253 | | | `gridMode` | string | Grid mode: `Grid On`, `Grid Off`, `Multimode Grid On`, `Multimode Grid Off`, `Grid Tied`, `Grid Forming` |
254 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
255 | | | `namePrefix` | boolean | Use accessory name for prefix |
256 | | `enpowerDryContactsControl` | | boolean | Enables `Dry Contacts` control and exposes `Switches` in Home app |
257 | | `enpowerDryContactsSensor` | | boolean | Enables `Dry Contacts` monitoring and exposes `Sensors` in Home app |
258 | | `generatorStateControl` | | key | `Generator State Control` for `Generator OFF/ON` control in Home app |
259 | | | `name` | string | Accessory name for Home app |
260 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Switch, `2` - Outlet, `3` - Lightbulb |
261 | | | `namePrefix` | boolean | Use accessory name for prefix |
262 | | `generatorStateSensor` | | key | `Generator State Sensor` for `State` monitoring. If `State not Off`, the contact was opened. |
263 | | | `name` | string | Accessory name for Home app |
264 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
265 | | | `namePrefix` | boolean | Use accessory name for prefix |
266 | | `generatorModeContol` | | key | `Generator Mode Control`, for `Generator OFF/ON/AUTO` control in Home app |
267 | | | `name` | string | Accessory name for Home app |
268 | | | `mode` | string | Grid mode: `Off`, `On`, `Auto` |
269 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Switch, `2` - Outlet, `3` - Lightbulb |
270 | | `generatorModeSensors` | | key | `Generator Mode Sensors` for monitoring, if the `Mode` matches, the contact was opened. |
271 | | | `name` | string | Accessory name for Home app |
272 | | | `mode` | string | Grid mode: `Off`, `On`, `Auto` |
273 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
274 | | | `namePrefix` | boolean | Use accessory name for prefix |
275 | | `acBatterieBackupLevelAccessory` | | key | `AC Battery Backup Level Accessory` in Home app, if present |
276 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, , `1` - Battery |
277 | | | `minSoc` | boolean | Minimum SoC level in (%) for ac battery backup level summary |
278 | | `dataRefreshControl` | | key | `Data Refresh Control` from HomeKit. |
279 | | | `name` | string | Accessory name for Home app |
280 | | | `displayType` | number | Here select the tile type to be displayed in Home app: `0` - None/Disabled, `1` - Switch, `2` - Outlet, `3` - Lightbulb |
281 | | | `namePrefix` | boolean | Use accessory name for prefix |
282 | | `dataRefreshSensor` | | key | `Data Refresh Sensor` for monitoring. If operating, the contact was opened. |
283 | | | `name` | string | Accessory name for Home app |
284 | | | `displayType` | number | Accessory type to be displayed in Home app: `0` - None/Disabled, `1` - Motion Sensor, `2` - Occupancy Sensor, `3` - Contact Sensor |
285 | | | `namePrefix` | boolean | Use accessory name for prefix |
286 | | `productionDataRefreshTime` | | number | `Production Data` refresh time (seconds) |
287 | | `liveDataRefreshTime` | | number | `Live Data` refresh time (seconds) |
288 | | `ensembleDataRefreshTime` | | number | `Ensemble Data` refresh time (seconds) |
289 | | `log` | | key | `Log` from HomeKit. |
290 | | | `deviceInfo` | boolean | If enabled, log device info will be displayed by every connections device to the network. |
291 | | | `success` | boolean | If enabled, success log will be displayed in console. |
292 | | | `info` | boolean | If enabled, info log will be displayed in console. |
293 | | | `warn` | boolean | If enabled, warn log will be displayed in console. |
294 | | | `error` | boolean | If enabled, error log will be displayed in console. |
295 | | | `debug` | boolean | If enabled, debug log will be displayed in console. |
296 | | `restFul` | | key | REST service |
297 | | | `enable` | boolean | Enables REST service to start automatically and respond to any request |
298 | | | `port` | number | `Port` for REST service |
299 | | `mqtt` | | key | MQTT broker |
300 | | | `enable` | boolean | Enables MQTT broker to start automatically and publish available data |
301 | | | `host` | string | `IP Address` or `Hostname` for MQTT Broker |
302 | | | `port` | number | `Port` for MQTT broker (default to 1883) |
303 | | | `clientId` | string | `Client Id` of MQTT broker (optional) |
304 | | | `prefix` | string | `Prefix` for `Topic` (optional) |
305 | | | `auth` | boolean | Enables MQTT broker authorization credentials |
306 | | | `user` | string | MQTT broker user |
307 | | | `passwd` | string | MQTT Broker password |
308 |
309 | ### REST Integration
310 |
311 | REST POST calls must include a content-type header of `application/json`.
312 | Path `status` response all available paths.
313 |
314 | | Method | URL | Path | Response | Type |
315 | | --- | --- | --- | --- | --- |
316 | | GET | `http//ip:port` | `token`, `info`, `home`, `homedata`, `inventory`, `microinvertersstatus`, `meters`, `metersreading`, `metersreports`, `detaileddevicesdata`, `microinvertersdata`, `qrelaysdata`, `metersdata`, `production`, `productionpdm`, `energypdm`, `productionct`,`powerandenergydata`, `acbatterydata`, `ensembleinventory`, `ensemblestatus`, `ensemblepower`, `enchargesettings`, `tariff`, `drycontacts`, `drycontactssettings`, `generator`, `generatorsettings`, `ensembledata`, `gridprofile`, `livedata`, `livedatadata`, `productionstate`, `plclevel`, `datasampling`. | `{wNow: 2353}` | JSON |
317 |
318 | | Method | URL | Key | Value | Type | Description |
319 | | --- | --- | --- | --- | --- | --- |
320 | | POST | `http//ip:port` | `DataSampling` | `true`, `false` | boolean | Data sampling Start/Stop |
321 | | | `http//ip:port` | `PowerProductionState` | `true`, `false` | boolean | Production state On/Off |
322 | | | `http//ip:port` | `PlcLevel` | `true` | boolean | Check Plc Level On |
323 | | | `http//ip:port` | `EnchargeProfile` | `self-consumption`, `savings-mode`, `economy`, `backup` | string | Set encharge profile |
324 | | | `http//ip:port` | `EnchargeReservedSoc` | `0-100` | number | Set encharge reserve SoC 0-100% |
325 | | | `http//ip:port` | `EnchargeChargeFromGrid` | `true`, `false` | boolean | Set encharge charge from grid On/Off |
326 | | | `http//ip:port` | `EnpowerGridState` | `true`, `false` | boolean | Grid state On/Off |
327 | | | `http//ip:port` | `GeneratorMode` | `off`, `on`, `auto` | string | Generator mode Off/On/Auto |
328 |
329 | ### MQTT Integration
330 |
331 | Subscribe using JSON `{ "EnchargeProfile": "savings" }`
332 |
333 | | Method | Topic | Message | Type |
334 | | --- | --- | --- | --- |
335 | | Publish | `Token`, `Info`, `Home`, `Home Data`, `Inventory`, `Microinverters Status`, `Meters`, `Meters Reading`, `Meters Reports`, `Detailed Devices Data`, `Microinverters Data`, `Q-Relays Data`, `Meters Data`, `Production`, `Production Pdm`, `Energy Pdm`, `Production CT`, `Power And Energy Data`, `AC Battery Data`, `Ensemble Inventory`, `Ensemble Status`, `Ensemble Status`, `Encharge Power`, `Tariff`, `Dry Contacts`, `Dry Contacts Settings`, `Generator`, `Generator Settings`, `Ensemble Data`, `Grid Profile`, `Live Data`, `Live Data Data`, `Production State`, `PLC Level`, `Data Sampling` | `{wNow: 2353}` | JSON |
336 |
337 | | Method | Topic | Key | Value | Type | Description |
338 | | --- | --- | --- | --- | --- | --- |
339 | | Subscribe | `Set` | `DataSampling` | `true`, `false` | boolean | Data sampling Start/Stop |
340 | | | `Set` | `ProductionState` | `true`, `false` | boolean | Production state On/Off |
341 | | | `Set` | `PlcLevel` | `true` | boolean | Check Plc Level On |
342 | | | `Set` | `EnchargeProfile` | `self-consumption`, `savings-mode`, `economy`, `backup` | string | Set encharge profile |
343 | | | `Set` | `EnchargeReservedSoc` | `0-100` | number | Set encharge reserve SoC 0-100% |
344 | | | `Set` | `EnchargeChargeFromGrid` | `true`, `false` | boolean | Set encharge charge from grid On/Off |
345 | | | `Set` | `EnpowerGridState` | `true`, `false` | boolean | Grid state On/Off |
346 | | | `Set` | `GeneratorMode` | `off`, `on`, `auto` | string | Generator mode Off/On/Auto |
347 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## Note
9 |
10 | - after update to v10.0.0 and above the accessory and bridge need to be removed from the homebridge / Home.app and added again
11 |
12 | ## [10.3.8] - (17.12.2025)
13 |
14 | ## Changes
15 |
16 | - fix [#222](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/222)
17 | - bump dependencies
18 |
19 | ## [10.3.7] - (09.12.2025)
20 |
21 | ## Changes
22 |
23 | - moved MQTT to v5
24 | - cleanup
25 |
26 | ## [10.3.5] - (13.11.2025)
27 |
28 | ## Changes
29 |
30 | - added encharges support connected to all phases
31 | - cleanup
32 |
33 | ## [10.3.4] - (12.11.2025)
34 |
35 | ## Changes
36 |
37 | - fix [#221](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/221)
38 | - bump dependencies
39 | - cleanup
40 |
41 | ## [10.3.2] - (30.10.2025)
42 |
43 | ## Changes
44 |
45 | - fix [#220](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/220)
46 |
47 | ## [10.3.1] - (29.10.2025)
48 |
49 | ## Changes
50 |
51 | - bump dependencies
52 | - redme updated
53 | - cleanup
54 |
55 | ## [10.3.0] - (20.10.2025)
56 |
57 | ## Changes
58 |
59 | - extend Eve Energy Meter to support (Production, Consumption Net, Consumption Total)
60 | - fix [#218](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/218)
61 | - stability and performance improvements
62 | - config schema updated
63 | - readme updated
64 | - cleanup
65 |
66 | ## [10.2.6] - (18.10.2025)
67 |
68 | ## Changes
69 |
70 | - fix [#216](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/216)
71 | - fix [#217](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/217)
72 | - fix wireless connections kit publish
73 | - added network interface service and characteristics
74 | - cleanup
75 |
76 | ## [10.2.5] - (17.10.2025)
77 |
78 | ## Changes
79 |
80 | - update EVE Energy Meter
81 | - cleanup
82 |
83 | ## [10.2.3] - (15.10.2025)
84 |
85 | ## Changes
86 |
87 | - fix [#215](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/215)
88 | - update EVE Energy Meter
89 | - other small fixes
90 | - cleanup
91 |
92 | ## [10.2.2] - (12.10.2025)
93 |
94 | ## Changes
95 |
96 | - fix power level not refresh if meter production not enabled [#213](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/213)
97 | - fix enable live data stream [#214](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/214)
98 | - changed OFF state to < 0.5% for power and backup level accessory, before was OFF if level < 1%
99 | - stability and performance improvements
100 | - other small fixes
101 | - redme updates
102 | - cleanup
103 |
104 | ## [10.2.1] - (03.10.2025)
105 |
106 | ## Changes
107 |
108 | - fix power level not refresh if meter production not enabled [#213](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/213)
109 |
110 | ## [10.2.0] - (03.10.2025)
111 |
112 | ## Changes
113 |
114 | - fix encharge profile control UI interface
115 | - fix [#205](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/205)
116 | - fix [#206](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/206)
117 | - fix [#207](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/207)
118 | - fix [#209](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/209)
119 | - fix [#211](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/211)
120 | - workaround for [#210](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/210), envoy firmware issue
121 | - prepare to add encharge profile controls option to allow charge from grid
122 | - added configurable system auto lock time
123 | - added EVE energy monitor option (need to be paired as a separate accessory)
124 | - added support for EVSE, PV3P, BackFeed meters
125 | - added support for C6 Combiner Controller, C6 RGM, IQ Meter Collar
126 | - refactor code of ensemble section
127 | - stability and improvements
128 | - config UI updated
129 | - bump dependencies
130 | - redme updated
131 | - cleanup
132 |
133 | ## [10.1.0] - (01.07.2025)
134 |
135 | ## Changes
136 |
137 | - fix update plc level for microinverters
138 | - added lockcontrol system for envoy section
139 |
140 | ## [10.0.3] - (29.06.2025)
141 |
142 | ## Changes
143 |
144 | - fix scale plc level to 100%
145 |
146 | ## [10.0.2] - (29.06.2025)
147 |
148 | ## Changes
149 |
150 | - fix generator mode
151 | - changed RESTFul path `powermode` to `productionstate`
152 | - changed MQTT set key `PowerProductionState` to `ProductionState`
153 | - stability and performance improvements
154 | - redme updated
155 | - cleanup
156 |
157 | ## [10.0.1] - (25.06.2025)
158 |
159 | ## Changes
160 |
161 | - fix RESTFul `detaileddevicesdata` and `token` paths
162 | - fix Mqtt `token` refresh
163 | - redme updated
164 |
165 | ## [10.0.0] - (24.06.2025)
166 |
167 | ## Changes
168 |
169 | - full code refactor
170 | - stability and performance improvements
171 | - added many detailed data for microinverters, meters, qrelays
172 | - RESTFul code refactor and updated
173 | - cleanup custom characteristics
174 | - cleanup
175 | - readme updated
176 | - many more small changes
177 |
178 | ## [9.20.1] - (15.06.2025)
179 |
180 | ## Changes
181 |
182 | - fix [#202](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/202)
183 | - cleanup
184 |
185 | ## [9.20.0] - (14.06.2025)
186 |
187 | ## Changes
188 |
189 | - stability and performance improvements
190 | - added devicesdata, metersRportsto to the RESTFul rquests
191 | - added Energy and Productin Consumption Total service if present
192 | - added energyLifetimeUpload characteristic for Production(mean self consumption) and Consumption Net(mean upload to the grid)
193 | - added node.js 24 support
194 | - bump dependencies
195 | - redme updated
196 | - cleanup
197 |
198 | ## [9.19.0] - (04.06.2025)
199 |
200 | ## Changes
201 |
202 | - added microinverters additional data (voltage, frequency, temperature, energy today, yesterday, last seven days, lifetime)
203 | - redme updated
204 | - cleanup
205 |
206 | ## [9.18.0] - (30.05.2025)
207 |
208 | ## Changes
209 |
210 | - removed extra production control accessory
211 | - added production control in the main lightbulb accessory
212 | - added control lock accessory to prevent device control accidentially
213 | - device control possible after unlock
214 | - locked automatically 30sec after unlock
215 | - config UI updated
216 | - redme updated
217 | - cleanup
218 |
219 | ## [9.17.7] - (28.05.2025)
220 |
221 | ## Changes
222 |
223 | - stability and performance improvements
224 | - cleanup
225 |
226 | ## [9.17.5] - (27.05.2025)
227 |
228 | ## Changes
229 |
230 | - prevent update meters characteristics if value are not valid
231 |
232 | ## [9.17.4] - (27.05.2025)
233 |
234 | ## Changes
235 |
236 | - fix voltage divide
237 | - cleanup
238 |
239 | ## [9.17.3] - (27.05.2025)
240 |
241 | ## Changes
242 |
243 | - fix power peak update characteristics
244 | - cleanup
245 |
246 | ## [9.17.2] - (26.05.2025)
247 |
248 | ## Changes
249 |
250 | - cleanup
251 |
252 | ## [9.17.1] - (26.05.2025)
253 |
254 | ## Changes
255 |
256 | - fix [#199](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/199)
257 |
258 | ## [9.17.0] - (26.05.2025)
259 |
260 | ## Changes
261 |
262 | - removed duplicated power and energy state sensors, the state sensor can be create by level sensors > 0
263 | - removed meters refresh time
264 | - fix consumption power peak detected
265 | - refactor production all code
266 | - refsctor charcteristics update
267 | - added conparator (!==) to sensors
268 | - config UI improvements
269 | - mqtt clientId and prefix updated
270 | - redme update
271 | - cleanup
272 |
273 | ## [9.16.0] - (21.05.2025)
274 |
275 | ## Changes
276 |
277 | - added grid quality sensors for(Current, Voltage, Frequency, Power Factor) if meters are installed
278 | - fix qRelay state update
279 | - redme update
280 | - cleanup
281 |
282 | ## [9.15.0] - (18.05.2025)
283 |
284 | ## Changes
285 |
286 | - fix [#198](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/198)
287 | - refactor code of production and consumption data update (support fw. >= 8.2.4xx)
288 | - bump dependencies
289 | - redme update
290 | - cleanup
291 |
292 | ## [9.14.6] - (12.05.2025)
293 |
294 | ## Changes
295 |
296 | - fix [#197](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/197)
297 | - bump dependencies
298 |
299 | ## [9.14.4] - (09.05.2025)
300 |
301 | ## Changes
302 |
303 | - fix read meters reading with envoy firmware 8.3.xx
304 | - better handle some errors/warn
305 | - bump dependencies
306 | - cleanup
307 |
308 | ## [9.14.3] - (20.04.2025)
309 |
310 | ## Changes
311 |
312 | - fix [#195](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/195)
313 | - fix [#196](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/196)
314 | - cleanup
315 |
316 | ## [9.14.2] - (20.04.2025)
317 |
318 | ## Changes
319 |
320 | - many cleanup and optimizations
321 | - cleanup
322 |
323 | ## [9.14.1] - (18.04.2025)
324 |
325 | ## Changes
326 |
327 | - fix namePrefix and call production state even not supported
328 |
329 | ## [9.14.0] - (18.04.2025)
330 |
331 | ## Changes
332 |
333 | - added multiphase support for q-relay sensor
334 | - digestauth refactor
335 | - passwdcalc refactor
336 | - envoytoken refactor
337 | - redme update
338 | - cleanup
339 |
340 | ## [9.13.4] - (18.04.2025)
341 |
342 | ## Changes
343 |
344 | - fix power peak level display and detected in consumption total and net
345 | - cleanup
346 |
347 | ## [9.13.3] - (18.04.2025)
348 |
349 | ## Changes
350 |
351 | - fix reference error in debug mode
352 | - cleanup
353 |
354 | ## [9.13.2] - (17.04.2025)
355 |
356 | ## Changes
357 |
358 | - fix microinverters publish in v9.13.0 and v9.13.1
359 | - refresh grid profile and update status in runtime
360 | - display in envoy db size and percent full of db only if supported
361 | - display update status in envoy only if supported
362 | - stability and performance optimizations
363 | - cleanup
364 |
365 | ## [9.13.1] - (16.04.2025)
366 |
367 | ## Changes
368 |
369 | - RESTFul and MQTT update
370 | - stability and performance optimizations
371 | - redme update
372 | - cleanup
373 |
374 | ## [9.13.0] - (15.04.2025)
375 |
376 | ## Changes
377 |
378 | - added pdm energy and production data to RESTFul and MQTT for Envoy FW >= 8.2.4xx
379 | - removed production all from RESTFul and MQTT
380 | - redme update
381 | - cleanup
382 |
383 | ## [9.12.6] - (08.04.2025)
384 |
385 | ## Changes
386 |
387 | - fix stop data sampling if error occured durig cookie refresh
388 | - fix set correct accessory category
389 | - added production state data refresh timer
390 | - config UI improvements in section Envoy
391 | - config schema updated
392 | - redme update
393 | - cleanup
394 |
395 | ## [9.12.0] - (05.04.2025)
396 |
397 | ## Changes
398 |
399 | - after update the plc level refresh control need to be configued again
400 | - after update the production state control and sensor need to be configued again
401 | - added production state sensor
402 | - config UI improvements in section Envoy
403 | - config schema updated
404 | - bump dependencies
405 | - redme update
406 | - cleanup
407 |
408 | ## [9.11.0] - (03.04.2025)
409 |
410 | ## Changes
411 |
412 | - after update the credentials method need to be configued again
413 | - after update the dry contact sensor and control need to be configued again
414 | - config UI improvements
415 | - config schema updated
416 | - bump dependencies
417 | - redme update
418 | - cleanup
419 |
420 | ## [9.10.9] - (30.03.2025)
421 |
422 | ## Changes
423 |
424 | - fix energyConsumptionNetStateSensor UI
425 | - config schema updated
426 |
427 | ## [9.10.8] - (28.03.2025)
428 |
429 | ## Changes
430 |
431 | - stability and performance improvements
432 | - config schema updated
433 | - cleanup
434 |
435 | ## [9.10.7] - (26.03.2025)
436 |
437 | ## Changes
438 |
439 | - fix [#192](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/192)
440 |
441 | ## [9.10.6] - (26.03.2025)
442 |
443 | ## Changes
444 |
445 | - fix Q-Relay state monitoring sensor
446 |
447 | ## [9.10.5] - (25.03.2025)
448 |
449 | ## Changes
450 |
451 | - added Q-Relay state monitoring sensor
452 | - stability and performance improvements
453 | - config schema updated
454 | - redme updated
455 | - cleanup
456 |
457 | ## [9.10.0] - (23.03.2025)
458 |
459 | ## Changes
460 |
461 | - added possibility to select accessory type for Envoy
462 | - added possibility to select accessory type for AC Battery, indyvidual and summary
463 | - added possibility to select accessory type for Encharge, indyvidual and summary
464 | - added possibility to set min SoC for light bulb Encharge accessory [#191](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/191)
465 | - stability and performance improvements
466 | - config schema updated
467 | - redme updated
468 | - cleanup
469 |
470 | ## [9.9.10] - (21.03.2025)
471 |
472 | ## Changes
473 |
474 | - fix [#190](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/190)
475 | - cleanup
476 |
477 | ## [9.9.9] - (21.03.2025)
478 |
479 | ## Changes
480 |
481 | - fix [#189](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/189)
482 | - cleanup
483 |
484 | ## [9.9.8] - (20.03.2025)
485 |
486 | ## Changes
487 |
488 | - config UI improvements from [#185](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/185)
489 | - config schema updated
490 |
491 | ## [9.9.7] - (20.03.2025)
492 |
493 | ## Changes
494 |
495 | - added possibility to set custom encharge name displayed in the home app, closes [#188](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/188)
496 | - added possibility to disable/display encharge light bulb accessory in the home app
497 | - bump dependencies
498 | - config schema updated
499 | - redme updated
500 | - cleanup
501 |
502 | ## [9.9.4] - (19.03.2025)
503 |
504 | ## Changes
505 |
506 | - fix backup level sensor update [#186](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/186)
507 | - config UI improvements [#185](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/185)
508 | - config schema updated
509 | - cleanup
510 |
511 | ## [9.9.3] - (18.03.2025)
512 |
513 | ## Changes
514 |
515 | - added default values to fix [#183](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/183)
516 | - cleanup
517 |
518 | ## [9.9.2] - (15.03.2025)
519 |
520 | ## Changes
521 |
522 | - fix [#182](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/182)
523 | - cleanup
524 |
525 | ## [9.9.1] - (15.03.2025)
526 |
527 | ## Changes
528 |
529 | - fix [#181](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/181)
530 | - cleanup
531 |
532 | ## [9.9.0] - (14.03.2025)
533 |
534 | ## Changes
535 |
536 | - added possibility to disable indyvidual accessory
537 | - added read production all (pcm, rgm, eim) and consumption (eim)
538 | - fix debug log
539 | - bump dependencies
540 | - config schema updated
541 | - redme updated
542 | - cleanup
543 |
544 | ## [9.8.7] - (04.03.2025)
545 |
546 | ## Changes
547 |
548 | - token handling improvements
549 | - digest installer and envoy handling improvements
550 | - error handling improvements
551 | - cleanup
552 |
553 | ## [9.8.6] - (02.03.2025)
554 |
555 | ## Changes
556 |
557 | - token and cookie handling improvements
558 | - impulse generator corect start state
559 | - cleanup
560 |
561 | ## [9.8.5] - (28.02.2025)
562 |
563 | ## Changes
564 |
565 | - token and digest authorization handling improvements
566 | - bump dependencies
567 | - cleanup
568 |
569 | ## [9.8.4] - (27.02.2025)
570 |
571 | ## Changes
572 |
573 | - token handling improvements
574 | - plugin start time improvements
575 | - cleanup
576 |
577 | ## [9.8.3] - (26.02.2025)
578 |
579 | ## Changes
580 |
581 | - bump dependencies
582 |
583 | ## [9.8.2] - (26.02.2025)
584 |
585 | ## Changes
586 |
587 | - refactor start external integrations
588 | - bump dependencies
589 | - cleanup
590 |
591 | ## [9.8.0] - (20.02.2025)
592 |
593 | ## Changes
594 |
595 | - fix enpower grid state error
596 | - added encharge grid state sensor
597 | - added solar grid state sensor
598 | - bump dependencies
599 | - cleanup
600 |
601 | ## [9.7.6] - (18.02.2025)
602 |
603 | ## Changes
604 |
605 | - stability and improvements
606 | - chore(config): tweak wording, thanks @nstuyvesant
607 | - Updates to the read me (spelling, punctuation, clarification), thanks @nstuyvesant
608 | - bump dependencies
609 | - cleanup
610 |
611 | ## [9.7.5] - (15.02.2025)
612 |
613 | ## Changes
614 |
615 | - moved custom characteristics and services to seperate file
616 | - added new opt_cheduless properties to storage setting
617 | - stability and improvements
618 | - cleanup
619 |
620 | ## [9.7.4] - (07.02.2025)
621 |
622 | ## Changes
623 |
624 | - stability and improvements
625 |
626 | ## [9.7.3] - (04.02.2025)
627 |
628 | ## Changes
629 |
630 | - update RESTFul
631 |
632 | ## [9.7.0] - (16.01.2025)
633 |
634 | ## Changes
635 |
636 | - added possibility to disable/enable log success, info, warn, error
637 | - config schema updated
638 | - redme updated
639 | - cleanup
640 |
641 | ## [9.6.12] - (03.01.2025)
642 |
643 | ## Changes
644 |
645 | - limit microinverters count to 70 due [#175](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/175)
646 | - fix powerLevel characteristics warning
647 | - fix display only active phase in live data
648 |
649 | ## [9.6.10] - (18.12.2024)
650 |
651 | ## Changes
652 |
653 | - update encharges led status
654 | - fix apparent power in live data
655 | - cleanup
656 |
657 | ## [9.6.9] - (17.12.2024)
658 |
659 | ## Changes
660 |
661 | - fix livedData characteristics warning [#173](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/173)
662 | - cleanup
663 |
664 | ## [9.6.8] - (16.12.2024)
665 |
666 | ## Changes
667 |
668 | - increase data refresh time issue [#172](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/172)
669 | - bump dependencies
670 | - cleanup
671 |
672 | ## [9.6.6] - (06.12.2024)
673 |
674 | ## Changes
675 |
676 | - better handle of error and cookies
677 | - bump dependencies
678 | - config.schema updated
679 | - cleanup
680 |
681 | ## [9.6.5] - (03.12.2024)
682 |
683 | ## Changes
684 |
685 | - check JWT toke is installer or user
686 | - add JWT Token installer option if use own generated token
687 | - config.schema updated
688 | - redme updated
689 | - cleanup
690 |
691 | ## [9.6.4] - (02.12.2024)
692 |
693 | ## Changes
694 |
695 | - prevent crasch if PLC Level is enabled and credentials data is not installer
696 |
697 | ## [9.6.3] - (02.12.2024)
698 |
699 | ## Changes
700 |
701 | - prevent crasch if production control is enabled and credentials data is not installer
702 |
703 | ## [9.6.0] - (30.11.2024)
704 |
705 | ## Changes
706 |
707 | - move from commonJS to esm module
708 | - moved constants.json to constants.js
709 | - cleanup
710 |
711 | ## [9.5.3] - (28.11.2024)
712 |
713 | ## Changes
714 |
715 | - better handle cookie and own token
716 | - config schema updated
717 | - cleanup
718 |
719 | ## [9.5.2] - (28.11.2024)
720 |
721 | ## Changes
722 |
723 | - fix display duplicate credentials in UI
724 | - better handle cookie and token
725 | - bump dependencies
726 | - config schema updated
727 | - cleanup
728 |
729 | ## [9.5.1] - (20.11.2024)
730 |
731 | ## Changes
732 |
733 | - fix reference error before initialization
734 |
735 | ## [9.5.0] - (19.11.2024)
736 |
737 | ## Changes
738 |
739 | - added possibility to select compare mode for power and energy level sensors
740 | - config schema updated
741 | - readme updated
742 | - cleanup
743 |
744 | ## [9.4.4] - (18.11.2024)
745 |
746 | ## Changes
747 |
748 | - fix data refresh after error occured
749 | - fix validate own token
750 |
751 | ## [9.4.3] - (17.11.2024)
752 |
753 | ## Changes
754 |
755 | - fix [#163](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/163)
756 | - added node 23 support
757 | - jwt token get and check refactor
758 | - correct some logs wording
759 | - cleanup
760 |
761 | ## [9.4.2] - (11.11.2024)
762 |
763 | ## Changes
764 |
765 | - fix reconnect if error ocurred during start
766 | - correct some logs wording
767 | - config.schema updated
768 | - cleanup
769 |
770 | ## [9.4.1] - (30.10.2024)
771 |
772 | ## Changes
773 |
774 | - fix stop data updating after error occured [#161](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/161)
775 | - added config schema validation
776 | - update dependencies
777 | - config.schema updated
778 | - cleanup
779 |
780 | ## [9.4.0] - (17.09.2024)
781 |
782 | ## Changes
783 |
784 | - added encharge profile sensors
785 | - fix battery/encharge state and backup level delay
786 | - fix grid state sensor
787 | - move some message to warn
788 | - use async/await for impulse generator
789 | - update dependencies
790 | - cleanup
791 |
792 | ## [9.3.5] - (31.08.2024)
793 |
794 | ## Changes
795 |
796 | - required upcomming homebridge 2.x.x required
797 | - fix [#153](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/153)
798 | - error handle improvements
799 | - increase axios timeout to 25sec
800 | - cleanup
801 |
802 | ## [9.3.4] - (27.08.2024)
803 |
804 | ## Changes
805 |
806 | - fix restFul data sampling response
807 | - fix duplicate start run afer error occur
808 | - fix characteristic Rest Power warning
809 | - increase axios timeout to 20sec
810 | - cleanup
811 |
812 | ## [9.3.3] - (23.08.2024)
813 |
814 | ## Changes
815 |
816 | - fix [#151](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/151)
817 |
818 | ## [9.3.0] - (23.08.2024)
819 |
820 | ## Changes
821 |
822 | - add control over RESTFul POST JSON Object
823 | - fix RESRFul enable
824 | - add timeout to axios
825 | - return axios error message instead of object if exist
826 |
827 | ## [9.2.9] - (21.08.2024)
828 |
829 | ## Changes
830 |
831 | - fix energy level sensors
832 | - refactor backbone app code to get envoy dev id
833 | - refactor envoy password calculate code
834 | - refactor installer password calculate code
835 | - add some warn message and allow app working without some not mandatory data
836 |
837 | ## [9.2.8] - (20.08.2024)
838 |
839 | ## Changes
840 |
841 | - fix encharge live data display
842 | - fix data refresh control
843 | - fix backup level sensors
844 | - cleanup
845 |
846 | ## [9.2.6] - (19.08.2024)
847 |
848 | ## Changes
849 |
850 | - fix [#149](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/149)
851 |
852 | ## [9.2.5] - (19.08.2024)
853 |
854 | ## Changes
855 |
856 | - fix correct display error instead empty object
857 | - move some error to warn and prevent to reconnect to envoy
858 |
859 | ## [9.2.4] - (19.08.2024)
860 |
861 | ## Changes
862 |
863 | - fix [#150](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/150)
864 | - fix voltage divide
865 | - correct some error logs
866 | - cleanup
867 |
868 | ## [9.2.3] - (18.08.2024)
869 |
870 | ## Changes
871 |
872 | - use warn instead error for not required data
873 | - cleanup
874 |
875 | ## [9.2.2] - (18.08.2024)
876 |
877 | ## Changes
878 |
879 | - fix [#149](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/149)
880 | - loging refactor
881 | - corect catch error
882 | - cleanup
883 |
884 | ## [9.2.0] - (16.08.2024)
885 |
886 | ## Changes
887 |
888 | - add generator mode Off/On/Auto control from home app as a extra tiles
889 | - arf profile refactor
890 | - cleanup
891 |
892 | ## [9.1.3] - (16.08.2024)
893 |
894 | ## Changes
895 |
896 | - decrease homebridge requirements to 1.8.0
897 |
898 | ## [9.1.2] - (16.08.2024)
899 |
900 | ## Changes
901 |
902 | - dynamically display arf profile only if supported
903 |
904 | ## [9.1.1] - (16.08.2024)
905 |
906 | ## Changes
907 |
908 | - fix PLC Level warning [#148](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/148)
909 |
910 | ## [9.1.0] - (16.08.2024)
911 |
912 | ## Changes
913 |
914 | - added enchrge profile cintrol over mqtt
915 | - added enpower state control over mqtt
916 | - added generator mode control over mqtt
917 | - cleanup
918 |
919 | ## [9.0.2] - (14.08.2024)
920 |
921 | ## Changes
922 |
923 | - fix threw new error characteristics
924 |
925 | ## [9.0.1] - (14.08.2024)
926 |
927 | ## Changes
928 |
929 | - fix corect remove sensitive data from config mqtt
930 | - remove sensitive data from debug log
931 | - hide passwords, tokens, serial numbers, by typing and display in Config UI
932 | - remove return duplicate promises from whole code
933 |
934 | ## [9.0.0] - (14.08.2024)
935 |
936 | ## Changes
937 |
938 | ### After update to v9.0.0 RESTFull and MQTT config settings need to be updated
939 |
940 | - support for Homebridge v2.0.0
941 | - full code refactor
942 | - RESTFul and MQTT config refactor
943 | - renamed config properties, `supportProductionPowerMode` to `supportPowerProductionState`
944 | - renamed config properties, `powerProductionControl` to `powerProductionStateControl`
945 |
946 | - system data refresh
947 | - added native control from home app as a extra tile
948 | - added control direct from envoy section, 3rd party app
949 | - added state sensor
950 |
951 | - plc level refresh:
952 | - added native control from home app as a extra tile
953 | - power production:
954 | - added native control from home app as a extra tile
955 | - generator:
956 | - added state native control from home app as a extra tile
957 | - added state direct control from envoy section, 3rd party app
958 | - added state sensor
959 | - added mode sensors
960 | - enpower:
961 | - added grid state native control from home app as a extra tile
962 | - added grid state control direct from envoy section, 3rd party appp
963 | - added grid state sensor
964 | - added dry contacts native control from home app as a extra tile
965 | - added dry contacts state sensors
966 | - encharge:
967 | - added state sensor
968 | - added profile native control from home app as a extra tile
969 | - other changes
970 | - added possibility to enable accessory name as a prefix for all services
971 | - stability and performance improvements
972 | - dependencies updated
973 | - config schema updated
974 | - bug fixes
975 | - cleanup
976 |
977 | ## [8.1.1] - (04.08.2024)
978 |
979 | ## Changes
980 |
981 | - fix display and publish ensemble status and sensors
982 |
983 | ## [8.1.0] - (04.08.2024)
984 |
985 | ## Changes
986 |
987 | - added new ensemble/encharge/solar sensor profile, grid-tied and grid-forming
988 | - config schema updated
989 | - redme updated
990 | - cleanup
991 |
992 | ## [8.0.2] - (04.08.2024)
993 |
994 | ## Changes
995 |
996 | - fix [#142](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/142).
997 | - fix characteristic name for encharge profile
998 | - add missing optional characteristic for enphaseWirelessConnectionKitService
999 | - redme updated
1000 | - cleanup
1001 |
1002 | ## [8.0.0] - (07.07.2024)
1003 |
1004 | ## Changes
1005 |
1006 | ### After update to v8.0.0 and above from plevious version all sennsors need to be activated in plugin config again
1007 |
1008 | - added possibility to set indyvidual characteristic type for sensors, `0 - None/Disabled`, `1 - Motion Sensor`, `2 - Occupancy Sensor`, `3 - Contact Sensor`.
1009 | - config schema updated
1010 | - redme updated
1011 | - cleanup
1012 |
1013 | ## [7.16.0] - (23.06.2024)
1014 |
1015 | ## Changes
1016 |
1017 | - added possibility to use Your own generated Token [#140](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/140)
1018 | - config schema updated
1019 | - redme updated
1020 | - cleanup
1021 |
1022 | ## [7.15.4] - (18.06.2024)
1023 |
1024 | ## Changes
1025 |
1026 | - bump node modules ws [#139](https://github.com/grzegorz914/homebridge-enphase-envoy/pull/139)
1027 |
1028 | ## [7.15.3] - (18.06.2024)
1029 |
1030 | ## Changes
1031 |
1032 | - polling code refactor, added impulse generator
1033 | - remove production properties from Q-Relay accessory
1034 | - cleanup
1035 |
1036 | ## [7.15.2] - (09.06.2024)
1037 |
1038 | ## Changes
1039 |
1040 | - remove possibility to enable/disable support for live data and ensemble status, now is check automatically
1041 | - moved refresh ensemble status refres time to envoy section
1042 | - config schema updated
1043 | - cleanup
1044 |
1045 | ## [7.15.1] - (08.06.2024)
1046 |
1047 | ## Changes
1048 |
1049 | - added compare mode to the encharge backup level sensors
1050 | - config schema updated
1051 |
1052 | ## [7.15.0] - (08.06.2024)
1053 |
1054 | ## Changes
1055 |
1056 | - added encharge backup level sensors
1057 | - readme updated
1058 | - config schema updated
1059 | - cleanup
1060 |
1061 | ## [7.14.9] - (08.06.2024)
1062 |
1063 | ## Changes
1064 |
1065 | - refactor check JWT token
1066 | - refactor check arf profile
1067 | - correct some logs
1068 | - cleanup
1069 |
1070 | ## [7.14.8] - (01.06.2024)
1071 |
1072 | ## Changes
1073 |
1074 | - fix 401 error after envoy reboot and refresh cocies
1075 | - fix characteristics warning for arf profile
1076 | - increase time for check token expired
1077 | = bump dependencies
1078 | - cleanup
1079 |
1080 | ## [7.14.5] - (12.05.2024)
1081 |
1082 | ## Changes
1083 |
1084 | - refactor token check and request
1085 | - added infot about token time expired
1086 | - cleanup
1087 |
1088 | ## [7.14.4] - (06.05.2024)
1089 |
1090 | ## Changes
1091 |
1092 | - stop data polling if token expired, start after refreshed
1093 | - fixed power peak handle
1094 | - refactor code in passwords calculation and check jwt token
1095 |
1096 | ## [7.14.0] - (27.04.2024)
1097 |
1098 | ## Changes
1099 |
1100 | - added support to check and control Production Power Mode, firmware 7.x.x required installer credentials data
1101 | - added support to check PLC Level, firmware 7.x.x required installer credentials data
1102 | - added support to check and control Production Power Mode over MQTT protocol, firmware 7.x.x required installer credentials data
1103 | - added support to check PLC Level over MQTT protocol, firmware 7.x.x required installer credentials data
1104 | - config.schema updated
1105 | - cleanup
1106 |
1107 | ## [7.13.0] - (27.04.2024)
1108 |
1109 | ## Changes
1110 |
1111 | ### After update to v7.13.0 and above from plevious version the refresh time need to be configured again
1112 |
1113 | - changed data refresh time from (ms) go (sec) and precision 0.5
1114 | - prevent to set refresh time to 0, now minimum is 0.5 sec
1115 | - config.schema updated
1116 | - cleanup
1117 |
1118 | ## [7.11.14] - (26.02.2024)
1119 |
1120 | ## Changes
1121 |
1122 | - fix [#127](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/127)
1123 | - fix [#126](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/126)
1124 | - fix [#125](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/125)
1125 | - cleanup
1126 |
1127 | ## [7.11.0] - (11.02.2024)
1128 |
1129 | ## Changes
1130 |
1131 | ### After update to v7.11.0 and above from plevious version the grid mode sensors need to be configured again
1132 |
1133 | - added support to create multiple enpower/encharge/solar grid mode sensors and select grid mode to match
1134 | - config.schema updated
1135 | - cleanup
1136 |
1137 | ## [7.10.0] - (10.02.2024)
1138 |
1139 | ## Changes
1140 |
1141 | - added support for Envoy Firmware 8.x.x
1142 | - added support for storage CT meters
1143 | - fixed [#114](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/114)
1144 | - config.schema updated
1145 | - cleanup
1146 |
1147 | ## [7.9.0] - (01.01.2024)
1148 |
1149 | ## Changes
1150 |
1151 | - added [#118](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/118)
1152 | - added state and level lightbulb for ac bateries and encharges
1153 | - config.schema updated
1154 | - cleanup
1155 |
1156 | ## [7.8.0] - (23.12.2023)
1157 |
1158 | ## Changes
1159 |
1160 | ### After update to v7.8.0 and above from plevious version the sensors need to be configured again
1161 |
1162 | - added [#117](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/117)
1163 | - added possibility to set custom name for sensors
1164 | - added possibility to activate/deactivate sensors
1165 | - added possibility to create multiple sensors for power and energy level
1166 | - config.schema updated
1167 | - cleanup
1168 |
1169 | ## [7.7.5] - (05.12.2023)
1170 |
1171 | ## Changes
1172 |
1173 | - fix missing aasync/wait for microinverters data update
1174 | - refactor code in section data update
1175 | - fix characteristic warning [#115](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/115)
1176 | - better handle to fix [#112](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/112)
1177 | - config.schema updated
1178 | - cleanup
1179 |
1180 | ## [7.7.4] - (02.12.2023)
1181 |
1182 | ## Changes
1183 |
1184 | - fix [#112](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/112)
1185 | - cleanup
1186 |
1187 | ## [7.7.3] - (29.11.2023)
1188 |
1189 | ## Changes
1190 |
1191 | - fix [#112](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/112)
1192 | - cleanup
1193 |
1194 | ## [7.7.2] - (26.11.2023)
1195 |
1196 | ## Changes
1197 |
1198 | - added debug log for services prepare
1199 | - prepare for generators support
1200 | - cleanup
1201 |
1202 | ## [7.7.1] - (26.11.2023)
1203 |
1204 | ## Changes
1205 |
1206 | - dynamically add *Live Data* characteristics based on installed devices
1207 | - cleanup
1208 |
1209 | ## [7.7.0] - (26.11.2023)
1210 |
1211 | ## Changes
1212 |
1213 | - added *Live Data PV* cheracteristics to the HomeKit
1214 | - added *Live Data Storage* cheracteristics to the HomeKit
1215 | - added *Live Data Grid* cheracteristics to the HomeKit
1216 | - added *Live Data Load* cheracteristics to the HomeKit
1217 | - added *Live Data Generator* cheracteristics to the HomeKit
1218 | - fix [#85](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/85)
1219 | - config schema updated
1220 | - cleanup
1221 |
1222 | ## [7.5.0] - (20.10.2023)
1223 |
1224 | ## Changes
1225 |
1226 | ### After update to v7.5.0 and above from plevious version the sensors need to be configured again
1227 |
1228 | - added *Power State* contact sensor (Consumption Total) for automations and notifications in HomeKit
1229 | - added *Energy State* contact sensor (Consumption Total) for automations and notifications in HomeKit
1230 | - added *Energy Level* contact sensor (Consumption Total) for automations and notifications in HomeKit
1231 | - added *Power State* contact sensor (Consumption Net) for automations and notifications in HomeKit
1232 | - added *Energy State* contact sensor (Consumption Net) for automations and notifications in HomeKit
1233 | - added *Energy Level* contact sensor (Consumption Net) for automations and notifications in HomeKit
1234 | - added *Enpower Grid State* contact sensor for automations and notifications in HomeKit
1235 | - added *Encharge Grid State* contact sensor for automations and notifications in HomeKit
1236 | - added *Solar Grid State* contact sensor for automations and notifications in HomeKit
1237 | - bump node to min 18.x.x and homebridge to 1.6
1238 | - config schema updated
1239 | - redme update
1240 | - cleanup
1241 |
1242 | ## [7.4.0] - (25.07.2023)
1243 |
1244 | ## Changes
1245 |
1246 | - added *Energy State* contact sensor for production monitoring, which can be used for notification and automations in HomeKit.
1247 | - added *Energy Level* contact sensor for production monitoring, which can be used for notification and automations in HomeKit.
1248 | - config schema updated
1249 | - cleanup
1250 |
1251 | ## [7.3.0] - (20.07.2023)
1252 |
1253 | ## Changes
1254 |
1255 | - added *Power Production On/Off* contact sensor for production monitoring, which can be used for notification and automations in HomeKit.
1256 | - Use encodeURIComponent in EnvoyToken URLs - thanks @chrisjshull
1257 | - config schema updated
1258 | - cleanup
1259 |
1260 | ## [7.2.0] - (17.07.2023)
1261 |
1262 | ## Changes
1263 |
1264 | - added power production level (0-100%) displayed as brightness level in Home app based on all microinvertzers power configured in plugin config
1265 | - config schema updated
1266 |
1267 | ## [7.1.0] - (16.07.2023)
1268 |
1269 | ## Changes
1270 |
1271 | - added accessory switch to display in Home app curren state of power production, if Production Power > 0 then switch is ON
1272 | - config schema updated
1273 |
1274 | ## [7.0.0] - (14.07.2023)
1275 |
1276 | ## After Update to this version need to make corespondent changes in plugin config
1277 |
1278 | ## Changes
1279 |
1280 | - added support to get JWT Token automatically from enlighten server using user credentials data
1281 | - added support to check expired JWT Token and get new if expired
1282 | - added debug for RESTFul server
1283 | - added `token` to the RESTFul server request
1284 | - added `Token` to the MQTT publisher
1285 | - config schema updated
1286 | - cleanup
1287 |
1288 | ### Removed properties
1289 |
1290 | - `envoyFirmware7xxToken`
1291 |
1292 | ### Added properties
1293 |
1294 | - `enlightenUser`
1295 | - `enlightenPasswd`
1296 | - `envoySerialNumber`
1297 |
1298 | ## [6.7.0] - (27.02.2023)
1299 |
1300 | ## Changes
1301 |
1302 | - added powerful RESTFul server to use with own automations
1303 | - cleanup
1304 | - config.schema updated
1305 |
1306 | ## [6.6.0] - (26.02.2023)
1307 |
1308 | ## Changes
1309 |
1310 | - added for ensemble summary Rest Power
1311 | - added for ensemble summary AGG Max Energy
1312 | - added for ensemble summary Encharges AGG SoC
1313 | - added for ensemble summary Encharges AGG Rated Power
1314 | - added for ensemble summary bias frequency, voltage for phasa L2/B and L3/C
1315 | - prevent HB crash if for some reason prepare accessory fail
1316 | - properties updated/added
1317 | - bump dependencies
1318 | - cleanup
1319 |
1320 | ## [6.5.0] - (17.01.2023)
1321 |
1322 | ## Changes
1323 |
1324 | - added possibility to set refresh time for live dta, meters data and production ct
1325 |
1326 | ## [6.4.1] - (16.01.2023)
1327 |
1328 | ## Changes
1329 |
1330 | - fix wirreles konnections kit crash
1331 |
1332 | ## [6.4.0] - (15.01.2023)
1333 |
1334 | ## Changes
1335 |
1336 | - code cleanup
1337 | - config schema updated
1338 | - stability improvements
1339 | - reduce memory and cpu ussage
1340 | - added *Power Peak* contact sensors for production, consumption total/net which can be used for notification and automations in HomeKit.
1341 | - fix display wirelesskit characteristics hovewer is not instlled
1342 | - fix [#73](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/73)
1343 |
1344 | ## [6.3.2] - (14.01.2023)
1345 |
1346 | ## Changes
1347 |
1348 | - fix [#71](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/71)
1349 | - fix [#72](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/72)
1350 | - fix read grid profile name
1351 | - added new properties to ensemble status data
1352 | - added profile data to mqtt
1353 |
1354 | ## [6.3.1] - (12.01.2023)
1355 |
1356 | ## Changes
1357 |
1358 | - code cleanup
1359 | - stability and performance improvement
1360 |
1361 | ## [6.3.0] - (10.01.2023)
1362 |
1363 | ## Changes
1364 |
1365 | - added possibility enable/disable support to check *Laive Data*
1366 | - Envoy cpu load reduction
1367 | - code cleanup
1368 | - performance improvement
1369 |
1370 | ## [6.2.0] - (10.01.2023)
1371 |
1372 | ## Changes
1373 |
1374 | - added possibility enable/disable support to check *Ensemble Status*
1375 | - code cleanup/refactor
1376 | - config schema updated
1377 |
1378 | ## [6.1.0] - (09.01.2023)
1379 |
1380 | ## Changes
1381 |
1382 | - fix [#70](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/70)
1383 | - added possibility enable/disable support to check *PLC Level*
1384 | - added possibility enable/disable support to check/control production *Power Mode*
1385 | - code cleanup
1386 |
1387 | ## [6.0.9] - (09.01.2023)
1388 |
1389 | ## Changes
1390 |
1391 | - fix [#69](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/69)
1392 | - added missing promise
1393 | - code cleanup
1394 | - some log corrections
1395 |
1396 | ## [6.0.8] - (05.01.2023)
1397 |
1398 | ## Changes
1399 |
1400 | - code cleanup
1401 | - log units and text corrections
1402 | - added auto check plc communication level on startup
1403 | - added encharges plc level characteristic
1404 |
1405 | ## [6.0.7] - (30.12.2022)
1406 |
1407 | ## Changes
1408 |
1409 | - fixed wireless connection kit set to true
1410 |
1411 | ## [6.0.6] - (30.12.2022)
1412 |
1413 | ## Changes
1414 |
1415 | - fixed wireless connection kit characteristics
1416 |
1417 | ## [6.0.5] - (29.12.2022)
1418 |
1419 | ## Changes
1420 |
1421 | - fixed ensembles, encharges and enpowers read data [#66](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/66)
1422 | - publish live data to MQTT if Envoy firmware >= 7.x.x
1423 | - bump dependencies
1424 |
1425 | ## [6.0.4] - (14.12.2022)
1426 |
1427 | ## Changes
1428 |
1429 | - code optimize
1430 |
1431 | ## [6.0.3] - (14.12.2022)
1432 |
1433 | ## Changes
1434 |
1435 | - fix axios instance with token
1436 |
1437 | ## [6.0.2] - (14.12.2022)
1438 |
1439 | ## Changes
1440 |
1441 | - digestAuth code refactor
1442 | - code cleanup
1443 |
1444 | ## [6.0.1] - (13.12.2022)
1445 |
1446 | ## Changes
1447 |
1448 | - fixed JWT authorization proces and store cookies for data request
1449 | - code optimization
1450 | - big thanks @NoSnow3 and @BenouGui for test
1451 |
1452 | ## [6.0.0] - (11.12.2022)
1453 |
1454 | ## Changes
1455 |
1456 | - added support for Envoy with firmware 7.x.x and Token Authorization
1457 | - config schema updated
1458 | - big thanks @NoSnow3 for test
1459 |
1460 | ## [5.9.7] - (06.12.2022)
1461 |
1462 | ## Changes
1463 |
1464 | - bump dependencies
1465 |
1466 | ## [5.9.6] - (15.09.2022)
1467 |
1468 | ## Changes
1469 |
1470 | - fix refresh inventory data
1471 | - bump dependencies
1472 |
1473 | ## [5.9.4] - (10.09.2022)
1474 |
1475 | ## Changes
1476 |
1477 | - cleanup
1478 | - fix mqtt
1479 | - bump dependencies
1480 |
1481 | ## [5.9.3] - (29.08.2022)
1482 |
1483 | ## Changes
1484 |
1485 | - cleanup
1486 | - update mqtt topics
1487 |
1488 | ## [5.9.2] - (26.08.2022)
1489 |
1490 | ## Changes
1491 |
1492 | - cleanup
1493 |
1494 | ## [5.9.1] - (26.08.2022)
1495 |
1496 | ## Changes
1497 |
1498 | - convert password generator to iuse promises async/await
1499 | - cleanup
1500 |
1501 | ## [5.9.0] - (25.08.2022)
1502 |
1503 | ## Changes
1504 |
1505 | - added installer password generator, no need generate it manually in external generator
1506 | - config schema updated
1507 |
1508 | ## [5.8.4] - (25.08.2022)
1509 |
1510 | ## Changes
1511 |
1512 | - rebuild refresh data process
1513 | - config schema updated
1514 | - cosmetics changes
1515 |
1516 | ## [5.8.3] - (23.08.2022)
1517 |
1518 | ## Changes
1519 |
1520 | - fix [#55](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/55)
1521 |
1522 | ## [5.8.2] - (21.08.2022)
1523 |
1524 | ## Changes
1525 |
1526 | - code cleanup
1527 | - better fix Power characteristic warning negative value [#54](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/54)
1528 |
1529 | ## [5.8.1] - (13.08.2022)
1530 |
1531 | ## Changes
1532 |
1533 | - fix Power characteristic warning negative value [#54](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/54)
1534 |
1535 | ## [5.8.0] - (12.08.2022)
1536 |
1537 | ## Changes
1538 |
1539 | - added possibility automatically 'Power peak reset' every day, week, month
1540 | - config schema updated
1541 |
1542 | ## [5.7.8] - (08.08.2022)
1543 |
1544 | ## Changes
1545 |
1546 | - fix [#53](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/53)
1547 |
1548 | ## [5.7.7] - (08.08.2022)
1549 |
1550 | ## Changes
1551 |
1552 | - fix production *Power peak detected* state
1553 | - rebuild log
1554 |
1555 | ## [5.7.6] - (07.08.2022)
1556 |
1557 | ## Changes
1558 |
1559 | - fix auto/manual consumptions 'Power peak reset and save'
1560 | - log updated
1561 | - properties in code updated
1562 |
1563 | ## [5.7.3] - (07.08.2022)
1564 |
1565 | ## Changes
1566 |
1567 | - fix auto 'Power peak reset' at midnight
1568 |
1569 | ## [5.7.2] - (06.08.2022)
1570 |
1571 | ## Changes
1572 |
1573 | - fix characteristic 'Power peak reset' warning
1574 |
1575 | ## [5.7.1] - (06.08.2022)
1576 |
1577 | ## Changes
1578 |
1579 | - fix update button state characteristics for power peak reset
1580 |
1581 | ## [5.7.0] - (06.08.2022)
1582 |
1583 | ## Changes
1584 |
1585 | - added possibility to manuall reset *Power peak* (in accessory using button)
1586 | - added possibility to automatically reset *Power peak* at midnight (in plugin setting configurable)
1587 | - updated config schema
1588 |
1589 | ## [5.6.22] - (06.08.2022)
1590 |
1591 | ## Changes
1592 |
1593 | - rename *Power Max* to *Power Peak*
1594 | - added extra refresh data for production (microinverters)
1595 |
1596 | ## [5.6.21] - (03.08.2022)
1597 |
1598 | ## Changes
1599 |
1600 | - fix [#52](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/52)
1601 |
1602 | ## [5.6.20] - (03.08.2022)
1603 |
1604 | ## Changes
1605 |
1606 | - added possibility to disable display device info in log after plugin restart
1607 | - check required properties to create accessory
1608 | - correct some logs typos
1609 |
1610 | ## [5.6.15] - (02.08.2022)
1611 |
1612 | ## Changes
1613 |
1614 | - fix refresh power and energy production data if no meters are installed
1615 |
1616 | ## [5.6.14] - (02.08.2022)
1617 |
1618 | ## Changes
1619 |
1620 | - fix display undefinded Power and Energy type if no meters are installed
1621 |
1622 | ## [5.6.13] - (23.07.2022)
1623 |
1624 | ## Changes
1625 |
1626 | - refactor information service
1627 |
1628 | ## [5.6.12] - (11.05.2022)
1629 |
1630 | ## Changes
1631 |
1632 | - fix [#50](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/50)
1633 |
1634 | ## [5.6.9] - (25.04.2022)
1635 |
1636 | ## Changes
1637 |
1638 | - update dependencies
1639 |
1640 | ## [5.6.8] - (25.04.2022)
1641 |
1642 | ## Changes
1643 |
1644 | - refactor send mqtt message
1645 |
1646 | ## [5.6.7] - (24.04.2022)
1647 |
1648 | ## Changes
1649 |
1650 | - update config.schema.json
1651 |
1652 | ## [5.6.6] - (30.03.2022)
1653 |
1654 | ## Changes
1655 |
1656 | - prevent poll Meters Reading Data if no Meters are installed
1657 | - prevent poll Microinverters Power Data if envoy password is not set
1658 |
1659 | ## [5.6.5] - (30.03.2022)
1660 |
1661 | ## Changes
1662 |
1663 | - refresh time for Meters Reading Data to 1,5sec and Production CT Data to 3 sec.
1664 |
1665 | ## [5.6.4] - (29.03.2022)
1666 |
1667 | ## Changes
1668 |
1669 | - fixed read microinverters data (error 401) if envoy uses standard password, fix [#48](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/48)
1670 |
1671 | ## [5.6.3] - (29.03.2022)
1672 |
1673 | ## Added
1674 |
1675 | - debug mode for MQTT Client
1676 | -
1677 |
1678 | ## Changes
1679 |
1680 | - update check state data
1681 | - update debug logging
1682 | - removed refresh interval
1683 | - update config schema
1684 | - removed Entrez Authorization functionality for Envoy with firmware 7.x.x at this time
1685 |
1686 | ## [5.6.1] - (20.02.2022)
1687 |
1688 | ## Added
1689 |
1690 | - wrire envoy device id to file
1691 |
1692 | ## [5.6.0] - (19.02.2022)
1693 |
1694 | ## Added
1695 |
1696 | - Entrez Authorization for Envoy with firmware 7.x.x (test phase)
1697 |
1698 | ## [5.5.0] - (17.02.2022)
1699 |
1700 | ## Added
1701 |
1702 | - MQTT Client, publish all PV installation data
1703 | - Debug mode
1704 | - Prepare for entrez authorization
1705 |
1706 | ## Changes
1707 |
1708 | - update dependencies
1709 | - code refactor
1710 |
1711 | ## [5.4.34] - (18.01.2022)
1712 |
1713 | ## Changes
1714 |
1715 | - update dependencies
1716 |
1717 | ## [5.4.33] - (17.01.2022)
1718 |
1719 | ## Changes
1720 |
1721 | - update dependencies
1722 |
1723 | ## [5.4.32] - (29.12.2021)
1724 |
1725 | - prepare directory and files synchronously
1726 |
1727 | ## [5.4.30] - (28.12.2021)
1728 |
1729 | - update node minimum requirements
1730 |
1731 | ## [5.4.29] - (20.11.2021)
1732 |
1733 | ## Changes
1734 |
1735 | - cosmetics
1736 |
1737 | ## [5.4.21] - (25.09.2021)
1738 |
1739 | ## Changes
1740 |
1741 | - code cleanup
1742 |
1743 | ## [5.4.19] - (24.09.2021)
1744 |
1745 | ## Changes
1746 |
1747 | ### WARNING - after this update nedd to remove and add accessory to the HomeKit again
1748 |
1749 | - code cleanup
1750 | - stability improvements
1751 |
1752 | ## [5.4.18] - (24.09.2021)
1753 |
1754 | ## Changes
1755 |
1756 | - code cleanup
1757 | - fix wrong voltage display, 1-phase instalation
1758 |
1759 | ## [5.4.17] - (19.09.2021)
1760 |
1761 | ## Changes
1762 |
1763 | - code cleanup
1764 |
1765 | ## [5.4.15] - (09.09.2021)
1766 |
1767 | ## Changes
1768 |
1769 | - bump dependencies
1770 | - stability improvements
1771 | - performance improvements
1772 |
1773 | ## [5.4.14] - (05.09.2021)
1774 |
1775 | ## Changes
1776 |
1777 | - bump dependencies
1778 |
1779 | ## [5.4.13] - (04.09.2021)
1780 |
1781 | ## Changes
1782 |
1783 | - bump dependencies
1784 |
1785 | ## [5.4.1] - (22.08.2021)
1786 |
1787 | ## Changes
1788 |
1789 | - removed *envoyDevId* property, now is detect automatically
1790 |
1791 | ## [5.4.0] - (21.08.2021)
1792 |
1793 | ## Changes
1794 |
1795 | - removed urllib
1796 | - added digestAuth method to Axios
1797 | - code rebuild and cleanup
1798 | - some fixes and improvements
1799 |
1800 | ## [5.3.1] - (21.08.2021)
1801 |
1802 | ## Changes
1803 |
1804 | - charcterristics data format fixes
1805 | - added grid profile characteristic for ensemble
1806 | - code rebuild and cleanup
1807 |
1808 | ## [5.3.0] - (17.08.2021)
1809 |
1810 | ## Changes
1811 |
1812 | - added wireless connection kit characteristics
1813 | - code rebuild and cleanup
1814 |
1815 | ## [5.2.15] - (16.08.2021)
1816 |
1817 | ## Changes
1818 |
1819 | - finally fixed not reconized ensemble (enpower and encharges) devices in previous versions
1820 |
1821 | ## [5.2.0] - (15.08.2021)
1822 |
1823 | ## Changes
1824 |
1825 | - added possibility Enable/Disable Power Production (in envoy section)
1826 |
1827 | ## [5.1.0] - (13.08.2021)
1828 |
1829 | ## Changes
1830 |
1831 | - added system Power Production state(in envoy section)
1832 | - added enpower status service
1833 | - fixed not reconized ensemble (enpower and encharges) devices in previous versions
1834 | - updated SKU and Part Nr.
1835 | - code rebuild and cleanup
1836 | - other fixes and improvements
1837 |
1838 | ## [5.0.0] - (05.08.2021)
1839 |
1840 | ## Changes
1841 |
1842 | - removed deprecated inherits and moved all characterictics to use ES6 class
1843 |
1844 | ## [4.9.0] - (03.08.2021)
1845 |
1846 | ## Changes
1847 |
1848 | - added support for Ensemble (Enpowers and Encharges)
1849 | - fixed wrong named Encharges to AC Batteries
1850 | - other fixes and performance improvements
1851 |
1852 | ## [4.8.0] - (12.03.2021)
1853 |
1854 | ## Changes
1855 |
1856 | - added possibility to check communications level of all devces on user request
1857 | - fixed many small bugs
1858 | - code cleanup
1859 |
1860 | ## [4.7.0] - (04.03.2021)
1861 |
1862 | ## Changes
1863 |
1864 | - update config.chema
1865 | - fixed many small bugs
1866 | - correct identyfi all hardware
1867 | - code cleanup
1868 |
1869 | ## [4.6.0] - (24.02.2021)
1870 |
1871 | ## Changes
1872 |
1873 | - added Characteristics for Apparent and Reactive Power
1874 | - fixed some bugs
1875 |
1876 | ## Important note v4.5.0 and above
1877 |
1878 | Version 4.5.0 and above need to be used with Homebridge min. v1.3.0.
1879 |
1880 | ## [4.5.0] - (23.02.2021)
1881 |
1882 | ## Changes
1883 |
1884 | - code rebuild, use Characteristic.onSet/onGet
1885 | - require Homebridge 1.3.x or above
1886 |
1887 | ## [4.4.0] - (10.02.2021)
1888 |
1889 | ## Changs
1890 |
1891 | - restored possibility to set own user and password for envoy
1892 | - added characteristic for communication level Q-Relays, Encharges, Microinverters
1893 | - added characteristic for all data from Encharges
1894 | - other improvements and fixes
1895 |
1896 | ## [4.3.0] - (07.02.2021)
1897 |
1898 | ## Changs
1899 |
1900 | - added more characteristics for encharges
1901 | - added characteristics for Current, Voltage and Power Factor
1902 | - fixed reported bugs
1903 |
1904 | ## [4.2.0] - (03.02.2021)
1905 |
1906 | ## Changs
1907 |
1908 | - added evnoy characteristics
1909 | - fixes and corrections
1910 |
1911 | ## [4.1.0] - (02.02.2021)
1912 |
1913 | ## Changs
1914 |
1915 | - removed envoyUser, envoyPasswd, Firmware and SerialNumber, now detect the data automatically
1916 | - data refresh improvements
1917 | - reconfigured config schema
1918 | - other fixes and corrections
1919 |
1920 | ## Important note v4.0.0 and above
1921 |
1922 | Version 4.0.0 whole new concept.
1923 |
1924 | ## [4.0.0] - (30.01.2021)
1925 |
1926 | ## Changs
1927 |
1928 | - refactoring whole code
1929 | - added Characteristics for Q-Relay, Meters, Microinverters, Encharges
1930 | - added whole base of status code all displayes in EVE or Controller app
1931 | - added and present state and power of all devices (Envoy, Q-Relay, Meters, Microinverters, Encharges)
1932 | - code cleanup and many more
1933 |
1934 | ## [3.6.0] - (29.01.2021)
1935 |
1936 | ## Changs
1937 |
1938 | - read Laast and Max Power of indyvidual inverters
1939 | - code rebuild
1940 |
1941 | ## [3.5.15] - (29.01.2021)
1942 |
1943 | ## Changs
1944 |
1945 | - list all devices in log with its status
1946 |
1947 | ## Important note v3.5.0 and above
1948 |
1949 | Version 3.5.0 detect automatically all installed devices, please check Your config after update to this version.
1950 |
1951 | ## [3.5.0] - (29.01.2021)
1952 |
1953 | ## Changs
1954 |
1955 | - full automatic check installed devices, Envoy, Inverters, Q-Relay, Meters, Encharges
1956 | - rebuild config
1957 |
1958 | ## [3.4.3] - (29.01.2021)
1959 |
1960 | ## Changs
1961 |
1962 | - added check for installed Q-Relay
1963 | - added check for installed Encharge
1964 | - added check for installed Meters
1965 | - reconfigured config menu
1966 | - code rebuild
1967 |
1968 | ## [3.3.15] - (26.01.2021)
1969 |
1970 | ## Changs
1971 |
1972 | - power Net and Total Max fixes
1973 |
1974 | ## [3.3.9] - (01.01.2021)
1975 |
1976 | ## Changs
1977 |
1978 | - bump dependiencies
1979 |
1980 | ## [3.3.5] - (22.10.2020)
1981 |
1982 | ## Changs
1983 |
1984 | - added encharge storage energy offset
1985 | - added possibility to select consumtion meter CT - Load only/Load with Solar production
1986 | - update config.schema
1987 |
1988 | ## [3.2.0] - (08.09.2020)
1989 |
1990 | ## Changs
1991 |
1992 | - added async/await function to read deviceInfo and updateStatus
1993 |
1994 | ## [3.1.0] - (06.09.2020)
1995 |
1996 | ## Changs
1997 |
1998 | - completly reconfigured config schema
1999 |
2000 | ## [3.0.15] - (05.09.2020)
2001 |
2002 | ## Changs
2003 |
2004 | - changed Characteristic.StatusActive to custom Characteristic.PowerMaxDetected
2005 |
2006 | ## [3.0.8] - (05.09.2020)
2007 |
2008 | ## Fix
2009 |
2010 | - fix wrong display power detection state
2011 |
2012 | ## [3.0.7] - (04.09.2020)
2013 |
2014 | ## Added
2015 |
2016 | - added Characteristic.StatusActive to identify Max Power Detection
2017 |
2018 | ## [3.0.4] - (04.09.2020)
2019 |
2020 | ## Fix
2021 |
2022 | - fix no display Last Seven Days energy
2023 |
2024 | ## [3.0.3] - (04.09.2020)
2025 |
2026 | ## Changes
2027 |
2028 | - code cleanup
2029 |
2030 | ## Important note
2031 |
2032 | Ab verion v3.0.0 accesory moved to Power Meter custom Characteristic, due to Apple HomeKit limitations right now only in EVE app displayed correctly, in HomeKit displayed as 'Unsupported'. If U want to use old CO2 sensor style just still with 2.x.x version
2033 |
2034 | ## [3.0.0] - (02.09.2020)
2035 |
2036 | ### New
2037 |
2038 | - accesory moved to Power Meter, due to Apple HomeKit limitations right now only in EVE app displayed, in HomeKit displayed as 'Unsupported'.
2039 | - added possibility to set lifetime energy offset for production, and consumption.
2040 | - added support for encharge storage.
2041 |
2042 | ## [2.3.0] - (28.08.2020)
2043 |
2044 | ### Added
2045 |
2046 | - added energy production and consumption tile (Today, Last 7D, Lifetime).
2047 |
2048 | ## [2.2.0] - (27.08.2020)
2049 |
2050 | ### Added
2051 |
2052 | - added possibility to display minus values, exported power to grid.
2053 |
2054 | ## [2.1.3] - (27.08.2020)
2055 |
2056 | ### Added
2057 |
2058 | - added extra accessory to present Total or Total and Net Consumption. Selectable in consumption power meter option.
2059 |
2060 | ## [2.0.6] - (27.08.2020)
2061 |
2062 | ### Added
2063 |
2064 | - added extra accessory to present Total Power Consumption if consumption Power meter is selected
2065 |
2066 | ## [1.1.2] - (25.08.2020)
2067 |
2068 | ### Changes
2069 |
2070 | - performance improvements
2071 | - other small fixes
2072 |
2073 | ## [1.1.0] - (09.08.2020)
2074 |
2075 | ### Added
2076 |
2077 | - performance improvements
2078 |
2079 | ## [1.0.3] - (02.07.2020)
2080 |
2081 | ### Fixed
2082 |
2083 | - fixed #2 crash if no production meters are installed
2084 |
2085 | ## [1.0.1] - (29.06.2020)
2086 |
2087 | ### Fixed
2088 |
2089 | - fixed display energy and power values
2090 |
2091 | ## [1.0.0] - (28.06.2020)
2092 |
2093 | ### Added
2094 |
2095 | - added possibility select consumption power meter
2096 |
2097 | ## [0.4.6] - (27.06.2020)
2098 |
2099 | ### Fixed
2100 |
2101 | - fixed display energy symbol in the log
2102 |
2103 | ## [0.4.5] - (27.06.2020)
2104 |
2105 | ### Added
2106 |
2107 | - added in the log possibility read all power and energy value
2108 |
2109 | ## [0.3.5] - (17.06.2020)
2110 |
2111 | ### Fixed
2112 |
2113 | - corrections in config.schema.json
2114 |
2115 | ## [0.3.0] - (15.06.2020)
2116 |
2117 | ### Added
2118 |
2119 | - added possibility to select production meter
2120 |
2121 | ## [0.2.0] - (010.06.2020)
2122 |
2123 | ### Added
2124 |
2125 | - stored max. Power Production too the file
2126 | - config.host now use 'envoy.local' path or Your configured iP adress
2127 |
2128 | ## [0.1.1] - (08.06.2020)
2129 |
2130 | ### Fixed
2131 |
2132 | - many fixes and more info in log
2133 |
2134 | ## [0.0.30] - (05.06.2020)
2135 |
2136 | - working release
2137 |
2138 | ## [0.0.1] - (05.06.2020)
2139 |
2140 | - initial release
2141 |
--------------------------------------------------------------------------------