myenergi-api 0.0.9-0 → 0.1.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myenergi-api",
3
- "version": "0.0.9-0",
3
+ "version": "0.1.0",
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",
@@ -25,13 +25,12 @@
25
25
  },
26
26
  "homepage": "https://github.com/bisand/myenergi-api#readme",
27
27
  "dependencies": {
28
- "dotenv": "^10.0.0",
29
- "node-digest-auth-client": "^1.0.6"
28
+ "dotenv": "^10.0.0"
30
29
  },
31
30
  "devDependencies": {
31
+ "@types/chai": "^4.2.22",
32
32
  "@types/mocha": "^9.0.0",
33
33
  "@types/node": "^16.11.9",
34
- "assert": "^2.0.0",
35
34
  "chai": "^4.3.4",
36
35
  "mocha": "^9.1.3",
37
36
  "ts-node": "^10.4.0",
package/src/AuthDigest.ts CHANGED
@@ -4,6 +4,7 @@ export class AuthDigest {
4
4
  private _password?: string | undefined;
5
5
  private _username?: string | undefined;
6
6
  private _initialized: boolean;
7
+ private _onError?: (errorMessage: string) => void;
7
8
 
8
9
  public get username(): string | undefined {
9
10
  return this._username;
@@ -20,8 +21,8 @@ export class AuthDigest {
20
21
  public get uri(): string | undefined {
21
22
  return this._uri;
22
23
  }
23
- private _algorithm?: string | undefined;
24
- public get algorithm(): string | undefined {
24
+ private _algorithm: string;
25
+ public get algorithm(): string {
25
26
  return this._algorithm;
26
27
  }
27
28
  private _response?: string | undefined;
@@ -54,11 +55,14 @@ export class AuthDigest {
54
55
  return result;
55
56
  }
56
57
 
57
- constructor(username: string, password: string) {
58
+ constructor(username: string, password: string, errorHandler?: (errorMessage: string) => void) {
58
59
  this._username = username;
59
60
  this._password = password;
60
61
  this._nc = 0;
61
62
  this._initialized = false;
63
+ this._algorithm = 'MD5';
64
+ if (errorHandler)
65
+ this._onError = errorHandler;
62
66
  }
63
67
 
64
68
  public init(wwwAuthHeader: string) {
@@ -89,19 +93,28 @@ export class AuthDigest {
89
93
  this._opaque = opaqueSplit[opaqueSplit.length - 1];
90
94
  this._opaque = this._opaque.substring(0, this._opaque.length - 1);
91
95
  }
96
+
97
+ if (item.indexOf('algorithm=') >= 0) {
98
+ let algorithmSplit = item.split('=');
99
+ this._algorithm = algorithmSplit[algorithmSplit.length - 1];
100
+ this._algorithm = this._algorithm.substring(0, this._algorithm.length);
101
+ if (this._onError && this.algorithm !== 'MD5') {
102
+ this._onError(`Algorithm ${this.algorithm} is ont supported. Only MD5 is supportet`);
103
+ }
104
+ }
92
105
  }
93
106
  this._initialized = true;
94
107
  }
95
108
 
96
109
  public getAuthorization(httpMethod: string, path: string): string {
97
- if(!this._initialized)
110
+ if (!this._initialized)
98
111
  return '';
99
112
 
100
113
  const nc = this.nc;
101
114
  const cnonce = this.cnonce;
102
- let HA1 = this.md5(this.username + ":" + this.realm + ":" + this._password);
103
- let HA2 = this.md5(httpMethod + ":" + path);
104
- let response = this.md5(HA1 + ":" + this.nonce + ":" + nc + ":" + cnonce + ":" + this.qop + ":" + HA2);
115
+ let HA1 = this.md5(this.username + ':' + this.realm + ':' + this._password);
116
+ let HA2 = this.md5(httpMethod + ':' + path);
117
+ let response = this.md5(HA1 + ':' + this.nonce + ':' + nc + ':' + cnonce + ':' + this.qop + ':' + HA2);
105
118
 
106
119
  let res = `Digest username="${this.username}",`;
107
120
  res += `realm="${this.realm}",`;
@@ -109,7 +122,7 @@ export class AuthDigest {
109
122
  res += `uri="${path}",`;
110
123
  res += `cnonce="${cnonce}",`;
111
124
  res += `nc=${nc},`;
112
- res += `algorithm=MD5,`;
125
+ res += `algorithm=${this.algorithm},`;
113
126
  res += `response="${response}",`;
114
127
  res += `qop="${this.qop}",`;
115
128
  res += `opaque="${this.opaque}"`;
package/src/Digest.ts CHANGED
@@ -7,7 +7,9 @@ export class Digest {
7
7
  private _authDigest?: AuthDigest;
8
8
 
9
9
  constructor(username: string, password: string) {
10
- this._authDigest = new AuthDigest(username, password);
10
+ this._authDigest = new AuthDigest(username, password, (err) => {
11
+ console.error(err);
12
+ });
11
13
  }
12
14
 
13
15
  private request(options: RequestOptions, data?: any, retryCount: number = 0): Promise<any> {
@@ -25,8 +27,7 @@ export class Digest {
25
27
  }
26
28
  retryCount++;
27
29
  const wwwAuth = res.headers["www-authenticate"] as string;
28
- if(!wwwAuth.startsWith('Digest'))
29
- {
30
+ if (!wwwAuth.startsWith('Digest')) {
30
31
  reject('Unsupported authentication method. Supported authentication schemes: Digest');
31
32
  return;
32
33
  }
package/src/MyEnergi.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Digest } from './Digest';
2
+ import { Zappi } from './models/Zappi';
2
3
 
3
4
  export enum ZappiChargeMode {
4
5
  Off = 4,
@@ -35,14 +36,34 @@ export class MyEnergi {
35
36
  this._digest = new Digest(this._config.username, this._config.password);
36
37
  }
37
38
 
38
- public async getStatus(): Promise<any> {
39
+ public async getStatusAll(): Promise<any> {
39
40
  const data = await this._digest.get(this._config.status_url);
40
41
  return data;
41
42
  }
42
43
 
43
- public async getZappi(): Promise<any> {
44
+ public async getStatusZappiAll(): Promise<Zappi[]> {
44
45
  const data = await this._digest.get(this._config.zappi_url);
45
- return data;
46
+ const jsonData = JSON.parse(data);
47
+ if (jsonData.zappi)
48
+ return Object.assign<Zappi[], any>([] as Zappi[], jsonData.zappi);
49
+ else
50
+ return [] as Zappi[];
51
+ }
52
+
53
+ public async getStatusZappi(serialNumber: string): Promise<Zappi | null> {
54
+ const data = await this._digest.get(this._config.zappi_url);
55
+ const jsonData = JSON.parse(data);
56
+ if (jsonData.zappi) {
57
+ const zappi = (Object.assign<Zappi[], any>([] as Zappi[], jsonData.zappi) as Zappi[]).find(zappi => {
58
+ return zappi.sno === serialNumber;
59
+ });
60
+ if (zappi)
61
+ return Object.assign<Zappi, any>({} as Zappi, zappi);
62
+ else
63
+ return null;
64
+ }
65
+ else
66
+ return null;
46
67
  }
47
68
 
48
69
  public async setZappiChargeMode(serialNo: string, chargeMode: ZappiChargeMode): Promise<any> {
@@ -0,0 +1,41 @@
1
+ export interface Zappi {
2
+ sno: string;
3
+ dat: string;
4
+ tim: string;
5
+ ectp1: number;
6
+ ectp2: number;
7
+ ectp3: number;
8
+ ectp4: number;
9
+ ectp5: number;
10
+ ectp6: number;
11
+ ectt1: string;
12
+ ectt2: string;
13
+ ectt3: string;
14
+ ectt4: string;
15
+ ectt5: string;
16
+ ectt6: string;
17
+ bsm: number;
18
+ bst: number;
19
+ cmt: number;
20
+ dst: number;
21
+ div: number;
22
+ frq: number;
23
+ fwv: string;
24
+ gen: number;
25
+ grd: number;
26
+ pha: number;
27
+ pri: number;
28
+ sta: number;
29
+ tz: number;
30
+ vol: number;
31
+ che: number;
32
+ bss: number;
33
+ lck: number;
34
+ pst: string;
35
+ zmo: number;
36
+ zs: number;
37
+ rdc: number;
38
+ rac: number;
39
+ rrac: number;
40
+ zsl: number;
41
+ }
@@ -1,10 +1,9 @@
1
1
  import { MyEnergi } from '../src/MyEnergi'
2
- import { equal } from "assert";
3
2
  import { expect } from 'chai'
4
3
 
5
4
  describe("MyEnergi Tests", () => {
6
5
  it("should be able to test", () => {
7
- equal(true, true);
6
+ expect(true).to.be.true;
8
7
  });
9
8
  it("should be able to create instance", () => {
10
9
  const myenergi = new MyEnergi('test', 'pwd');
package/tests/debug.ts CHANGED
@@ -5,18 +5,24 @@ import { ZappiBoostMode, ZappiChargeMode } from '../src/MyEnergi';
5
5
 
6
6
  dotenv.config();
7
7
  const myenergi = new MyEnergi(process.env.USERNAME as string, process.env.PASSWORD as string);
8
- myenergi.getStatus().then(val => {
8
+ myenergi.getStatusAll().then(val => {
9
9
  console.log(val);
10
- myenergi.getZappi().then(v => {
10
+ myenergi.getStatusZappiAll().then(v => {
11
11
  console.log(v);
12
- const sno: string = JSON.parse(v).zappi[0].sno;
12
+ const sno: string = v[0].sno;
13
13
  myenergi.setZappiChargeMode(sno, ZappiChargeMode.Fast).then(x => {
14
14
  console.log(x);
15
15
  myenergi.setZappiBoostMode(sno, ZappiBoostMode.Stop).then(x => {
16
16
  console.log(x);
17
17
  myenergi.setZappiGreenLevel(sno, 0).then(x => {
18
18
  console.log(x);
19
- exit();
19
+ myenergi.getStatusZappi(sno).then(x => {
20
+ console.log(x);
21
+ exit();
22
+ }).catch(err => {
23
+ console.error(err);
24
+ exit();
25
+ });
20
26
  }).catch(err => {
21
27
  console.error(err);
22
28
  exit();