cleaned up detection - #283

This commit is contained in:
Paul
2020-01-04 23:15:41 +01:00
parent ae61c357c0
commit daf24af323
6 changed files with 84 additions and 123 deletions

View File

@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- improved MQTT publishing to stop flooding
### Removed
- `autodetect scan`
## [1.9.4] 15-12-2019

View File

@@ -113,7 +113,7 @@ static const command_t project_cmds[] PROGMEM = {
{false, "refresh", "fetch values from the EMS devices"},
{false, "devices", "list detected EMS devices"},
{false, "queue", "show current Tx queue"},
{false, "autodetect [scan]", "detect EMS devices and attempt to automatically set boiler and thermostat types"},
{false, "autodetect", "detect EMS devices and attempt to automatically set boiler and thermostat types"},
{false, "send XX ...", "send raw telegram data to EMS bus (XX are hex values)"},
{false, "thermostat read <type ID>", "send read request to the thermostat for heating circuit hc 1-4"},
{false, "thermostat temp [hc] <degrees>", "set current thermostat temperature"},
@@ -1218,18 +1218,10 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
}
if (strcmp(first_cmd, "autodetect") == 0) {
if (wc == 2) {
char * second_cmd = _readWord();
if (strcmp(second_cmd, "scan") == 0) {
ems_scanDevices(); // known device scan
ok = true;
}
} else {
ems_clearDeviceList();
ems_doReadCommand(EMS_TYPE_UBADevices, EMS_Boiler.device_id);
ok = true;
}
}
// logging
if ((strcmp(first_cmd, "log") == 0) && (wc >= 2)) {

View File

@@ -881,7 +881,7 @@ void _printMessage(_EMS_RxTelegram * EMS_RxTelegram) {
char type_s[30];
// source
ems_getDeviceTypeDescription(src, type_s);
(void)ems_getDeviceTypeDescription(src, type_s);
strlcpy(output_str, type_s, sizeof(output_str));
strlcat(output_str, " -> ", sizeof(output_str));
@@ -1622,10 +1622,8 @@ bool _addDevice(_EMS_DEVICE_TYPE device_type, uint8_t product_id, uint8_t device
// get type as a string
char type_s[50];
if (ems_getDeviceTypeDescription(device_id, type_s)) {
if (ems_getDeviceTypeName(device_type, type_s)) {
strlcat(line, type_s, sizeof(line));
} else {
strlcat(line, "?", sizeof(line));
}
char tmp[6] = {0}; // for formatting numbers
@@ -1738,19 +1736,6 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
while (i < _EMS_Devices_max) {
if (EMS_Devices[i].product_id == product_id) {
// we have a matching product id
/*
// this code is to check also that we have a matching device type (e.g. boiler, thermostat etc)
// now lets see if there is a matching device_id since product_id can be on multiple devices
// e.g. with UBAMasters, there is only one device_id 0x08. To avoid https://github.com/proddy/EMS-ESP/issues/271
_EMS_DEVICE_TYPE device_type = EMS_Devices[i].type;
for (uint8_t j = 0; j < _EMS_Devices_Types_max; j++) {
if ((EMS_Devices_Types[j].device_type == device_type) && (EMS_Devices_Types[j].device_id == device_id)) {
typeFound = true;
found_index = i;
break;
}
}
*/
typeFound = true;
found_index = i;
break;
@@ -1960,35 +1945,67 @@ void ems_getSolarModuleValues() {
}
}
/**
* takes a device_id and tries to find the corresponding type name (e.g. Boiler)
* If it can't find it, it will use the hex value and function returns false
*/
bool ems_getDeviceTypeDescription(uint8_t device_id, char * buffer) {
// takes a device type (e.g. EMS_DEVICE_TYPE_MIXING) and stores the english name in the given buffer
// returns buffer or "unknown"
char * ems_getDeviceTypeName(_EMS_DEVICE_TYPE device_type, char * buffer) {
uint8_t i = 0;
bool typeFound = false;
// scan through known ID types
while (i < _EMS_Devices_Types_max) {
if (EMS_Devices_Types[i].device_id == device_id) {
if (EMS_Devices_Types[i].device_type == device_type) {
typeFound = true; // we have a match
break;
}
i++;
}
if (typeFound) {
if (!typeFound) {
i = 0; // this will point to "Unknown" in the lookup
}
strlcpy(buffer, EMS_Devices_Types[i].device_type_string, 30);
return true;
return buffer;
}
/**
* takes a device_id and tries to find the corresponding type name (e.g. Boiler)
* If it can't find it, it will use the hex value and function returns false
*/
bool ems_getDeviceTypeDescription(uint8_t device_id, char * buffer) {
_EMS_DEVICE_TYPE device_type = EMS_DEVICE_TYPE_UNKNOWN;
// check for the fixed device IDs we already know about, like 0x00 for broadcast, 0x0B for me, 0x08 for Boiler
if (device_id == EMS_ID_BOILER) {
device_type = EMS_DEVICE_TYPE_BOILER;
} else if (device_id == EMS_ID_ME) {
device_type = EMS_DEVICE_TYPE_SERVICEKEY;
} else if (device_id == EMS_ID_NONE) {
device_type = EMS_DEVICE_TYPE_NONE;
} else {
// print as hex value
// see if its a device we already know about (via earlier detection)
if (!Devices.empty()) {
for (std::list<_Detected_Device>::iterator it = Devices.begin(); it != Devices.end(); ++it) {
if (it->device_id == device_id) {
device_type = it->device_type;
break;
}
}
}
}
// if its not unknown, fetch the real name of the type
if (device_type != EMS_DEVICE_TYPE_UNKNOWN) {
ems_getDeviceTypeName(device_type, buffer);
return true;
}
// we didn't find anything. Use the hex value of the device ID
char hexbuffer[16] = {0};
strlcpy(buffer, "0x", 30);
strlcat(buffer, _hextoa(device_id, hexbuffer), 30);
return false;
}
}
/**
* returns current device details as a string for known thermostat,boiler,solar and heatpump
@@ -2056,38 +2073,6 @@ char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, boo
return buffer;
}
/**
* Find the versions of our connected devices
*/
void ems_scanDevices() {
myDebug_P(PSTR("Started scanning the EMS bus for known devices"));
std::list<uint8_t> Device_Ids; // create a new list
Device_Ids.push_back(EMS_ID_BOILER); // UBAMaster/Boilers - 0x08
Device_Ids.push_back(EMS_ID_HP); // HeatPump - 0x38
Device_Ids.push_back(EMS_ID_SM); // Solar Module - 0x30
Device_Ids.push_back(EMS_ID_CONTROLLER); // Controllers - 0x09
Device_Ids.push_back(EMS_ID_CONNECT1); // Connect - 0x02
Device_Ids.push_back(EMS_ID_CONNECT2); // Connect - 0x50
Device_Ids.push_back(EMS_ID_GATEWAY); // Gateway - 0x48
Device_Ids.push_back(EMS_ID_MIXING1); // Mixing Devices - 0x20, 0x21
Device_Ids.push_back(EMS_ID_MIXING2); // Mixing Devices - 0x20, 0x21
Device_Ids.push_back(EMS_ID_THERMOSTAT1); // Thermostats - 0x10, 0x17, 0x18
Device_Ids.push_back(EMS_ID_THERMOSTAT2); // Thermostats - 0x10, 0x17, 0x18
Device_Ids.push_back(EMS_ID_THERMOSTAT3); // Thermostats - 0x10, 0x17, 0x18
Device_Ids.push_back(EMS_ID_SWITCH); // Switch - 0x11
// remove duplicates and reserved IDs (like our own device)
Device_Ids.sort();
// Device_Ids.unique();
// send the read command with Version command
for (uint8_t device_id : Device_Ids) {
ems_doReadCommand(EMS_TYPE_Version, device_id);
}
}
/**
* print out contents of the device list that was captured
*/
@@ -2126,8 +2111,7 @@ void ems_printDevices() {
char device_type[30];
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) {
ems_getDeviceTypeDescription(it->device_id, device_type); // get type string, e.g. "Boiler"
ems_getDeviceTypeName(it->device_type, device_type); // get type string, e.g. "Boiler"
if (it->known) {
strlcpy(device_string, it->device_desc_p, sizeof(device_string));
} else {

View File

@@ -207,14 +207,36 @@ typedef enum : uint8_t {
EMS_DEVICE_TYPE_SOLAR,
EMS_DEVICE_TYPE_HEATPUMP,
EMS_DEVICE_TYPE_GATEWAY,
EMS_DEVICE_TYPE_OTHER,
EMS_DEVICE_TYPE_SWITCH,
EMS_DEVICE_TYPE_CONTROLLER,
EMS_DEVICE_TYPE_CONNECT,
EMS_DEVICE_TYPE_MODEM,
EMS_DEVICE_TYPE_UNKNOWN
} _EMS_DEVICE_TYPE;
// to store mapping of device_ids to their string name
typedef struct {
_EMS_DEVICE_TYPE device_type;
char device_type_string[30];
} _EMS_Device_Types;
// mapping for EMS_Devices_Type
const _EMS_Device_Types EMS_Devices_Types[] = {
{EMS_DEVICE_TYPE_UNKNOWN, EMS_MODELTYPE_UNKNOWN_STRING}, // the first, at index 0 is reserved for "unknown"
{EMS_DEVICE_TYPE_NONE, "All"},
{EMS_DEVICE_TYPE_SERVICEKEY, "Me"},
{EMS_DEVICE_TYPE_BOILER, "UBAMaster"},
{EMS_DEVICE_TYPE_THERMOSTAT, "Thermostat"},
{EMS_DEVICE_TYPE_MIXING, "Mixing Module"},
{EMS_DEVICE_TYPE_SOLAR, "Solar Module"},
{EMS_DEVICE_TYPE_HEATPUMP, "Heat Pump"},
{EMS_DEVICE_TYPE_GATEWAY, "Gateway"},
{EMS_DEVICE_TYPE_SWITCH, "Switching Module"},
{EMS_DEVICE_TYPE_CONTROLLER, "Controller"},
{EMS_DEVICE_TYPE_CONNECT, "Connect"}
};
// to store all known EMS devices to date
typedef struct {
uint8_t product_id;
@@ -223,13 +245,6 @@ typedef struct {
uint8_t flags;
} _EMS_Device;
// to store mapping of device_ids to their string name
typedef struct {
uint8_t device_id;
_EMS_DEVICE_TYPE device_type;
char device_type_string[30];
} _EMS_Device_Types;
// for storing all recognised EMS devices
typedef struct {
_EMS_DEVICE_TYPE device_type; // type (see above)
@@ -404,7 +419,6 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t len);
void ems_init();
void ems_doReadCommand(uint16_t type, uint8_t dest);
void ems_sendRawTelegram(char * telegram);
void ems_scanDevices();
void ems_printDevices();
uint8_t ems_printDevices_s(char * buffer, uint16_t len);
void ems_printTxQueue();
@@ -428,6 +442,7 @@ void ems_setTxMode(uint8_t mode);
void ems_setMasterThermostat(uint8_t product_id);
char * ems_getDeviceDescription(_EMS_DEVICE_TYPE device_type, char * buffer, bool name_only = false);
bool ems_getDeviceTypeDescription(uint8_t device_id, char * buffer);
char * ems_getDeviceTypeName(_EMS_DEVICE_TYPE device_type, char * buffer);
void ems_getThermostatValues();
void ems_getBoilerValues();
void ems_getSolarModuleValues();

View File

@@ -14,39 +14,8 @@
// Fixed EMS Device IDs
#define EMS_ID_ME 0x0B // our device, hardcoded as the "Service Key"
#define EMS_ID_BOILER 0x08 // all UBA Boilers have 0x08
#define EMS_ID_SM 0x30 // Solar Module SM10, SM100, SM200 and ISM1
#define EMS_ID_HP 0x38 // HeatPump
#define EMS_ID_GATEWAY 0x48 // Gateway Modem e.g. KM200 Web Gateway. Also on 0x0A->0x0D
#define EMS_ID_MIXING1 0x20 // Mixing
#define EMS_ID_MIXING2 0x21 // Mixing
#define EMS_ID_SWITCH 0x11 // Switch
#define EMS_ID_CONTROLLER 0x09 // Controller
#define EMS_ID_CONNECT1 0x02 // Connect
#define EMS_ID_CONNECT2 0x50 // Connect
#define EMS_ID_THERMOSTAT1 0x10 // Thermostat
#define EMS_ID_THERMOSTAT2 0x17 // Thermostat
#define EMS_ID_THERMOSTAT3 0x18 // Thermostat
// mapping for EMS_Devices_Type
const _EMS_Device_Types EMS_Devices_Types[] = {
{EMS_ID_BOILER, EMS_DEVICE_TYPE_BOILER, "UBAMaster"},
{EMS_ID_THERMOSTAT1, EMS_DEVICE_TYPE_THERMOSTAT, "Thermostat"},
{EMS_ID_THERMOSTAT2, EMS_DEVICE_TYPE_THERMOSTAT, "Thermostat"},
{EMS_ID_THERMOSTAT3, EMS_DEVICE_TYPE_THERMOSTAT, "Thermostat"},
{EMS_ID_SM, EMS_DEVICE_TYPE_SOLAR, "Solar Module"},
{EMS_ID_HP, EMS_DEVICE_TYPE_HEATPUMP, "Heat Pump"},
{EMS_ID_GATEWAY, EMS_DEVICE_TYPE_GATEWAY, "Gateway"},
{EMS_ID_ME, EMS_DEVICE_TYPE_SERVICEKEY, "Me"},
{EMS_ID_NONE, EMS_DEVICE_TYPE_NONE, "All"},
{EMS_ID_MIXING1, EMS_DEVICE_TYPE_MIXING, "Mixing Module"},
{EMS_ID_MIXING2, EMS_DEVICE_TYPE_MIXING, "Mixing Module"},
{EMS_ID_SWITCH, EMS_DEVICE_TYPE_SWITCH, "Switching Module"},
{EMS_ID_CONTROLLER, EMS_DEVICE_TYPE_CONTROLLER, "Controller"},
{EMS_ID_CONNECT1, EMS_DEVICE_TYPE_CONNECT, "Connect"},
{EMS_ID_CONNECT2, EMS_DEVICE_TYPE_CONNECT, "Connect"}
};
/*
* Common Type
@@ -283,7 +252,7 @@ static const _EMS_Device EMS_Devices[] = {
{206, EMS_DEVICE_TYPE_CONNECT, "Bosch Easy Connect", EMS_DEVICE_FLAG_NONE}, // 0x02
{171, EMS_DEVICE_TYPE_CONNECT, "EMS-OT OpenTherm converter", EMS_DEVICE_FLAG_NONE}, // 0x02
{189, EMS_DEVICE_TYPE_GATEWAY, "Web Gateway KM200", EMS_DEVICE_FLAG_NONE}, // 0x48
{94, EMS_DEVICE_TYPE_MODEM, "RC Remote Device", EMS_DEVICE_FLAG_NONE}, // 0x18
{94, EMS_DEVICE_TYPE_GATEWAY, "RC Remote Device", EMS_DEVICE_FLAG_NONE}, // 0x18
//
// Thermostats, typically device id of 0x10, 0x17, 0x18, 0x38 (RC100), 0x39 (Easy)

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.5b13"
#define APP_VERSION "1.9.5b14"