diff --git a/src/custom.js b/src/custom.js index 18f64b74c..5d8a16fd7 100644 --- a/src/custom.js +++ b/src/custom.js @@ -99,13 +99,13 @@ function listCustomStats() { var l = document.createElement("li"); var type = obj[i].type; var color = ""; - if (type === 1) { + if (type === "UBAMaster") { color = "list-group-item-success"; - } else if (type === 2) { + } else if (type === "Thermostat") { color = "list-group-item-info"; - } else if (type === 3) { + } else if (type === "Solar Module") { color = "list-group-item-warning"; - } else if (type === 4) { + } else if (type === "Heat Pump") { color = "list-group-item-success"; } l.innerHTML = obj[i].model + " (Version:" + obj[i].version + " ProductID:" + obj[i].productid + " DeviceID:0x" + obj[i].deviceid + ")"; diff --git a/src/ems-esp.cpp b/src/ems-esp.cpp index a3e37ff7e..c98086d36 100644 --- a/src/ems-esp.cpp +++ b/src/ems-esp.cpp @@ -1669,7 +1669,6 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) { } } - // Init callback, which is used to set functions and call methods after a wifi connection has been established void WIFICallback() { // This is where we enable the UART service to scan the incoming serial Tx/Rx bus signals @@ -1712,8 +1711,8 @@ void WebCallback(JsonObject root) { (void)ems_getDeviceTypeDescription((it)->device_id, buffer); item["type"] = buffer; - if ((it)->known) { - item["model"] = EMS_Devices[(it)->device_index].device_desc; + if ((it)->known == true) { + item["model"] = (it)->device_desc_p; } else { item["model"] = EMS_MODELTYPE_UNKNOWN_STRING; } diff --git a/src/ems.cpp b/src/ems.cpp index da60b7b86..f66a3ff8b 100644 --- a/src/ems.cpp +++ b/src/ems.cpp @@ -256,8 +256,6 @@ void ems_init() { EMS_Mixing.hc[i].flowTemp = EMS_VALUE_SHORT_NOTSET; EMS_Mixing.hc[i].pumpMod = EMS_VALUE_INT_NOTSET; EMS_Mixing.hc[i].valveStatus = EMS_VALUE_INT_NOTSET; - EMS_Mixing.hc[i].device_id = EMS_ID_NONE; - EMS_Mixing.hc[i].product_id = EMS_ID_NONE; } // UBAParameterWW @@ -1846,7 +1844,7 @@ void ems_clearDeviceList() { * add an EMS device to our list of detected devices if its unique * returns true if already in list */ -bool _addDevice(_EMS_DEVICE_TYPE device_type, uint8_t product_id, uint8_t device_id, uint8_t device_index, const char * version, const char * device_desc) { +bool _addDevice(_EMS_DEVICE_TYPE device_type, uint8_t product_id, uint8_t device_id, const char * device_desc_p, const char * version) { _Detected_Device device; // check for duplicates @@ -1858,10 +1856,10 @@ bool _addDevice(_EMS_DEVICE_TYPE device_type, uint8_t product_id, uint8_t device } // create a new record and add it to list - device.device_type = device_type; - device.product_id = product_id; - device.device_id = device_id; - device.device_index = device_index; // where it is in the EMS_Devices table + device.device_type = device_type; + device.product_id = product_id; + device.device_id = device_id; + device.device_desc_p = device_desc_p; // pointer to the description in the EMS_Devices table strlcpy(device.version, version, sizeof(device.version)); device.known = (device_type != EMS_DEVICE_TYPE_UNKNOWN); Devices.push_back(device); @@ -1879,8 +1877,11 @@ bool _addDevice(_EMS_DEVICE_TYPE device_type, uint8_t product_id, uint8_t device char tmp[6] = {0}; // for formatting numbers - strlcat(line, ": ", sizeof(line)); - strlcat(line, device_desc, sizeof(line)); + if (device_desc_p != nullptr) { + strlcat(line, ": ", sizeof(line)); + strlcat(line, device_desc_p, sizeof(line)); + } + strlcat(line, " (DeviceID:0x", sizeof(line)); strlcat(line, _hextoa(device_id, tmp), sizeof(line)); strlcat(line, " ProductID:", sizeof(line)); @@ -1919,7 +1920,7 @@ void _process_UBADevices(_EMS_RxTelegram * EMS_RxTelegram) { if ((byte & 0x01) && ((saved_byte & 0x01) == 0)) { uint8_t device_id = ((data_byte + 1) * 8) + bit; if (device_id != EMS_ID_ME) { - myDebug("[EMS] Detected new EMS Device with ID 0x%02X", device_id); + // myDebug("[EMS] Detected new EMS Device with ID 0x%02X", device_id); if (!ems_getTxDisabled()) { ems_doReadCommand(EMS_TYPE_Version, device_id); // get version, but ignore ourselves } @@ -1979,52 +1980,54 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) { // if not found, just add it if (!typeFound) { - (void)_addDevice(EMS_DEVICE_TYPE_UNKNOWN, product_id, device_id, 0xFF, version, EMS_MODELTYPE_UNKNOWN_STRING); // use device_index of 255 + (void)_addDevice(EMS_DEVICE_TYPE_UNKNOWN, product_id, device_id, nullptr, version); return; } + const char * device_desc_p = (EMS_Devices[i].device_desc); // pointer to the full description of the device + _EMS_DEVICE_TYPE type = EMS_Devices[i].type; // type + // we recognized it, see if we already have it in our recognized list - if (_addDevice(EMS_Devices[i].type, product_id, device_id, i, version, EMS_Devices[i].device_desc)) { + if (_addDevice(type, product_id, device_id, device_desc_p, version)) { return; // already in list } - // its a new entry, set the specifics - uint8_t flags = EMS_Devices[i].flags; + uint8_t flags = EMS_Devices[i].flags; // its a new entry, set the specifics - if (EMS_Devices[i].type == EMS_DEVICE_TYPE_BOILER) { - EMS_Boiler.device_id = device_id; - EMS_Boiler.product_id = product_id; - EMS_Boiler.device_flags = flags; - EMS_Boiler.device_index = i; + if (type == EMS_DEVICE_TYPE_BOILER) { + EMS_Boiler.device_id = device_id; + EMS_Boiler.product_id = product_id; + EMS_Boiler.device_flags = flags; + EMS_Boiler.device_desc_p = device_desc_p; strlcpy(EMS_Boiler.version, version, sizeof(EMS_Boiler.version)); ems_getBoilerValues(); // get Boiler values that we would usually have to wait for - } else if (EMS_Devices[i].type == EMS_DEVICE_TYPE_THERMOSTAT) { + } else if (type == EMS_DEVICE_TYPE_THERMOSTAT) { EMS_Thermostat.device_id = device_id; EMS_Thermostat.device_flags = (flags & 0x7F); // remove 7th bit EMS_Thermostat.write_supported = (flags & EMS_DEVICE_FLAG_NO_WRITE) == 0; EMS_Thermostat.product_id = product_id; - EMS_Thermostat.device_index = i; + EMS_Thermostat.device_desc_p = device_desc_p; strlcpy(EMS_Thermostat.version, version, sizeof(EMS_Thermostat.version)); ems_getThermostatValues(); // get Thermostat values - } else if (EMS_Devices[i].type == EMS_DEVICE_TYPE_SOLAR) { - EMS_SolarModule.device_id = device_id; - EMS_SolarModule.product_id = product_id; - EMS_SolarModule.device_flags = flags; - EMS_SolarModule.device_index = i; + } else if (type == EMS_DEVICE_TYPE_SOLAR) { + EMS_SolarModule.device_id = device_id; + EMS_SolarModule.product_id = product_id; + EMS_SolarModule.device_flags = flags; + EMS_SolarModule.device_desc_p = device_desc_p; strlcpy(EMS_SolarModule.version, version, sizeof(EMS_SolarModule.version)); ems_getSolarModuleValues(); // fetch Solar Module values - } else if (EMS_Devices[i].type == EMS_DEVICE_TYPE_HEATPUMP) { - EMS_HeatPump.device_id = device_id; - EMS_HeatPump.product_id = product_id; - EMS_HeatPump.device_flags = flags; - EMS_HeatPump.device_index = i; + } else if (type == EMS_DEVICE_TYPE_HEATPUMP) { + EMS_HeatPump.device_id = device_id; + EMS_HeatPump.product_id = product_id; + EMS_HeatPump.device_flags = flags; + EMS_HeatPump.device_desc_p = device_desc_p; strlcpy(EMS_HeatPump.version, version, sizeof(EMS_HeatPump.version)); - } else if (EMS_Devices[i].type == EMS_DEVICE_TYPE_MIXING) { - EMS_Mixing.device_id = device_id; - EMS_Mixing.product_id = product_id; - EMS_Mixing.device_index = i; - EMS_Mixing.device_flags = flags; - EMS_Mixing.detected = true; + } else if (type == EMS_DEVICE_TYPE_MIXING) { + EMS_Mixing.device_id = device_id; + EMS_Mixing.product_id = product_id; + EMS_Mixing.device_desc_p = device_desc_p; + EMS_Mixing.device_flags = flags; + EMS_Mixing.detected = true; ems_doReadCommand(EMS_TYPE_MMPLUSStatusMessage_HC1, device_id); // fetch MM values } } @@ -2209,29 +2212,34 @@ char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, boo const uint8_t size = 128; bool enabled = false; uint8_t device_id; - uint8_t device_index = 0; + uint8_t product_id; char * version; + const char * device_desc_p; if (device_type == EMS_DEVICE_TYPE_THERMOSTAT) { - enabled = ems_getThermostatEnabled(); - device_id = EMS_Thermostat.device_id; - device_index = EMS_Thermostat.device_index; - version = EMS_Thermostat.version; + enabled = ems_getThermostatEnabled(); + device_id = EMS_Thermostat.device_id; + product_id = EMS_Thermostat.product_id; + device_desc_p = EMS_Thermostat.device_desc_p; + version = EMS_Thermostat.version; } else if (device_type == EMS_DEVICE_TYPE_BOILER) { - enabled = ems_getBoilerEnabled(); - device_id = EMS_Boiler.device_id; - device_index = EMS_Boiler.device_index; - version = EMS_Boiler.version; + enabled = ems_getBoilerEnabled(); + device_id = EMS_Boiler.device_id; + product_id = EMS_Boiler.product_id; + device_desc_p = EMS_Boiler.device_desc_p; + version = EMS_Boiler.version; } else if (device_type == EMS_DEVICE_TYPE_SOLAR) { - enabled = ems_getSolarModuleEnabled(); - device_id = EMS_SolarModule.device_id; - device_index = EMS_SolarModule.device_index; - version = EMS_SolarModule.version; + enabled = ems_getSolarModuleEnabled(); + device_id = EMS_SolarModule.device_id; + product_id = EMS_SolarModule.product_id; + device_desc_p = EMS_SolarModule.device_desc_p; + version = EMS_SolarModule.version; } else if (device_type == EMS_DEVICE_TYPE_HEATPUMP) { - enabled = ems_getHeatPumpEnabled(); - device_id = EMS_HeatPump.device_id; - device_index = EMS_HeatPump.device_index; - version = EMS_HeatPump.version; + enabled = ems_getHeatPumpEnabled(); + device_id = EMS_HeatPump.device_id; + product_id = EMS_HeatPump.product_id; + device_desc_p = EMS_HeatPump.device_desc_p; + version = EMS_HeatPump.version; } if (!enabled) { @@ -2239,8 +2247,14 @@ char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, boo return buffer; } + // assume at this point we have a known device. // get device description - strlcpy(buffer, EMS_Devices[device_index].device_desc, size); + if (device_desc_p == nullptr) { + strlcpy(buffer, EMS_MODELTYPE_UNKNOWN_STRING, size); + } else { + strlcpy(buffer, device_desc_p, size); + } + if (name_only) { return buffer; // only interested in the model name } @@ -2249,7 +2263,7 @@ char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, boo char tmp[6] = {0}; strlcat(buffer, _hextoa(device_id, tmp), size); strlcat(buffer, " ProductID:", size); - strlcat(buffer, itoa(EMS_Devices[device_index].product_id, tmp, 10), size); + strlcat(buffer, itoa(product_id, tmp, 10), size); strlcat(buffer, " Version:", size); strlcat(buffer, version, size); strlcat(buffer, ")", size); @@ -2321,19 +2335,19 @@ void ems_printDevices() { // print out the ones we recognized if (!Devices.empty()) { bool have_unknowns = false; - char device_name[200]; + char device_string[100]; myDebug_P(PSTR("and %d were recognized by EMS-ESP as:"), Devices.size()); for (std::list<_Detected_Device>::iterator it = Devices.begin(); it != Devices.end(); ++it) { if ((it)->known) { - strlcpy(device_name, EMS_Devices[(it)->device_index].device_desc, sizeof(device_name)); + strlcpy(device_string, (it)->device_desc_p, sizeof(device_string)); } else { - strlcpy(device_name, EMS_MODELTYPE_UNKNOWN_STRING, sizeof(device_name)); // Unknown + strlcpy(device_string, EMS_MODELTYPE_UNKNOWN_STRING, sizeof(device_string)); // Unknown have_unknowns = true; } myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d Version:%s)"), COLOR_BOLD_ON, - device_name, + device_string, COLOR_BOLD_OFF, (it)->device_id, (it)->product_id, @@ -2343,7 +2357,8 @@ void ems_printDevices() { myDebug_P(PSTR("")); // newline if (have_unknowns) { - myDebug_P(PSTR("You have a device is that is not known by EMS-ESP. Please report this as a GitHub issue so we can expand the EMS device library.")); + myDebug_P( + PSTR("You have a device is that is not yet known by EMS-ESP. Please report this as a GitHub issue so we can expand the EMS device library.")); } } else { myDebug_P(PSTR("No were devices recognized. This may be because Tx is disabled or failing.")); diff --git a/src/ems.h b/src/ems.h index 52659aa12..c2bea1000 100644 --- a/src/ems.h +++ b/src/ems.h @@ -73,16 +73,6 @@ typedef enum { #define EMS_SYS_DEVICEMAP_LENGTH 15 // size of the 0x07 telegram data part which stores all active EMS devices -// define the model types -// which get rendered to html colors in the web interface in file custom.js in function listCustomStats() -#define EMS_MODELTYPE_BOILER 1 // success color -#define EMS_MODELTYPE_THERMOSTAT 2 // info color -#define EMS_MODELTYPE_SM 3 // warning color -#define EMS_MODELTYPE_HP 4 // success color -#define EMS_MODELTYPE_OTHER 5 // no color -#define EMS_MODELTYPE_UNKNOWN 6 // no color -#define EMS_MODELTYPE_MIXING 7 - #define EMS_MODELTYPE_UNKNOWN_STRING "unknown?" // model type text to use when discovering an unknown device /* EMS UART transfer status */ @@ -209,7 +199,7 @@ typedef enum { EMS_DEVICE_TYPE_UNKNOWN } _EMS_DEVICE_TYPE; -// to store all know EMS devices +// to store all known EMS devices to date typedef struct { uint8_t product_id; _EMS_DEVICE_TYPE type; @@ -246,12 +236,12 @@ const _EMS_Device_Types EMS_Devices_Types[] = { // for storing all recognised EMS devices typedef struct { - _EMS_DEVICE_TYPE device_type; // type - uint8_t product_id; // product id for looking up details in EMS_Devices - uint8_t device_id; // the device_id - uint8_t device_index; // where it is in the EMS_Devices table - char version[10]; // the version number XX.XX - bool known; // is this a known device? + _EMS_DEVICE_TYPE device_type; // type (see above) + uint8_t product_id; // product id + uint8_t device_id; // device_id + const char * device_desc_p; // pointer to description string in EMS_Devices table + char version[10]; // the version number XX.XX + bool known; // is this a known device? } _Detected_Device; #define EMS_DEVICE_FLAG_NONE 0 // no flags set @@ -275,7 +265,7 @@ typedef struct { // settings uint8_t device_id; // this is typically always 0x08 uint8_t device_flags; - uint8_t device_index; + const char * device_desc_p; uint8_t product_id; char version[10]; @@ -339,19 +329,15 @@ typedef struct { typedef struct { uint8_t device_id; // the device ID of the Heat Pump (e.g. 0x30) uint8_t device_flags; - uint8_t device_index; + const char * device_desc_p; uint8_t product_id; char version[10]; uint8_t HPModulation; // heatpump modulation in % uint8_t HPSpeed; // speed 0-100 % } _EMS_HeatPump; +// Mixing Module per HC typedef struct { - uint8_t device_id; - uint8_t device_flags; - uint8_t device_index; - uint8_t product_id; - char version[10]; uint8_t hc; // heating circuit 1, 2, 3 or 4 bool active; // true if there is data for this HC uint16_t flowTemp; @@ -363,17 +349,18 @@ typedef struct { typedef struct { uint8_t device_id; uint8_t device_flags; - uint8_t device_index; + const char * device_desc_p; uint8_t product_id; + char version[10]; bool detected; _EMS_Mixing_HC hc[EMS_THERMOSTAT_MAXHC]; // array for the 4 heating circuits } _EMS_Mixing; -// SM Solar Module - SM10/SM100/ISM1 +// Solar Module - SM10/SM100/ISM1 typedef struct { uint8_t device_id; // the device ID of the Solar Module uint8_t device_flags; // Solar Module flags - uint8_t device_index; + const char * device_desc_p; uint8_t product_id; char version[10]; int16_t collectorTemp; // collector temp @@ -408,7 +395,7 @@ typedef struct { typedef struct { uint8_t device_id; // the device ID of the thermostat uint8_t device_flags; // thermostat model flags - uint8_t device_index; + const char * device_desc_p; uint8_t product_id; char version[10]; char datetime[25]; // HH:MM:SS DD/MM/YYYY @@ -427,37 +414,33 @@ typedef struct { } _EMS_Type; // function definitions -extern void ems_dumpBuffer(const char * prefix, uint8_t * telegram, uint8_t length); -extern void ems_parseTelegram(uint8_t * telegram, uint8_t len); -void ems_init(); -void ems_doReadCommand(uint16_t type, uint8_t dest, bool forceRefresh = false); -void ems_sendRawTelegram(char * telegram); -void ems_scanDevices(); -void ems_printDevices(); -uint8_t ems_printDevices_s(char * buffer, uint16_t len); -void ems_printTxQueue(); -void ems_testTelegram(uint8_t test_num); -void ems_startupTelegrams(); -bool ems_checkEMSBUSAlive(); -void ems_clearDeviceList(); - -void ems_setThermostatTemp(float temperature, uint8_t hc, uint8_t temptype = 0); -void ems_setThermostatMode(uint8_t mode, uint8_t hc); -void ems_setWarmWaterTemp(uint8_t temperature); -void ems_setFlowTemp(uint8_t temperature); -void ems_setWarmWaterActivated(bool activated); -void ems_setWarmWaterOnetime(bool activated); -void ems_setWarmTapWaterActivated(bool activated); -void ems_setPoll(bool b); -void ems_setLogging(_EMS_SYS_LOGGING loglevel, bool silent = false); -void ems_setEmsRefreshed(bool b); -void ems_setWarmWaterModeComfort(uint8_t comfort); -void ems_setModels(); -void ems_setTxDisabled(bool b); -void ems_setTxMode(uint8_t mode); - -uint8_t _getHeatingCircuit(_EMS_RxTelegram * EMS_RxTelegram); - +void ems_dumpBuffer(const char * prefix, uint8_t * telegram, uint8_t length); +void ems_parseTelegram(uint8_t * telegram, uint8_t len); +void ems_init(); +void ems_doReadCommand(uint16_t type, uint8_t dest, bool forceRefresh = false); +void ems_sendRawTelegram(char * telegram); +void ems_scanDevices(); +void ems_printDevices(); +uint8_t ems_printDevices_s(char * buffer, uint16_t len); +void ems_printTxQueue(); +void ems_testTelegram(uint8_t test_num); +void ems_startupTelegrams(); +bool ems_checkEMSBUSAlive(); +void ems_clearDeviceList(); +void ems_setThermostatTemp(float temperature, uint8_t hc, uint8_t temptype = 0); +void ems_setThermostatMode(uint8_t mode, uint8_t hc); +void ems_setWarmWaterTemp(uint8_t temperature); +void ems_setFlowTemp(uint8_t temperature); +void ems_setWarmWaterActivated(bool activated); +void ems_setWarmWaterOnetime(bool activated); +void ems_setWarmTapWaterActivated(bool activated); +void ems_setPoll(bool b); +void ems_setLogging(_EMS_SYS_LOGGING loglevel, bool silent = false); +void ems_setEmsRefreshed(bool b); +void ems_setWarmWaterModeComfort(uint8_t comfort); +void ems_setModels(); +void ems_setTxDisabled(bool b); +void ems_setTxMode(uint8_t mode); char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, bool name_only = false); bool ems_getDeviceTypeDescription(uint8_t device_id, char * buffer); void ems_getThermostatValues(); @@ -486,6 +469,7 @@ void _processType(_EMS_RxTelegram * EMS_RxTelegram); void _debugPrintPackage(const char * prefix, _EMS_RxTelegram * EMS_RxTelegram, const char * color); void _ems_clearTxData(); void _removeTxQueue(); +uint8_t _getHeatingCircuit(_EMS_RxTelegram * EMS_RxTelegram); // global so can referenced in other classes extern _EMS_Sys_Status EMS_Sys_Status; diff --git a/src/ems_devices.h b/src/ems_devices.h index d0d5d289e..a7218634b 100644 --- a/src/ems_devices.h +++ b/src/ems_devices.h @@ -159,7 +159,7 @@ * Table of all known EMS Devices * ProductID, DeviceType, Description, Flags */ -const _EMS_Device EMS_Devices[] = { +static const _EMS_Device EMS_Devices[] = { // // UBA Masters - typically with device_id of 0x08 diff --git a/src/version.h b/src/version.h index 8d57dc8c4..7d7b21be6 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define APP_VERSION "1.9.4b11" +#define APP_VERSION "1.9.4b12"