mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
added 'autodetect deep' for a full scan
This commit is contained in:
@@ -16,6 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- `boiler flowtemp` command to set the flow temperature [(issue 59)](https://github.com/proddy/EMS-ESP/issues/59)
|
- `boiler flowtemp` command to set the flow temperature [(issue 59)](https://github.com/proddy/EMS-ESP/issues/59)
|
||||||
- `tx_delay` setting for circuits where we needed to slow down Tx transmission
|
- `tx_delay` setting for circuits where we needed to slow down Tx transmission
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `types` renamed to `devices` to also show all detected devices
|
||||||
|
|
||||||
|
|
||||||
## [1.6.0] 2019-03-24
|
## [1.6.0] 2019-03-24
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ Ticker scanThermostat;
|
|||||||
#define SCANTHERMOSTAT_TIME 1
|
#define SCANTHERMOSTAT_TIME 1
|
||||||
uint8_t scanThermostat_count = 0;
|
uint8_t scanThermostat_count = 0;
|
||||||
|
|
||||||
|
// ems bus scan
|
||||||
|
Ticker scanDevices;
|
||||||
|
#define SCANDEVICES_TIME 1
|
||||||
|
uint8_t scanDevices_count;
|
||||||
|
|
||||||
Ticker showerColdShotStopTimer;
|
Ticker showerColdShotStopTimer;
|
||||||
|
|
||||||
// if using the shower timer, change these settings
|
// if using the shower timer, change these settings
|
||||||
@@ -107,9 +112,9 @@ command_t PROGMEM project_cmds[] = {
|
|||||||
{false, "log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
|
{false, "log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
|
||||||
{false, "publish", "publish all values to MQTT"},
|
{false, "publish", "publish all values to MQTT"},
|
||||||
{false, "refresh", "fetch values from the EMS devices"},
|
{false, "refresh", "fetch values from the EMS devices"},
|
||||||
{false, "types", "list supported EMS telegram type IDs"},
|
{false, "devices", "list all supported and detected EMS devices and types IDs"},
|
||||||
{false, "queue", "show current Tx queue"},
|
{false, "queue", "show current Tx queue"},
|
||||||
{false, "autodetect", "detect EMS devices and attempt to automatically set boiler and thermostat types"},
|
{false, "autodetect [deep]", "detect EMS devices and attempt to automatically set boiler and thermostat types"},
|
||||||
{false, "shower <timer | alert>", "toggle either timer or alert on/off"},
|
{false, "shower <timer | alert>", "toggle either timer or alert on/off"},
|
||||||
{false, "send XX ...", "send raw telegram data as hex to EMS bus"},
|
{false, "send XX ...", "send raw telegram data as hex to EMS bus"},
|
||||||
{false, "thermostat read <type ID>", "send read request to the thermostat"},
|
{false, "thermostat read <type ID>", "send read request to the thermostat"},
|
||||||
@@ -814,6 +819,42 @@ void do_regularUpdates() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stop devices scan and restart all other timers
|
||||||
|
void stopDeviceScan() {
|
||||||
|
publishValuesTimer.attach(EMSESP_Status.publish_wait, do_publishValues); // post MQTT EMS values
|
||||||
|
publishSensorValuesTimer.attach(EMSESP_Status.publish_wait, do_publishSensorValues); // post MQTT sensor values
|
||||||
|
regularUpdatesTimer.attach(REGULARUPDATES_TIME, do_regularUpdates); // regular reads from the EMS
|
||||||
|
systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if Boiler is online
|
||||||
|
scanThermostat_count = 0;
|
||||||
|
scanThermostat.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
// EMS device scan
|
||||||
|
void do_scanDevices() {
|
||||||
|
if (scanDevices_count == 0) {
|
||||||
|
// we're at the finish line
|
||||||
|
myDebug("Finished a deep EMS device scan. Type 'devices' to see what was discovered");
|
||||||
|
stopDeviceScan();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ems_getBusConnected()) && (!myESP.getUseSerial())) {
|
||||||
|
myDebug("> Scanning EMS bus for a device type 0x%02X...", scanDevices_count); // TODO: remove debug line
|
||||||
|
ems_doReadCommand(EMS_TYPE_Version, scanDevices_count++); // ask for version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// initiate a force scan by sending a version command to all type ids
|
||||||
|
void startDeviceScan() {
|
||||||
|
publishValuesTimer.detach();
|
||||||
|
systemCheckTimer.detach();
|
||||||
|
regularUpdatesTimer.detach();
|
||||||
|
publishSensorValuesTimer.detach();
|
||||||
|
scanDevices_count = 1;
|
||||||
|
myDebug("Starting a deep EMS device scan...");
|
||||||
|
scanThermostat.attach(SCANDEVICES_TIME, do_scanDevices);
|
||||||
|
}
|
||||||
|
|
||||||
// initiate a force scan by sending type read requests from 0 to FF to the thermostat
|
// initiate a force scan by sending type read requests from 0 to FF to the thermostat
|
||||||
// used to analyze responses for debugging
|
// used to analyze responses for debugging
|
||||||
void startThermostatScan(uint8_t start) {
|
void startThermostatScan(uint8_t start) {
|
||||||
@@ -1126,8 +1167,8 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
|||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(first_cmd, "types") == 0) {
|
if (strcmp(first_cmd, "devices") == 0) {
|
||||||
ems_printAllTypes();
|
ems_printAllDevices();
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1137,8 +1178,16 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(first_cmd, "autodetect") == 0) {
|
if (strcmp(first_cmd, "autodetect") == 0) {
|
||||||
ems_scanDevices();
|
if (wc == 2) {
|
||||||
ok = true;
|
char * second_cmd = _readWord();
|
||||||
|
if (strcmp(second_cmd, "deep") == 0) {
|
||||||
|
startDeviceScan();
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ems_scanDevices();
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(first_cmd, "startup") == 0) {
|
if (strcmp(first_cmd, "startup") == 0) {
|
||||||
|
|||||||
61
src/ems.cpp
61
src/ems.cpp
@@ -21,6 +21,9 @@ _EMS_Sys_Status EMS_Sys_Status; // EMS Status
|
|||||||
|
|
||||||
CircularBuffer<_EMS_TxTelegram, EMS_TX_TELEGRAM_QUEUE_MAX> EMS_TxQueue; // FIFO queue for Tx send buffer
|
CircularBuffer<_EMS_TxTelegram, EMS_TX_TELEGRAM_QUEUE_MAX> EMS_TxQueue; // FIFO queue for Tx send buffer
|
||||||
|
|
||||||
|
// for storing all detected EMS devices
|
||||||
|
std::list<_Generic_Type> Devices;
|
||||||
|
|
||||||
// macros used in the _process* functions
|
// macros used in the _process* functions
|
||||||
#define _toByte(i) (data[i])
|
#define _toByte(i) (data[i])
|
||||||
#define _toShort(i) ((data[i] << 8) + data[i + 1])
|
#define _toShort(i) ((data[i] << 8) + data[i + 1])
|
||||||
@@ -1311,6 +1314,29 @@ void _process_RCTime(uint8_t src, uint8_t * data, uint8_t length) {
|
|||||||
EMS_Thermostat.year = _toByte(0);
|
EMS_Thermostat.year = _toByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add an EMS device to our list of detected devices
|
||||||
|
*/
|
||||||
|
void _addDevice(uint8_t product_id, uint8_t type_id, char * version, const char * model_string) {
|
||||||
|
_Generic_Type device;
|
||||||
|
|
||||||
|
// if its a duplicate don't add
|
||||||
|
bool found = false;
|
||||||
|
for (std::list<_Generic_Type>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
||||||
|
if (((it)->product_id == product_id) && ((it)->type_id == type_id)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
device.product_id = product_id;
|
||||||
|
device.type_id = type_id;
|
||||||
|
strlcpy(device.version, version, sizeof(device.version));
|
||||||
|
strlcpy(device.model_string, model_string, sizeof(device.model_string));
|
||||||
|
Devices.push_back(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* type 0x02 - get the firmware version and type of an EMS device
|
* type 0x02 - get the firmware version and type of an EMS device
|
||||||
* look up known devices via the product id and setup if not already set
|
* look up known devices via the product id and setup if not already set
|
||||||
@@ -1344,6 +1370,9 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
|
|||||||
product_id,
|
product_id,
|
||||||
version);
|
version);
|
||||||
|
|
||||||
|
// add to list
|
||||||
|
_addDevice(product_id, Boiler_Types[i].type_id, version, Boiler_Types[i].model_string);
|
||||||
|
|
||||||
// if its a boiler set it, unless it already has been set by checking for a productID
|
// if its a boiler set it, unless it already has been set by checking for a productID
|
||||||
// it will take the first one found in the list
|
// it will take the first one found in the list
|
||||||
if (((EMS_Boiler.type_id == EMS_ID_NONE) || (EMS_Boiler.type_id == Boiler_Types[i].type_id)) && EMS_Boiler.product_id == EMS_ID_NONE) {
|
if (((EMS_Boiler.type_id == EMS_ID_NONE) || (EMS_Boiler.type_id == Boiler_Types[i].type_id)) && EMS_Boiler.product_id == EMS_ID_NONE) {
|
||||||
@@ -1384,6 +1413,9 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
|
|||||||
version);
|
version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add to list
|
||||||
|
_addDevice(product_id, Boiler_Types[i].type_id, version, Thermostat_Types[i].model_string);
|
||||||
|
|
||||||
// if we don't have a thermostat set, use this one
|
// if we don't have a thermostat set, use this one
|
||||||
if (((EMS_Thermostat.type_id == EMS_ID_NONE) || (EMS_Thermostat.model_id == EMS_MODEL_NONE)
|
if (((EMS_Thermostat.type_id == EMS_ID_NONE) || (EMS_Thermostat.model_id == EMS_MODEL_NONE)
|
||||||
|| (EMS_Thermostat.type_id == Thermostat_Types[i].type_id))
|
|| (EMS_Thermostat.type_id == Thermostat_Types[i].type_id))
|
||||||
@@ -1426,6 +1458,9 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
|
|||||||
product_id,
|
product_id,
|
||||||
version);
|
version);
|
||||||
|
|
||||||
|
// add to list
|
||||||
|
_addDevice(product_id, Other_Types[i].type_id, version, Other_Types[i].model_string);
|
||||||
|
|
||||||
// see if this is a Solar Module SM10
|
// see if this is a Solar Module SM10
|
||||||
if (Other_Types[i].type_id == EMS_ID_SM10) {
|
if (Other_Types[i].type_id == EMS_ID_SM10) {
|
||||||
EMS_Other.SM10 = true; // we have detected a SM10
|
EMS_Other.SM10 = true; // we have detected a SM10
|
||||||
@@ -1438,6 +1473,9 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
myDebug("Unrecognized device found. TypeID 0x%02X, ProductID %d, Version %s", src, product_id, version);
|
myDebug("Unrecognized device found. TypeID 0x%02X, ProductID %d, Version %s", src, product_id, version);
|
||||||
|
|
||||||
|
// add to list
|
||||||
|
_addDevice(product_id, src, version, "unknown?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1686,10 +1724,10 @@ void ems_scanDevices() {
|
|||||||
/**
|
/**
|
||||||
* Print out all handled types
|
* Print out all handled types
|
||||||
*/
|
*/
|
||||||
void ems_printAllTypes() {
|
void ems_printAllDevices() {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
myDebug("\nThese %d devices are defined as boiler units:", _Boiler_Types_max);
|
myDebug("\nThese %d devices are supported as boiler units:", _Boiler_Types_max);
|
||||||
for (i = 0; i < _Boiler_Types_max; i++) {
|
for (i = 0; i < _Boiler_Types_max; i++) {
|
||||||
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d)",
|
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d)",
|
||||||
COLOR_BOLD_ON,
|
COLOR_BOLD_ON,
|
||||||
@@ -1699,7 +1737,7 @@ void ems_printAllTypes() {
|
|||||||
Boiler_Types[i].product_id);
|
Boiler_Types[i].product_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
myDebug("\nThese %d devices are defined as other EMS devices:", _Other_Types_max);
|
myDebug("\nThese %d devices are supported as other known EMS devices:", _Other_Types_max);
|
||||||
for (i = 0; i < _Other_Types_max; i++) {
|
for (i = 0; i < _Other_Types_max; i++) {
|
||||||
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d)",
|
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d)",
|
||||||
COLOR_BOLD_ON,
|
COLOR_BOLD_ON,
|
||||||
@@ -1709,7 +1747,7 @@ void ems_printAllTypes() {
|
|||||||
Other_Types[i].product_id);
|
Other_Types[i].product_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
myDebug("\nThe following telegram type IDs are recognized:");
|
myDebug("\nThe following telegram type IDs are supported:");
|
||||||
for (i = 0; i < _EMS_Types_max; i++) {
|
for (i = 0; i < _EMS_Types_max; i++) {
|
||||||
if ((EMS_Types[i].model_id == EMS_MODEL_ALL) || (EMS_Types[i].model_id == EMS_MODEL_UBA)) {
|
if ((EMS_Types[i].model_id == EMS_MODEL_ALL) || (EMS_Types[i].model_id == EMS_MODEL_UBA)) {
|
||||||
myDebug(" type %02X (%s)", EMS_Types[i].type, EMS_Types[i].typeString);
|
myDebug(" type %02X (%s)", EMS_Types[i].type, EMS_Types[i].typeString);
|
||||||
@@ -1727,6 +1765,21 @@ void ems_printAllTypes() {
|
|||||||
(Thermostat_Types[i].read_supported) ? 'y' : 'n',
|
(Thermostat_Types[i].read_supported) ? 'y' : 'n',
|
||||||
(Thermostat_Types[i].write_supported) ? 'y' : 'n');
|
(Thermostat_Types[i].write_supported) ? 'y' : 'n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Devices.size() != 0) {
|
||||||
|
myDebug("\nThese %d EMS devices were detected on your system:", Devices.size());
|
||||||
|
for (std::list<_Generic_Type>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
||||||
|
myDebug(" %s%s%s (TypeID:0x%02X ProductID:%d Version:%s)",
|
||||||
|
COLOR_BOLD_ON,
|
||||||
|
(it)->model_string,
|
||||||
|
COLOR_BOLD_OFF,
|
||||||
|
(it)->type_id,
|
||||||
|
(it)->product_id,
|
||||||
|
(it)->version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
myDebug(""); // newline
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -163,6 +163,13 @@ typedef struct {
|
|||||||
bool write_supported;
|
bool write_supported;
|
||||||
} _Thermostat_Type;
|
} _Thermostat_Type;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t product_id;
|
||||||
|
uint8_t type_id;
|
||||||
|
char version[10];
|
||||||
|
char model_string[50];
|
||||||
|
} _Generic_Type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Telegram package defintions
|
* Telegram package defintions
|
||||||
*/
|
*/
|
||||||
@@ -312,7 +319,7 @@ bool ems_getTxCapable();
|
|||||||
uint32_t ems_getPollFrequency();
|
uint32_t ems_getPollFrequency();
|
||||||
|
|
||||||
void ems_scanDevices();
|
void ems_scanDevices();
|
||||||
void ems_printAllTypes();
|
void ems_printAllDevices();
|
||||||
char * ems_getThermostatDescription(char * buffer);
|
char * ems_getThermostatDescription(char * buffer);
|
||||||
void ems_printTxQueue();
|
void ems_printTxQueue();
|
||||||
char * ems_getBoilerDescription(char * buffer);
|
char * ems_getBoilerDescription(char * buffer);
|
||||||
|
|||||||
@@ -109,8 +109,9 @@ void ICACHE_FLASH_ATTR emsuart_init() {
|
|||||||
// UCTOE = RX TimeOut enable (default is 1)
|
// UCTOE = RX TimeOut enable (default is 1)
|
||||||
// UCTOT = RX TimeOut Threshold (7bit) = want this when no more data after 2 characters. (default is 2)
|
// UCTOT = RX TimeOut Threshold (7bit) = want this when no more data after 2 characters. (default is 2)
|
||||||
// UCFFT = RX FIFO Full Threshold (7 bit) = want this to be 31 for 32 bytes of buffer. (default was 127).
|
// UCFFT = RX FIFO Full Threshold (7 bit) = want this to be 31 for 32 bytes of buffer. (default was 127).
|
||||||
|
// see https://www.espressif.com/sites/default/files/documentation/esp8266-technical_reference_en.pdf
|
||||||
USC1(EMSUART_UART) = 0; // reset config first
|
USC1(EMSUART_UART) = 0; // reset config first
|
||||||
USC1(EMSUART_UART) = (31 << UCFFT) | (0x02 << UCTOT) | (1 << UCTOE); // enable interupts
|
USC1(EMSUART_UART) = (EMS_MAX_TELEGRAM_LENGTH << UCFFT) | (0x02 << UCTOT) | (1 << UCTOE); // enable interupts
|
||||||
|
|
||||||
// set interrupts for triggers
|
// set interrupts for triggers
|
||||||
USIC(EMSUART_UART) = 0xffff; // clear all interupts
|
USIC(EMSUART_UART) = 0xffff; // clear all interupts
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define APP_NAME "EMS-ESP"
|
#define APP_NAME "EMS-ESP"
|
||||||
#define APP_VERSION "1.7.0b5"
|
#define APP_VERSION "1.7.0b6"
|
||||||
#define APP_HOSTNAME "ems-esp"
|
#define APP_HOSTNAME "ems-esp"
|
||||||
|
|||||||
Reference in New Issue
Block a user