mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
fixed project cmds issue and added new 'h' function
This commit is contained in:
@@ -15,10 +15,11 @@
|
|||||||
#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
|
#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
|
||||||
#include <CRC32.h> // https://github.com/bakercp/CRC32
|
#include <CRC32.h> // https://github.com/bakercp/CRC32
|
||||||
|
|
||||||
// standard libs
|
// standard arduino libs
|
||||||
#include <Ticker.h> // https://github.com/esp8266/Arduino/tree/master/libraries/Ticker
|
#include <Ticker.h> // https://github.com/esp8266/Arduino/tree/master/libraries/Ticker
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
// these are set as -D build flags. If you're not using PlatformIO hard code them
|
// these are set as -D build flags during compilation
|
||||||
//#define WIFI_SSID "<my_ssid>"
|
//#define WIFI_SSID "<my_ssid>"
|
||||||
//#define WIFI_PASSWORD "<my_password>"
|
//#define WIFI_PASSWORD "<my_password>"
|
||||||
//#define MQTT_IP "<broker_ip>"
|
//#define MQTT_IP "<broker_ip>"
|
||||||
@@ -38,25 +39,6 @@ Ticker showerColdShotStopTimer;
|
|||||||
uint8_t regularUpdatesCount = 0;
|
uint8_t regularUpdatesCount = 0;
|
||||||
#define MAX_MANUAL_CALLS 2 // number of ems reads we do during the fetch cycle (in regularUpdates)
|
#define MAX_MANUAL_CALLS 2 // number of ems reads we do during the fetch cycle (in regularUpdates)
|
||||||
|
|
||||||
// Project commands for telnet
|
|
||||||
// Note: ?, *, $, ! and & are reserved
|
|
||||||
#define PROJECT_CMDS \
|
|
||||||
"* s show statistics\n\r" \
|
|
||||||
"* P publish stats to MQTT\n\r" \
|
|
||||||
"* v [n] set logging (0=none, 1=basic, 2=verbose)\n\r" \
|
|
||||||
"* p poll response on/off\n\r" \
|
|
||||||
"* T thermostat Support on/off\n\r" \
|
|
||||||
"* S shower timer on/off\n\r" \
|
|
||||||
"* A shower alert on/off\n\r" \
|
|
||||||
"* r [n] request for data from EMS. Examples:\n\r" \
|
|
||||||
"* from Boiler: 33=UBAParameterWW, 18=UBAMonitorFast, 19=UBAMonitorSlow, 34=UBAMonitorWWMessage\n\r" \
|
|
||||||
"* from Thermostat: 91=RC20StatusMessage, A8=RC20Temperature, 6=RC20Time, 2=Version\n\r" \
|
|
||||||
"* t [n] set thermostat temperature to n\n\r" \
|
|
||||||
"* m [n] set thermostat mode (0=low, 1=manual, 2=clock)\n\r" \
|
|
||||||
"* w [n] set boiler warm water temperature to n (min 30)\n\r" \
|
|
||||||
"* a [n] boiler warm water on (n=1) or off (n=0)\n\r" \
|
|
||||||
"* x [n] experimental (warning: for debugging only!)"
|
|
||||||
|
|
||||||
// GPIOs
|
// GPIOs
|
||||||
#define LED_RX D1 // GPIO5
|
#define LED_RX D1 // GPIO5
|
||||||
#define LED_TX D2 // GPIO4
|
#define LED_TX D2 // GPIO4
|
||||||
@@ -137,6 +119,28 @@ netInfo homeNet = {.mqttHost = MQTT_IP,
|
|||||||
|
|
||||||
ESPHelper myESP(&homeNet);
|
ESPHelper myESP(&homeNet);
|
||||||
|
|
||||||
|
command_t PROGMEM
|
||||||
|
project_cmds[] = {{"s", "show statistics"},
|
||||||
|
{"h", "show which EMS telegram types have special logic"},
|
||||||
|
{"P", "publish data to MQTT"},
|
||||||
|
{"v", "[n] set logging (0=none, 1=basic, 2=verbose)"},
|
||||||
|
{"p", "poll response on/off (default is off)"},
|
||||||
|
{"T", "thermostat Support on/off"},
|
||||||
|
{"S", "shower timer on/off"},
|
||||||
|
{"A", "shower alert on/off"},
|
||||||
|
{"r", "[n] send EMS request (n=telegram type id. Use 'h' to list which are the common ones)"},
|
||||||
|
{"t", "[n] set thermostat temperature to n"},
|
||||||
|
{"m", "[n] set thermostat mode (0=low, 1=manual, 2=clock)"},
|
||||||
|
{"w", "[n] set boiler warm water temperature to n (min 30)"},
|
||||||
|
{"a", "[n] boiler warm water on (n=1) or off (n=0)"},
|
||||||
|
{"x", "[n] experimental (warning: for debugging only!)"}};
|
||||||
|
|
||||||
|
// calculates size of an 2d array at compile time
|
||||||
|
template <typename T, size_t N>
|
||||||
|
constexpr size_t ArraySize(T (&)[N]) {
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
// store for overall system status
|
// store for overall system status
|
||||||
_Boiler_Status Boiler_Status;
|
_Boiler_Status Boiler_Status;
|
||||||
_Boiler_Shower Boiler_Shower;
|
_Boiler_Shower Boiler_Shower;
|
||||||
@@ -259,7 +263,9 @@ void showInfo() {
|
|||||||
myDebug("None");
|
myDebug("None");
|
||||||
}
|
}
|
||||||
|
|
||||||
myDebug("\n Thermostat is %s, Poll is %s, Shower timer is %s, Shower alert is %s\n",
|
myDebug("\n # EMS type handlers: %d\n", ems_getEmsTypesCount());
|
||||||
|
|
||||||
|
myDebug(" Thermostat is %s, Poll is %s, Shower timer is %s, Shower alert is %s\n",
|
||||||
((Boiler_Status.thermostat_enabled) ? "enabled" : "disabled"),
|
((Boiler_Status.thermostat_enabled) ? "enabled" : "disabled"),
|
||||||
((EMS_Sys_Status.emsPollEnabled) ? "enabled" : "disabled"),
|
((EMS_Sys_Status.emsPollEnabled) ? "enabled" : "disabled"),
|
||||||
((Boiler_Status.shower_timer) ? "enabled" : "disabled"),
|
((Boiler_Status.shower_timer) ? "enabled" : "disabled"),
|
||||||
@@ -496,6 +502,9 @@ void myDebugCallback() {
|
|||||||
case 't': // set thermostat temp
|
case 't': // set thermostat temp
|
||||||
ems_setThermostatTemp(strtof(&cmd[2], 0));
|
ems_setThermostatTemp(strtof(&cmd[2], 0));
|
||||||
break;
|
break;
|
||||||
|
case 'h': // show type handlers
|
||||||
|
ems_printAllTypes();
|
||||||
|
break;
|
||||||
case 'm': // set thermostat mode
|
case 'm': // set thermostat mode
|
||||||
ems_setThermostatMode(cmd[2] - '0');
|
ems_setThermostatMode(cmd[2] - '0');
|
||||||
break;
|
break;
|
||||||
@@ -645,7 +654,7 @@ void _initBoiler() {
|
|||||||
|
|
||||||
// init boiler
|
// init boiler
|
||||||
Boiler_Status.wifi_connected = false;
|
Boiler_Status.wifi_connected = false;
|
||||||
Boiler_Status.boiler_online = true; // assume we have a connection, it will be checked in the loop() anyway
|
Boiler_Status.boiler_online = false;
|
||||||
|
|
||||||
// init shower
|
// init shower
|
||||||
Boiler_Shower.timerStart = 0;
|
Boiler_Shower.timerStart = 0;
|
||||||
@@ -694,11 +703,8 @@ void setup() {
|
|||||||
myESP.addSubscription(TOPIC_BOILER_WARM_WATER_SELECTED_TEMPERATURE);
|
myESP.addSubscription(TOPIC_BOILER_WARM_WATER_SELECTED_TEMPERATURE);
|
||||||
myESP.addSubscription(TOPIC_SHOWER_COLDSHOT);
|
myESP.addSubscription(TOPIC_SHOWER_COLDSHOT);
|
||||||
|
|
||||||
// set up Telnet
|
myESP.consoleSetCallBackProjectCmds(project_cmds, ArraySize(project_cmds), myDebugCallback); // set up Telnet commands
|
||||||
|
myESP.begin(HOSTNAME); // start wifi and mqtt services
|
||||||
myESP.consoleSetHelpProjectsCmds(PROJECT_CMDS);
|
|
||||||
myESP.consoleSetCallBackProjectCmds(myDebugCallback);
|
|
||||||
myESP.begin(HOSTNAME);
|
|
||||||
|
|
||||||
// init ems stats
|
// init ems stats
|
||||||
ems_init();
|
ems_init();
|
||||||
|
|||||||
31
src/ems.cpp
31
src/ems.cpp
@@ -21,11 +21,15 @@ extern ESPHelper myESP;
|
|||||||
#define myDebug(x, ...) myESP.printf(x, ##__VA_ARGS__)
|
#define myDebug(x, ...) myESP.printf(x, ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// calculates size of an 2d array at compile time
|
||||||
|
template <typename T, size_t N>
|
||||||
|
constexpr size_t ArraySize(T (&)[N]) {
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
|
||||||
_EMS_Sys_Status EMS_Sys_Status; // EMS Status
|
_EMS_Sys_Status EMS_Sys_Status; // EMS Status
|
||||||
_EMS_TxTelegram EMS_TxTelegram; // Empty buffer for sending telegrams
|
_EMS_TxTelegram EMS_TxTelegram; // Empty buffer for sending telegrams
|
||||||
|
|
||||||
// and call backs
|
|
||||||
#define MAX_TYPECALLBACK 13 // make sure it matches the #types you have
|
|
||||||
// callbacks per type
|
// callbacks per type
|
||||||
bool _process_UBAMonitorFast(uint8_t * data, uint8_t length);
|
bool _process_UBAMonitorFast(uint8_t * data, uint8_t length);
|
||||||
bool _process_UBAMonitorSlow(uint8_t * data, uint8_t length);
|
bool _process_UBAMonitorSlow(uint8_t * data, uint8_t length);
|
||||||
@@ -37,7 +41,7 @@ bool _process_RC20Temperature(uint8_t * data, uint8_t length);
|
|||||||
bool _process_RCTempMessage(uint8_t * data, uint8_t length);
|
bool _process_RCTempMessage(uint8_t * data, uint8_t length);
|
||||||
bool _process_Version(uint8_t * data, uint8_t length);
|
bool _process_Version(uint8_t * data, uint8_t length);
|
||||||
|
|
||||||
const _EMS_Types EMS_Types[MAX_TYPECALLBACK] =
|
const _EMS_Types EMS_Types[] =
|
||||||
{{EMS_ID_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", _process_UBAMonitorFast},
|
{{EMS_ID_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", _process_UBAMonitorFast},
|
||||||
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", _process_UBAMonitorSlow},
|
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", _process_UBAMonitorSlow},
|
||||||
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", _process_UBAMonitorWWMessage},
|
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", _process_UBAMonitorWWMessage},
|
||||||
@@ -52,6 +56,7 @@ const _EMS_Types EMS_Types[MAX_TYPECALLBACK] =
|
|||||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", _process_RC20Temperature},
|
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", _process_RC20Temperature},
|
||||||
{EMS_ID_THERMOSTAT, EMS_TYPE_RCTempMessage, "RCTempMessage", _process_RCTempMessage},
|
{EMS_ID_THERMOSTAT, EMS_TYPE_RCTempMessage, "RCTempMessage", _process_RCTempMessage},
|
||||||
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", _process_Version}};
|
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", _process_Version}};
|
||||||
|
uint8_t _EMS_Types_max = ArraySize(EMS_Types); // number of defined types
|
||||||
|
|
||||||
// reserve space for the data we collect from the Boiler and Thermostat
|
// reserve space for the data we collect from the Boiler and Thermostat
|
||||||
_EMS_Boiler EMS_Boiler;
|
_EMS_Boiler EMS_Boiler;
|
||||||
@@ -181,6 +186,10 @@ _EMS_SYS_LOGGING ems_getLogging() {
|
|||||||
return EMS_Sys_Status.emsLogging;
|
return EMS_Sys_Status.emsLogging;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t ems_getEmsTypesCount() {
|
||||||
|
return _EMS_Types_max;
|
||||||
|
}
|
||||||
|
|
||||||
void ems_setLogging(_EMS_SYS_LOGGING loglevel) {
|
void ems_setLogging(_EMS_SYS_LOGGING loglevel) {
|
||||||
if (loglevel <= EMS_SYS_LOGGING_VERBOSE) {
|
if (loglevel <= EMS_SYS_LOGGING_VERBOSE) {
|
||||||
EMS_Sys_Status.emsLogging = loglevel;
|
EMS_Sys_Status.emsLogging = loglevel;
|
||||||
@@ -224,6 +233,18 @@ uint16_t _toLong(uint8_t i, uint8_t * data) {
|
|||||||
return (((data[i]) << 16) + ((data[i + 1]) << 8) + (data[i + 2]));
|
return (((data[i]) << 16) + ((data[i + 1]) << 8) + (data[i + 2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debugging only - print out all handled types
|
||||||
|
void ems_printAllTypes() {
|
||||||
|
myDebug("These %d telegram types are recognized:\n", _EMS_Types_max);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < _EMS_Types_max; i++) {
|
||||||
|
myDebug(" %s:\ttype:%02x (%s)\n",
|
||||||
|
EMS_Types[i].src == EMS_ID_THERMOSTAT ? "Thermostat" : "Boiler",
|
||||||
|
EMS_Types[i].type,
|
||||||
|
EMS_Types[i].typeString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the pointer to the EMS_Types array for a given type ID
|
* Find the pointer to the EMS_Types array for a given type ID
|
||||||
*/
|
*/
|
||||||
@@ -231,7 +252,7 @@ int ems_findType(uint8_t type) {
|
|||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
bool typeFound = false;
|
bool typeFound = false;
|
||||||
// scan through known ID types
|
// scan through known ID types
|
||||||
while (i < MAX_TYPECALLBACK) {
|
while (i < _EMS_Types_max) {
|
||||||
if (EMS_Types[i].type == type) {
|
if (EMS_Types[i].type == type) {
|
||||||
typeFound = true; // we have a match
|
typeFound = true; // we have a match
|
||||||
break;
|
break;
|
||||||
@@ -396,7 +417,7 @@ void _processType(uint8_t * telegram, uint8_t length) {
|
|||||||
// set typeFound if we found a match
|
// set typeFound if we found a match
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool typeFound = false;
|
bool typeFound = false;
|
||||||
while (i < MAX_TYPECALLBACK) {
|
while (i < _EMS_Types_max) {
|
||||||
if ((EMS_Types[i].src == src) && (EMS_Types[i].type == type)) {
|
if ((EMS_Types[i].src == src) && (EMS_Types[i].type == type)) {
|
||||||
// we have a match
|
// we have a match
|
||||||
typeFound = true;
|
typeFound = true;
|
||||||
|
|||||||
36
src/ems.h
36
src/ems.h
@@ -163,10 +163,9 @@ typedef bool (*EMS_processType_cb)(uint8_t * data, uint8_t length);
|
|||||||
|
|
||||||
// Definition for each type, including the relative callback function
|
// Definition for each type, including the relative callback function
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t src;
|
uint8_t src;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
const char typeString[50];
|
const char typeString[50];
|
||||||
//uint8_t size; // size of telegram, excluding the 4-byte header and crc
|
|
||||||
EMS_processType_cb processType_cb;
|
EMS_processType_cb processType_cb;
|
||||||
} _EMS_Types;
|
} _EMS_Types;
|
||||||
|
|
||||||
@@ -184,23 +183,22 @@ typedef struct {
|
|||||||
#define COLOR_BOLD_OFF "\x1B[21m"
|
#define COLOR_BOLD_OFF "\x1B[21m"
|
||||||
|
|
||||||
// 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);
|
void ems_doReadCommand(uint8_t type);
|
||||||
void ems_setThermostatTemp(float temp);
|
void ems_setThermostatTemp(float temp);
|
||||||
void ems_setThermostatMode(uint8_t mode);
|
void ems_setThermostatMode(uint8_t mode);
|
||||||
void ems_setWarmWaterTemp(uint8_t temperature);
|
void ems_setWarmWaterTemp(uint8_t temperature);
|
||||||
void ems_setWarmWaterActivated(bool activated);
|
void ems_setWarmWaterActivated(bool activated);
|
||||||
void ems_setExperimental(uint8_t value);
|
void ems_setExperimental(uint8_t value);
|
||||||
|
void ems_setPoll(bool b);
|
||||||
void ems_setPoll(bool b);
|
bool ems_getPoll();
|
||||||
bool ems_getPoll();
|
bool ems_getThermostatEnabled();
|
||||||
|
void ems_setThermostatEnabled(bool b);
|
||||||
bool ems_getThermostatEnabled();
|
|
||||||
void ems_setThermostatEnabled(bool b);
|
|
||||||
|
|
||||||
void ems_setLogging(_EMS_SYS_LOGGING loglevel);
|
void ems_setLogging(_EMS_SYS_LOGGING loglevel);
|
||||||
_EMS_SYS_LOGGING ems_getLogging();
|
_EMS_SYS_LOGGING ems_getLogging();
|
||||||
|
uint8_t ems_getEmsTypesCount();
|
||||||
|
void ems_printAllTypes();
|
||||||
|
|
||||||
// private functions
|
// private functions
|
||||||
uint8_t _crcCalculator(uint8_t * data, uint8_t len);
|
uint8_t _crcCalculator(uint8_t * data, uint8_t len);
|
||||||
|
|||||||
Reference in New Issue
Block a user