diff --git a/src/decoder.cpp b/src/decoder.cpp index b7885cfd0..d4a7845ba 100644 --- a/src/decoder.cpp +++ b/src/decoder.cpp @@ -125,6 +125,48 @@ double TheengsDecoder::value_from_hex_string(const char* data_str, return value; } +/* + * @brief Extracts bit-aligned values from a hex string. + * Bit 0 is the least significant bit of the first byte. + */ +double TheengsDecoder::value_from_bit_string(const char* data_str, + int bit_offset, int bit_length, + bool canBeNegative) { + if (bit_offset < 0 || bit_length <= 0 || bit_length > 63) { + return 0; + } + + size_t data_chars = strlen(data_str); + size_t required_chars = ((size_t)(bit_offset + bit_length + 7) / 8) * 2; + if (data_chars < required_chars) { + return 0; + } + + unsigned long long value = 0; + for (int i = 0; i < bit_length; ++i) { + int abs_bit = bit_offset + i; + size_t byte_idx = (size_t)abs_bit / 8; + uint8_t bit_idx = (uint8_t)(abs_bit % 8); + size_t hex_idx = byte_idx * 2; + + uint8_t byte = (uint8_t)((getBinaryData(data_str[hex_idx]) << 4) | + getBinaryData(data_str[hex_idx + 1])); + if ((byte >> bit_idx) & 0x01) { + value |= (1ULL << i); + } + } + + long long signed_value = (long long)value; + if (canBeNegative) { + unsigned long long sign_bit = (1ULL << (bit_length - 1)); + if (value & sign_bit) { + signed_value -= (long long)(1ULL << bit_length); + } + } + + return (double)signed_value; +} + /* * @brief Removes the underscores at the beginning of key strings * when duplicate properties exist in a device. @@ -695,7 +737,8 @@ int TheengsDecoder::decodeBLEJson(JsonObject& jsondata) { if (checkPropCondition(prop["condition"], svc_data, mfg_data, dev_name)) { JsonArray decoder = prop["decoder"]; - if (strstr((const char*)decoder[0], "value_from_hex_data") != nullptr) { + if (strstr((const char*)decoder[0], "value_from_hex_data") != nullptr || + strstr((const char*)decoder[0], "value_from_bit_data") != nullptr) { const char* src = svc_data; if (strstr((const char*)decoder[1], MFG_DATA)) { src = mfg_data; @@ -706,7 +749,21 @@ int TheengsDecoder::decodeBLEJson(JsonObject& jsondata) { static double cal_val = 0; std::string proc_str = ""; - if (data_index_is_valid(src, decoder[2].as(), decoder[3].as())) { + if (strstr((const char*)decoder[0], "value_from_bit_data") != nullptr) { + int bit_offset = decoder[2].as(); + int bit_length = decoder[3].as(); + size_t required_chars = ((size_t)(bit_offset + bit_length + 7) / 8) * 2; + + if (data_index_is_valid(src, 0, required_chars)) { + temp_val = value_from_bit_string( + src, + bit_offset, + bit_length, + decoder[4].isNull() ? true : decoder[4].as()); + } else { + break; + } + } else if (data_index_is_valid(src, decoder[2].as(), decoder[3].as())) { decoder_function dec_fun = &TheengsDecoder::value_from_hex_string; if (strstr((const char*)decoder[0], "bf") != nullptr) { @@ -819,6 +876,28 @@ int TheengsDecoder::decodeBLEJson(JsonObject& jsondata) { } } + /* Optional enum-style lookup for numeric decoders. */ + if (prop.containsKey("lookup")) { + JsonArray lookup = prop["lookup"]; + for (unsigned int i = 0; i + 1 < lookup.size(); i += 2) { + long long lookup_key = LLONG_MIN; + + if (lookup[i].is()) { + const char* key_str = lookup[i].as(); + if (key_str != nullptr) { + lookup_key = strtoll(key_str, NULL, 16); + } + } + + if (lookup_key != LLONG_MIN && + (long long)temp_val == lookup_key && + lookup[i + 1].is()) { + proc_str = lookup[i + 1].as(); + break; + } + } + } + /* If there is any underscores at the beginning of the property name, there is multiple * properties of this type, we need remove the underscores for creating the key. */ diff --git a/src/decoder.h b/src/decoder.h index 0c590acb2..0c0bdf160 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -177,6 +177,7 @@ class TheengsDecoder { UT363BT, VICTRON_ENCR, VICTBSC, + VICTORIONTR, VICTORIONXS, VICTSBP, VICTSBS, @@ -202,6 +203,7 @@ class TheengsDecoder { private: void reverse_hex_data(const char* in, char* out, int l); double value_from_hex_string(const char* data_str, int offset, int data_length, bool reverse, bool canBeNegative = true, bool isFloat = false); + double value_from_bit_string(const char* data_str, int bit_offset, int bit_length, bool canBeNegative = true); double bf_value_from_hex_string(const char* data_str, int offset, int data_length, bool reverse, bool canBeNegative = true, bool isFloat = false); bool data_index_is_valid(const char* str, size_t index, size_t len); bool data_length_is_valid(size_t data_len, size_t default_min, const JsonArray& condition, int *idx); diff --git a/src/devices.h b/src/devices.h index 7013cff14..b509e3b94 100644 --- a/src/devices.h +++ b/src/devices.h @@ -123,6 +123,7 @@ #include "devices/UT363BT_json.h" #include "devices/VICTRON__ENCR_json.h" #include "devices/VICTRON_BSC_json.h" +#include "devices/VICTRON_ORIONTR_json.h" #include "devices/VICTRON_ORIONXS_json.h" #include "devices/VICTRON_SBP_json.h" #include "devices/VICTRON_SBS_json.h" @@ -276,6 +277,7 @@ const char* _devices[][2] = { {_UT363BT_json, _UT363BT_json_props}, {_VICTRON_ENCR_json, _VICTRON_ENCR_json_props}, {_VICTBSC_json, _VICTBSC_json_props}, + {_VICTORIONTR_json, _VICTORIONTR_json_props}, {_VICTORIONXS_json, _VICTORIONXS_json_props}, {_VICTSBP_json, _VICTSBP_json_props}, {_VICTSBS_json, _VICTSBS_json_props}, diff --git a/src/devices/VICTRON_BAT_MON_json.h b/src/devices/VICTRON_BAT_MON_json.h new file mode 100644 index 000000000..e21972be1 --- /dev/null +++ b/src/devices/VICTRON_BAT_MON_json.h @@ -0,0 +1,83 @@ +const char* _VICTRON_BAT_MON_json = "{\"brand\":\"Victron Energy\",\"model\":\"Bat Mon\",\"model_id\":\"VICTRON_BAT_MON\",\"tag\":\"0c48\",\"condition\":[\"manufacturerdata\",\"=\",50,\"index\",0,\"e10211\",\"&\",\"manufacturerdata\",\"index\",8,\"83a3\",\"&\",\"manufacturerdata\",\"index\",12,\"02ffff\"],\"properties\":{\"ttg\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",80,16,false]},\"volt\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",96,16,true],\"post_proc\":[\"/\",100]},\"alarm_reason\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",112,16,false]},\"aux_voltage\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",128,16,true],\"post_proc\":[\"/\",100]},\"aux_input\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",144,2,false],\"lookup\":[\"00\",\"auxiliary voltage\",\"01\",\"mid-point voltage\",\"02\",\"battery temperature\",\"03\",\"none\"]},\"current\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",146,22,true],\"post_proc\":[\"/\",1000]},\"consumed_ah\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",168,20,true],\"post_proc\":[\"/\",-10]},\"soc\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",188,10,false],\"post_proc\":[\"/\",10]}}}"; +/*R""""( +{ + "brand":"Victron Energy", + "model":"Bat Mon", + "model_id":"VICTRON_BAT_MON", + "tag":"0c48", + "condition":["manufacturerdata", "=", 50, "index", 0, "e10211", "&", "manufacturerdata", "index", 8, "83a3", "&", "manufacturerdata", "index", 12, "02ffff"], + "properties":{ + "ttg":{ + "decoder":["value_from_bit_data", "manufacturerdata", 80, 16, false] + }, + "volt":{ + "decoder":["value_from_bit_data", "manufacturerdata", 96, 16, true], + "post_proc":["/", 100] + }, + "alarm_reason":{ + "decoder":["value_from_bit_data", "manufacturerdata", 112, 16, false] + }, + "aux_voltage":{ + "decoder":["value_from_bit_data", "manufacturerdata", 128, 16, true], + "post_proc":["/", 100] + }, + "aux_input":{ + "decoder":["value_from_bit_data", "manufacturerdata", 144, 2, false], + "lookup":["00", "auxiliary voltage", + "01", "mid-point voltage", + "02", "battery temperature", + "03", "none"] + }, + "current":{ + "decoder":["value_from_bit_data", "manufacturerdata", 146, 22, true], + "post_proc":["/", 1000] + }, + "consumed_ah":{ + "decoder":["value_from_bit_data", "manufacturerdata", 168, 20, true], + "post_proc":["/", -10] + }, + "soc":{ + "decoder":["value_from_bit_data", "manufacturerdata", 188, 10, false], + "post_proc":["/", 10] + } + } +})"""";*/ + +const char* _VICTRON_BAT_MON_json_props = "{\"properties\":{\"ttg\":{\"unit\":\"min\",\"name\":\"time to go\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"alarm_reason\":{\"unit\":\"int\",\"name\":\"alarm reason\"},\"aux_voltage\":{\"unit\":\"V\",\"name\":\"auxiliary voltage\"},\"aux_input\":{\"unit\":\"string\",\"name\":\"aux input\"},\"current\":{\"unit\":\"A\",\"name\":\"current\"},\"consumed_ah\":{\"unit\":\"Ah\",\"name\":\"consumed ampere hours\"},\"soc\":{\"unit\":\"%\",\"name\":\"state of charge\"}}}"; +/*R""""( +{ + "properties":{ + "ttg":{ + "unit":"min", + "name":"time to go" + }, + "volt":{ + "unit":"V", + "name":"voltage" + }, + "alarm_reason":{ + "unit":"int", + "name":"alarm reason" + }, + "aux_voltage":{ + "unit":"V", + "name":"auxiliary voltage" + }, + "aux_input":{ + "unit":"string", + "name":"aux input" + }, + "current":{ + "unit":"A", + "name":"current" + }, + "consumed_ah":{ + "unit":"Ah", + "name":"consumed ampere hours" + }, + "soc":{ + "unit":"%", + "name":"state of charge" + } + } +})"""";*/ diff --git a/src/devices/VICTRON_ORIONTR_json.h b/src/devices/VICTRON_ORIONTR_json.h new file mode 100644 index 000000000..5e33e9d95 --- /dev/null +++ b/src/devices/VICTRON_ORIONTR_json.h @@ -0,0 +1,86 @@ +const char* _VICTORIONTR_json = "{\"brand\":\"Victron Energy\",\"model\":\"Orion TR\",\"model_id\":\"VICTORIONTR\",\"tag\":\"0c48\",\"condition\":[\"manufacturerdata\",\"=\",40,\"index\",0,\"e10211\",\"&\",\"manufacturerdata\",\"index\",8,\"d0a3\",\"&\",\"manufacturerdata\",\"index\",12,\"04ffff\"],\"properties\":{\"device_state\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,2],\"lookup\":[\"00\",\"off\",\"01\",\"low power\",\"02\",\"fault\",\"03\",\"bulk\",\"04\",\"absorption\",\"05\",\"float\",\"06\",\"storage\",\"07\",\"equalize manual\",\"09\",\"inverting\",\"0b\",\"power_supply\",\"f5\",\"starting up\",\"f6\",\"repeated absorption\",\"f7\",\"recondition\",\"f8\",\"battery safe\",\"f9\",\"active\",\"fc\",\"external control\",\"ff\",\"N/A\"]},\"volt_in\":{\"condition\":[\"manufacturerdata\",24,\"!\",\"ff7f\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,true,true],\"post_proc\":[\"/\",100]},\"current_out\":{\"condition\":[\"manufacturerdata\",28,\"!\",\"ff7f\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,true,true],\"post_proc\":[\"/\",10]},\"volt_out\":{\"condition\":[\"manufacturerdata\",32,\"!\",\"ffff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,4,true,false],\"post_proc\":[\"/\",100]},\"current_in\":{\"condition\":[\"manufacturerdata\",36,\"!\",\"ffff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",36,4,true,false],\"post_proc\":[\"/\",10]},\"error_code\":{\"condition\":[\"manufacturerdata\",22,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",22,2]}}}"; +/*R""""( +{ + "brand":"Victron Energy", + "model":"Orion TR", + "model_id":"VICTORIONTR", + "tag":"0c48", + "condition":["manufacturerdata", "=", 40, "index", 0, "e10211", "&", "manufacturerdata", "index", 8, "d0a3", "&", "manufacturerdata", "index", 12, "04ffff"], + "properties":{ + "device_state":{ + "decoder":["string_from_hex_data", "manufacturerdata", 20, 2], + "lookup":["00", "off", + "01", "low power", + "02", "fault", + "03", "bulk", + "04", "absorption", + "05", "float", + "06", "storage", + "07", "equalize manual", + "09", "inverting", + "0b", "power_supply", + "f5", "starting up", + "f6", "repeated absorption", + "f7", "recondition", + "f8", "battery safe", + "f9", "active", + "fc", "external control", + "ff", "N/A"] + }, + "volt_in":{ + "condition":["manufacturerdata", 24, "!", "ff7f"], + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, true, true], + "post_proc":["/", 100] + }, + "current_out":{ + "condition":["manufacturerdata", 28, "!", "ff7f"], + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, true, true], + "post_proc":["/", 10] + }, + "volt_out":{ + "condition":["manufacturerdata", 32, "!", "ffff"], + "decoder":["value_from_hex_data", "manufacturerdata", 32, 4, true, false], + "post_proc":["/", 100] + }, + "current_in":{ + "condition":["manufacturerdata", 36, "!", "ffff"], + "decoder":["value_from_hex_data", "manufacturerdata", 36, 4, true, false], + "post_proc":["/", 10] + }, + "error_code":{ + "condition":["manufacturerdata", 22, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 22, 2] + } + } +})"""";*/ + +const char* _VICTORIONTR_json_props = "{\"properties\":{\"device_state\":{\"unit\":\"string\",\"name\":\"device state\"},\"volt_out\":{\"unit\":\"V\",\"name\":\"voltage\"},\"current_out\":{\"unit\":\"A\",\"name\":\"current\"},\"volt_in\":{\"unit\":\"V\",\"name\":\"voltage\"},\"current_in\":{\"unit\":\"A\",\"name\":\"current\"},\"error_code\":{\"unit\":\"int\",\"name\":\"error code\"}}}"; +/*R""""( +{ + "properties":{ + "device_state":{ + "unit":"string", + "name":"device state" + }, + "volt_out": { + "unit": "V", + "name": "voltage" + }, + "current_out": { + "unit": "A", + "name": "current" + }, + "volt_in": { + "unit": "V", + "name": "voltage" + }, + "current_in": { + "unit": "A", + "name": "current" + }, + "error_code":{ + "unit":"int", + "name":"error code" + } + } +})"""";*/ diff --git a/src/devices/VICTRON_SBS_json.h b/src/devices/VICTRON_SBS_json.h index bb909f1dd..4883045b4 100644 --- a/src/devices/VICTRON_SBS_json.h +++ b/src/devices/VICTRON_SBS_json.h @@ -1,21 +1,49 @@ -const char* _VICTSBS_json = "{\"brand\":\"Victron Energy\",\"model\":\"Smart Battery Sense\",\"model_id\":\"VICTSBS\",\"tag\":\"0c48\",\"condition\":[\"manufacturerdata\",\"index\",8,\"a5a3\",\"|\",\"manufacturerdata\",\"index\",8,\"a4a3\",\"&\",\"manufacturerdata\",\"=\",50,\"index\",0,\"e10211\",\"&\",\"manufacturerdata\",\"index\",12,\"02ffff\"],\"properties\":{\"volt\":{\"condition\":[\"manufacturerdata\",24,\"!\",\"ffff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,true,false],\"post_proc\":[\"/\",100]},\"tempc\":{\"condition\":[\"manufacturerdata\",37,\"bit\",0,0,\"&\",\"manufacturerdata\",37,\"bit\",1,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,4,true,false],\"post_proc\":[\"-\",27315,\"/\",100]},\"alarm_reason\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4]}}}"; +const char* _VICTSBS_json = "{\"brand\":\"Victron Energy\",\"model\":\"Battery Monitor/Smart Battery Sense/SmartShunt\",\"model_id\":\"VICTSBS\",\"tag\":\"0c48\",\"condition\":[\"manufacturerdata\",\"=\",50,\"index\",0,\"e10211\",\"&\",\"manufacturerdata\",\"index\",12,\"02ffff\"],\"properties\":{\"ttg\":{\"condition\":[\"manufacturerdata\",20,\"!\",\"ffff\"],\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",80,16,false]},\"volt\":{\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",96,16,true],\"post_proc\":[\"/\",100]},\"volt_aux\":{\"condition\":[\"manufacturerdata\",37,\"bit\",0,0,\"&\",\"manufacturerdata\",37,\"bit\",1,0],\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",128,16,true],\"post_proc\":[\"/\",100]},\"volt_mid\":{\"condition\":[\"manufacturerdata\",37,\"bit\",0,1,\"&\",\"manufacturerdata\",37,\"bit\",1,0],\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",128,16,true],\"post_proc\":[\"/\",100]},\"tempc\":{\"condition\":[\"manufacturerdata\",37,\"bit\",0,0,\"&\",\"manufacturerdata\",37,\"bit\",1,1],\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",128,16,true],\"post_proc\":[\"-\",27315,\"/\",100]},\"current\":{\"condition\":[\"manufacturerdata\",38,\"!\",\"ff\"],\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",146,22,true],\"post_proc\":[\"/\",1000]},\"consumed_ah\":{\"condition\":[\"manufacturerdata\",41,\"!\",\"fffff\"],\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",168,20,true],\"post_proc\":[\"/\",-10]},\"soc\":{\"condition\":[\"manufacturerdata\",46,\"!\",\"fff\"],\"decoder\":[\"value_from_bit_data\",\"manufacturerdata\",188,10,false],\"post_proc\":[\"/\",10]},\"alarm_reason\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4]}}}"; /*R""""( { "brand":"Victron Energy", - "model":"Smart Battery Sense", + "model":"Battery Monitor/Smart Battery Sense/SmartShunt", "model_id":"VICTSBS", "tag":"0c48", - "condition":["manufacturerdata", "index", 8, "a5a3", "|", "manufacturerdata", "index", 8, "a4a3", "&", "manufacturerdata", "=", 50, "index", 0, "e10211", "&", "manufacturerdata", "index", 12, "02ffff"], + "condition":["manufacturerdata", "=", 50, "index", 0, "e10211", "&", "manufacturerdata", "index", 12, "02ffff"], "properties":{ + "ttg":{ + "condition":["manufacturerdata", 20, "!", "ffff"], + "decoder":["value_from_bit_data", "manufacturerdata", 80, 16, false] + }, "volt":{ - "condition":["manufacturerdata", 24, "!", "ffff"], - "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, true, false], - "post_proc":["/", 100] + "decoder":["value_from_bit_data", "manufacturerdata", 96, 16, true], + "post_proc":["/", 100] + }, + "volt_aux":{ + "condition":["manufacturerdata", 37, "bit", 0, 0, "&", "manufacturerdata", 37, "bit", 1, 0], + "decoder":["value_from_bit_data", "manufacturerdata", 128, 16, true], + "post_proc":["/", 100] + }, + "volt_mid":{ + "condition":["manufacturerdata", 37, "bit", 0, 1, "&", "manufacturerdata", 37, "bit", 1, 0], + "decoder":["value_from_bit_data", "manufacturerdata", 128, 16, true], + "post_proc":["/", 100] }, "tempc":{ - "condition":["manufacturerdata", 37, "bit", 0, 0, "&", "manufacturerdata", 37, "bit", 1, 1], - "decoder":["value_from_hex_data", "manufacturerdata", 32, 4, true, false], - "post_proc":["-", 27315, "/", 100] + "condition":["manufacturerdata", 37, "bit", 0, 0, "&", "manufacturerdata", 37, "bit", 1, 1], + "decoder":["value_from_bit_data", "manufacturerdata", 128, 16, true], + "post_proc":["-", 27315, "/", 100] + }, + "current":{ + "condition":["manufacturerdata", 38, "!", "ff"], + "decoder":["value_from_bit_data", "manufacturerdata", 146, 22, true], + "post_proc":["/", 1000] + }, + "consumed_ah":{ + "condition":["manufacturerdata", 41, "!", "fffff"], + "decoder":["value_from_bit_data", "manufacturerdata", 168, 20, true], + "post_proc":["/", -10] + }, + "soc":{ + "condition":["manufacturerdata", 46, "!", "fff"], + "decoder":["value_from_bit_data", "manufacturerdata", 188, 10, false], + "post_proc":["/", 10] }, "alarm_reason":{ "decoder":["value_from_hex_data", "manufacturerdata", 28, 4] @@ -23,18 +51,42 @@ const char* _VICTSBS_json = "{\"brand\":\"Victron Energy\",\"model\":\"Smart Bat } })"""";*/ -const char* _VICTSBS_json_props = "{\"properties\":{\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"alarm_reason\":{\"unit\":\"int\",\"name\":\"alarm reason\"}}}"; +const char* _VICTSBS_json_props = "{\"properties\":{\"ttg\":{\"unit\":\"min\",\"name\":\"duration\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"volt_aux\":{\"unit\":\"V\",\"name\":\"voltage\"},\"volt_mid\":{\"unit\":\"V\",\"name\":\"voltage\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"current\":{\"unit\":\"A\",\"name\":\"current\"},\"consumed_ah\":{\"unit\":\"Ah\",\"name\":\"consumed ampere hours\"},\"soc\":{\"unit\":\"%\",\"name\":\"state of charge\"},\"alarm_reason\":{\"unit\":\"int\",\"name\":\"alarm reason\"}}}"; /*R""""( { "properties":{ + "ttg":{ + "unit":"min", + "name":"duration" + }, "volt": { "unit": "V", "name": "voltage" }, + "volt_aux":{ + "unit":"V", + "name":"voltage" + }, + "volt_mid":{ + "unit":"V", + "name":"voltage" + }, "tempc":{ "unit":"°C", "name":"temperature" }, + "current":{ + "unit":"A", + "name":"current" + }, + "consumed_ah":{ + "unit":"Ah", + "name":"consumed ampere hours" + }, + "soc":{ + "unit":"%", + "name":"state of charge" + }, "alarm_reason":{ "unit":"int", "name":"alarm reason" diff --git a/src/devices/VICTRON__ENCR_json.h b/src/devices/VICTRON__ENCR_json.h index 29c90f1f9..862319c8f 100644 --- a/src/devices/VICTRON__ENCR_json.h +++ b/src/devices/VICTRON__ENCR_json.h @@ -1,25 +1,29 @@ -const char* _VICTRON_ENCR_json = "{\"brand\":\"Victron Energy\",\"model\":\"Victron encrypted\",\"model_id\":\"VICTRON_ENCR\",\"tag\":\"0c0003\",\"condition\":[\"manufacturerdata\",\">=\",44,\"index\",0,\"e10210\"],\"properties\":{\"cipher\":{\"condition\":[\"manufacturerdata\",\"=\",44],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,24]},\"_cipher\":{\"condition\":[\"manufacturerdata\",\"=\",46],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,26]},\"__cipher\":{\"condition\":[\"manufacturerdata\",\"=\",48],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,28]},\"___cipher\":{\"condition\":[\"manufacturerdata\",\"=\",50],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,30]},\"ctr\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",14,4,true]},\"mic\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",18,2]}}}"; +const char* _VICTRON_ENCR_json = "{\"brand\":\"Victron Energy\",\"model\":\"Victron encrypted\",\"model_id\":\"VICTRON_ENCR\",\"tag\":\"0c0003\",\"condition\":[\"manufacturerdata\",\">=\",40,\"index\",0,\"e10210\"],\"properties\":{\"cipher\":{\"condition\":[\"manufacturerdata\",\"=\",40],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,20]},\"_cipher\":{\"condition\":[\"manufacturerdata\",\"=\",44],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,24]},\"__cipher\":{\"condition\":[\"manufacturerdata\",\"=\",46],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,26]},\"___cipher\":{\"condition\":[\"manufacturerdata\",\"=\",48],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,28]},\"____cipher\":{\"condition\":[\"manufacturerdata\",\"=\",50],\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,30]},\"ctr\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",14,4,true]},\"mic\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",18,2]}}}"; /*R""""( { "brand":"Victron Energy", "model":"Victron encrypted", "model_id":"VICTRON_ENCR", "tag":"0c0003", - "condition":["manufacturerdata", ">=", 44, "index", 0, "e10210"], + "condition":["manufacturerdata", ">=", 40, "index", 0, "e10210"], "properties":{ "cipher":{ + "condition":["manufacturerdata", "=", 40], + "decoder":["string_from_hex_data", "manufacturerdata", 20, 20] + }, + "_cipher":{ "condition":["manufacturerdata", "=", 44], "decoder":["string_from_hex_data", "manufacturerdata", 20, 24] }, - "_cipher":{ + "__cipher":{ "condition":["manufacturerdata", "=", 46], "decoder":["string_from_hex_data", "manufacturerdata", 20, 26] }, - "__cipher":{ + "___cipher":{ "condition":["manufacturerdata", "=", 48], "decoder":["string_from_hex_data", "manufacturerdata", 20, 28] }, - "___cipher":{ + "____cipher":{ "condition":["manufacturerdata", "=", 50], "decoder":["string_from_hex_data", "manufacturerdata", 20, 30] }, diff --git a/tests/BLE/test_ble.cpp b/tests/BLE/test_ble.cpp index 730c61d93..06548a650 100644 --- a/tests/BLE/test_ble.cpp +++ b/tests/BLE/test_ble.cpp @@ -234,9 +234,9 @@ const char* expected_mfg[] = { "{\"brand\":\"Victron Energy\",\"model\":\"Victron encrypted\",\"model_id\":\"VICTRON_ENCR\",\"type\":\"ENRG\",\"encr\":3,\"cipher\":\"378a5d06e864839e6311898e6911f7\",\"ctr\":\"0e02\",\"mic\":\"a6\"}", "{\"brand\":\"Victron Energy\",\"model\":\"Victron encrypted\",\"model_id\":\"VICTRON_ENCR\",\"type\":\"ENRG\",\"encr\":3,\"cipher\":\"caf5109829476880bc658f4afe79fd\",\"ctr\":\"7c00\",\"mic\":\"a6\"}", "{\"brand\":\"Victron Energy\",\"model\":\"Victron encrypted\",\"model_id\":\"VICTRON_ENCR\",\"type\":\"ENRG\",\"encr\":3,\"cipher\":\"ef9c2669e3b2e28f109d7cc484eef9\",\"ctr\":\"b3b8\",\"mic\":\"f5\"}", - "{\"brand\":\"Victron Energy\",\"model\":\"Smart Battery Sense\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"volt\":12.99,\"tempc\":17.5,\"tempf\":63.5,\"alarm_reason\":0}", - "{\"brand\":\"Victron Energy\",\"model\":\"Smart Battery Sense\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"volt\":14.01,\"tempc\":17.5,\"tempf\":63.5,\"alarm_reason\":0}", - "{\"brand\":\"Victron Energy\",\"model\":\"Smart Battery Sense\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"volt\":12.22,\"tempc\":22.5,\"tempf\":72.5,\"alarm_reason\":0}", + "{\"brand\":\"Victron Energy\",\"model\":\"Battery Monitor/Smart Battery Sense/SmartShunt\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"volt\":12.99,\"tempc\":17.5,\"tempf\":63.5,\"alarm_reason\":0}", + "{\"brand\":\"Victron Energy\",\"model\":\"Battery Monitor/Smart Battery Sense/SmartShunt\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"volt\":14.01,\"tempc\":17.5,\"tempf\":63.5,\"alarm_reason\":0}", + "{\"brand\":\"Victron Energy\",\"model\":\"Battery Monitor/Smart Battery Sense/SmartShunt\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"volt\":12.22,\"tempc\":22.5,\"tempf\":72.5,\"alarm_reason\":0}", "{\"brand\":\"Govee\",\"model\":\"Smart CO2 Monitor\",\"model_id\":\"H5140\",\"type\":\"AIR\",\"cidc\":false,\"acts\":true,\"tempc\":26.1311,\"tempf\":79.03598,\"hum\":31.1,\"co2\":1100}", "{\"brand\":\"Govee\",\"model\":\"Smart CO2 Monitor\",\"model_id\":\"H5140\",\"type\":\"AIR\",\"cidc\":false,\"acts\":true,\"tempc\":15.56,\"tempf\":60.008,\"hum\":60,\"co2\":500}", "{\"brand\":\"Govee\",\"model\":\"Smart CO2 Monitor\",\"model_id\":\"H5140\",\"type\":\"AIR\",\"cidc\":false,\"acts\":true,\"tempc\":23.8048,\"tempf\":74.84864,\"hum\":4.8,\"co2\":1700}", @@ -247,6 +247,9 @@ const char* expected_mfg[] = { "{\"brand\":\"Schneider Electric\",\"model\":\"Odace WLBL\",\"model_id\":\"S520104\",\"type\":\"BTN\",\"cont\":true,\"uid\":\"005942\",\"action\":\"toggle\"}", "{\"brand\":\"Schneider Electric\",\"model\":\"Odace WLBL\",\"model_id\":\"S520104\",\"type\":\"BTN\",\"cont\":true,\"uid\":\"005942\",\"action\":\"toggle\"}", "{\"brand\":\"Schneider Electric\",\"model\":\"Odace WLBL\",\"model_id\":\"S520104\",\"type\":\"BTN\",\"cont\":true,\"uid\":\"005942\",\"action\":\"toggle\"}", + "{\"brand\":\"Victron Energy\",\"model\":\"Battery Monitor/Smart Battery Sense/SmartShunt\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"ttg\":14400,\"volt\":13.28,\"volt_aux\":12.47,\"current\":-0.116,\"consumed_ah\":-20.1,\"soc\":92,\"alarm_reason\":0}", + "{\"brand\":\"Victron Energy\",\"model\":\"Victron encrypted\",\"model_id\":\"VICTRON_ENCR\",\"type\":\"ENRG\",\"encr\":3,\"cipher\":\"0751889a5d8c22e24014\",\"ctr\":\"e308\",\"mic\":\"f9\"}", + "{\"brand\":\"Victron Energy\",\"model\":\"Orion TR\",\"model_id\":\"VICTORIONTR\",\"type\":\"ENRG\",\"track\":true,\"bvpp\":true,\"device_state\":\"off\",\"volt_in\":12.51,\"volt_out\":1.29,\"current_in\":0,\"error_code\":0}", }; const char* expected_name_uuid_mfgsvcdata[] = { @@ -849,6 +852,9 @@ const char* test_mfgdata[][3] = { {"Odace WLBL", "", "b6028e4401010042590001020000040000000000923995c4cc19"}, {"Odace WLBL", "", "b6028e4401010042590001020000040000000000232c37285846"}, {"Odace WLBL", "", "b6028e44010100425900010200000400000000005b2bd3805d97"}, + {"Victron Battery Monitor", "", "e102110283a302ffff8d403830050000df0430feffc90080f9"}, + {"Victron Orion TR Smart ENCR", "", "e1021000d0a304e308f90751889a5d8c22e24014"}, + {"Victron Orion TR", "", "e1021100d0a304fffff90000e304ff7f81000000"}, }; TheengsDecoder::BLE_ID_NUM test_mfgdata_id_num[]{ @@ -1079,6 +1085,9 @@ TheengsDecoder::BLE_ID_NUM test_mfgdata_id_num[]{ TheengsDecoder::BLE_ID_NUM::ODACE_WLBL, TheengsDecoder::BLE_ID_NUM::ODACE_WLBL, TheengsDecoder::BLE_ID_NUM::ODACE_WLBL, + TheengsDecoder::BLE_ID_NUM::VICTSBS, + TheengsDecoder::BLE_ID_NUM::VICTRON_ENCR, + TheengsDecoder::BLE_ID_NUM::VICTORIONTR, }; // uuid test input [test name] [device name] [uuid] [manufacturer data] [service data]