myenergi-api 0.9.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/AuthDigest.js +16 -16
- package/dist/Digest.js +19 -21
- package/dist/MyEnergi.d.ts +4 -4
- package/dist/MyEnergi.js +14 -15
- package/dist/index.d.ts +6 -6
- package/dist/index.js +3 -1
- package/dist/models/Types.d.ts +8 -0
- package/dist/models/Types.js +10 -1
- package/dist/models/Zappi.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
# myenergi-api
|
|
2
|
+
|
|
3
|
+
[](https://deepscan.io/dashboard#view=project&tid=16513&pid=19831&bid=520479)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
2
10
|
NodeJS implementation of MyEnergi API for controlling Zappi, Eddi and other MyEnergi products
|
package/dist/AuthDigest.js
CHANGED
|
@@ -27,7 +27,7 @@ class AuthDigest {
|
|
|
27
27
|
this._password = password;
|
|
28
28
|
this._nc = 0;
|
|
29
29
|
this._initialized = false;
|
|
30
|
-
this._algorithm =
|
|
30
|
+
this._algorithm = "MD5";
|
|
31
31
|
if (errorHandler)
|
|
32
32
|
this._onError = errorHandler;
|
|
33
33
|
}
|
|
@@ -58,7 +58,7 @@ class AuthDigest {
|
|
|
58
58
|
get nc() {
|
|
59
59
|
var _a;
|
|
60
60
|
this._nc++;
|
|
61
|
-
var myHex = (
|
|
61
|
+
var myHex = ("0000000" + ((_a = this._nc) === null || _a === void 0 ? void 0 : _a.toString(16))).substr(-8);
|
|
62
62
|
return myHex;
|
|
63
63
|
}
|
|
64
64
|
get cnonce() {
|
|
@@ -66,38 +66,38 @@ class AuthDigest {
|
|
|
66
66
|
return this._cnonce;
|
|
67
67
|
}
|
|
68
68
|
md5(data) {
|
|
69
|
-
let md5 = crypto.createHash(
|
|
70
|
-
let result = md5.update(data).digest(
|
|
69
|
+
let md5 = crypto.createHash("md5");
|
|
70
|
+
let result = md5.update(data).digest("hex");
|
|
71
71
|
return result;
|
|
72
72
|
}
|
|
73
73
|
init(wwwAuthHeader) {
|
|
74
|
-
let authSplit = wwwAuthHeader.split(
|
|
74
|
+
let authSplit = wwwAuthHeader.split(",");
|
|
75
75
|
for (let item of authSplit) {
|
|
76
|
-
if (item.indexOf(
|
|
76
|
+
if (item.indexOf("realm=") >= 0) {
|
|
77
77
|
let realmSplit = item.split('="');
|
|
78
78
|
this._realm = realmSplit[realmSplit.length - 1];
|
|
79
79
|
this._realm = this._realm.substring(0, this._realm.length - 1);
|
|
80
80
|
}
|
|
81
|
-
if (item.indexOf(
|
|
81
|
+
if (item.indexOf("nonce=") >= 0) {
|
|
82
82
|
let nonceSplit = item.split('="');
|
|
83
83
|
this._nonce = nonceSplit[nonceSplit.length - 1];
|
|
84
84
|
this._nonce = this._nonce.substring(0, this._nonce.length - 1);
|
|
85
85
|
}
|
|
86
|
-
if (item.indexOf(
|
|
86
|
+
if (item.indexOf("qop=") >= 0) {
|
|
87
87
|
let qopSplit = item.split('="');
|
|
88
88
|
this._qop = qopSplit[qopSplit.length - 1];
|
|
89
89
|
this._qop = this._qop.substring(0, this._qop.length - 1);
|
|
90
90
|
}
|
|
91
|
-
if (item.indexOf(
|
|
91
|
+
if (item.indexOf("opaque=") >= 0) {
|
|
92
92
|
let opaqueSplit = item.split('="');
|
|
93
93
|
this._opaque = opaqueSplit[opaqueSplit.length - 1];
|
|
94
94
|
this._opaque = this._opaque.substring(0, this._opaque.length - 1);
|
|
95
95
|
}
|
|
96
|
-
if (item.indexOf(
|
|
97
|
-
let algorithmSplit = item.split(
|
|
96
|
+
if (item.indexOf("algorithm=") >= 0) {
|
|
97
|
+
let algorithmSplit = item.split("=");
|
|
98
98
|
this._algorithm = algorithmSplit[algorithmSplit.length - 1];
|
|
99
99
|
this._algorithm = this._algorithm.substring(0, this._algorithm.length);
|
|
100
|
-
if (this._onError && this.algorithm !==
|
|
100
|
+
if (this._onError && this.algorithm !== "MD5") {
|
|
101
101
|
this._onError(`Algorithm ${this.algorithm} is ont supported. Only MD5 is supportet`);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -106,12 +106,12 @@ class AuthDigest {
|
|
|
106
106
|
}
|
|
107
107
|
getAuthorization(httpMethod, path) {
|
|
108
108
|
if (!this._initialized)
|
|
109
|
-
return
|
|
109
|
+
return "";
|
|
110
110
|
const nc = this.nc;
|
|
111
111
|
const cnonce = this.cnonce;
|
|
112
|
-
let HA1 = this.md5(this.username +
|
|
113
|
-
let HA2 = this.md5(httpMethod +
|
|
114
|
-
let response = this.md5(HA1 +
|
|
112
|
+
let HA1 = this.md5(this.username + ":" + this.realm + ":" + this._password);
|
|
113
|
+
let HA2 = this.md5(httpMethod + ":" + path);
|
|
114
|
+
let response = this.md5(HA1 + ":" + this.nonce + ":" + nc + ":" + cnonce + ":" + this.qop + ":" + HA2);
|
|
115
115
|
let res = `Digest username="${this.username}",`;
|
|
116
116
|
res += `realm="${this.realm}",`;
|
|
117
117
|
res += `nonce="${this.nonce}",`;
|
package/dist/Digest.js
CHANGED
|
@@ -33,7 +33,7 @@ class Digest {
|
|
|
33
33
|
request(options, data, retryCount = 0, redirectCount = 0) {
|
|
34
34
|
return new Promise((resolve, reject) => {
|
|
35
35
|
var _a;
|
|
36
|
-
let resData =
|
|
36
|
+
let resData = "";
|
|
37
37
|
if (!options.headers)
|
|
38
38
|
options.headers = {};
|
|
39
39
|
options.headers.Authorization = (_a = this._authDigest) === null || _a === void 0 ? void 0 : _a.getAuthorization(options.method, options.path);
|
|
@@ -41,13 +41,13 @@ class Digest {
|
|
|
41
41
|
var _a, _b;
|
|
42
42
|
if (res.statusCode == 401) {
|
|
43
43
|
if (retryCount > 1) {
|
|
44
|
-
reject(
|
|
44
|
+
reject("Authentication failed");
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
retryCount++;
|
|
48
|
-
const wwwAuth = res.headers[
|
|
49
|
-
if (!wwwAuth.startsWith(
|
|
50
|
-
reject(
|
|
48
|
+
const wwwAuth = res.headers["www-authenticate"];
|
|
49
|
+
if (!wwwAuth.startsWith("Digest")) {
|
|
50
|
+
reject("Unsupported authentication method. Supported authentication schemes: Digest");
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
(_a = this._authDigest) === null || _a === void 0 ? void 0 : _a.init(wwwAuth);
|
|
@@ -63,9 +63,8 @@ class Digest {
|
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
65
|
else if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (myenergiAsn && myenergiAsn !== 'undefined' && myenergiAsn !== this._baseUrl.host) {
|
|
66
|
+
const myenergiAsn = res.headers["x_myenergi-asn"];
|
|
67
|
+
if (myenergiAsn && myenergiAsn !== "undefined" && myenergiAsn !== this._baseUrl.host) {
|
|
69
68
|
if (redirectCount > 2) {
|
|
70
69
|
reject(`Too many redirects: ${myenergiAsn}`);
|
|
71
70
|
return;
|
|
@@ -83,21 +82,20 @@ class Digest {
|
|
|
83
82
|
reject(resaon);
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
|
-
|
|
87
|
-
res.
|
|
88
|
-
res.on('data', (chunk) => {
|
|
85
|
+
res.setEncoding("utf8");
|
|
86
|
+
res.on("data", (chunk) => {
|
|
89
87
|
resData += chunk;
|
|
90
88
|
});
|
|
91
|
-
res.on(
|
|
89
|
+
res.on("end", () => {
|
|
92
90
|
resolve(resData);
|
|
93
91
|
});
|
|
94
92
|
}
|
|
95
93
|
else if (res.statusCode >= 300 && res.statusCode < 400) {
|
|
96
94
|
if (redirectCount > 2) {
|
|
97
|
-
reject(`Too many redirects: ${res.headers[
|
|
95
|
+
reject(`Too many redirects: ${res.headers["location"]}`);
|
|
98
96
|
return;
|
|
99
97
|
}
|
|
100
|
-
const location = res.headers[
|
|
98
|
+
const location = res.headers["location"];
|
|
101
99
|
const uri = url.parse(location, true);
|
|
102
100
|
if (uri.host !== this._baseUrl.host) {
|
|
103
101
|
this._baseUrl.host = uri.host;
|
|
@@ -112,12 +110,12 @@ class Digest {
|
|
|
112
110
|
});
|
|
113
111
|
}
|
|
114
112
|
else {
|
|
115
|
-
console.error(
|
|
116
|
-
reject(
|
|
113
|
+
console.error("status code failed!!");
|
|
114
|
+
reject("status code failed!!");
|
|
117
115
|
return;
|
|
118
116
|
}
|
|
119
117
|
});
|
|
120
|
-
req.on(
|
|
118
|
+
req.on("error", (e) => {
|
|
121
119
|
console.error(`problem with request: ${e.message}`);
|
|
122
120
|
reject(e);
|
|
123
121
|
});
|
|
@@ -134,11 +132,11 @@ class Digest {
|
|
|
134
132
|
host: this._baseUrl.host,
|
|
135
133
|
port: this._baseUrl.port,
|
|
136
134
|
path: uri.path,
|
|
137
|
-
method:
|
|
135
|
+
method: "GET",
|
|
138
136
|
headers: {
|
|
139
|
-
Connection:
|
|
140
|
-
|
|
141
|
-
Accept:
|
|
137
|
+
Connection: "Keep-Alive",
|
|
138
|
+
"Content-Type": "application/json",
|
|
139
|
+
Accept: "application/json",
|
|
142
140
|
Host: uri.hostname,
|
|
143
141
|
},
|
|
144
142
|
};
|
package/dist/MyEnergi.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Eddi } from
|
|
2
|
-
import { Harvi } from
|
|
3
|
-
import { EddiBoost, EddiMode, ZappiBoostMode, ZappiChargeMode } from
|
|
4
|
-
import { Zappi } from
|
|
1
|
+
import { Eddi } from "./models/Eddi";
|
|
2
|
+
import { Harvi } from "./models/Harvi";
|
|
3
|
+
import { EddiBoost, EddiMode, ZappiBoostMode, ZappiChargeMode } from "./models/Types";
|
|
4
|
+
import { Zappi } from "./models/Zappi";
|
|
5
5
|
export declare class MyEnergi {
|
|
6
6
|
private _config;
|
|
7
7
|
private _digest;
|
package/dist/MyEnergi.js
CHANGED
|
@@ -15,19 +15,18 @@ const Types_1 = require("./models/Types");
|
|
|
15
15
|
class MyEnergi {
|
|
16
16
|
constructor(username, password) {
|
|
17
17
|
this._config = {
|
|
18
|
-
username:
|
|
19
|
-
password:
|
|
20
|
-
base_url:
|
|
21
|
-
eddi_url:
|
|
22
|
-
zappi_url:
|
|
23
|
-
harvi_url:
|
|
24
|
-
status_url:
|
|
25
|
-
dayhour_url:
|
|
26
|
-
zappi_mode_url:
|
|
27
|
-
zappi_min_green_url:
|
|
28
|
-
eddi_mode_url:
|
|
29
|
-
eddi_boost_url:
|
|
30
|
-
//https://s18.myenergi.net/cgi-jdayhour-Znnnnnnnn-YYYY-MM-DD
|
|
18
|
+
username: "",
|
|
19
|
+
password: "",
|
|
20
|
+
base_url: "https://s18.myenergi.net",
|
|
21
|
+
eddi_url: "/cgi-jstatus-E",
|
|
22
|
+
zappi_url: "/cgi-jstatus-Z",
|
|
23
|
+
harvi_url: "/cgi-jstatus-H",
|
|
24
|
+
status_url: "/cgi-jstatus-*",
|
|
25
|
+
dayhour_url: "/cgi-jdayhour-",
|
|
26
|
+
zappi_mode_url: "/cgi-zappi-mode-Z",
|
|
27
|
+
zappi_min_green_url: "/cgi-set-min-green-Z",
|
|
28
|
+
eddi_mode_url: "/cgi-eddi-mode-E",
|
|
29
|
+
eddi_boost_url: "/cgi-eddi-boost-E",
|
|
31
30
|
};
|
|
32
31
|
this._config.username = username;
|
|
33
32
|
this._config.password = password;
|
|
@@ -75,11 +74,11 @@ class MyEnergi {
|
|
|
75
74
|
return jsonData;
|
|
76
75
|
});
|
|
77
76
|
}
|
|
78
|
-
setZappiBoostMode(serialNo, boostMode, kwh = 0, completeTime =
|
|
77
|
+
setZappiBoostMode(serialNo, boostMode, kwh = 0, completeTime = "0000") {
|
|
79
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
79
|
if (boostMode === Types_1.ZappiBoostMode.Stop) {
|
|
81
80
|
kwh = 0;
|
|
82
|
-
completeTime =
|
|
81
|
+
completeTime = "0000";
|
|
83
82
|
}
|
|
84
83
|
const url = `${this._config.zappi_mode_url}${serialNo}-0-${boostMode}-${kwh}-${completeTime}`;
|
|
85
84
|
const data = yield this._digest.get(url);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Eddi } from
|
|
2
|
-
import { Harvi } from
|
|
3
|
-
import { EddiBoost, EddiMode, ZappiBoostMode, ZappiChargeMode } from
|
|
4
|
-
import { Zappi } from
|
|
5
|
-
import { MyEnergi } from
|
|
6
|
-
export { MyEnergi, Eddi, Zappi, Harvi, EddiBoost, EddiMode, ZappiBoostMode, ZappiChargeMode };
|
|
1
|
+
import { Eddi } from "./models/Eddi";
|
|
2
|
+
import { Harvi } from "./models/Harvi";
|
|
3
|
+
import { EddiBoost, EddiHeaterStatus, EddiMode, ZappiBoostMode, ZappiChargeMode, ZappiStatus } from "./models/Types";
|
|
4
|
+
import { Zappi } from "./models/Zappi";
|
|
5
|
+
import { MyEnergi } from "./MyEnergi";
|
|
6
|
+
export { MyEnergi, Eddi, Zappi, Harvi, EddiBoost, EddiMode, EddiHeaterStatus, ZappiBoostMode, ZappiChargeMode, ZappiStatus };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ZappiChargeMode = exports.ZappiBoostMode = exports.EddiMode = exports.EddiBoost = exports.MyEnergi = void 0;
|
|
3
|
+
exports.ZappiStatus = exports.ZappiChargeMode = exports.ZappiBoostMode = exports.EddiHeaterStatus = exports.EddiMode = exports.EddiBoost = exports.MyEnergi = void 0;
|
|
4
4
|
const Types_1 = require("./models/Types");
|
|
5
5
|
Object.defineProperty(exports, "EddiBoost", { enumerable: true, get: function () { return Types_1.EddiBoost; } });
|
|
6
|
+
Object.defineProperty(exports, "EddiHeaterStatus", { enumerable: true, get: function () { return Types_1.EddiHeaterStatus; } });
|
|
6
7
|
Object.defineProperty(exports, "EddiMode", { enumerable: true, get: function () { return Types_1.EddiMode; } });
|
|
7
8
|
Object.defineProperty(exports, "ZappiBoostMode", { enumerable: true, get: function () { return Types_1.ZappiBoostMode; } });
|
|
8
9
|
Object.defineProperty(exports, "ZappiChargeMode", { enumerable: true, get: function () { return Types_1.ZappiChargeMode; } });
|
|
10
|
+
Object.defineProperty(exports, "ZappiStatus", { enumerable: true, get: function () { return Types_1.ZappiStatus; } });
|
|
9
11
|
const MyEnergi_1 = require("./MyEnergi");
|
|
10
12
|
Object.defineProperty(exports, "MyEnergi", { enumerable: true, get: function () { return MyEnergi_1.MyEnergi; } });
|
package/dist/models/Types.d.ts
CHANGED
package/dist/models/Types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ZappiChargeMode = exports.ZappiBoostMode = exports.EddiMode = exports.EddiHeaterStatus = exports.EddiBoost = void 0;
|
|
3
|
+
exports.ZappiStatus = exports.ZappiChargeMode = exports.ZappiBoostMode = exports.EddiMode = exports.EddiHeaterStatus = exports.EddiBoost = void 0;
|
|
4
4
|
var EddiBoost;
|
|
5
5
|
(function (EddiBoost) {
|
|
6
6
|
EddiBoost["CancelHeater1"] = "1-1";
|
|
@@ -38,3 +38,12 @@ var ZappiChargeMode;
|
|
|
38
38
|
ZappiChargeMode[ZappiChargeMode["Eco"] = 2] = "Eco";
|
|
39
39
|
ZappiChargeMode[ZappiChargeMode["EcoPlus"] = 3] = "EcoPlus";
|
|
40
40
|
})(ZappiChargeMode = exports.ZappiChargeMode || (exports.ZappiChargeMode = {}));
|
|
41
|
+
var ZappiStatus;
|
|
42
|
+
(function (ZappiStatus) {
|
|
43
|
+
ZappiStatus["EvDisconnected"] = "A";
|
|
44
|
+
ZappiStatus["EvConnected"] = "B1";
|
|
45
|
+
ZappiStatus["WaitingForEv"] = "B2";
|
|
46
|
+
ZappiStatus["EvReadyToCharge"] = "C1";
|
|
47
|
+
ZappiStatus["Charging"] = "C2";
|
|
48
|
+
ZappiStatus["Fault"] = "F";
|
|
49
|
+
})(ZappiStatus = exports.ZappiStatus || (exports.ZappiStatus = {}));
|
package/dist/models/Zappi.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myenergi-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "NodeJS implementation of MyEnergi API for controlling Zappi, Eddi and other MyEnergi products",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"test": "env TS_NODE_PROJECT='tsconfig.testing.json' mocha -r ts-node/register tests/**/*-spec.ts",
|
|
13
|
-
"format": "prettier --write \"src/**/*.ts\" \"
|
|
13
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
14
14
|
"lint": "tslint -p tsconfig.json",
|
|
15
15
|
"prepare": "tsc",
|
|
16
16
|
"preversion": "npm test",
|