diff --git a/main/User_config.h b/main/User_config.h index 20d3f94..47e8077 100755 --- a/main/User_config.h +++ b/main/User_config.h @@ -367,7 +367,7 @@ uint8_t wifiProtocol = 0; // default mode, automatic selection # define STRTO_UL_ULL strtoul #endif -#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) +#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) // variable to avoid duplicates # define time_avoid_duplicate 3000 // if you want to avoid duplicate mqtt message received set this to > 0, the value is the time in milliseconds during which we don't publish duplicates #endif diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index 41507c1..310d9c8 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -819,28 +819,6 @@ void RemoveJsonPropertyIf(JsonObject& obj, char* key, bool condition) { } } -/** - * Retrieve a long value from a char array extract representing hexadecimal data, reversed or not - */ -long value_from_service_data(const char* service_data, int offset, int data_length, bool reverse) { - char data[data_length + 1]; - memcpy(data, &service_data[offset], data_length); - data[data_length] = '\0'; - long value; - if (reverse) { - // reverse data order - char rev_data[data_length + 1]; - revert_hex_data(data, rev_data, data_length + 1); - value = strtol(rev_data, NULL, 16); - } else { - value = strtol(data, NULL, 16); - } - if (value > 65000 && data_length <= 4) - value = value - 65535; - Log.trace(F("value %D" CR), value); - return value; -} - boolean valid_service_data(const char* data) { int size = strlen(data); for (int i = 0; i < size; ++i) { @@ -1062,7 +1040,7 @@ JsonObject& process_bledata(JsonObject& BLEdata) { } } Log.trace(F("Is it a iNode Energy Meter?" CR)); - if (strlen(manufacturerdata) == 26 && ((long)value_from_service_data(manufacturerdata, 0, 4, true) & 0xFFF9) == 0x8290) { + if (strlen(manufacturerdata) == 26 && ((long)value_from_hex_data(manufacturerdata, 0, 4, true) & 0xFFF9) == 0x8290) { Log.trace(F("iNode Energy Meter data reading" CR)); BLEdata.set("model", "INODE_EM"); if (device->sensorModel == -1) @@ -1096,7 +1074,7 @@ JsonObject& process_sensors(int offset, JsonObject& BLEdata) { } double value = 9999; - value = (double)value_from_service_data(servicedata, 28 + offset, data_length, true); + value = (double)value_from_hex_data(servicedata, 28 + offset, data_length, true); // Mi flora provides tem(perature), (earth) moi(sture), fer(tility) and lux (illuminance) // Mi Jia provides tem(perature), batt(erry) and hum(idity) @@ -1127,12 +1105,12 @@ JsonObject& process_sensors(int offset, JsonObject& BLEdata) { break; case 'd': // temperature - value = (double)value_from_service_data(servicedata, 28 + offset, 4, true); + value = (double)value_from_hex_data(servicedata, 28 + offset, 4, true); BLEdata.set("tem", (double)value / 10); // remove for 0.9.6 release BLEdata.set("tempc", (double)value / 10); BLEdata.set("tempf", (double)convertTemp_CtoF(value / 10)); // humidity - value = (double)value_from_service_data(servicedata, 32 + offset, 4, true); + value = (double)value_from_hex_data(servicedata, 32 + offset, 4, true); BLEdata.set("hum", (double)value / 10); break; default: @@ -1145,7 +1123,7 @@ JsonObject& process_sensors(int offset, JsonObject& BLEdata) { JsonObject& process_scale_v1(JsonObject& BLEdata) { const char* servicedata = BLEdata["servicedata"].as(); - double weight = (double)value_from_service_data(servicedata, 2, 4, true) / 200; + double weight = (double)value_from_hex_data(servicedata, 2, 4, true) / 200; //Set Json value BLEdata.set("weight", (double)weight); @@ -1156,8 +1134,8 @@ JsonObject& process_scale_v1(JsonObject& BLEdata) { JsonObject& process_scale_v2(JsonObject& BLEdata) { const char* servicedata = BLEdata["servicedata"].as(); - double weight = (double)value_from_service_data(servicedata, 22, 4, true) / 200; - double impedance = (double)value_from_service_data(servicedata, 18, 4, true); + double weight = (double)value_from_hex_data(servicedata, 22, 4, true) / 200; + double impedance = (double)value_from_hex_data(servicedata, 18, 4, true); //Set Json values BLEdata.set("weight", (double)weight); @@ -1169,9 +1147,9 @@ JsonObject& process_scale_v2(JsonObject& BLEdata) { JsonObject& process_inkbird(JsonObject& BLEdata) { const char* manufacturerdata = BLEdata["manufacturerdata"].as(); - double temperature = (double)value_from_service_data(manufacturerdata, 0, 4, true) / 100; - double humidity = (double)value_from_service_data(manufacturerdata, 4, 4, true) / 100; - double battery = (double)value_from_service_data(manufacturerdata, 14, 2, true); + double temperature = (double)value_from_hex_data(manufacturerdata, 0, 4, true) / 100; + double humidity = (double)value_from_hex_data(manufacturerdata, 4, 4, true) / 100; + double battery = (double)value_from_hex_data(manufacturerdata, 14, 2, true); //Set Json values BLEdata.set("tem", (double)temperature); // remove for 0.9.6 release @@ -1186,7 +1164,7 @@ JsonObject& process_inkbird(JsonObject& BLEdata) { JsonObject& process_miband(JsonObject& BLEdata) { const char* servicedata = BLEdata["servicedata"].as(); - double steps = (double)value_from_service_data(servicedata, 0, 4, true); + double steps = (double)value_from_hex_data(servicedata, 0, 4, true); //Set Json value BLEdata.set("steps", (double)steps); @@ -1197,7 +1175,7 @@ JsonObject& process_miband(JsonObject& BLEdata) { JsonObject& process_milamp(JsonObject& BLEdata) { const char* servicedata = BLEdata["servicedata"].as(); - long darkness = (double)value_from_service_data(servicedata, 8, 2, true); + long darkness = (double)value_from_hex_data(servicedata, 8, 2, true); //Set Json value BLEdata.set("presence", (bool)"true"); @@ -1211,16 +1189,16 @@ JsonObject& process_cleargrass(JsonObject& BLEdata, boolean air) { double value = 9999; // temperature - value = (double)value_from_service_data(servicedata, 20, 4, true); + value = (double)value_from_hex_data(servicedata, 20, 4, true); BLEdata.set("tem", (double)value / 10); // remove for 0.9.6 release BLEdata.set("tempc", (double)value / 10); BLEdata.set("tempf", (double)convertTemp_CtoF(value / 10)); // humidity - value = (double)value_from_service_data(servicedata, 24, 4, true); + value = (double)value_from_hex_data(servicedata, 24, 4, true); BLEdata.set("hum", (double)value / 10); if (air) { // air pressure - value = (double)value_from_service_data(servicedata, 32, 4, true); + value = (double)value_from_hex_data(servicedata, 32, 4, true); BLEdata.set("pres", (double)value / 100); } @@ -1230,10 +1208,10 @@ JsonObject& process_cleargrass(JsonObject& BLEdata, boolean air) { JsonObject& process_atc(JsonObject& BLEdata) { const char* servicedata = BLEdata["servicedata"].as(); - double temperature = (double)value_from_service_data(servicedata, 12, 4, false) / 10; - double humidity = (double)value_from_service_data(servicedata, 16, 2, false); - double battery = (double)value_from_service_data(servicedata, 18, 2, false); - double voltage = (double)value_from_service_data(servicedata, 20, 4, false) / 1000; + double temperature = (double)value_from_hex_data(servicedata, 12, 4, false) / 10; + double humidity = (double)value_from_hex_data(servicedata, 16, 2, false); + double battery = (double)value_from_hex_data(servicedata, 18, 2, false); + double voltage = (double)value_from_hex_data(servicedata, 20, 4, false) / 1000; //Set Json values BLEdata.set("tempc", (double)temperature); @@ -1248,10 +1226,10 @@ JsonObject& process_atc(JsonObject& BLEdata) { JsonObject& process_inode_em(JsonObject& BLEdata) { const char* manufacturerdata = BLEdata["manufacturerdata"].as(); - long impPerKWh = value_from_service_data(manufacturerdata, 16, 4, true) & 0x3FFF; - double power = ((double)value_from_service_data(manufacturerdata, 4, 4, true) / impPerKWh) * 60000; - double energy = (double)value_from_service_data(manufacturerdata, 8, 8, true) / impPerKWh; - long battery = ((value_from_service_data(manufacturerdata, 20, 2, true) >> 4) - 2) * 10; + long impPerKWh = value_from_hex_data(manufacturerdata, 16, 4, true) & 0x3FFF; + double power = ((double)value_from_hex_data(manufacturerdata, 4, 4, true) / impPerKWh) * 60000; + double energy = (double)value_from_hex_data(manufacturerdata, 8, 8, true) / impPerKWh; + long battery = ((value_from_hex_data(manufacturerdata, 20, 2, true) >> 4) - 2) * 10; //Set Json values BLEdata.set("power", (double)power); diff --git a/main/ZgatewaySRFB.ino b/main/ZgatewaySRFB.ino index 33f5a68..b3c6b1e 100644 --- a/main/ZgatewaySRFB.ino +++ b/main/ZgatewaySRFB.ino @@ -104,26 +104,18 @@ void _rfbDecode() { Log.trace(F("Creating SRFB buffer" CR)); StaticJsonBuffer jsonBuffer; JsonObject& SRFBdata = jsonBuffer.createObject(); - SRFBdata.set("raw", (char*)buffer); + SRFBdata.set("raw", String(buffer).substring(0, 18)); - char Tsyn[4] = {0}; - extract_char(buffer, Tsyn, 0, 4, false, true); - int val_Tsyn = (int)strtol(Tsyn, NULL, 10); + int val_Tsyn = (int)(int)value_from_hex_data(buffer, 0, 4, false, false); SRFBdata.set("delay", (int)val_Tsyn); - char Tlow[4] = {0}; - extract_char(buffer, Tlow, 4, 4, false, true); - int val_Tlow = (int)strtol(Tlow, NULL, 10); + int val_Tlow = (int)value_from_hex_data(buffer, 4, 4, false, false); SRFBdata.set("val_Tlow", (int)val_Tlow); - char Thigh[4] = {0}; - extract_char(buffer, Thigh, 8, 4, false, true); - int val_Thigh = (int)strtol(Thigh, NULL, 10); + int val_Thigh = (int)value_from_hex_data(buffer, 8, 4, false, false); SRFBdata.set("val_Thigh", (int)val_Thigh); - char val[8] = {0}; - extract_char(buffer, val, 12, 8, false, true); - unsigned long MQTTvalue = (unsigned long)strtoul(val, NULL, 10); + unsigned long MQTTvalue = (unsigned long)value_from_hex_data(buffer, 12, 8, false, false); SRFBdata.set("value", (unsigned long)MQTTvalue); if (!isAduplicateSignal(MQTTvalue) && MQTTvalue != 0) { // conditions to avoid duplications of RF -->MQTT diff --git a/main/main.ino b/main/main.ino index 90ad967..8975502 100644 --- a/main/main.ino +++ b/main/main.ino @@ -28,7 +28,7 @@ #include "User_config.h" // Macros and structure to enable the duplicates removing on the following gateways -#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) +#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) // array to store previous received RFs, IRs codes and their timestamps struct ReceivedSignal { SIGNAL_SIZE_UL_ULL value; @@ -223,19 +223,27 @@ void revert_hex_data(const char* in, char* out, int l) { out[l - 1] = '\0'; } -void extract_char(const char* token_char, char* subset, int start, int l, bool reverse, bool isNumber) { - if (isNumber) { - if (reverse) - revert_hex_data(token_char + start, subset, l + 1); - long long_value = strtoul(subset, NULL, 16); - sprintf(subset, "%ld", long_value); +/** + * Retrieve an unsigned long value from a char array extract representing hexadecimal data, reversed or not, + * This value can represent a negative value if canBeNegative is set to true + */ +long value_from_hex_data(const char* service_data, int offset, int data_length, bool reverse, bool canBeNegative = true) { + char data[data_length + 1]; + memcpy(data, &service_data[offset], data_length); + data[data_length] = '\0'; + long value; + if (reverse) { + // reverse data order + char rev_data[data_length + 1]; + revert_hex_data(data, rev_data, data_length + 1); + value = strtol(rev_data, NULL, 16); } else { - if (reverse) - revert_hex_data(token_char + start, subset, l + 1); - else - strncpy(subset, token_char + start, l + 1); + value = strtol(data, NULL, 16); } - subset[l] = '\0'; + if (value > 65000 && data_length <= 4 && canBeNegative) + value = value - 65535; + Log.trace(F("value %D" CR), value); + return value; } char* ip2CharArray(IPAddress ip) { //from Nick Lee https://stackoverflow.com/questions/28119653/arduino-display-ethernet-localip @@ -1402,7 +1410,7 @@ void stateMeasures() { } #endif -#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) +#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) /** * Store signal values from RF, IR, SRFB or Weather stations so as to avoid duplicates */ @@ -1460,7 +1468,7 @@ void receivingMQTT(char* topicOri, char* datacallback) { StaticJsonBuffer jsonBuffer; JsonObject& jsondata = jsonBuffer.parseObject(datacallback); -#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) +#if defined(ZgatewayRF) || defined(ZgatewayIR) || defined(ZgatewaySRFB) || defined(ZgatewayWeatherStation) if (strstr(topicOri, subjectMultiGTWKey) != NULL) { // storing received value so as to avoid publishing this value if it has been already sent by this or another OpenMQTTGateway SIGNAL_SIZE_UL_ULL data = jsondata.success() ? jsondata["value"] : STRTO_UL_ULL(datacallback, NULL, 10); if (data != 0 && !isAduplicateSignal(data)) {