mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
Merge branch 'dev' of https://github.com/proddy/EMS-ESP-Boiler into txmode2
* 'dev' of https://github.com/proddy/EMS-ESP-Boiler: tidy up includes write to ems+ thermostats (https://github.com/proddy/EMS-ESP/issues/145)
This commit is contained in:
257
src/ems.cpp
257
src/ems.cpp
@@ -9,7 +9,6 @@
|
|||||||
#include "ems.h"
|
#include "ems.h"
|
||||||
#include "ems_devices.h"
|
#include "ems_devices.h"
|
||||||
#include "emsuart.h"
|
#include "emsuart.h"
|
||||||
#include <Arduino.h>
|
|
||||||
#include <CircularBuffer.h> // https://github.com/rlogiacco/CircularBuffer
|
#include <CircularBuffer.h> // https://github.com/rlogiacco/CircularBuffer
|
||||||
#include <MyESP.h>
|
#include <MyESP.h>
|
||||||
#include <list> // std::list
|
#include <list> // std::list
|
||||||
@@ -28,7 +27,7 @@ _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
|
// for storing all detected EMS devices
|
||||||
std::list<_Generic_Type> Devices;
|
std::list<_Generic_Device> Devices;
|
||||||
|
|
||||||
// macros used in the _process* functions
|
// macros used in the _process* functions
|
||||||
#define _toByte(i) (EMS_RxTelegram->data[i])
|
#define _toByte(i) (EMS_RxTelegram->data[i])
|
||||||
@@ -95,8 +94,6 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram);
|
|||||||
// RC1010, RC300, RC310
|
// RC1010, RC300, RC310
|
||||||
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram);
|
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram);
|
||||||
void _process_RCPLUSSetMessage(_EMS_RxTelegram * EMS_RxTelegram);
|
void _process_RCPLUSSetMessage(_EMS_RxTelegram * EMS_RxTelegram);
|
||||||
void _process_RCPLUSStatusHeating(_EMS_RxTelegram * EMS_RxTelegram);
|
|
||||||
void _process_RCPLUSStatusHeating(_EMS_RxTelegram * EMS_RxTelegram);
|
|
||||||
void _process_RCPLUSStatusMode(_EMS_RxTelegram * EMS_RxTelegram);
|
void _process_RCPLUSStatusMode(_EMS_RxTelegram * EMS_RxTelegram);
|
||||||
|
|
||||||
// Junkers FR10 & FW100
|
// Junkers FR10 & FW100
|
||||||
@@ -176,7 +173,6 @@ const _EMS_Type EMS_Types[] = {
|
|||||||
// Nefit 1010, RC300, RC310 (EMS Plus)
|
// Nefit 1010, RC300, RC310 (EMS Plus)
|
||||||
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSStatusMessage, "RCPLUSStatusMessage", _process_RCPLUSStatusMessage},
|
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSStatusMessage, "RCPLUSStatusMessage", _process_RCPLUSStatusMessage},
|
||||||
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSSet, "RCPLUSSetMessage", _process_RCPLUSSetMessage},
|
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSSet, "RCPLUSSetMessage", _process_RCPLUSSetMessage},
|
||||||
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSStatusHeating, "RCPLUSStatusHeating", _process_RCPLUSStatusHeating},
|
|
||||||
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSStatusMode, "RCPLUSStatusMode", _process_RCPLUSStatusMode},
|
{EMS_MODEL_ALL, EMS_TYPE_RCPLUSStatusMode, "RCPLUSStatusMode", _process_RCPLUSStatusMode},
|
||||||
|
|
||||||
// Junkers FR10
|
// Junkers FR10
|
||||||
@@ -186,12 +182,12 @@ const _EMS_Type EMS_Types[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// calculate sizes of arrays at compile
|
// calculate sizes of arrays at compile
|
||||||
uint8_t _EMS_Types_max = ArraySize(EMS_Types); // number of defined types
|
uint8_t _EMS_Types_max = ArraySize(EMS_Types); // number of defined types
|
||||||
uint8_t _Boiler_Types_max = ArraySize(Boiler_Types); // number of boiler models
|
uint8_t _Boiler_Devices_max = ArraySize(Boiler_Devices); // number of boiler models
|
||||||
uint8_t _Solar_Module_Types_max = ArraySize(SolarModule_Types); // number of solar module types
|
uint8_t _SolarModule_Types_max = ArraySize(SolarModule_Devices); // number of solar module types
|
||||||
uint8_t _Other_Types_max = ArraySize(Other_Types); // number of other ems devices
|
uint8_t _Other_Devices_max = ArraySize(Other_Devices); // number of other ems devices
|
||||||
uint8_t _Thermostat_Types_max = ArraySize(Thermostat_Types); // number of defined thermostat types
|
uint8_t _Thermostat_Devices_max = ArraySize(Thermostat_Devices); // number of defined thermostat types
|
||||||
uint8_t _HeatPump_Types_max = ArraySize(HeatPump_Types); // number of defined heatpuimp types
|
uint8_t _HeatPump_Devices_max = ArraySize(HeatPump_Devices); // number of defined heatpuimp types
|
||||||
|
|
||||||
// these structs contain the data we store from the specific EMS devices
|
// these structs contain the data we store from the specific EMS devices
|
||||||
_EMS_Boiler EMS_Boiler; // for boiler
|
_EMS_Boiler EMS_Boiler; // for boiler
|
||||||
@@ -1396,7 +1392,7 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* type 0x01A5 - data from the Nefit RC1010 thermostat (0x18) and RC300/310s on 0x10
|
* type 0x01A5 - data from the Nefit RC1010/3000 thermostat (0x18) and RC300/310s on 0x10
|
||||||
* EMS+ messages may come in with different offsets so handle them here
|
* EMS+ messages may come in with different offsets so handle them here
|
||||||
*/
|
*/
|
||||||
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||||
@@ -1432,14 +1428,6 @@ void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* type 0x01B9 - heating data from the Nefit RC1010 thermostat (0x18) and RC300/310s on 0x10
|
|
||||||
*/
|
|
||||||
void _process_RCPLUSStatusHeating(_EMS_RxTelegram * EMS_RxTelegram) {
|
|
||||||
// see wiki
|
|
||||||
// operation mode, comfort levels 1,2,3, eco level
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* type 0x01AF - summer/winter mode from the Nefit RC1010 thermostat (0x18) and RC300/310s on 0x10
|
* type 0x01AF - summer/winter mode from the Nefit RC1010 thermostat (0x18) and RC300/310s on 0x10
|
||||||
*/
|
*/
|
||||||
@@ -1460,10 +1448,14 @@ void _process_JunkersStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* to complete....
|
* type 0x01B9 EMS+ for reading the mode from RC300/RC310 thermostat
|
||||||
*/
|
*/
|
||||||
void _process_RCPLUSSetMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
void _process_RCPLUSSetMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||||
// to complete
|
EMS_Thermostat.mode = _toByte(EMS_OFFSET_RCPLUSSet_mode);
|
||||||
|
EMS_Thermostat.daytemp = _toByte(EMS_OFFSET_RCPLUSSet_temp_comfort2); // is * 2
|
||||||
|
EMS_Thermostat.nighttemp = _toByte(EMS_OFFSET_RCPLUSSet_temp_eco); // is * 2
|
||||||
|
|
||||||
|
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1690,10 +1682,10 @@ void ems_clearDeviceList() {
|
|||||||
* add an EMS device to our list of detected devices
|
* add an EMS device to our list of detected devices
|
||||||
*/
|
*/
|
||||||
void _addDevice(uint8_t product_id, uint8_t device_id, char * version, const char * model_string) {
|
void _addDevice(uint8_t product_id, uint8_t device_id, char * version, const char * model_string) {
|
||||||
_Generic_Type device;
|
_Generic_Device device;
|
||||||
// if its a duplicate don't add
|
// if its a duplicate don't add
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (std::list<_Generic_Type>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
for (std::list<_Generic_Device>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
||||||
if (((it)->product_id == product_id) && ((it)->device_id == device_id)) {
|
if (((it)->product_id == product_id) && ((it)->device_id == device_id)) {
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
@@ -1725,8 +1717,8 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
// see if its a known boiler
|
// see if its a known boiler
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool typeFound = false;
|
bool typeFound = false;
|
||||||
while (i < _Boiler_Types_max) {
|
while (i < _Boiler_Devices_max) {
|
||||||
if ((Boiler_Types[i].product_id == product_id) && ((EMS_RxTelegram->src & 0x7F) == EMS_ID_BOILER)) {
|
if ((Boiler_Devices[i].product_id == product_id) && ((EMS_RxTelegram->src & 0x7F) == EMS_ID_BOILER)) {
|
||||||
typeFound = true; // we have a matching product id. i is the index.
|
typeFound = true; // we have a matching product id. i is the index.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1735,22 +1727,22 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
|
|
||||||
if (typeFound) {
|
if (typeFound) {
|
||||||
// its a boiler
|
// its a boiler
|
||||||
myDebug_P(PSTR("Boiler found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"), Boiler_Types[i].model_string, EMS_ID_BOILER, product_id, version);
|
myDebug_P(PSTR("Boiler found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"), Boiler_Devices[i].model_string, EMS_ID_BOILER, product_id, version);
|
||||||
|
|
||||||
// add to list
|
// add to list
|
||||||
_addDevice(product_id, EMS_ID_BOILER, version, Boiler_Types[i].model_string);
|
_addDevice(product_id, EMS_ID_BOILER, version, Boiler_Devices[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.device_id == EMS_ID_NONE) || ((EMS_Boiler.device_id == EMS_ID_BOILER) && EMS_Boiler.product_id == EMS_ID_NONE)) {
|
if ((EMS_Boiler.device_id == EMS_ID_NONE) || ((EMS_Boiler.device_id == EMS_ID_BOILER) && EMS_Boiler.product_id == EMS_ID_NONE)) {
|
||||||
myDebug_P(PSTR("* Setting Boiler to model %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
myDebug_P(PSTR("* Setting Boiler to model %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
||||||
Boiler_Types[i].model_string,
|
Boiler_Devices[i].model_string,
|
||||||
EMS_ID_BOILER,
|
EMS_ID_BOILER,
|
||||||
product_id,
|
product_id,
|
||||||
version);
|
version);
|
||||||
|
|
||||||
EMS_Boiler.device_id = EMS_ID_BOILER;
|
EMS_Boiler.device_id = EMS_ID_BOILER;
|
||||||
EMS_Boiler.product_id = Boiler_Types[i].product_id;
|
EMS_Boiler.product_id = Boiler_Devices[i].product_id;
|
||||||
strlcpy(EMS_Boiler.version, version, sizeof(EMS_Boiler.version));
|
strlcpy(EMS_Boiler.version, version, sizeof(EMS_Boiler.version));
|
||||||
|
|
||||||
// check to see if its a Junkers Heatronic3, which has a different poll'ing logic
|
// check to see if its a Junkers Heatronic3, which has a different poll'ing logic
|
||||||
@@ -1768,8 +1760,8 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
|
|
||||||
// its not a boiler, maybe its a known thermostat?
|
// its not a boiler, maybe its a known thermostat?
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < _Thermostat_Types_max) {
|
while (i < _Thermostat_Devices_max) {
|
||||||
if (Thermostat_Types[i].product_id == product_id) {
|
if (Thermostat_Devices[i].product_id == product_id) {
|
||||||
typeFound = true; // we have a matching product id. i is the index.
|
typeFound = true; // we have a matching product id. i is the index.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1780,28 +1772,28 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
// its a known thermostat
|
// its a known thermostat
|
||||||
if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_BASIC) {
|
if (EMS_Sys_Status.emsLogging >= EMS_SYS_LOGGING_BASIC) {
|
||||||
myDebug_P(PSTR("Thermostat found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
myDebug_P(PSTR("Thermostat found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
||||||
Thermostat_Types[i].model_string,
|
Thermostat_Devices[i].model_string,
|
||||||
Thermostat_Types[i].device_id,
|
Thermostat_Devices[i].device_id,
|
||||||
product_id,
|
product_id,
|
||||||
version);
|
version);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add to list
|
// add to list
|
||||||
_addDevice(product_id, Thermostat_Types[i].device_id, version, Thermostat_Types[i].model_string);
|
_addDevice(product_id, Thermostat_Devices[i].device_id, version, Thermostat_Devices[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.device_id == EMS_ID_NONE) || (EMS_Thermostat.model_id == EMS_MODEL_NONE)
|
if (((EMS_Thermostat.device_id == EMS_ID_NONE) || (EMS_Thermostat.model_id == EMS_MODEL_NONE)
|
||||||
|| (EMS_Thermostat.device_id == Thermostat_Types[i].device_id))
|
|| (EMS_Thermostat.device_id == Thermostat_Devices[i].device_id))
|
||||||
&& EMS_Thermostat.product_id == EMS_ID_NONE) {
|
&& EMS_Thermostat.product_id == EMS_ID_NONE) {
|
||||||
myDebug_P(PSTR("* Setting Thermostat to %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
myDebug_P(PSTR("* Setting Thermostat to %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
||||||
Thermostat_Types[i].model_string,
|
Thermostat_Devices[i].model_string,
|
||||||
Thermostat_Types[i].device_id,
|
Thermostat_Devices[i].device_id,
|
||||||
product_id,
|
product_id,
|
||||||
version);
|
version);
|
||||||
|
|
||||||
EMS_Thermostat.model_id = Thermostat_Types[i].model_id;
|
EMS_Thermostat.model_id = Thermostat_Devices[i].model_id;
|
||||||
EMS_Thermostat.device_id = Thermostat_Types[i].device_id;
|
EMS_Thermostat.device_id = Thermostat_Devices[i].device_id;
|
||||||
EMS_Thermostat.write_supported = Thermostat_Types[i].write_supported;
|
EMS_Thermostat.write_supported = Thermostat_Devices[i].write_supported;
|
||||||
EMS_Thermostat.product_id = product_id;
|
EMS_Thermostat.product_id = product_id;
|
||||||
strlcpy(EMS_Thermostat.version, version, sizeof(EMS_Thermostat.version));
|
strlcpy(EMS_Thermostat.version, version, sizeof(EMS_Thermostat.version));
|
||||||
|
|
||||||
@@ -1816,8 +1808,8 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
|
|
||||||
// look for Solar Modules
|
// look for Solar Modules
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < _Solar_Module_Types_max) {
|
while (i < _SolarModule_Types_max) {
|
||||||
if (SolarModule_Types[i].product_id == product_id) {
|
if (SolarModule_Devices[i].product_id == product_id) {
|
||||||
typeFound = true; // we have a matching product id. i is the index.
|
typeFound = true; // we have a matching product id. i is the index.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1826,16 +1818,16 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
|
|
||||||
if (typeFound) {
|
if (typeFound) {
|
||||||
myDebug_P(PSTR("Solar Module found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
myDebug_P(PSTR("Solar Module found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
||||||
SolarModule_Types[i].model_string,
|
SolarModule_Devices[i].model_string,
|
||||||
SolarModule_Types[i].device_id,
|
SolarModule_Devices[i].device_id,
|
||||||
product_id,
|
product_id,
|
||||||
version);
|
version);
|
||||||
|
|
||||||
// add to list
|
// add to list
|
||||||
_addDevice(product_id, SolarModule_Types[i].device_id, version, SolarModule_Types[i].model_string);
|
_addDevice(product_id, SolarModule_Devices[i].device_id, version, SolarModule_Devices[i].model_string);
|
||||||
|
|
||||||
myDebug_P(PSTR("Solar Module support enabled."));
|
myDebug_P(PSTR("Solar Module support enabled."));
|
||||||
EMS_SolarModule.device_id = SolarModule_Types[i].device_id;
|
EMS_SolarModule.device_id = SolarModule_Devices[i].device_id;
|
||||||
EMS_SolarModule.product_id = product_id;
|
EMS_SolarModule.product_id = product_id;
|
||||||
strlcpy(EMS_SolarModule.version, version, sizeof(EMS_SolarModule.version));
|
strlcpy(EMS_SolarModule.version, version, sizeof(EMS_SolarModule.version));
|
||||||
|
|
||||||
@@ -1846,8 +1838,8 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
|
|
||||||
// look for heatpumps
|
// look for heatpumps
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < _HeatPump_Types_max) {
|
while (i < _HeatPump_Devices_max) {
|
||||||
if (HeatPump_Types[i].product_id == product_id) {
|
if (HeatPump_Devices[i].product_id == product_id) {
|
||||||
typeFound = true; // we have a matching product id. i is the index.
|
typeFound = true; // we have a matching product id. i is the index.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1856,16 +1848,16 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
|
|
||||||
if (typeFound) {
|
if (typeFound) {
|
||||||
myDebug_P(PSTR("Heat Pump found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
myDebug_P(PSTR("Heat Pump found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
||||||
HeatPump_Types[i].model_string,
|
HeatPump_Devices[i].model_string,
|
||||||
HeatPump_Types[i].device_id,
|
HeatPump_Devices[i].device_id,
|
||||||
product_id,
|
product_id,
|
||||||
version);
|
version);
|
||||||
|
|
||||||
// add to list
|
// add to list
|
||||||
_addDevice(product_id, HeatPump_Types[i].device_id, version, HeatPump_Types[i].model_string);
|
_addDevice(product_id, HeatPump_Devices[i].device_id, version, HeatPump_Devices[i].model_string);
|
||||||
|
|
||||||
myDebug_P(PSTR("Heat Pump support enabled."));
|
myDebug_P(PSTR("Heat Pump support enabled."));
|
||||||
EMS_HeatPump.device_id = SolarModule_Types[i].device_id;
|
EMS_HeatPump.device_id = SolarModule_Devices[i].device_id;
|
||||||
EMS_HeatPump.product_id = product_id;
|
EMS_HeatPump.product_id = product_id;
|
||||||
strlcpy(EMS_HeatPump.version, version, sizeof(EMS_HeatPump.version));
|
strlcpy(EMS_HeatPump.version, version, sizeof(EMS_HeatPump.version));
|
||||||
return;
|
return;
|
||||||
@@ -1873,8 +1865,8 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
|
|
||||||
// finally look for the other EMS devices
|
// finally look for the other EMS devices
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < _Other_Types_max) {
|
while (i < _Other_Devices_max) {
|
||||||
if (Other_Types[i].product_id == product_id) {
|
if (Other_Devices[i].product_id == product_id) {
|
||||||
typeFound = true; // we have a matching product id. i is the index.
|
typeFound = true; // we have a matching product id. i is the index.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1882,10 +1874,10 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeFound) {
|
if (typeFound) {
|
||||||
myDebug_P(PSTR("Device found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"), Other_Types[i].model_string, Other_Types[i].device_id, product_id, version);
|
myDebug_P(PSTR("Device found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"), Other_Devices[i].model_string, Other_Devices[i].device_id, product_id, version);
|
||||||
|
|
||||||
// add to list
|
// add to list
|
||||||
_addDevice(product_id, Other_Types[i].device_id, version, Other_Types[i].model_string);
|
_addDevice(product_id, Other_Devices[i].device_id, version, Other_Devices[i].model_string);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
myDebug_P(PSTR("Unrecognized device found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"), EMS_RxTelegram->src, product_id, version);
|
myDebug_P(PSTR("Unrecognized device found: %s (DeviceID:0x%02X ProductID:%d Version:%s)"), EMS_RxTelegram->src, product_id, version);
|
||||||
@@ -1995,39 +1987,39 @@ void ems_getThermostatValues() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t model_id = EMS_Thermostat.model_id;
|
uint8_t model_id = EMS_Thermostat.model_id;
|
||||||
uint8_t type = EMS_Thermostat.device_id;
|
uint8_t device_id = EMS_Thermostat.device_id;
|
||||||
uint8_t hc = EMS_Thermostat.hc;
|
uint8_t hc = EMS_Thermostat.hc;
|
||||||
|
|
||||||
switch (model_id) {
|
switch (model_id) {
|
||||||
case EMS_MODEL_RC20:
|
case EMS_MODEL_RC20:
|
||||||
ems_doReadCommand(EMS_TYPE_RC20StatusMessage, type); // to get the temps
|
ems_doReadCommand(EMS_TYPE_RC20StatusMessage, device_id); // to get the temps
|
||||||
ems_doReadCommand(EMS_TYPE_RC20Set, type); // to get the mode
|
ems_doReadCommand(EMS_TYPE_RC20Set, device_id); // to get the mode
|
||||||
break;
|
break;
|
||||||
case EMS_MODEL_RC30:
|
case EMS_MODEL_RC30:
|
||||||
ems_doReadCommand(EMS_TYPE_RC30StatusMessage, type); // to get the temps
|
ems_doReadCommand(EMS_TYPE_RC30StatusMessage, device_id); // to get the temps
|
||||||
ems_doReadCommand(EMS_TYPE_RC30Set, type); // to get the mode
|
ems_doReadCommand(EMS_TYPE_RC30Set, device_id); // to get the mode
|
||||||
break;
|
break;
|
||||||
case EMS_MODEL_EASY:
|
case EMS_MODEL_EASY:
|
||||||
ems_doReadCommand(EMS_TYPE_EasyStatusMessage, type);
|
ems_doReadCommand(EMS_TYPE_EasyStatusMessage, device_id);
|
||||||
break;
|
break;
|
||||||
case EMS_MODEL_RC35:
|
case EMS_MODEL_RC35:
|
||||||
case EMS_MODEL_ES73:
|
case EMS_MODEL_ES73:
|
||||||
if (hc == 1) {
|
if (hc == 1) {
|
||||||
ems_doReadCommand(EMS_TYPE_RC35StatusMessage_HC1, type); // to get the temps
|
ems_doReadCommand(EMS_TYPE_RC35StatusMessage_HC1, device_id); // to get the temps
|
||||||
ems_doReadCommand(EMS_TYPE_RC35Set_HC1, type); // to get the mode
|
ems_doReadCommand(EMS_TYPE_RC35Set_HC1, device_id); // to get the mode
|
||||||
} else if (hc == 2) {
|
} else if (hc == 2) {
|
||||||
ems_doReadCommand(EMS_TYPE_RC35StatusMessage_HC2, type); // to get the temps
|
ems_doReadCommand(EMS_TYPE_RC35StatusMessage_HC2, device_id); // to get the temps
|
||||||
ems_doReadCommand(EMS_TYPE_RC35Set_HC2, type); // to get the mode
|
ems_doReadCommand(EMS_TYPE_RC35Set_HC2, device_id); // to get the mode
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EMS_MODEL_RC300:
|
case EMS_MODEL_RC300:
|
||||||
ems_doReadCommand(EMS_TYPE_RCPLUSStatusMessage, type);
|
ems_doReadCommand(EMS_TYPE_RCPLUSStatusMessage, device_id);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ems_doReadCommand(EMS_TYPE_RCTime, type); // get Thermostat time
|
ems_doReadCommand(EMS_TYPE_RCTime, device_id); // get Thermostat time
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2070,8 +2062,8 @@ char * ems_getThermostatDescription(char * buffer) {
|
|||||||
char tmp[6] = {0};
|
char tmp[6] = {0};
|
||||||
|
|
||||||
// scan through known ID types
|
// scan through known ID types
|
||||||
while (i < _Thermostat_Types_max) {
|
while (i < _Thermostat_Devices_max) {
|
||||||
if (Thermostat_Types[i].product_id == EMS_Thermostat.product_id) {
|
if (Thermostat_Devices[i].product_id == EMS_Thermostat.product_id) {
|
||||||
found = true; // we have a match
|
found = true; // we have a match
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2079,7 +2071,7 @@ char * ems_getThermostatDescription(char * buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
strlcpy(buffer, Thermostat_Types[i].model_string, size);
|
strlcpy(buffer, Thermostat_Devices[i].model_string, size);
|
||||||
} else {
|
} else {
|
||||||
strlcpy(buffer, "DeviceID: 0x", size);
|
strlcpy(buffer, "DeviceID: 0x", size);
|
||||||
strlcat(buffer, _hextoa(EMS_Thermostat.device_id, tmp), size);
|
strlcat(buffer, _hextoa(EMS_Thermostat.device_id, tmp), size);
|
||||||
@@ -2112,15 +2104,15 @@ char * ems_getBoilerDescription(char * buffer) {
|
|||||||
char tmp[6] = {0};
|
char tmp[6] = {0};
|
||||||
|
|
||||||
// scan through known ID types
|
// scan through known ID types
|
||||||
while (i < _Boiler_Types_max) {
|
while (i < _Boiler_Devices_max) {
|
||||||
if (Boiler_Types[i].product_id == EMS_Boiler.product_id) {
|
if (Boiler_Devices[i].product_id == EMS_Boiler.product_id) {
|
||||||
found = true; // we have a match
|
found = true; // we have a match
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
strlcpy(buffer, Boiler_Types[i].model_string, size);
|
strlcpy(buffer, Boiler_Devices[i].model_string, size);
|
||||||
} else {
|
} else {
|
||||||
strlcpy(buffer, "DeviceID: 0x", size);
|
strlcpy(buffer, "DeviceID: 0x", size);
|
||||||
strlcat(buffer, _hextoa(EMS_Boiler.device_id, tmp), size);
|
strlcat(buffer, _hextoa(EMS_Boiler.device_id, tmp), size);
|
||||||
@@ -2153,15 +2145,15 @@ char * ems_getSolarModuleDescription(char * buffer) {
|
|||||||
char tmp[6] = {0};
|
char tmp[6] = {0};
|
||||||
|
|
||||||
// scan through known ID types
|
// scan through known ID types
|
||||||
while (i < _Solar_Module_Types_max) {
|
while (i < _SolarModule_Types_max) {
|
||||||
if (SolarModule_Types[i].product_id == EMS_SolarModule.product_id) {
|
if (SolarModule_Devices[i].product_id == EMS_SolarModule.product_id) {
|
||||||
found = true; // we have a match
|
found = true; // we have a match
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
strlcpy(buffer, SolarModule_Types[i].model_string, size);
|
strlcpy(buffer, SolarModule_Devices[i].model_string, size);
|
||||||
} else {
|
} else {
|
||||||
strlcpy(buffer, "DeviceID: 0x", size);
|
strlcpy(buffer, "DeviceID: 0x", size);
|
||||||
strlcat(buffer, _hextoa(EMS_SolarModule.device_id, tmp), size);
|
strlcat(buffer, _hextoa(EMS_SolarModule.device_id, tmp), size);
|
||||||
@@ -2194,15 +2186,15 @@ char * ems_getHeatPumpDescription(char * buffer) {
|
|||||||
char tmp[6] = {0};
|
char tmp[6] = {0};
|
||||||
|
|
||||||
// scan through known ID types
|
// scan through known ID types
|
||||||
while (i < _HeatPump_Types_max) {
|
while (i < _HeatPump_Devices_max) {
|
||||||
if (HeatPump_Types[i].product_id == EMS_HeatPump.product_id) {
|
if (HeatPump_Devices[i].product_id == EMS_HeatPump.product_id) {
|
||||||
found = true; // we have a match
|
found = true; // we have a match
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
strlcpy(buffer, HeatPump_Types[i].model_string, size);
|
strlcpy(buffer, HeatPump_Devices[i].model_string, size);
|
||||||
} else {
|
} else {
|
||||||
strlcpy(buffer, "DeviceID: 0x", size);
|
strlcpy(buffer, "DeviceID: 0x", size);
|
||||||
strlcat(buffer, _hextoa(EMS_HeatPump.device_id, tmp), size);
|
strlcat(buffer, _hextoa(EMS_HeatPump.device_id, tmp), size);
|
||||||
@@ -2234,17 +2226,17 @@ void ems_scanDevices() {
|
|||||||
Device_Ids.push_back(EMS_ID_BOILER);
|
Device_Ids.push_back(EMS_ID_BOILER);
|
||||||
|
|
||||||
// copy over thermostats
|
// copy over thermostats
|
||||||
for (_Thermostat_Type tt : Thermostat_Types) {
|
for (_Thermostat_Device tt : Thermostat_Devices) {
|
||||||
Device_Ids.push_back(tt.device_id);
|
Device_Ids.push_back(tt.device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy over solar modules
|
// copy over solar modules
|
||||||
for (_SolarModule_Type sm : SolarModule_Types) {
|
for (_SolarModule_Device sm : SolarModule_Devices) {
|
||||||
Device_Ids.push_back(sm.device_id);
|
Device_Ids.push_back(sm.device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy over others
|
// copy over others
|
||||||
for (_Other_Type ot : Other_Types) {
|
for (_Other_Device ot : Other_Devices) {
|
||||||
Device_Ids.push_back(ot.device_id);
|
Device_Ids.push_back(ot.device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2268,34 +2260,34 @@ void ems_scanDevices() {
|
|||||||
void ems_printAllDevices() {
|
void ems_printAllDevices() {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
myDebug_P(PSTR("\nThese %d devices are supported as boiler units:"), _Boiler_Types_max);
|
myDebug_P(PSTR("\nThese %d devices are supported as boiler units:"), _Boiler_Devices_max);
|
||||||
for (i = 0; i < _Boiler_Types_max; i++) {
|
for (i = 0; i < _Boiler_Devices_max; i++) {
|
||||||
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d)"),
|
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d)"),
|
||||||
COLOR_BOLD_ON,
|
COLOR_BOLD_ON,
|
||||||
Boiler_Types[i].model_string,
|
Boiler_Devices[i].model_string,
|
||||||
COLOR_BOLD_OFF,
|
COLOR_BOLD_OFF,
|
||||||
EMS_ID_BOILER,
|
EMS_ID_BOILER,
|
||||||
Boiler_Types[i].product_id);
|
Boiler_Devices[i].product_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
myDebug_P(PSTR("\nThese %d devices are supported as solar module devices:"), _Solar_Module_Types_max);
|
myDebug_P(PSTR("\nThese %d devices are supported as solar module devices:"), _SolarModule_Types_max);
|
||||||
for (i = 0; i < _Solar_Module_Types_max; i++) {
|
for (i = 0; i < _SolarModule_Types_max; i++) {
|
||||||
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d)"),
|
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d)"),
|
||||||
COLOR_BOLD_ON,
|
COLOR_BOLD_ON,
|
||||||
SolarModule_Types[i].model_string,
|
SolarModule_Devices[i].model_string,
|
||||||
COLOR_BOLD_OFF,
|
COLOR_BOLD_OFF,
|
||||||
SolarModule_Types[i].device_id,
|
SolarModule_Devices[i].device_id,
|
||||||
SolarModule_Types[i].product_id);
|
SolarModule_Devices[i].product_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
myDebug_P(PSTR("\nThese %d devices are supported as other known EMS devices:"), _Other_Types_max);
|
myDebug_P(PSTR("\nThese %d devices are supported as other known EMS devices:"), _Other_Devices_max);
|
||||||
for (i = 0; i < _Other_Types_max; i++) {
|
for (i = 0; i < _Other_Devices_max; i++) {
|
||||||
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d)"),
|
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d)"),
|
||||||
COLOR_BOLD_ON,
|
COLOR_BOLD_ON,
|
||||||
Other_Types[i].model_string,
|
Other_Devices[i].model_string,
|
||||||
COLOR_BOLD_OFF,
|
COLOR_BOLD_OFF,
|
||||||
Other_Types[i].device_id,
|
Other_Devices[i].device_id,
|
||||||
Other_Types[i].product_id);
|
Other_Devices[i].product_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
myDebug_P(PSTR("\nThe following telegram type IDs are supported:"));
|
myDebug_P(PSTR("\nThe following telegram type IDs are supported:"));
|
||||||
@@ -2305,15 +2297,15 @@ void ems_printAllDevices() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
myDebug_P(PSTR("\nThese %d thermostat devices are supported:"), _Thermostat_Types_max);
|
myDebug_P(PSTR("\nThese %d thermostat devices are supported:"), _Thermostat_Devices_max);
|
||||||
for (i = 0; i < _Thermostat_Types_max; i++) {
|
for (i = 0; i < _Thermostat_Devices_max; i++) {
|
||||||
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d) can write:%c"),
|
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d) can write:%c"),
|
||||||
COLOR_BOLD_ON,
|
COLOR_BOLD_ON,
|
||||||
Thermostat_Types[i].model_string,
|
Thermostat_Devices[i].model_string,
|
||||||
COLOR_BOLD_OFF,
|
COLOR_BOLD_OFF,
|
||||||
Thermostat_Types[i].device_id,
|
Thermostat_Devices[i].device_id,
|
||||||
Thermostat_Types[i].product_id,
|
Thermostat_Devices[i].product_id,
|
||||||
(Thermostat_Types[i].write_supported) ? 'y' : 'n');
|
(Thermostat_Devices[i].write_supported) ? 'y' : 'n');
|
||||||
}
|
}
|
||||||
|
|
||||||
// print out known devices
|
// print out known devices
|
||||||
@@ -2328,7 +2320,7 @@ void ems_printAllDevices() {
|
|||||||
void ems_printDevices() {
|
void ems_printDevices() {
|
||||||
if (Devices.size() != 0) {
|
if (Devices.size() != 0) {
|
||||||
myDebug_P(PSTR("\nThese %d EMS devices were detected:"), Devices.size());
|
myDebug_P(PSTR("\nThese %d EMS devices were detected:"), Devices.size());
|
||||||
for (std::list<_Generic_Type>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
for (std::list<_Generic_Device>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
||||||
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
myDebug_P(PSTR(" %s%s%s (DeviceID:0x%02X ProductID:%d Version:%s)"),
|
||||||
COLOR_BOLD_ON,
|
COLOR_BOLD_ON,
|
||||||
(it)->model_string,
|
(it)->model_string,
|
||||||
@@ -2352,7 +2344,7 @@ uint8_t ems_printDevices_s(char * buffer, uint16_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char s[100];
|
char s[100];
|
||||||
for (std::list<_Generic_Type>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
for (std::list<_Generic_Device>::iterator it = Devices.begin(); it != Devices.end(); it++) {
|
||||||
sprintf(s, "%s (DeviceID:0x%02X ProductID:%d Version:%s)<br>", (it)->model_string, (it)->device_id, (it)->product_id, (it)->version);
|
sprintf(s, "%s (DeviceID:0x%02X ProductID:%d Version:%s)<br>", (it)->model_string, (it)->device_id, (it)->product_id, (it)->version);
|
||||||
strlcat(buffer, s, len);
|
strlcat(buffer, s, len);
|
||||||
}
|
}
|
||||||
@@ -2468,7 +2460,7 @@ void ems_setThermostatTemp(float temperature, uint8_t temptype) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!EMS_Thermostat.write_supported) {
|
if (!EMS_Thermostat.write_supported) {
|
||||||
myDebug_P(PSTR("Write not supported for this model Thermostat"));
|
myDebug_P(PSTR("Write not supported for this Thermostat model"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2476,17 +2468,15 @@ void ems_setThermostatTemp(float temperature, uint8_t temptype) {
|
|||||||
EMS_TxTelegram.timestamp = millis(); // set timestamp
|
EMS_TxTelegram.timestamp = millis(); // set timestamp
|
||||||
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
|
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
|
||||||
|
|
||||||
uint8_t model_id = EMS_Thermostat.model_id;
|
uint8_t model_id = EMS_Thermostat.model_id;
|
||||||
uint8_t type = EMS_Thermostat.device_id;
|
uint8_t device_id = EMS_Thermostat.device_id;
|
||||||
uint8_t hc = EMS_Thermostat.hc; // heating circuit
|
uint8_t hc = EMS_Thermostat.hc; // heating circuit
|
||||||
|
|
||||||
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
|
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
|
||||||
EMS_TxTelegram.dest = type;
|
EMS_TxTelegram.dest = device_id;
|
||||||
|
|
||||||
myDebug_P(PSTR("Setting new thermostat temperature"));
|
myDebug_P(PSTR("Setting new thermostat temperature"));
|
||||||
|
|
||||||
// when doing a comparison to validate the new temperature we call a different type
|
|
||||||
|
|
||||||
if (model_id == EMS_MODEL_RC20) {
|
if (model_id == EMS_MODEL_RC20) {
|
||||||
EMS_TxTelegram.type = EMS_TYPE_RC20Set;
|
EMS_TxTelegram.type = EMS_TYPE_RC20Set;
|
||||||
EMS_TxTelegram.offset = EMS_OFFSET_RC20Set_temp;
|
EMS_TxTelegram.offset = EMS_OFFSET_RC20Set_temp;
|
||||||
@@ -2499,6 +2489,15 @@ void ems_setThermostatTemp(float temperature, uint8_t temptype) {
|
|||||||
EMS_TxTelegram.type = EMS_TYPE_RC30Set;
|
EMS_TxTelegram.type = EMS_TYPE_RC30Set;
|
||||||
EMS_TxTelegram.offset = EMS_OFFSET_RC30Set_temp;
|
EMS_TxTelegram.offset = EMS_OFFSET_RC30Set_temp;
|
||||||
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC30StatusMessage;
|
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_RC30StatusMessage;
|
||||||
|
|
||||||
|
} else if (model_id == EMS_MODEL_RC300) {
|
||||||
|
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet; // for 3000 and 1010, e.g. 0B 10 FF (0A | 08) 01 89 2B
|
||||||
|
// check mode
|
||||||
|
if (EMS_Thermostat.mode == 1) { // auto
|
||||||
|
EMS_TxTelegram.offset = 0x08; // auto offset
|
||||||
|
} else if (EMS_Thermostat.mode == 0) { // manuaL
|
||||||
|
EMS_TxTelegram.offset = 0x0A; // manual offset
|
||||||
|
}
|
||||||
} else if ((model_id == EMS_MODEL_RC35) || (model_id == EMS_MODEL_ES73)) {
|
} else if ((model_id == EMS_MODEL_RC35) || (model_id == EMS_MODEL_ES73)) {
|
||||||
switch (temptype) {
|
switch (temptype) {
|
||||||
case 1: // change the night temp
|
case 1: // change the night temp
|
||||||
@@ -2519,7 +2518,6 @@ void ems_setThermostatTemp(float temperature, uint8_t temptype) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hc == 1) {
|
if (hc == 1) {
|
||||||
// heating circuit 1
|
// heating circuit 1
|
||||||
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC1;
|
EMS_TxTelegram.type = EMS_TYPE_RC35Set_HC1;
|
||||||
@@ -2532,7 +2530,7 @@ void ems_setThermostatTemp(float temperature, uint8_t temptype) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||||
EMS_TxTelegram.dataValue = (uint8_t)((float)temperature * (float)2); // value
|
EMS_TxTelegram.dataValue = (uint8_t)((float)temperature * (float)2); // value * 2
|
||||||
EMS_TxTelegram.type_validate = EMS_TxTelegram.type;
|
EMS_TxTelegram.type_validate = EMS_TxTelegram.type;
|
||||||
EMS_TxTelegram.comparisonOffset = EMS_TxTelegram.offset;
|
EMS_TxTelegram.comparisonOffset = EMS_TxTelegram.offset;
|
||||||
EMS_TxTelegram.comparisonValue = EMS_TxTelegram.dataValue;
|
EMS_TxTelegram.comparisonValue = EMS_TxTelegram.dataValue;
|
||||||
@@ -2542,8 +2540,9 @@ void ems_setThermostatTemp(float temperature, uint8_t temptype) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the thermostat working mode (0=low/night, 1=manual/day, 2=auto/clock)
|
* Set the thermostat working mode
|
||||||
* 0xA8 on a RC20 and 0xA7 on RC30
|
* (0=low/night, 1=manual/day, 2=auto/clock), 0xA8 on a RC20 and 0xA7 on RC30
|
||||||
|
* 0x01B9 for EMS+ 300/1000/3000, Auto=0xFF Manual=0x00. See https://github.com/proddy/EMS-ESP/wiki/RC3xx-Thermostats
|
||||||
*/
|
*/
|
||||||
void ems_setThermostatMode(uint8_t mode) {
|
void ems_setThermostatMode(uint8_t mode) {
|
||||||
if (!ems_getThermostatEnabled()) {
|
if (!ems_getThermostatEnabled()) {
|
||||||
@@ -2555,9 +2554,18 @@ void ems_setThermostatMode(uint8_t mode) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t model_id = EMS_Thermostat.model_id;
|
uint8_t model_id = EMS_Thermostat.model_id;
|
||||||
uint8_t type = EMS_Thermostat.device_id;
|
uint8_t device_id = EMS_Thermostat.device_id;
|
||||||
uint8_t hc = EMS_Thermostat.hc;
|
uint8_t hc = EMS_Thermostat.hc;
|
||||||
|
|
||||||
|
// RC300/1000/3000 have different settings
|
||||||
|
if (model_id == EMS_MODEL_RC300) {
|
||||||
|
if (mode == 1) {
|
||||||
|
mode = 0; // manual
|
||||||
|
} else {
|
||||||
|
mode = 0xFF; // auto
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
myDebug_P(PSTR("Setting thermostat mode to %d"), mode);
|
myDebug_P(PSTR("Setting thermostat mode to %d"), mode);
|
||||||
|
|
||||||
@@ -2566,7 +2574,7 @@ void ems_setThermostatMode(uint8_t mode) {
|
|||||||
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
|
EMS_Sys_Status.txRetryCount = 0; // reset retry counter
|
||||||
|
|
||||||
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
|
EMS_TxTelegram.action = EMS_TX_TELEGRAM_WRITE;
|
||||||
EMS_TxTelegram.dest = type;
|
EMS_TxTelegram.dest = device_id;
|
||||||
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
|
||||||
EMS_TxTelegram.dataValue = mode;
|
EMS_TxTelegram.dataValue = mode;
|
||||||
|
|
||||||
@@ -2580,6 +2588,9 @@ void ems_setThermostatMode(uint8_t mode) {
|
|||||||
} else if ((model_id == EMS_MODEL_RC35) || (model_id == EMS_MODEL_ES73)) {
|
} else if ((model_id == EMS_MODEL_RC35) || (model_id == EMS_MODEL_ES73)) {
|
||||||
EMS_TxTelegram.type = (hc == 2) ? EMS_TYPE_RC35Set_HC2 : EMS_TYPE_RC35Set_HC1;
|
EMS_TxTelegram.type = (hc == 2) ? EMS_TYPE_RC35Set_HC2 : EMS_TYPE_RC35Set_HC1;
|
||||||
EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_mode;
|
EMS_TxTelegram.offset = EMS_OFFSET_RC35Set_mode;
|
||||||
|
} else if (model_id == EMS_MODEL_RC300) {
|
||||||
|
EMS_TxTelegram.type = EMS_TYPE_RCPLUSSet; // for 3000 and 1010, e.g. 48 10 FF 00 01 B9 00 for manual
|
||||||
|
EMS_TxTelegram.offset = EMS_OFFSET_RCPLUSSet_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMS_TxTelegram.type_validate = EMS_TxTelegram.type; // callback to EMS_TYPE_RC30Temperature to fetch temps
|
EMS_TxTelegram.type_validate = EMS_TxTelegram.type; // callback to EMS_TYPE_RC30Temperature to fetch temps
|
||||||
|
|||||||
12
src/ems.h
12
src/ems.h
@@ -223,25 +223,25 @@ const _EMS_TxTelegram EMS_TX_TELEGRAM_NEW = {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t product_id;
|
uint8_t product_id;
|
||||||
char model_string[50];
|
char model_string[50];
|
||||||
} _Boiler_Type;
|
} _Boiler_Device;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t product_id;
|
uint8_t product_id;
|
||||||
uint8_t device_id;
|
uint8_t device_id;
|
||||||
char model_string[50];
|
char model_string[50];
|
||||||
} _SolarModule_Type;
|
} _SolarModule_Device;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t product_id;
|
uint8_t product_id;
|
||||||
uint8_t device_id;
|
uint8_t device_id;
|
||||||
char model_string[50];
|
char model_string[50];
|
||||||
} _Other_Type;
|
} _Other_Device;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t product_id;
|
uint8_t product_id;
|
||||||
uint8_t device_id;
|
uint8_t device_id;
|
||||||
char model_string[50];
|
char model_string[50];
|
||||||
} _HeatPump_Type;
|
} _HeatPump_Device;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t model_id;
|
uint8_t model_id;
|
||||||
@@ -249,7 +249,7 @@ typedef struct {
|
|||||||
uint8_t device_id;
|
uint8_t device_id;
|
||||||
char model_string[50];
|
char model_string[50];
|
||||||
bool write_supported;
|
bool write_supported;
|
||||||
} _Thermostat_Type;
|
} _Thermostat_Device;
|
||||||
|
|
||||||
// for consolidating all types
|
// for consolidating all types
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -257,7 +257,7 @@ typedef struct {
|
|||||||
uint8_t device_id;
|
uint8_t device_id;
|
||||||
char version[10];
|
char version[10];
|
||||||
char model_string[50];
|
char model_string[50];
|
||||||
} _Generic_Type;
|
} _Generic_Device;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Telegram package defintions
|
* Telegram package defintions
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
#include "ems.h"
|
#include "ems.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common
|
* Common Type
|
||||||
*/
|
*/
|
||||||
#define EMS_TYPE_Version 0x02
|
#define EMS_TYPE_Version 0x02
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Boiler...
|
* Boiler Telegram Types...
|
||||||
*/
|
*/
|
||||||
#define EMS_TYPE_UBAMonitorFast 0x18 // is an automatic monitor broadcast
|
#define EMS_TYPE_UBAMonitorFast 0x18 // is an automatic monitor broadcast
|
||||||
#define EMS_TYPE_UBAMonitorSlow 0x19 // is an automatic monitor broadcast
|
#define EMS_TYPE_UBAMonitorSlow 0x19 // is an automatic monitor broadcast
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
#define EMS_OFFSET_UBASetPoints_flowtemp 0 // flow temp
|
#define EMS_OFFSET_UBASetPoints_flowtemp 0 // flow temp
|
||||||
|
|
||||||
// Other
|
// SM and HP Types
|
||||||
#define EMS_TYPE_SM10Monitor 0x97 // SM10Monitor
|
#define EMS_TYPE_SM10Monitor 0x97 // SM10Monitor
|
||||||
#define EMS_TYPE_SM100Monitor 0x0262 // SM100Monitor
|
#define EMS_TYPE_SM100Monitor 0x0262 // SM100Monitor
|
||||||
#define EMS_TYPE_SM100Status 0x0264 // SM100Status
|
#define EMS_TYPE_SM100Status 0x0264 // SM100Status
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
#define EMS_OFFSET_ISM1Set_MaxBoilerTemp 6 // position of max boiler temp e.g. 50 in the following example: 90 30 FF 06 00 01 50 (CRC=2C)
|
#define EMS_OFFSET_ISM1Set_MaxBoilerTemp 6 // position of max boiler temp e.g. 50 in the following example: 90 30 FF 06 00 01 50 (CRC=2C)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thermostats...
|
* Thermostat Types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Common for all thermostats
|
// Common for all thermostats
|
||||||
@@ -106,13 +106,17 @@
|
|||||||
|
|
||||||
// RC1010, RC310 and RC300 specific (EMS Plus)
|
// RC1010, RC310 and RC300 specific (EMS Plus)
|
||||||
#define EMS_TYPE_RCPLUSStatusMessage 0x01A5 // is an automatic thermostat broadcast giving us temps
|
#define EMS_TYPE_RCPLUSStatusMessage 0x01A5 // is an automatic thermostat broadcast giving us temps
|
||||||
#define EMS_TYPE_RCPLUSStatusHeating 0x01B9 // heating mode
|
|
||||||
#define EMS_TYPE_RCPLUSStatusMode 0x1AF // summer/winter mode
|
#define EMS_TYPE_RCPLUSStatusMode 0x1AF // summer/winter mode
|
||||||
#define EMS_TYPE_RCPLUSSet 0x03 // setpoint temp message
|
#define EMS_TYPE_RCPLUSSet 0x01B9 // setpoint temp message and mode
|
||||||
#define EMS_OFFSET_RCPLUSStatusMessage_setpoint 3 // setpoint temp
|
#define EMS_OFFSET_RCPLUSStatusMessage_setpoint 3 // setpoint temp
|
||||||
#define EMS_OFFSET_RCPLUSStatusMessage_curr 0 // current temp
|
#define EMS_OFFSET_RCPLUSStatusMessage_curr 0 // current temp
|
||||||
#define EMS_OFFSET_RCPLUSGet_mode_day 8 // day/night mode
|
#define EMS_OFFSET_RCPLUSGet_mode_day 10 // day/night mode
|
||||||
|
#define EMS_OFFSET_RCPLUSSet_mode 0 // operation mode (Auto=xFF, Manual=x00)
|
||||||
#define EMS_OFFSET_RCPLUSStatusMessage_mode 0x0A // thermostat mode (auto, manual)
|
#define EMS_OFFSET_RCPLUSStatusMessage_mode 0x0A // thermostat mode (auto, manual)
|
||||||
|
#define EMS_OFFSET_RCPLUSSet_temp_comfort3 1 // comfort3 level
|
||||||
|
#define EMS_OFFSET_RCPLUSSet_temp_comfort2 2 // comfort2 level
|
||||||
|
#define EMS_OFFSET_RCPLUSSet_temp_comfort1 3 // comfort1 level
|
||||||
|
#define EMS_OFFSET_RCPLUSSet_temp_eco 4 // eco level
|
||||||
|
|
||||||
// Junkers FR10, FW100 (EMS Plus)
|
// Junkers FR10, FW100 (EMS Plus)
|
||||||
#define EMS_TYPE_JunkersStatusMessage 0x6F // is an automatic thermostat broadcast giving us temps
|
#define EMS_TYPE_JunkersStatusMessage 0x6F // is an automatic thermostat broadcast giving us temps
|
||||||
@@ -120,7 +124,7 @@
|
|||||||
#define EMS_OFFSET_JunkersStatusMessage_curr 4 // current temp
|
#define EMS_OFFSET_JunkersStatusMessage_curr 4 // current temp
|
||||||
|
|
||||||
|
|
||||||
// Known EMS types
|
// Known EMS devices
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EMS_MODEL_NONE, // unset
|
EMS_MODEL_NONE, // unset
|
||||||
EMS_MODEL_ALL, // common for all devices
|
EMS_MODEL_ALL, // common for all devices
|
||||||
@@ -157,7 +161,7 @@ typedef enum {
|
|||||||
// EMS types for known boilers. This list will be extended when new devices are recognized.
|
// EMS types for known boilers. This list will be extended when new devices are recognized.
|
||||||
// The device_id is always 0x08
|
// The device_id is always 0x08
|
||||||
// format is PRODUCT ID, DESCRIPTION
|
// format is PRODUCT ID, DESCRIPTION
|
||||||
const _Boiler_Type Boiler_Types[] = {
|
const _Boiler_Device Boiler_Devices[] = {
|
||||||
|
|
||||||
{72, "MC10 Module"},
|
{72, "MC10 Module"},
|
||||||
{123, "Buderus GB172/Nefit Trendline/Junkers Cerapur"},
|
{123, "Buderus GB172/Nefit Trendline/Junkers Cerapur"},
|
||||||
@@ -175,7 +179,7 @@ const _Boiler_Type Boiler_Types[] = {
|
|||||||
* Known Solar Module types
|
* Known Solar Module types
|
||||||
* format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
* format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||||
*/
|
*/
|
||||||
const _SolarModule_Type SolarModule_Types[] = {
|
const _SolarModule_Device SolarModule_Devices[] = {
|
||||||
|
|
||||||
{EMS_PRODUCTID_SM10, EMS_ID_SM, "SM10 Solar Module"},
|
{EMS_PRODUCTID_SM10, EMS_ID_SM, "SM10 Solar Module"},
|
||||||
{EMS_PRODUCTID_SM100, EMS_ID_SM, "SM100 Solar Module"},
|
{EMS_PRODUCTID_SM100, EMS_ID_SM, "SM100 Solar Module"},
|
||||||
@@ -185,7 +189,7 @@ const _SolarModule_Type SolarModule_Types[] = {
|
|||||||
|
|
||||||
// Other EMS devices which are not considered boilers, thermostats or solar modules
|
// Other EMS devices which are not considered boilers, thermostats or solar modules
|
||||||
// format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
// format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||||
const _Other_Type Other_Types[] = {
|
const _Other_Device Other_Devices[] = {
|
||||||
|
|
||||||
{69, 0x21, "MM10 Mixer Module"},
|
{69, 0x21, "MM10 Mixer Module"},
|
||||||
{71, 0x11, "WM10 Switch Module"},
|
{71, 0x11, "WM10 Switch Module"},
|
||||||
@@ -207,13 +211,13 @@ const _Other_Type Other_Types[] = {
|
|||||||
|
|
||||||
// heatpump
|
// heatpump
|
||||||
// format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
// format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||||
const _HeatPump_Type HeatPump_Types[] = {{252, EMS_ID_HP, "HeatPump Module"}};
|
const _HeatPump_Device HeatPump_Devices[] = {{252, EMS_ID_HP, "HeatPump Module"}};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Known thermostat types and their capabilities
|
* Known thermostat types and their capabilities
|
||||||
* format is MODEL_ID, PRODUCT ID, DEVICE ID, DESCRIPTION
|
* format is MODEL_ID, PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||||
*/
|
*/
|
||||||
const _Thermostat_Type Thermostat_Types[] = {
|
const _Thermostat_Device Thermostat_Devices[] = {
|
||||||
|
|
||||||
// Easy devices - not currently supporting write operations
|
// Easy devices - not currently supporting write operations
|
||||||
{EMS_MODEL_EASY, 202, 0x18, "Logamatic TC100/Nefit Moduline Easy", EMS_THERMOSTAT_WRITE_NO},
|
{EMS_MODEL_EASY, 202, 0x18, "Logamatic TC100/Nefit Moduline Easy", EMS_THERMOSTAT_WRITE_NO},
|
||||||
@@ -226,7 +230,7 @@ const _Thermostat_Type Thermostat_Types[] = {
|
|||||||
{EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_WRITE_YES},
|
{EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_WRITE_YES},
|
||||||
{EMS_MODEL_RC30, 78, 0x10, "RC30/Nefit Moduline 400", EMS_THERMOSTAT_WRITE_YES},
|
{EMS_MODEL_RC30, 78, 0x10, "RC30/Nefit Moduline 400", EMS_THERMOSTAT_WRITE_YES},
|
||||||
{EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_WRITE_YES},
|
{EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_WRITE_YES},
|
||||||
{EMS_MODEL_RC300, 158, 0x10, "RC300/RC310/Nefit Moduline 3000", EMS_THERMOSTAT_WRITE_NO},
|
{EMS_MODEL_RC300, 158, 0x10, "RC300/RC310/Nefit Moduline 3000", EMS_THERMOSTAT_WRITE_YES},
|
||||||
{EMS_MODEL_1010, 165, 0x18, "Nefit Moduline 1010", EMS_THERMOSTAT_WRITE_NO},
|
{EMS_MODEL_1010, 165, 0x18, "Nefit Moduline 1010", EMS_THERMOSTAT_WRITE_NO},
|
||||||
|
|
||||||
// Sieger
|
// Sieger
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "emsuart.h"
|
#include "emsuart.h"
|
||||||
#include "ems.h"
|
#include "ems.h"
|
||||||
#include <Arduino.h>
|
|
||||||
#include <user_interface.h>
|
#include <user_interface.h>
|
||||||
|
|
||||||
_EMSRxBuf * pEMSRxBuf;
|
_EMSRxBuf * pEMSRxBuf;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ems.h>
|
#include <ems.h>
|
||||||
|
|
||||||
#define EMSUART_UART 0 // UART 0
|
#define EMSUART_UART 0 // UART 0
|
||||||
|
|||||||
Reference in New Issue
Block a user