iobroker.zendure-solarflow 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +71 -0
- package/admin/.watch/index.css +270 -0
- package/admin/.watch/index.js +59658 -0
- package/admin/build/index.css +2 -0
- package/admin/build/index.css.map +7 -0
- package/admin/build/index.js +145 -0
- package/admin/build/index.js.map +7 -0
- package/admin/donate-with-paypal.png +0 -0
- package/admin/index_m.html +18 -0
- package/admin/style.css +32 -0
- package/admin/zendure-solarflow.png +0 -0
- package/build/constants/paths.js +50 -0
- package/build/constants/paths.js.map +7 -0
- package/build/main.js +106 -0
- package/build/main.js.map +7 -0
- package/build/models/IPackData.js +17 -0
- package/build/models/IPackData.js.map +7 -0
- package/build/models/ISolarFlowDeviceDetails.js +17 -0
- package/build/models/ISolarFlowDeviceDetails.js.map +7 -0
- package/build/models/ISolarFlowPaths.js +17 -0
- package/build/models/ISolarFlowPaths.js.map +7 -0
- package/build/services/adapterService.js +387 -0
- package/build/services/adapterService.js.map +7 -0
- package/build/services/mqttService.js +242 -0
- package/build/services/mqttService.js.map +7 -0
- package/build/services/webService.js +103 -0
- package/build/services/webService.js.map +7 -0
- package/io-package.json +104 -0
- package/package.json +96 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/services/mqttService.ts"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\nimport { MqttClient } from \"mqtt\";\r\nimport * as mqtt from \"mqtt\";\r\nimport { ZendureSolarflow } from \"../main\";\r\nimport { ISolarFlowDeviceDetails } from \"../models/ISolarFlowDeviceDetails\";\r\nimport { addOrUpdatePackData, createSolarFlowStates, updateSolarFlowState } from \"./adapterService\";\r\n\r\nlet client: MqttClient | undefined = undefined;\r\nlet adapter: ZendureSolarflow | undefined = undefined;\r\n\r\nconst onConnected = () => {\r\n adapter?.log.info(\"Connected with MQTT!\");\r\n};\r\n\r\nconst onError = (error: any) => {\r\n adapter?.log.error(\"Connection to MQTT failed! Error: \" + error);\r\n};\r\n\r\nconst onSubscribe = (err: Error | null) => {\r\n if (err) {\r\n adapter?.log.error(\"Subscription to MQTT failed! Error: \" + err);\r\n } else {\r\n adapter?.log.info(\"Subscription successful!\");\r\n }\r\n};\r\n\r\nconst onMessage = async (topic: string, message: Buffer) => {\r\n if (adapter) {\r\n const splitted = topic.split(\"/\");\r\n const productKey = splitted[1];\r\n const deviceKey = splitted[2];\r\n\r\n const obj = JSON.parse(message.toString());\r\n\r\n // lastUpdate f\u00FCr den deviceKey setzen\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"lastUpdate\",\r\n new Date().getTime(),\r\n );\r\n\r\n if (\r\n obj.properties?.electricLevel != null &&\r\n obj.properties?.electricLevel != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"electricLevel\",\r\n obj.properties.electricLevel,\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputHomePower != null &&\r\n obj.properties?.outputHomePower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputHomePower\",\r\n obj.properties.outputHomePower,\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputLimit != null &&\r\n obj.properties?.outputLimit != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputLimit\",\r\n obj.properties.outputLimit,\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.outputPackPower != null &&\r\n obj.properties?.outputPackPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputPackPower\",\r\n obj.properties.outputPackPower,\r\n );\r\n\r\n // if outPutPackPower set packInputPower to 0\r\n updateSolarFlowState(adapter, productKey, deviceKey, \"packInputPower\", 0);\r\n }\r\n\r\n if (\r\n obj.properties?.packInputPower != null &&\r\n obj.properties?.packInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"packInputPower\",\r\n obj.properties.packInputPower,\r\n );\r\n\r\n // if packInputPower set outputPackPower to 0\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"outputPackPower\",\r\n 0,\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.solarInputPower != null &&\r\n obj.properties?.solarInputPower != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"solarInputPower\",\r\n obj.properties.solarInputPower,\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.remainInputTime != null &&\r\n obj.properties?.remainInputTime != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"remainInputTime\",\r\n obj.properties.remainInputTime,\r\n );\r\n }\r\n\r\n if (\r\n obj.properties?.remainOutTime != null &&\r\n obj.properties?.remainOutTime != undefined\r\n ) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"remainOutTime\",\r\n obj.properties.remainOutTime,\r\n );\r\n }\r\n\r\n if (obj.properties?.socSet != null && obj.properties?.socSet != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"socSet\",\r\n Number(obj.properties.socSet) / 10,\r\n );\r\n }\r\n\r\n if (obj.properties?.minSoc != null && obj.properties?.minSoc != undefined) {\r\n updateSolarFlowState(\r\n adapter,\r\n productKey,\r\n deviceKey,\r\n \"minSoc\",\r\n Number(obj.properties.minSoc) / 10,\r\n );\r\n }\r\n\r\n if (obj.packData) {\r\n addOrUpdatePackData(adapter, productKey, deviceKey, obj.packData);\r\n }\r\n }\r\n\r\n if (client) {\r\n //client.end();\r\n }\r\n};\r\n\r\nexport const setOutputLimit = async (\r\n adapter: ZendureSolarflow,\r\n productKey: string,\r\n deviceKey: string,\r\n limit: number,\r\n) => {\r\n if (client && productKey && deviceKey) {\r\n // Das Limit kann unter 100 nur in 30er Schritten gesetzt werden, dH. 30/60/90/100, wir rechnen das also um\r\n const currentLimit = (\r\n await adapter.getStateAsync(productKey + \".\" + deviceKey + \".outputLimit\")\r\n )?.val;\r\n\r\n if (currentLimit != null && currentLimit != undefined) {\r\n if (currentLimit != limit) {\r\n if (\r\n limit < 100 &&\r\n limit != 90 &&\r\n limit != 60 &&\r\n limit != 30 &&\r\n limit != 0\r\n ) {\r\n if (limit < 100 && limit > 90) {\r\n limit = 90;\r\n } else if (limit < 90 && limit > 60) {\r\n limit = 60;\r\n } else if (limit < 60 && limit > 30) {\r\n limit = 30;\r\n } else if (limit < 30) {\r\n limit = 30;\r\n }\r\n }\r\n\r\n // 'iot/{auth.productKey}/{auth.deviceKey}/properties/write' == Topic? Oder productKey,deviceKey aus Device Details?\r\n const topic = `iot/${productKey}/${deviceKey}/properties/write`;\r\n\r\n const outputlimit = { properties: { outputLimit: limit } };\r\n adapter.log.info(\r\n `Setting Output Limit for device key ${deviceKey} to ${limit}!`,\r\n );\r\n client?.publish(topic, JSON.stringify(outputlimit));\r\n } else {\r\n adapter.log.info(\r\n `Output Limit for device key ${deviceKey} is already at ${limit}!`,\r\n );\r\n }\r\n }\r\n }\r\n};\r\n\r\nexport const connectMqttClient = (_adapter: ZendureSolarflow) => {\r\n adapter = _adapter;\r\n\r\n const options: mqtt.IClientOptions = {\r\n clientId: adapter.accessToken,\r\n username: \"zenApp\",\r\n password: \"oK#PCgy6OZxd\",\r\n clean: true,\r\n protocolVersion: 5,\r\n };\r\n\r\n if (mqtt && adapter && adapter.paths) {\r\n client = mqtt.connect(\r\n \"mqtt://\" + adapter.paths.mqttUrl + \":\" + adapter.paths.mqttPort,\r\n options,\r\n ); // create a client\r\n\r\n if (client && adapter) {\r\n client.on(\"connect\", onConnected);\r\n client.on(\"error\", onError);\r\n\r\n // Subscribe to Topic (appkey von Zendure)\r\n adapter.deviceList.forEach((device: ISolarFlowDeviceDetails) => {\r\n // States erstellen\r\n if (adapter) {\r\n createSolarFlowStates(adapter, device.productKey, device.deviceKey);\r\n\r\n // Set electricLevel (soc) from device details.\r\n updateSolarFlowState(\r\n adapter,\r\n device.productKey,\r\n device.deviceKey,\r\n \"electricLevel\",\r\n device.electricity,\r\n );\r\n\r\n const reportTopic = `/${device.productKey}/${device.deviceKey}/properties/report`;\r\n const iotTopic = `iot/${device.productKey}/${device.deviceKey}/#`;\r\n\r\n adapter.log.info(`Subscribing to MQTT Topic: ${reportTopic}`);\r\n client?.subscribe(reportTopic, onSubscribe);\r\n adapter.log.info(`Subscribing to MQTT Topic: ${iotTopic}`);\r\n client?.subscribe(iotTopic, onSubscribe);\r\n }\r\n });\r\n\r\n client.on(\"message\", onMessage);\r\n }\r\n }\r\n};\r\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,WAAsB;AAGtB,4BAAiF;AAEjF,IAAI,SAAiC;AACrC,IAAI,UAAwC;AAE5C,MAAM,cAAc,MAAM;AACxB,qCAAS,IAAI,KAAK;AACpB;AAEA,MAAM,UAAU,CAAC,UAAe;AAC9B,qCAAS,IAAI,MAAM,uCAAuC;AAC5D;AAEA,MAAM,cAAc,CAAC,QAAsB;AACzC,MAAI,KAAK;AACP,uCAAS,IAAI,MAAM,yCAAyC;AAAA,EAC9D,OAAO;AACL,uCAAS,IAAI,KAAK;AAAA,EACpB;AACF;AAEA,MAAM,YAAY,OAAO,OAAe,YAAoB;AA1B5D;AA2BE,MAAI,SAAS;AACX,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,UAAM,aAAa,SAAS;AAC5B,UAAM,YAAY,SAAS;AAE3B,UAAM,MAAM,KAAK,MAAM,QAAQ,SAAS,CAAC;AAGzC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,KAAK,EAAE,QAAQ;AAAA,IACrB;AAEA,UACE,SAAI,eAAJ,mBAAgB,kBAAiB,UACjC,SAAI,eAAJ,mBAAgB,kBAAiB,QACjC;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAAA,IACF;AAEA,UACE,SAAI,eAAJ,mBAAgB,oBAAmB,UACnC,SAAI,eAAJ,mBAAgB,oBAAmB,QACnC;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAAA,IACF;AAEA,UACE,SAAI,eAAJ,mBAAgB,gBAAe,UAC/B,SAAI,eAAJ,mBAAgB,gBAAe,QAC/B;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAAA,IACF;AAEA,UACE,SAAI,eAAJ,mBAAgB,oBAAmB,UACnC,SAAI,eAAJ,mBAAgB,oBAAmB,QACnC;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAGA,sDAAqB,SAAS,YAAY,WAAW,kBAAkB,CAAC;AAAA,IAC1E;AAEA,UACE,SAAI,eAAJ,mBAAgB,mBAAkB,UAClC,SAAI,eAAJ,mBAAgB,mBAAkB,QAClC;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAGA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UACE,SAAI,eAAJ,mBAAgB,oBAAmB,UACnC,SAAI,eAAJ,mBAAgB,oBAAmB,QACnC;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAAA,IACF;AAEA,UACE,SAAI,eAAJ,mBAAgB,oBAAmB,UACnC,SAAI,eAAJ,mBAAgB,oBAAmB,QACnC;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAAA,IACF;AAEA,UACE,SAAI,eAAJ,mBAAgB,kBAAiB,UACjC,SAAI,eAAJ,mBAAgB,kBAAiB,QACjC;AACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,WAAW;AAAA,MACjB;AAAA,IACF;AAEA,UAAI,SAAI,eAAJ,mBAAgB,WAAU,UAAQ,SAAI,eAAJ,mBAAgB,WAAU,QAAW;AACzE;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,IAAI,WAAW,MAAM,IAAI;AAAA,MAClC;AAAA,IACF;AAEA,UAAI,SAAI,eAAJ,mBAAgB,WAAU,UAAQ,SAAI,eAAJ,mBAAgB,WAAU,QAAW;AACzE;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,IAAI,WAAW,MAAM,IAAI;AAAA,MAClC;AAAA,IACF;AAEA,QAAI,IAAI,UAAU;AAChB,qDAAoB,SAAS,YAAY,WAAW,IAAI,QAAQ;AAAA,IAClE;AAAA,EACF;AAEA,MAAI,QAAQ;AAAA,EAEZ;AACF;AAEO,MAAM,iBAAiB,OAC5BA,UACA,YACA,WACA,UACG;AAlML;AAmME,MAAI,UAAU,cAAc,WAAW;AAErC,UAAM,gBACJ,WAAMA,SAAQ,cAAc,aAAa,MAAM,YAAY,cAAc,MAAzE,mBACC;AAEH,QAAI,gBAAgB,QAAQ,gBAAgB,QAAW;AACrD,UAAI,gBAAgB,OAAO;AACzB,YACE,QAAQ,OACR,SAAS,MACT,SAAS,MACT,SAAS,MACT,SAAS,GACT;AACA,cAAI,QAAQ,OAAO,QAAQ,IAAI;AAC7B,oBAAQ;AAAA,UACV,WAAW,QAAQ,MAAM,QAAQ,IAAI;AACnC,oBAAQ;AAAA,UACV,WAAW,QAAQ,MAAM,QAAQ,IAAI;AACnC,oBAAQ;AAAA,UACV,WAAW,QAAQ,IAAI;AACrB,oBAAQ;AAAA,UACV;AAAA,QACF;AAGA,cAAM,QAAQ,OAAO,cAAc;AAEnC,cAAM,cAAc,EAAE,YAAY,EAAE,aAAa,MAAM,EAAE;AACzD,QAAAA,SAAQ,IAAI;AAAA,UACV,uCAAuC,gBAAgB;AAAA,QACzD;AACA,yCAAQ,QAAQ,OAAO,KAAK,UAAU,WAAW;AAAA,MACnD,OAAO;AACL,QAAAA,SAAQ,IAAI;AAAA,UACV,+BAA+B,2BAA2B;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,oBAAoB,CAAC,aAA+B;AAC/D,YAAU;AAEV,QAAM,UAA+B;AAAA,IACnC,UAAU,QAAQ;AAAA,IAClB,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,EACnB;AAEA,MAAI,QAAQ,WAAW,QAAQ,OAAO;AACpC,aAAS,KAAK;AAAA,MACZ,YAAY,QAAQ,MAAM,UAAU,MAAM,QAAQ,MAAM;AAAA,MACxD;AAAA,IACF;AAEA,QAAI,UAAU,SAAS;AACrB,aAAO,GAAG,WAAW,WAAW;AAChC,aAAO,GAAG,SAAS,OAAO;AAG1B,cAAQ,WAAW,QAAQ,CAAC,WAAoC;AAE9D,YAAI,SAAS;AACX,2DAAsB,SAAS,OAAO,YAAY,OAAO,SAAS;AAGlE;AAAA,YACE;AAAA,YACA,OAAO;AAAA,YACP,OAAO;AAAA,YACP;AAAA,YACA,OAAO;AAAA,UACT;AAEA,gBAAM,cAAc,IAAI,OAAO,cAAc,OAAO;AACpD,gBAAM,WAAW,OAAO,OAAO,cAAc,OAAO;AAEpD,kBAAQ,IAAI,KAAK,8BAA8B,aAAa;AAC5D,2CAAQ,UAAU,aAAa;AAC/B,kBAAQ,IAAI,KAAK,8BAA8B,UAAU;AACzD,2CAAQ,UAAU,UAAU;AAAA,QAC9B;AAAA,MACF,CAAC;AAED,aAAO,GAAG,WAAW,SAAS;AAAA,IAChC;AAAA,EACF;AACF;",
|
|
6
|
+
"names": ["adapter"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
|
+
var webService_exports = {};
|
|
26
|
+
__export(webService_exports, {
|
|
27
|
+
getDeviceList: () => getDeviceList,
|
|
28
|
+
login: () => login
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(webService_exports);
|
|
31
|
+
var import_paths = require("../constants/paths");
|
|
32
|
+
var import_axios = __toESM(require("axios"));
|
|
33
|
+
const config = {
|
|
34
|
+
headers: {
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
"Accept-Language": "de-DE",
|
|
37
|
+
appVersion: "4.3.1",
|
|
38
|
+
"User-Agent": "Zendure/4.3.1 (iPhone; iOS 14.4.2; Scale/3.00)",
|
|
39
|
+
Accept: "*/*",
|
|
40
|
+
Authorization: "Basic Q29uc3VtZXJBcHA6NX4qUmRuTnJATWg0WjEyMw==",
|
|
41
|
+
"Blade-Auth": "bearer (null)"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const login = (adapter) => {
|
|
45
|
+
var _a;
|
|
46
|
+
const auth = Buffer.from(
|
|
47
|
+
`${adapter.config.userName}:${adapter.config.password}`
|
|
48
|
+
).toString("base64");
|
|
49
|
+
config.headers.Authorization = "Basic " + auth;
|
|
50
|
+
const authBody = {
|
|
51
|
+
password: adapter.config.password,
|
|
52
|
+
account: adapter.config.userName,
|
|
53
|
+
appId: "121c83f761305d6cf7b",
|
|
54
|
+
appType: "iOS",
|
|
55
|
+
grantType: "password",
|
|
56
|
+
tenantId: ""
|
|
57
|
+
};
|
|
58
|
+
adapter.log.info("tokenurl: " + ((_a = adapter == null ? void 0 : adapter.paths) == null ? void 0 : _a.solarFlowTokenUrl));
|
|
59
|
+
if (adapter.paths && adapter.paths.solarFlowTokenUrl) {
|
|
60
|
+
return import_axios.default.post(adapter.paths.solarFlowTokenUrl, authBody, config).then(function(response) {
|
|
61
|
+
if (response.data.success) {
|
|
62
|
+
adapter.log.info("Login to Rest API successful!");
|
|
63
|
+
if (response.data.data.accessToken) {
|
|
64
|
+
return response.data.data.accessToken;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}).catch(function(error) {
|
|
68
|
+
adapter.log.error(error);
|
|
69
|
+
return Promise.reject("Failed to login to Zendure REST API!");
|
|
70
|
+
});
|
|
71
|
+
} else
|
|
72
|
+
return Promise.reject("Path error!");
|
|
73
|
+
};
|
|
74
|
+
const getDeviceList = (adapter) => {
|
|
75
|
+
adapter.setState("errorMessage", "");
|
|
76
|
+
adapter.log.info("Getting device list from Zendure Rest API!");
|
|
77
|
+
if (adapter.accessToken) {
|
|
78
|
+
config.headers["Blade-Auth"] = "bearer " + adapter.accessToken;
|
|
79
|
+
const body = {};
|
|
80
|
+
let paths = void 0;
|
|
81
|
+
if (adapter.config.server == "eu") {
|
|
82
|
+
paths = import_paths.pathsEu;
|
|
83
|
+
} else {
|
|
84
|
+
paths = import_paths.pathsGlobal;
|
|
85
|
+
}
|
|
86
|
+
return import_axios.default.post(paths.solarFlowQueryDeviceListUrl, JSON.stringify(body), config).then(function(response) {
|
|
87
|
+
if (response.data.data && response.data.data.length > 0) {
|
|
88
|
+
return response.data.data;
|
|
89
|
+
} else {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
adapter.log.error("No Access Token found!");
|
|
95
|
+
return Promise.reject("No Access Token found!");
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
99
|
+
0 && (module.exports = {
|
|
100
|
+
getDeviceList,
|
|
101
|
+
login
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=webService.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/services/webService.ts"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/indent */\r\nimport { pathsEu, pathsGlobal } from \"../constants/paths\";\r\nimport { ZendureSolarflow } from \"../main\";\r\nimport axios from \"axios\";\r\nimport { ISolarFlowDeviceDetails } from \"../models/ISolarFlowDeviceDetails\";\r\n\r\nconst config = {\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n \"Accept-Language\": \"de-DE\",\r\n appVersion: \"4.3.1\",\r\n \"User-Agent\": \"Zendure/4.3.1 (iPhone; iOS 14.4.2; Scale/3.00)\",\r\n Accept: \"*/*\",\r\n Authorization: \"Basic Q29uc3VtZXJBcHA6NX4qUmRuTnJATWg0WjEyMw==\",\r\n \"Blade-Auth\": \"bearer (null)\",\r\n },\r\n};\r\n\r\n/* eslint-disable @typescript-eslint/indent */\r\nexport const login = (adapter: ZendureSolarflow) => {\r\n const auth = Buffer.from(\r\n `${adapter.config.userName}:${adapter.config.password}`,\r\n ).toString(\"base64\");\r\n\r\n config.headers.Authorization = \"Basic \" + auth;\r\n\r\n const authBody = {\r\n password: adapter.config.password,\r\n account: adapter.config.userName,\r\n appId: \"121c83f761305d6cf7b\",\r\n appType: \"iOS\",\r\n grantType: \"password\",\r\n tenantId: \"\",\r\n };\r\n adapter.log.info(\"tokenurl: \" + adapter?.paths?.solarFlowTokenUrl)\r\n if (adapter.paths && adapter.paths.solarFlowTokenUrl) {\r\n return axios\r\n .post(adapter.paths.solarFlowTokenUrl, authBody, config)\r\n .then(function (response) {\r\n if (response.data.success) {\r\n adapter.log.info(\"Login to Rest API successful!\");\r\n\r\n if (response.data.data.accessToken) {\r\n return response.data.data.accessToken;\r\n }\r\n }\r\n })\r\n .catch(function (error) {\r\n adapter.log.error(error);\r\n return Promise.reject(\"Failed to login to Zendure REST API!\");\r\n });\r\n }\r\n else return Promise.reject(\"Path error!\");\r\n};\r\n\r\nexport const getDeviceList = (adapter: ZendureSolarflow) => {\r\n adapter.setState(\"errorMessage\", \"\");\r\n adapter.log.info(\"Getting device list from Zendure Rest API!\");\r\n\r\n if (adapter.accessToken) {\r\n config.headers[\"Blade-Auth\"] = \"bearer \" + adapter.accessToken;\r\n\r\n const body = {};\r\n\r\n let paths = undefined;\r\n\r\n if (adapter.config.server == \"eu\") {\r\n paths = pathsEu;\r\n } else {\r\n paths = pathsGlobal;\r\n }\r\n\r\n return axios\r\n .post(paths.solarFlowQueryDeviceListUrl, JSON.stringify(body), config)\r\n .then(function (response) {\r\n if (response.data.data && response.data.data.length > 0) {\r\n return response.data.data as ISolarFlowDeviceDetails[];\r\n } else {\r\n return [];\r\n }\r\n });\r\n } else {\r\n adapter.log.error(\"No Access Token found!\");\r\n return Promise.reject(\"No Access Token found!\");\r\n }\r\n};\r\n\r\n/* export const createDeveloperAccount = (adapter: ZendureSolarflow) => {\r\n adapter.log.info(\"Function createDeveloperAccount\");\r\n\r\n adapter.setState(\"errorMessage\", \"\");\r\n\r\n const body = {\r\n snNumber: adapter.snNumber,\r\n account: adapter.config.userName,\r\n };\r\n\r\n let paths = undefined;\r\n\r\n if (adapter.config.server == \"eu\") {\r\n paths = pathsEu;\r\n } else {\r\n paths = pathsGlobal;\r\n }\r\n\r\n return axios\r\n .post(paths.solarFlowDevRegisterUrl, JSON.stringify(body), config)\r\n .then(function (response) {\r\n adapter.log.info(\"Successfully created Developer Account!\");\r\n\r\n if (response.data && response.data.success == true) {\r\n return response.data.data;\r\n } else {\r\n console.warn(\"No Response Data!\");\r\n return undefined;\r\n }\r\n })\r\n .catch(function (error) {\r\n adapter.setObjectNotExists(\"errorMessage\", {\r\n type: \"state\",\r\n common: {\r\n name: \"errorMessage\",\r\n type: \"string\",\r\n role: \"indicator\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n adapter.setState(\r\n \"errorMessage\",\r\n error.response?.data?.code + \" - \" + error.response.data.msg,\r\n );\r\n\r\n if (error.response?.data?.code && error.response?.data?.msg) {\r\n // The request was made and the server responded with a status code\r\n // that falls out of the range of 2xx\r\n adapter.log.error(\r\n \"Failed to created Zendure Developer Account: \" +\r\n error.response?.data?.code +\r\n \" - \" +\r\n error.response.data.msg,\r\n );\r\n }\r\n\r\n return Promise.reject(\"Failed to created Zendure Developer Account!\");\r\n });\r\n};*/\r\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAqC;AAErC,mBAAkB;AAGlB,MAAM,SAAS;AAAA,EACb,SAAS;AAAA,IACP,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,cAAc;AAAA,EAChB;AACF;AAGO,MAAM,QAAQ,CAAC,YAA8B;AAnBpD;AAoBE,QAAM,OAAO,OAAO;AAAA,IAClB,GAAG,QAAQ,OAAO,YAAY,QAAQ,OAAO;AAAA,EAC/C,EAAE,SAAS,QAAQ;AAEnB,SAAO,QAAQ,gBAAgB,WAAW;AAE1C,QAAM,WAAW;AAAA,IACf,UAAU,QAAQ,OAAO;AAAA,IACzB,SAAS,QAAQ,OAAO;AAAA,IACxB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AACA,UAAQ,IAAI,KAAK,iBAAe,wCAAS,UAAT,mBAAgB,kBAAiB;AACjE,MAAI,QAAQ,SAAS,QAAQ,MAAM,mBAAmB;AACpD,WAAO,aAAAA,QACJ,KAAK,QAAQ,MAAM,mBAAmB,UAAU,MAAM,EACtD,KAAK,SAAU,UAAU;AACxB,UAAI,SAAS,KAAK,SAAS;AACzB,gBAAQ,IAAI,KAAK,+BAA+B;AAEhD,YAAI,SAAS,KAAK,KAAK,aAAa;AAClC,iBAAO,SAAS,KAAK,KAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,CAAC,EACA,MAAM,SAAU,OAAO;AACtB,cAAQ,IAAI,MAAM,KAAK;AACvB,aAAO,QAAQ,OAAO,sCAAsC;AAAA,IAC9D,CAAC;AAAA,EACL;AACK,WAAO,QAAQ,OAAO,aAAa;AAC1C;AAEO,MAAM,gBAAgB,CAAC,YAA8B;AAC1D,UAAQ,SAAS,gBAAgB,EAAE;AACnC,UAAQ,IAAI,KAAK,4CAA4C;AAE7D,MAAI,QAAQ,aAAa;AACvB,WAAO,QAAQ,gBAAgB,YAAY,QAAQ;AAEnD,UAAM,OAAO,CAAC;AAEd,QAAI,QAAQ;AAEZ,QAAI,QAAQ,OAAO,UAAU,MAAM;AACjC,cAAQ;AAAA,IACV,OAAO;AACL,cAAQ;AAAA,IACV;AAEA,WAAO,aAAAA,QACJ,KAAK,MAAM,6BAA6B,KAAK,UAAU,IAAI,GAAG,MAAM,EACpE,KAAK,SAAU,UAAU;AACxB,UAAI,SAAS,KAAK,QAAQ,SAAS,KAAK,KAAK,SAAS,GAAG;AACvD,eAAO,SAAS,KAAK;AAAA,MACvB,OAAO;AACL,eAAO,CAAC;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACL,OAAO;AACL,YAAQ,IAAI,MAAM,wBAAwB;AAC1C,WAAO,QAAQ,OAAO,wBAAwB;AAAA,EAChD;AACF;",
|
|
6
|
+
"names": ["axios"]
|
|
7
|
+
}
|
package/io-package.json
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"name": "zendure-solarflow",
|
|
4
|
+
"version": "0.1.0-alpha.0",
|
|
5
|
+
"news": {
|
|
6
|
+
"0.1.0-alpha.0": {
|
|
7
|
+
"en": "Get battery information\nReset states if no new data comes in (e.g. when Hub goes offline). Currently the last value still persist when Hub goes offline, so you may have 'pseudo' data in your states.",
|
|
8
|
+
"de": "Batterieinformationen erhalten\nRücksetzen von Zuständen, wenn keine neuen Daten einkommen (z.B. wenn Hub offline geht). Derzeit bleibt der letzte Wert immer noch bestehen, wenn Hub offline geht, so dass Sie möglicherweise Pseudodaten in Ihren Staaten haben.",
|
|
9
|
+
"ru": "Получить информацию о аккумуляторе\nСброс состояния, если нет новых данных в (например, когда Hub выходит в оффлайн.) В настоящее время последнее значение по-прежнему сохраняется, когда Hub идет оффлайн, так что вы можете иметь данные pseudo в ваших штатах.",
|
|
10
|
+
"pt": "Obtenha informações da bateria\nRepor estados se nenhum novo dado entrar (por exemplo, quando o Hub estiver offline.) Atualmente, o último valor ainda persiste quando o Hub fica offline, então você pode ter pseudo dados em seus estados.",
|
|
11
|
+
"nl": "Haal batterij informatie\nReset staat als er geen nieuwe data binnenkomt als Hub offline gaat. Momenteel houdt de laatste waarde nog vol als Hub offline gaat, dus je hebt misschien pseudo gegevens in je staat.",
|
|
12
|
+
"fr": "Obtenir des informations de batterie\nRéinitialiser les états s'il n'y a pas de nouvelles données (p. ex. lorsque Hub va hors ligne.) Actuellement, la dernière valeur persiste quand Hub va hors ligne, de sorte que vous pouvez avoir des données pseudo dans vos états.",
|
|
13
|
+
"it": "Ottieni informazioni sulla batteria\nRipristina gli stati se non entrano nuovi dati (ad esempio quando Hub va offline.) Attualmente l'ultimo valore persiste ancora quando Hub va offline, quindi potresti avere dati pseudo nei tuoi stati.",
|
|
14
|
+
"es": "Obtener información de la batería\nReiniciar estados si no hay nuevos datos entra (por ejemplo, cuando el Hub se desconecta). Actualmente el último valor todavía persiste cuando Hub va fuera de línea, por lo que puede tener datos pseudo en sus estados.",
|
|
15
|
+
"pl": "Informacje o baterie\nReset stwierdza, że nie ma żadnych nowych danych (np. gdy Hub odchodzi z linii). Obecnie ostatnia wartość nadal utrzymuje się, gdy Hub odchodzi z linii, więc może mieć dane w swoich stanach.",
|
|
16
|
+
"uk": "Отримати інформацію про акумулятор\nОновити стани, якщо нові дані не надходять (наприклад, коли Hub вимкнено.) В даний час останнє значення все ще зберігається, коли Hub йде в автономному режимі, тому ви можете мати псевдо дані в ваших штатах.",
|
|
17
|
+
"zh-cn": "Get电池信息\n如果没有新的数据(例如,在Herb流落线时)出现新的数据,则重新确定。 目前,在Hhub偏离线时仍存在最后价值,因此,你可能在贵国有假的数据。."
|
|
18
|
+
},
|
|
19
|
+
"0.0.1": {
|
|
20
|
+
"en": "initial release",
|
|
21
|
+
"de": "Erstveröffentlichung",
|
|
22
|
+
"ru": "Начальная версия",
|
|
23
|
+
"pt": "lançamento inicial",
|
|
24
|
+
"nl": "Eerste uitgave",
|
|
25
|
+
"fr": "Première version",
|
|
26
|
+
"it": "Versione iniziale",
|
|
27
|
+
"es": "Versión inicial",
|
|
28
|
+
"pl": "Pierwsze wydanie",
|
|
29
|
+
"uk": "Початкова версія",
|
|
30
|
+
"zh-cn": "首次出版"
|
|
31
|
+
},
|
|
32
|
+
"0.0.2": {
|
|
33
|
+
"en": "Bug fixes and improvements"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"title": "Zendure Solarflow",
|
|
37
|
+
"titleLang": {
|
|
38
|
+
"en": "Zendure Solarflow",
|
|
39
|
+
"de": "Zendure Solarflow",
|
|
40
|
+
"ru": "Зендуре Соларфлоу",
|
|
41
|
+
"pt": "Zendure Solarflow",
|
|
42
|
+
"nl": "Zendure Solarflow",
|
|
43
|
+
"fr": "Flux solaire Zendure",
|
|
44
|
+
"it": "Zendur Solarflow",
|
|
45
|
+
"es": "Zendure Solarflow",
|
|
46
|
+
"pl": "Zendure Solarflow",
|
|
47
|
+
"uk": "Zendure Solarflow",
|
|
48
|
+
"zh-cn": "Zendure Solarflow"
|
|
49
|
+
},
|
|
50
|
+
"desc": {
|
|
51
|
+
"en": "zendure-solarflow",
|
|
52
|
+
"de": "Zendure-Solarflow",
|
|
53
|
+
"ru": "Zendure-Solarflow",
|
|
54
|
+
"pt": "zendure-solarflow",
|
|
55
|
+
"nl": "zendure-solarflow",
|
|
56
|
+
"fr": "zendure-solarflow",
|
|
57
|
+
"it": "zendure-solarflow",
|
|
58
|
+
"es": "flujo-solar-zendure",
|
|
59
|
+
"pl": "zendure-solarflow",
|
|
60
|
+
"uk": "zendure-solarflow",
|
|
61
|
+
"zh-cn": "zendure-solarflow"
|
|
62
|
+
},
|
|
63
|
+
"authors": [
|
|
64
|
+
"Peter <peter.frommert@outlook.com>"
|
|
65
|
+
],
|
|
66
|
+
"keywords": [
|
|
67
|
+
"Zendure",
|
|
68
|
+
"Solarflow"
|
|
69
|
+
],
|
|
70
|
+
"license": "MIT",
|
|
71
|
+
"platform": "Javascript/Node.js",
|
|
72
|
+
"main": "build/main.js",
|
|
73
|
+
"icon": "zendure-solarflow.png",
|
|
74
|
+
"enabled": true,
|
|
75
|
+
"extIcon": "https://raw.githubusercontent.com/nograx/ioBroker.zendure-solarflow/main/admin/zendure-solarflow.png",
|
|
76
|
+
"readme": "https://github.com/nograx/ioBroker.zendure-solarflow/blob/main/README.md",
|
|
77
|
+
"loglevel": "info",
|
|
78
|
+
"mode": "daemon",
|
|
79
|
+
"type": "energy",
|
|
80
|
+
"compact": true,
|
|
81
|
+
"connectionType": "cloud",
|
|
82
|
+
"dataSource": "poll",
|
|
83
|
+
"adminUI": {
|
|
84
|
+
"config": "materialize"
|
|
85
|
+
},
|
|
86
|
+
"eraseOnUpload": true,
|
|
87
|
+
"dependencies": [
|
|
88
|
+
{
|
|
89
|
+
"js-controller": ">=3.3.22"
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
"globalDependencies": [
|
|
93
|
+
{
|
|
94
|
+
"admin": ">=5.0.0"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
"native": {
|
|
99
|
+
"username": "",
|
|
100
|
+
"password": ""
|
|
101
|
+
},
|
|
102
|
+
"objects": [],
|
|
103
|
+
"instanceObjects": []
|
|
104
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "iobroker.zendure-solarflow",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "zendure-solarflow",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Peter",
|
|
7
|
+
"email": "peter.frommert@outlook.com"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/nograx/ioBroker.zendure-solarflow",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"Zendure",
|
|
13
|
+
"Solarflow"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/nograx/ioBroker.zendure-solarflow.git"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">= 16"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@iobroker/adapter-core": "^3.0.3",
|
|
24
|
+
"axios": "^1.5.1",
|
|
25
|
+
"mqtt": "^5.1.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@alcalzone/release-script": "^3.6.0",
|
|
29
|
+
"@alcalzone/release-script-plugin-iobroker": "^3.6.0",
|
|
30
|
+
"@alcalzone/release-script-plugin-license": "^3.5.9",
|
|
31
|
+
"@alcalzone/release-script-plugin-manual-review": "^3.5.9",
|
|
32
|
+
"@iobroker/adapter-dev": "^1.2.0",
|
|
33
|
+
"@iobroker/adapter-react": "2.0.22",
|
|
34
|
+
"@iobroker/testing": "^4.1.0",
|
|
35
|
+
"@material-ui/core": "^4.12.4",
|
|
36
|
+
"@tsconfig/node16": "^16.1.1",
|
|
37
|
+
"@types/chai": "^4.3.6",
|
|
38
|
+
"@types/chai-as-promised": "^7.1.6",
|
|
39
|
+
"@types/mocha": "^10.0.2",
|
|
40
|
+
"@types/node": "^16.18.57",
|
|
41
|
+
"@types/proxyquire": "^1.3.29",
|
|
42
|
+
"@types/react": "^17.0.67",
|
|
43
|
+
"@types/react-dom": "^17.0.21",
|
|
44
|
+
"@types/sinon": "^10.0.18",
|
|
45
|
+
"@types/sinon-chai": "^3.2.10",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
|
47
|
+
"@typescript-eslint/parser": "^6.7.4",
|
|
48
|
+
"chai": "^4.3.10",
|
|
49
|
+
"chai-as-promised": "^7.1.1",
|
|
50
|
+
"eslint": "^8.50.0",
|
|
51
|
+
"eslint-plugin-react": "^7.33.2",
|
|
52
|
+
"mocha": "^10.2.0",
|
|
53
|
+
"proxyquire": "^2.1.3",
|
|
54
|
+
"react": "^17.0.2",
|
|
55
|
+
"react-dom": "^17.0.2",
|
|
56
|
+
"rimraf": "^5.0.5",
|
|
57
|
+
"sinon": "^15.2.0",
|
|
58
|
+
"sinon-chai": "^3.7.0",
|
|
59
|
+
"source-map-support": "^0.5.21",
|
|
60
|
+
"ts-node": "^10.9.1",
|
|
61
|
+
"typescript": "~5.0.4"
|
|
62
|
+
},
|
|
63
|
+
"main": "build/main.js",
|
|
64
|
+
"files": [
|
|
65
|
+
"admin{,/!(src)/**}/!(tsconfig|tsconfig.*|.eslintrc).{json,json5}",
|
|
66
|
+
"admin{,/!(src)/**}/*.{html,css,png,svg,jpg,js}",
|
|
67
|
+
"admin/build/",
|
|
68
|
+
"build/",
|
|
69
|
+
"www/",
|
|
70
|
+
"io-package.json",
|
|
71
|
+
"LICENSE"
|
|
72
|
+
],
|
|
73
|
+
"scripts": {
|
|
74
|
+
"prebuild": "rimraf build admin/build",
|
|
75
|
+
"build": "build-adapter all",
|
|
76
|
+
"watch": "build-adapter all --watch",
|
|
77
|
+
"prebuild:ts": "rimraf build",
|
|
78
|
+
"build:ts": "build-adapter ts",
|
|
79
|
+
"watch:ts": "build-adapter ts --watch",
|
|
80
|
+
"prebuild:react": "rimraf admin/build",
|
|
81
|
+
"build:react": "build-adapter react",
|
|
82
|
+
"watch:react": "build-adapter react --watch",
|
|
83
|
+
"test:ts": "mocha --config test/mocharc.custom.json src/**/*.test.ts",
|
|
84
|
+
"test:package": "mocha test/package --exit",
|
|
85
|
+
"test:integration": "mocha test/integration --exit",
|
|
86
|
+
"test": "npm run test:ts && npm run test:package",
|
|
87
|
+
"check": "tsc --noEmit && tsc --noEmit -p admin/tsconfig.json",
|
|
88
|
+
"lint": "eslint --ext .ts,.tsx src/ admin/src/",
|
|
89
|
+
"translate": "translate-adapter",
|
|
90
|
+
"release": "release-script"
|
|
91
|
+
},
|
|
92
|
+
"bugs": {
|
|
93
|
+
"url": "https://github.com/nograx/ioBroker.zendure-solarflow/issues"
|
|
94
|
+
},
|
|
95
|
+
"readmeFilename": "README.md"
|
|
96
|
+
}
|