generic support for EMS+

This commit is contained in:
proddy
2019-04-17 22:59:07 +02:00
parent 9253b7b233
commit 84042e8d59
7 changed files with 309 additions and 333 deletions

View File

@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.7.0 dev] 2019-04-14 ## [1.7.0 dev] 2019-04-17
### Added ### Added
@@ -15,10 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for multiple thermostat heating circuits like the HC1/HC2 on a RC35, also via MQTT (thanks @lobocobra) - Support for multiple thermostat heating circuits like the HC1/HC2 on a RC35, also via MQTT (thanks @lobocobra)
- `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
- nefit proline hrc 24 cw4 thermostat
### Changed ### Changed
- `types` renamed to `devices` to also show all detected devices - `types` renamed to `devices` to also show all detected devices
- EMS Plus logic optimized
## [1.6.0] 2019-03-24 ## [1.6.0] 2019-03-24

View File

@@ -21,9 +21,6 @@ There are 3 parts to this project, first the design of the circuit, secondly the
- [EMS Polling](#ems-polling) - [EMS Polling](#ems-polling)
- [EMS Broadcasting](#ems-broadcasting) - [EMS Broadcasting](#ems-broadcasting)
- [EMS Reading and Writing](#ems-reading-and-writing) - [EMS Reading and Writing](#ems-reading-and-writing)
- [EMS Plus](#ems-plus)
- [Message layout](#message-layout)
- [Message types](#message-types)
- [The ESP8266 Source Code](#the-esp8266-source-code) - [The ESP8266 Source Code](#the-esp8266-source-code)
- [Special EMS Types](#special-ems-types) - [Special EMS Types](#special-ems-types)
- [Which thermostats are supported?](#which-thermostats-are-supported) - [Which thermostats are supported?](#which-thermostats-are-supported)
@@ -69,12 +66,12 @@ The code and circuit has been tested with a few ESP8266 development boards such
3. Optionally add external Dallas temperature sensors (to D1) and an external LED (to D5). 3. Optionally add external Dallas temperature sensors (to D1) and an external LED (to D5).
4. Decide whether to compile and upload the code yourself using PlatformIO or just upload the pre-baked firmware using the esptool (read these [instructions](#using-the-pre-built-firmware)). If you want to build yourself now is the time to customize your settings in `my_custom.h`. Upload the firmware via USB. 4. Decide whether to compile and upload the code yourself using PlatformIO or just upload the pre-baked firmware using the esptool (read these [instructions](#using-the-pre-built-firmware)). If you want to build yourself now is the time to customize your settings in `my_custom.h`. Upload the firmware via USB.
5. Connect an external USB 5v power adapter to the ESP8266 board. 5. Connect an external USB 5v power adapter to the ESP8266 board.
7. When the ESP8266 starts up for the first time the onboard LED will be flashing. This is because the EMS bus is not yet connected and receiving data. 6. When the ESP8266 starts up for the first time the onboard LED will be flashing. This is because the EMS bus is not yet connected and receiving data.
8. If you haven't hardcoded the WiFi credentials in step 4, the ESP8266 will boot up in a WiFi Access Point (AP) mode with the ssid name `ems-esp`. Now you can either use a laptop and connect to this AP using Telnet to `192.168.1.4` or if its powered from a computers USB use a Serial monitor tool to the ESP's COM port. Tip: to enable Telnet on Windows 10 run `dism /online /Enable-Feature /FeatureName:TelnetClient` or install something like [putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html). 7. If you haven't hardcoded the WiFi credentials in step 4, the ESP8266 will boot up in a WiFi Access Point (AP) mode with the ssid name `ems-esp`. Now you can either use a laptop and connect to this AP using Telnet to `192.168.1.4` or if its powered from a computers USB use a Serial monitor tool to the ESP's COM port. Tip: to enable Telnet on Windows 10 run `dism /online /Enable-Feature /FeatureName:TelnetClient` or install something like [putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html).
9. Next is to customize some of the onboard settings. Type `set` to list the current stored settings and `?` to see the syntax. Use `set wifi_ssid` and `set wifi_password` to add your WiFi credentials and if you're using MQTT set the host, username and password. There is no need to reboot the ESP. 8. Next is to customize some of the onboard settings. Type `set` to list the current stored settings and `?` to see the syntax. Use `set wifi_ssid` and `set wifi_password` to add your WiFi credentials and if you're using MQTT set the host, username and password. There is no need to reboot the ESP.
10. The `led_gpio` will default to the onboard LED (which is probably blinking now). Ignore `thermostat_type` and `boiler_type` as these will be auto-detected hopefully later on. 9. The `led_gpio` will default to the onboard LED (which is probably blinking now). Ignore `thermostat_type` and `boiler_type` as these will be auto-detected hopefully later on.
11. **Important**: By default the serial port is enabled and the EMS bus disabled. This is to allow users to configure their ESP via the serial monitor when pluged into a PC/laptop. You must disable serial with `set serial off` to get the EMS transmission working. 10. **Important**: By default the serial port is enabled and the EMS bus disabled. This is to allow users to configure their ESP via the serial monitor when pluged into a PC/laptop. You must disable serial with `set serial off` to get the EMS transmission working.
12. Hook up the ESP to the EMS board as follows: 11. Hook up the ESP to the EMS board as follows:
| EMS board | ESP8266 dev board | | EMS board | ESP8266 dev board |
| ----------- | ----------------- | | ----------- | ----------------- |
@@ -82,12 +79,12 @@ The code and circuit has been tested with a few ESP8266 development boards such
| Rx/J2 | D7 | | Rx/J2 | D7 |
| Tx/J2 | D8 | | Tx/J2 | D8 |
| VC/J2 | 3v3 | | VC/J2 | 3v3 |
13. Connect the EMS lines to the ESP. This can be done via the two EMS wires or via the 3.5mm service jack if you have an bbqkees board. 12. Connect the EMS lines to the ESP. This can be done via the two EMS wires or via the 3.5mm service jack if you have an bbqkees board.
14. Reboot the ESP, either by the reset switch or pulling the power. 13. Reboot the ESP, either by the reset switch or pulling the power.
15. The ESP will first perform an autodetect to try and discover the EMS devices attached. If your boiler and thermostat are recognized it will set these types and store them for ever and ever. You can trace the output by telnet'ing to the board `telnet ems-esp.local`. Also use `info` to check the status. 14. The ESP will first perform an autodetect to try and discover the EMS devices attached. If your boiler and thermostat are recognized it will set these types and store them for ever and ever. You can trace the output by telnet'ing to the board `telnet ems-esp.local`. Also use `info` to check the status.
16. If your boiler/thermostat is not discovered create a GitHub issue stating the type and Product ID. These will be added to the file `ems_devices.h` in a future release. 15. If your boiler/thermostat is not discovered create a GitHub issue stating the type and Product ID. These will be added to the file `ems_devices.h` in a future release.
17. If all is well and there is traffic on the EMS bus the onboard LED will stop blinking and be permanently on. If this is annoying you can disable with `set led off`. To see the EMS messages type `set log v` for verbose logging. 16. If all is well and there is traffic on the EMS bus the onboard LED will stop blinking and be permanently on. If this is annoying you can disable with `set led off`. To see the EMS messages type `set log v` for verbose logging.
18. And all is not well, check the wiring, make sure serial is off and look at the telnet session for errors. If in doubt, wipe the ESP with `pio run -t erase` and start again with step #3 17. And all is not well, check the wiring, make sure serial is off and look at the telnet session for errors. If in doubt, wipe the ESP with `pio run -t erase` and start again with step #3
## Monitoring The Output ## Monitoring The Output
@@ -199,24 +196,6 @@ Following a write request, the `[dest]` doesn't have the 8th bit set and after t
Every telegram sent is echo'd back to Rx, along the same Bus used for all Rx/Tx transmissions. Every telegram sent is echo'd back to Rx, along the same Bus used for all Rx/Tx transmissions.
## EMS Plus
In this chapter we will report our findings on the EMS plus protocol which differs slighly from EMS 1.0.
### Message layout
| 0 | 1 | 2 | 3 | 4 | 5 | n....n-1 | n |
| ----------- | -------- | ------------- | ------------ | ------ | ------------------- | -------- | --- |
| transmitter | receiver | ems plus mark | message type | offset | device intended for | data | cnc |
| 18 | 00 | FF | 03 | 01 | A5 | 28 | 46 |
### Message types
| Message type | Definition |
| ------------ | --------------- |
| 03 | Set temperature |
| 00 | Status message |
## The ESP8266 Source Code ## The ESP8266 Source Code
`emsuart.cpp` handles the low level UART read and write logic to the bus. You shouldn't need to touch this. All receive commands from the EMS bus are handled asynchronously using a circular buffer via an interrupt. A separate function processes the buffer and extracts the telegrams. `emsuart.cpp` handles the low level UART read and write logic to the bus. You shouldn't need to touch this. All receive commands from the EMS bus are handled asynchronously using a circular buffer via an interrupt. A separate function processes the buffer and extracts the telegrams.
@@ -312,7 +291,7 @@ You can find the .yaml configuration files under `doc/ha`. See also this [HA for
- Download and install [Visual Studio Code](https://code.visualstudio.com/docs/?dv=win) (VSC). It's like 40MB so don't confuse with the commercial Microsoft Visual Studio. - Download and install [Visual Studio Code](https://code.visualstudio.com/docs/?dv=win) (VSC). It's like 40MB so don't confuse with the commercial Microsoft Visual Studio.
- Restart the PC (if using Windows) to apply the new PATH settings. It should now detect Git - Restart the PC (if using Windows) to apply the new PATH settings. It should now detect Git
- Install the VSC extension "PlatformIO IDE" then click reload to activate it - Install the VSC extension "PlatformIO IDE" then click reload to activate it
- Git clone this repo, eith using `git clone` from PlatformIO's terminal or the Git GUI interface - Git clone this repo using `git clone` from PlatformIO's terminal or the Git GUI interface
- Create a `platformio.ini` based on the `platformio.ini-example` making the necessary changes for your board type - Create a `platformio.ini` based on the `platformio.ini-example` making the necessary changes for your board type
**On Linux (e.g. Ubuntu under Windows 10):** **On Linux (e.g. Ubuntu under Windows 10):**

View File

@@ -99,8 +99,8 @@ command_t PROGMEM project_cmds[] = {
{true, "led_gpio <gpio>", "set the LED pin. Default is the onboard LED (D1=5)"}, {true, "led_gpio <gpio>", "set the LED pin. Default is the onboard LED (D1=5)"},
{true, "dallas_gpio <gpio>", "set the pin for external Dallas temperature sensors (D5=14)"}, {true, "dallas_gpio <gpio>", "set the pin for external Dallas temperature sensors (D5=14)"},
{true, "dallas_parasite <on | off>", "set to on if powering Dallas via parasite"}, {true, "dallas_parasite <on | off>", "set to on if powering Dallas via parasite"},
{true, "thermostat_type <type ID>", "set the thermostat type id (e.g. 10 for 0x10)"}, {true, "thermostat_type <device ID>", "set the thermostat type id (e.g. 10 for 0x10)"},
{true, "boiler_type <type ID>", "set the boiler type id (e.g. 8 for 0x08)"}, {true, "boiler_type <device ID>", "set the boiler type id (e.g. 8 for 0x08)"},
{true, "silent_mode <on | off>", "when on all automatic Tx is disabled"}, {true, "silent_mode <on | off>", "when on all automatic Tx is disabled"},
{true, "shower_timer <on | off>", "notify via MQTT all shower durations"}, {true, "shower_timer <on | off>", "notify via MQTT all shower durations"},
{true, "shower_alert <on | off>", "send a warning of cold water after shower time is exceeded"}, {true, "shower_alert <on | off>", "send a warning of cold water after shower time is exceeded"},
@@ -358,7 +358,7 @@ void showInfo() {
myDebug("%sBoiler stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF); myDebug("%sBoiler stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
// version details // version details
myDebug(" Boiler type: %s", ems_getBoilerDescription(buffer_type)); myDebug(" Boiler: %s", ems_getBoilerDescription(buffer_type));
// active stats // active stats
if (ems_getBusConnected()) { if (ems_getBusConnected()) {
@@ -461,7 +461,7 @@ void showInfo() {
if (ems_getThermostatEnabled()) { if (ems_getThermostatEnabled()) {
myDebug(""); // newline myDebug(""); // newline
myDebug("%sThermostat stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF); myDebug("%sThermostat stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
myDebug(" Thermostat type: %s", ems_getThermostatDescription(buffer_type)); myDebug(" Thermostat: %s", ems_getThermostatDescription(buffer_type));
if ((ems_getThermostatModel() == EMS_MODEL_EASY) || (ems_getThermostatModel() == EMS_MODEL_BOSCHEASY)) { if ((ems_getThermostatModel() == EMS_MODEL_EASY) || (ems_getThermostatModel() == EMS_MODEL_BOSCHEASY)) {
// for easy temps are * 100 // for easy temps are * 100
// also we don't have the time or mode // also we don't have the time or mode
@@ -796,7 +796,7 @@ void do_ledcheck() {
void do_scanThermostat() { void do_scanThermostat() {
if ((ems_getBusConnected()) && (!myESP.getUseSerial())) { if ((ems_getBusConnected()) && (!myESP.getUseSerial())) {
myDebug("> Scanning thermostat message type #0x%02X...", scanThermostat_count); myDebug("> Scanning thermostat message type #0x%02X...", scanThermostat_count);
ems_doReadCommand(scanThermostat_count, EMS_Thermostat.type_id); ems_doReadCommand(scanThermostat_count, EMS_Thermostat.device_id);
scanThermostat_count++; scanThermostat_count++;
} }
} }
@@ -913,13 +913,13 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) {
EMSESP_Status.dallas_parasite = json["dallas_parasite"]; EMSESP_Status.dallas_parasite = json["dallas_parasite"];
// thermostat_type // thermostat_type
if (!(EMS_Thermostat.type_id = json["thermostat_type"])) { if (!(EMS_Thermostat.device_id = json["thermostat_type"])) {
EMS_Thermostat.type_id = EMSESP_THERMOSTAT_TYPE; // set default EMS_Thermostat.device_id = EMSESP_THERMOSTAT_TYPE; // set default
} }
// boiler_type // boiler_type
if (!(EMS_Boiler.type_id = json["boiler_type"])) { if (!(EMS_Boiler.device_id = json["boiler_type"])) {
EMS_Boiler.type_id = EMSESP_BOILER_TYPE; // set default EMS_Boiler.device_id = EMSESP_BOILER_TYPE; // set default
} }
// silent mode // silent mode
@@ -950,8 +950,8 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) {
} }
if (action == MYESP_FSACTION_SAVE) { if (action == MYESP_FSACTION_SAVE) {
json["thermostat_type"] = EMS_Thermostat.type_id; json["thermostat_type"] = EMS_Thermostat.device_id;
json["boiler_type"] = EMS_Boiler.type_id; json["boiler_type"] = EMS_Boiler.device_id;
json["led"] = EMSESP_Status.led; json["led"] = EMSESP_Status.led;
json["led_gpio"] = EMSESP_Status.led_gpio; json["led_gpio"] = EMSESP_Status.led_gpio;
@@ -1039,13 +1039,13 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c
// thermostat_type // thermostat_type
if (strcmp(setting, "thermostat_type") == 0) { if (strcmp(setting, "thermostat_type") == 0) {
EMS_Thermostat.type_id = ((wc == 2) ? (uint8_t)strtol(value, 0, 16) : EMS_ID_NONE); EMS_Thermostat.device_id = ((wc == 2) ? (uint8_t)strtol(value, 0, 16) : EMS_ID_NONE);
ok = true; ok = true;
} }
// boiler_type // boiler_type
if (strcmp(setting, "boiler_type") == 0) { if (strcmp(setting, "boiler_type") == 0) {
EMS_Boiler.type_id = ((wc == 2) ? (uint8_t)strtol(value, 0, 16) : EMS_ID_NONE); EMS_Boiler.device_id = ((wc == 2) ? (uint8_t)strtol(value, 0, 16) : EMS_ID_NONE);
ok = true; ok = true;
} }
@@ -1113,18 +1113,18 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c
myDebug(" dallas_gpio=%d", EMSESP_Status.dallas_gpio); myDebug(" dallas_gpio=%d", EMSESP_Status.dallas_gpio);
myDebug(" dallas_parasite=%s", EMSESP_Status.dallas_parasite ? "on" : "off"); myDebug(" dallas_parasite=%s", EMSESP_Status.dallas_parasite ? "on" : "off");
if (EMS_Thermostat.type_id == EMS_ID_NONE) { if (EMS_Thermostat.device_id == EMS_ID_NONE) {
myDebug(" thermostat_type=<not set>"); myDebug(" thermostat_type=<not set>");
} else { } else {
myDebug(" thermostat_type=%02X", EMS_Thermostat.type_id); myDebug(" thermostat_type=%02X", EMS_Thermostat.device_id);
} }
myDebug(" heating_circuit=%d", EMSESP_Status.heating_circuit); myDebug(" heating_circuit=%d", EMSESP_Status.heating_circuit);
if (EMS_Boiler.type_id == EMS_ID_NONE) { if (EMS_Boiler.device_id == EMS_ID_NONE) {
myDebug(" boiler_type=<not set>"); myDebug(" boiler_type=<not set>");
} else { } else {
myDebug(" boiler_type=%02X", EMS_Boiler.type_id); myDebug(" boiler_type=%02X", EMS_Boiler.device_id);
} }
myDebug(" silent_mode=%s", EMSESP_Status.silent_mode ? "on" : "off"); myDebug(" silent_mode=%s", EMSESP_Status.silent_mode ? "on" : "off");
@@ -1243,7 +1243,7 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
ems_setThermostatMode(_readIntNumber()); ems_setThermostatMode(_readIntNumber());
ok = true; ok = true;
} else if (strcmp(second_cmd, "read") == 0) { } else if (strcmp(second_cmd, "read") == 0) {
ems_doReadCommand(_readHexNumber(), EMS_Thermostat.type_id); ems_doReadCommand(_readHexNumber(), EMS_Thermostat.device_id);
ok = true; ok = true;
} else if (strcmp(second_cmd, "scan") == 0) { } else if (strcmp(second_cmd, "scan") == 0) {
startThermostatScan(_readIntNumber()); startThermostatScan(_readIntNumber());
@@ -1270,7 +1270,7 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
ok = true; ok = true;
} }
} else if (strcmp(second_cmd, "read") == 0) { } else if (strcmp(second_cmd, "read") == 0) {
ems_doReadCommand(_readHexNumber(), EMS_Boiler.type_id); ems_doReadCommand(_readHexNumber(), EMS_Boiler.device_id);
ok = true; ok = true;
} else if (strcmp(second_cmd, "tapwater") == 0) { } else if (strcmp(second_cmd, "tapwater") == 0) {
char * third_cmd = _readWord(); char * third_cmd = _readWord();

File diff suppressed because it is too large Load Diff

View File

@@ -13,8 +13,8 @@
#include <Arduino.h> #include <Arduino.h>
// EMS IDs // EMS IDs
#define EMS_ID_NONE 0x00 // Fixed - used as a dest in broadcast messages and empty type IDs #define EMS_ID_NONE 0x00 // Fixed - used as a dest in broadcast messages and empty device IDs
#define EMS_PLUS_ID_NONE 0x01 // Fixed - used as a dest in broadcast messages and empty type IDs #define EMS_PLUS_ID_NONE 0x01 // Fixed - used as a dest in broadcast messages and empty device IDs
#define EMS_ID_ME 0x0B // Fixed - our device, hardcoded as the "Service Key" #define EMS_ID_ME 0x0B // Fixed - our device, hardcoded as the "Service Key"
#define EMS_ID_DEFAULT_BOILER 0x08 #define EMS_ID_DEFAULT_BOILER 0x08
#define EMS_ID_SM 0x30 // Solar Module SM10 and SM100 #define EMS_ID_SM 0x30 // Solar Module SM10 and SM100
@@ -102,14 +102,14 @@ typedef struct {
typedef struct { typedef struct {
_EMS_TX_TELEGRAM_ACTION action; // read, write, validate, init _EMS_TX_TELEGRAM_ACTION action; // read, write, validate, init
uint8_t dest; uint8_t dest;
uint8_t type; uint16_t type;
uint8_t offset; uint8_t offset;
uint8_t length; uint8_t length;
uint8_t dataValue; // value to validate against uint8_t dataValue; // value to validate against
uint8_t type_validate; // type to call after a successful Write command uint16_t type_validate; // type to call after a successful Write command
uint8_t comparisonValue; // value to compare against during a validate uint8_t comparisonValue; // value to compare against during a validate
uint8_t comparisonOffset; // offset of where the byte is we want to compare too later uint8_t comparisonOffset; // offset of where the byte is we want to compare too later
uint8_t comparisonPostRead; // after a successful write call this to read uint16_t comparisonPostRead; // after a successful write call this to read from this type ID
bool forceRefresh; // should we send to MQTT after a successful Tx? bool forceRefresh; // should we send to MQTT after a successful Tx?
uint32_t timestamp; // when created uint32_t timestamp; // when created
uint8_t data[EMS_MAX_TELEGRAM_LENGTH]; uint8_t data[EMS_MAX_TELEGRAM_LENGTH];
@@ -120,6 +120,12 @@ typedef struct {
uint32_t timestamp; // timestamp from millis() uint32_t timestamp; // timestamp from millis()
uint8_t * telegram; // the full data package uint8_t * telegram; // the full data package
uint8_t length; // length in bytes uint8_t length; // length in bytes
uint8_t src; // source ID
uint8_t dest; // destination ID
uint16_t type; // type ID as a double byte to support EMS+
uint8_t offset; // offset
uint8_t * data; // pointer to where telegram data starts
bool emsplus; // true if ems+/ems 2.0
} _EMS_RxTelegram; } _EMS_RxTelegram;
// default empty Tx // default empty Tx
@@ -142,22 +148,22 @@ const _EMS_TxTelegram EMS_TX_TELEGRAM_NEW = {
typedef struct { typedef struct {
uint8_t model_id; uint8_t model_id;
uint8_t product_id; uint8_t product_id;
uint8_t type_id; uint8_t device_id;
char model_string[50]; char model_string[50];
} _Boiler_Type; } _Boiler_Type;
typedef struct { typedef struct {
uint8_t model_id; uint8_t model_id;
uint8_t product_id; uint8_t product_id;
uint8_t type_id; uint8_t device_id;
char model_string[50]; char model_string[50];
} _Other_Type; } _Other_Type;
// Definition for thermostat type // Definition for thermostat devices
typedef struct { typedef struct {
uint8_t model_id; uint8_t model_id;
uint8_t product_id; uint8_t product_id;
uint8_t type_id; uint8_t device_id;
char model_string[50]; char model_string[50];
bool read_supported; bool read_supported;
bool write_supported; bool write_supported;
@@ -165,7 +171,7 @@ typedef struct {
typedef struct { typedef struct {
uint8_t product_id; uint8_t product_id;
uint8_t type_id; uint8_t device_id;
char version[10]; char version[10];
char model_string[50]; char model_string[50];
} _Generic_Type; } _Generic_Type;
@@ -226,7 +232,7 @@ typedef struct { // UBAParameterWW
// settings // settings
char version[10]; char version[10];
uint8_t type_id; // this is typically always 0x08 uint8_t device_id; // this is typically always 0x08
uint8_t product_id; uint8_t product_id;
} _EMS_Boiler; } _EMS_Boiler;
@@ -244,8 +250,8 @@ typedef struct {
// Thermostat data // Thermostat data
typedef struct { typedef struct {
uint8_t type_id; // the type ID of the thermostat uint8_t device_id; // the device ID of the thermostat
uint8_t model_id; // which Thermostat type uint8_t model_id; // thermostat model
uint8_t product_id; uint8_t product_id;
bool read_supported; bool read_supported;
bool write_supported; bool write_supported;
@@ -269,21 +275,20 @@ typedef struct {
} _EMS_Thermostat; } _EMS_Thermostat;
// call back function signature for processing telegram types // call back function signature for processing telegram types
typedef void (*EMS_processType_cb)(uint8_t src, uint8_t * data, uint8_t length); typedef void (*EMS_processType_cb)(_EMS_RxTelegram * EMS_RxTelegram);
// Definition for each EMS type, including the relative callback function // Definition for each EMS type, including the relative callback function
typedef struct { typedef struct {
uint8_t model_id; uint8_t model_id;
uint8_t type; uint16_t type; // long to support EMS+
const char typeString[50]; const char typeString[50];
EMS_processType_cb processType_cb; EMS_processType_cb processType_cb;
bool emsplus;
} _EMS_Type; } _EMS_Type;
// function definitions // function definitions
extern void ems_parseTelegram(uint8_t * telegram, uint8_t len); extern void ems_parseTelegram(uint8_t * telegram, uint8_t len);
void ems_init(); void ems_init();
void ems_doReadCommand(uint8_t type, uint8_t dest, bool forceRefresh = false); void ems_doReadCommand(uint16_t type, uint8_t dest, bool forceRefresh = false);
void ems_sendRawTelegram(char * telegram); void ems_sendRawTelegram(char * telegram);
void ems_setThermostatTemp(float temperature, uint8_t temptype = 0); void ems_setThermostatTemp(float temperature, uint8_t temptype = 0);

View File

@@ -12,7 +12,6 @@
#include "ems.h" #include "ems.h"
/* /*
* Common * Common
*/ */
@@ -96,7 +95,7 @@
#define EMS_OFFSET_EasyStatusMessage_curr 8 // current temp #define EMS_OFFSET_EasyStatusMessage_curr 8 // current temp
// RC1010 specific // RC1010 specific
#define EMS_TYPE_RC1010StatusMessage 0x00 // is an automatic thermostat broadcast giving us temps #define EMS_TYPE_RC1010StatusMessage 0x01A5 // is an automatic thermostat broadcast giving us temps
#define EMS_TYPE_RC1010Set 0x03 // setpoint temp message #define EMS_TYPE_RC1010Set 0x03 // setpoint temp message
#define EMS_OFFSET_RC1010StatusMessage_setpoint 3 // setpoint temp #define EMS_OFFSET_RC1010StatusMessage_setpoint 3 // setpoint temp
#define EMS_OFFSET_RC1010StatusMessage_curr 1 // current temp #define EMS_OFFSET_RC1010StatusMessage_curr 1 // current temp
@@ -129,16 +128,22 @@ typedef enum {
} _EMS_MODEL_ID; } _EMS_MODEL_ID;
// EMS types for known Buderus/Bosch devices. This list will be extended when new devices are recognized. // EMS types for known Buderus/Bosch devices. This list will be extended when new devices are recognized.
// format is MODEL_ID, PRODUCT ID, TYPE_ID, DESCRIPTION // format is MODEL_ID, PRODUCT ID, TYPE_ID, DESCRIPTION, EMSPLUS
const _Boiler_Type Boiler_Types[] = { const _Boiler_Type Boiler_Types[] = {
{EMS_MODEL_UBA, 72, 0x08, "MC10 Module"}, {EMS_MODEL_UBA, 72, 0x08, "MC10 Module"},
{EMS_MODEL_UBA, 123, 0x08, "Buderus GB172/Nefit Trendline"}, {
EMS_MODEL_UBA,
123,
0x08,
"Buderus GB172/Nefit Trendline",
},
{EMS_MODEL_UBA, 115, 0x08, "Nefit Topline Compact"}, {EMS_MODEL_UBA, 115, 0x08, "Nefit Topline Compact"},
{EMS_MODEL_UBA, 203, 0x08, "Buderus Logamax U122"}, {EMS_MODEL_UBA, 203, 0x08, "Buderus Logamax U122"},
{EMS_MODEL_UBA, 208, 0x08, "Buderus Logamax plus"}, {EMS_MODEL_UBA, 208, 0x08, "Buderus Logamax plus"},
{EMS_MODEL_UBA, 64, 0x08, "Sieger BK15 Boiler/Nefit Smartline"}, {EMS_MODEL_UBA, 64, 0x08, "Sieger BK15 Boiler/Nefit Smartline"},
{EMS_MODEL_UBA, 95, 0x08, "Bosch Condens 2500"} {EMS_MODEL_UBA, 95, 0x08, "Bosch Condens 2500/Junkers Cerapur Comfort"},
{EMS_MODEL_UBA, 122, 0x08, "Nefit Proline"}
}; };
@@ -173,7 +178,7 @@ const _Thermostat_Type Thermostat_Types[] = {
{EMS_MODEL_BOSCHEASY, 206, 0x02, "Bosch Easy", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_NO}, {EMS_MODEL_BOSCHEASY, 206, 0x02, "Bosch Easy", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_RC310, 158, 0x10, "RC310", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO}, {EMS_MODEL_RC310, 158, 0x10, "RC310", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_CW100, 255, 0x18, "Bosch CW100", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO}, {EMS_MODEL_CW100, 255, 0x18, "Bosch CW100", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_CW100, 255, 0x18, "Bosch CW100", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO},
{EMS_MODEL_RC1010, 165, 0x18, "RC1010/Nefit Moduline 1010", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO} {EMS_MODEL_RC1010, 165, 0x18, "RC1010/Nefit Moduline 1010", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO}
}; };

View File

@@ -6,5 +6,5 @@
#pragma once #pragma once
#define APP_NAME "EMS-ESP" #define APP_NAME "EMS-ESP"
#define APP_VERSION "1.7.0b6" #define APP_VERSION "1.7.0b8"
#define APP_HOSTNAME "ems-esp" #define APP_HOSTNAME "ems-esp"