iobroker.ecoflow-mqtt
Version:
connects to ecoflow products
219 lines (207 loc) • 6.93 kB
JavaScript
const deviceStates = {
action: {
switch: {
latestQuotas: {
entity_type: 'switch',
device_class: 'switch',
role: 'switch',
name: 'Get latest Quotas',
payload_off: 'no trigger',
payload_on: 'trigger',
latestQuotas: { 0: 'no trigger', 1: 'trigger' },
},
},
},
info: {
number: {
msgCount: {
min: 0,
unit_of_measurement: '',
mult: 1,
entity_type: 'sensor',
name: 'received MSG#',
role: 'value',
},
},
diagnostic: {
status: {
entity_type: 'text',
entity_category: 'diagnostic',
name: 'Cloud Connection Status',
role: 'info',
status: { '-2': 'offline', 0: 'offline', 1: 'online' },
},
},
},
};
const deviceStatesDict = {
unknown: {
action: {
latestQuotas: { entity: 'switch' },
},
info: {
msgCount: { entity: 'number' },
status: { entity: 'diagnostic' },
},
},
};
const deviceCmd = {
unknown: {
action: {
latestQuotas: { msg: { cmdFunc: 20, cmdId: 1, dataLen: 0 } },
},
},
};
const protoMsg = {};
const msgNameObj = {
DisplayPropertyUpload: { cmdId: 21, cmdFunc: 254 },
};
const protobuf = require('protobufjs');
const compareUpdate = require('../ecoflow_utils.js').compareUpdate;
const setOnlineStatus = require('../ecoflow_utils.js').setOnlineStatus;
const setOfflineStatus = require('../ecoflow_utils.js').setOfflineStatus;
/**
*
* @param adapter - THIS transfer
* @param {object} stateDictObj - dictionary of states
* @param {object} stateObj - states definition
* @param {string} topic - the TOPIC is the Serial#
* @param {object} payloadarr - payload of MQTT telegram
* @param {string} devtype - device type
* @param {boolean} haenable -if HA is enabled
* @param {boolean} logged - if logged
*/
async function storeProtoPayload(adapter, stateDictObj, stateObj, topic, payloadarr, devtype, haenable, logged) {
let haUpdate = [];
if (payloadarr) {
if (stateDictObj) {
if (stateObj) {
for (let i = 0; i < payloadarr.length; i++) {
const payload = payloadarr[i];
for (let channel in payload) {
//other incomming data is ignored (EnergyPack/PowerPack/timeConfig...)
switch (channel) {
case 'test':
// all cases without nested states
await setOnlineStatus(adapter, topic);
for (let state in payload[channel]) {
let val;
let haupd;
switch (state) {
default:
val = payload[channel][state];
haupd = await compareUpdate(
adapter,
stateDictObj,
stateObj,
haenable,
topic,
channel,
state,
val,
channel,
logged,
);
if (Object.keys(haupd).length !== 0) {
haUpdate.push(haupd);
}
break;
}
}
break;
case 'info':
//channel info is only received when offline, no need to check the content
await setOfflineStatus(adapter, topic);
break;
default:
//nothing todo
break;
}
}
}
} else {
adapter.log.warn('storeStreamPayload no stateObj');
}
} else {
adapter.log.warn('storeStreamPayload no stateDictobj');
}
} else {
adapter.log.debug('nothing to process');
}
return haUpdate;
}
/**
* @param adapter - THIS transfer
* @param {any} serial - serial# of device
* @param {any} streamType - option to use
* @param {string} state - the state reference, state name
* @param {string | number | boolean} value - the value of the command
* @param {object} cmd - cmd dictionary
* @param {boolean} log - logging eneabled
*/
async function prepareProtoCmd(adapter, serial, streamType, state, value, cmd, log) {
if (state === 'latestQuotas') {
if (log === true) {
adapter.log.debug(`preparaing latestQuotas: ${serial}`);
}
let muster = {
header: {
src: 32,
dest: 32,
seq: Date.now(),
from: 'ios',
},
};
const root = protobuf.parse(protoSource).root;
const SetMessage = root.lookupType('setMessage');
const message = SetMessage.create(muster);
const messageBuffer = SetMessage.encode(message).finish();
return messageBuffer;
}
}
const protoSource = `
syntax = "proto3";
message setMessage {
setHeader header = 1;
}
message setValue {
optional int32 value = 1;
optional int32 value2 = 2;
}
message setHeader {
setValue pdata = 1;
int32 src = 2;
int32 dest = 3;
int32 d_src = 4;
int32 d_dest = 5;
int32 enc_type = 6;
int32 check_type = 7;
int32 cmd_func = 8;
int32 cmd_id = 9;
int32 data_len = 10;
int32 need_ack = 11;
int32 is_ack = 12;
int32 seq = 14;
int32 product_id = 15;
int32 version = 16;
int32 payload_ver = 17;
int32 time_snap = 18;
int32 is_rw_cmd = 19;
int32 is_queue = 20;
int32 ack_type = 21;
string code = 22;
string from = 23;
string module_sn = 24;
string device_sn = 25;
}
`;
module.exports = {
deviceStates,
deviceStatesDict,
deviceCmd,
protoMsg,
protoSource,
storeProtoPayload,
prepareProtoCmd,
msgNameObj,
};