mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
#632 - still experimental
This commit is contained in:
49
CHANGELOG.md
49
CHANGELOG.md
@@ -5,6 +5,51 @@ 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).
|
||||||
|
|
||||||
|
## [2.2.0] December 28 2020
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- function keys in editor: cursor, del, home, end. F1=help, F2=show, and other shortcuts
|
||||||
|
- SM100 pump working time and energy units
|
||||||
|
- heating curve parameters and commands for RC300
|
||||||
|
- `wwonetime` for RC300 thermostat
|
||||||
|
- expose test framework via api (#611)
|
||||||
|
- SysLog has enable/disable flag in WebUI
|
||||||
|
- Add solar configuration telegrams (#616) [thanks @hpanther]
|
||||||
|
- `log trace` shows decoded or optional raw telegrams, `watch unknown` for only unknown telegrams
|
||||||
|
- WM10 switch telegrams
|
||||||
|
- boiler information (#633), pumpmod min/max commands
|
||||||
|
- maintenance message and command
|
||||||
|
- thermostat program, reducemode, controlmode
|
||||||
|
- optional delayed start for sending tx-telegrams to prevent conflicts with KM200
|
||||||
|
- RC35 holiday setting with `+` for 'at home'
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- mixer IPM pumpstatus
|
||||||
|
- mixer devices in HA were incorrectly named
|
||||||
|
- Prevent HA MQTT config messages for thermostat that has no 'currtemp' (#582)
|
||||||
|
- serviceCodeNumber, 3-char serviceCode, exhausttemp and heating_active for newer ems+ boilers
|
||||||
|
- prevent MQTT publish messages from sending twice
|
||||||
|
- repeated output on read commands
|
||||||
|
- heating_active for ems+
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- optimized MQTT for HA to reduce heap fragmentation issues
|
||||||
|
- change syslog settings without reboot
|
||||||
|
- HA-config split in smaller blocks
|
||||||
|
- commands `fetch` and `publish [ha]` as call
|
||||||
|
- mqtt json package sizes
|
||||||
|
- renamed the command system info (which showed settings) to `settings`
|
||||||
|
- renamed the command system report (Which dumped debug info) to `info`
|
||||||
|
- Changing settings via web restarts only selected services
|
||||||
|
- renamed pio targets (esp8266-ci and esp32-ci for GitHub CI)
|
||||||
|
- telnet default settings `log info`, timeout 60 min
|
||||||
|
- `log debug` not showing telegram names, use `log trace` or `watch on` to show the telegrams
|
||||||
|
- optimized how console and web display device data ([#632](https://github.com/proddy/EMS-ESP/issues/632))
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- old shell and python build scripts
|
||||||
|
|
||||||
|
|
||||||
## [2.1.0] October 31 2020
|
## [2.1.0] October 31 2020
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -39,7 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Fix writing to the Junkers FR120 thermostat
|
- Fix writing to the Junkers FR120 thermostat
|
||||||
- support for changing summermode
|
- support for changing summermode
|
||||||
- added missing `heatingtype` to thermostat data
|
- added missing `heatingtype` to thermostat data
|
||||||
- handle incomming ems+ read requests, ignore F7 telegrams with 3byte-id
|
- handle incoming ems+ read requests, ignore F7 telegrams with 3byte-id
|
||||||
- fix month for setting clock from NTP
|
- fix month for setting clock from NTP
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
@@ -675,4 +720,4 @@ There are breaking changes in this release. See `publish_time` below and make su
|
|||||||
|
|
||||||
## [0.1.0] 2018-05-14
|
## [0.1.0] 2018-05-14
|
||||||
|
|
||||||
- Initial development version
|
- Initial development version
|
||||||
@@ -1,40 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- function keys in editor: cursor, del, home, end. F1=help, F2=show, and other shortcuts
|
- See https://github.com/proddy/EMS-ESP/issues/632
|
||||||
- SM100 pump working time and energy units
|
|
||||||
- heating curve parameters and commands for RC300
|
|
||||||
- `wwonetime` for RC300 thermostat
|
|
||||||
- expose test framework via api (#611)
|
|
||||||
- SysLog has enable/disable flag in WebUI
|
|
||||||
- Add solar configuration telegrams (#616) [thanks @hpanther]
|
|
||||||
- `log trace` shows decoded telegrams, `watch unknown` for only unknown telegrams
|
|
||||||
- WM10 switch telegrams
|
|
||||||
- boiler information (#633), pumpmod min/max commands
|
|
||||||
- maintenance message and command
|
|
||||||
- thermostat program, reducemode, controlmode
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- mixer IPM pumpstatus
|
|
||||||
- mixer devices in HA were incorrectly named
|
|
||||||
- Prevent HA MQTT config messages for thermostat that has no 'currtemp' (#582)
|
|
||||||
- serviceCodeNumber, 3-char serviceCode, exhausttemp and heating_active for newer ems+ boilers
|
|
||||||
- prevent MQTT publish messages from sending twice
|
|
||||||
- repeated output on read commands
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- optimized MQTT for HA to reduce heap fragmentation issues
|
|
||||||
- change syslog settings without reboot
|
|
||||||
- HA-config split in smaller blocks
|
|
||||||
- commands `fetch` and `publish [ha]` as call
|
|
||||||
- mqtt json package sizes
|
|
||||||
- renamed the command system info (which showed settings) to `settings`
|
|
||||||
- renamed the command system report (Which dumped debug info) to `info`
|
|
||||||
- Changing settings via web restarts only selected services
|
|
||||||
- renamed pio targets (esp8266-ci and esp32-ci for GitHub CI)
|
|
||||||
- telnet default settings `log info`, timeout 60 min
|
|
||||||
- `log debug` not showing telegram names, use `log trace` or `watch on` to show the telegrams
|
|
||||||
- optimized how console and web display device data ([#632](https://github.com/proddy/EMS-ESP/issues/632))
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- old shell and python build scripts
|
|
||||||
@@ -94,17 +94,6 @@ class SystemStatusForm extends Component<SystemStatusFormProps, SystemStatusForm
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
</Fragment>)
|
</Fragment>)
|
||||||
}
|
}
|
||||||
<ListItem>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Avatar>
|
|
||||||
<BatteryUnknownIcon />
|
|
||||||
</Avatar>
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText
|
|
||||||
primary="Free System Memory"
|
|
||||||
secondary={data.free_mem + "%"}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
<ListItem >
|
<ListItem >
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ void APSettingsService::reconfigureAP() {
|
|||||||
|
|
||||||
void APSettingsService::loop() {
|
void APSettingsService::loop() {
|
||||||
unsigned long currentMillis = uuid::get_uptime();
|
unsigned long currentMillis = uuid::get_uptime();
|
||||||
unsigned long manageElapsed = (unsigned long)(currentMillis - _lastManaged);
|
unsigned long manageElapsed = (uint32_t)(currentMillis - _lastManaged);
|
||||||
if (manageElapsed >= MANAGE_NETWORK_DELAY) {
|
if (manageElapsed >= MANAGE_NETWORK_DELAY) {
|
||||||
_lastManaged = currentMillis;
|
_lastManaged = currentMillis;
|
||||||
manageAP();
|
manageAP();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class ESPUtils {
|
|||||||
public:
|
public:
|
||||||
static String defaultDeviceValue(String prefix = "") {
|
static String defaultDeviceValue(String prefix = "") {
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
return prefix + String((unsigned long)ESP.getEfuseMac(), HEX);
|
return prefix + String((uint32_t)ESP.getEfuseMac(), HEX);
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
return prefix + String(ESP.getChipId(), HEX);
|
return prefix + String(ESP.getChipId(), HEX);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ void MqttSettingsService::begin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettingsService::loop() {
|
void MqttSettingsService::loop() {
|
||||||
if (_reconfigureMqtt || (_disconnectedAt && (unsigned long)(uuid::get_uptime() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) {
|
if (_reconfigureMqtt || (_disconnectedAt && (uint32_t)(uuid::get_uptime() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) {
|
||||||
// reconfigure MQTT client
|
// reconfigure MQTT client
|
||||||
configureMqtt();
|
configureMqtt();
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,11 @@ void NTPSettingsService::configureTime(AsyncWebServerRequest * request, JsonVari
|
|||||||
if (!sntp_enabled() && json.is<JsonObject>()) {
|
if (!sntp_enabled() && json.is<JsonObject>()) {
|
||||||
String timeUtc = json["time_utc"];
|
String timeUtc = json["time_utc"];
|
||||||
struct tm tm = {0};
|
struct tm tm = {0};
|
||||||
char * s = strptime(timeUtc.c_str(), "%Y-%m-%dT%H:%M:%SZ", &tm);
|
|
||||||
|
// TODO fix strptime, which is not included in xtensa
|
||||||
|
// char * s = strptime(timeUtc.c_str(), "%Y-%m-%dT%H:%M:%SZ", &tm);
|
||||||
|
|
||||||
|
char * s = nullptr;
|
||||||
if (s != nullptr) {
|
if (s != nullptr) {
|
||||||
time_t time = mktime(&tm);
|
time_t time = mktime(&tm);
|
||||||
struct timeval now = {.tv_sec = time};
|
struct timeval now = {.tv_sec = time};
|
||||||
@@ -80,6 +84,7 @@ void NTPSettingsService::configureTime(AsyncWebServerRequest * request, JsonVari
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncWebServerResponse * response = request->beginResponse(400);
|
AsyncWebServerResponse * response = request->beginResponse(400);
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ SystemStatus::SystemStatus(AsyncWebServer * server, SecurityManager * securityMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SystemStatus::systemStatus(AsyncWebServerRequest * request) {
|
void SystemStatus::systemStatus(AsyncWebServerRequest * request) {
|
||||||
uint8_t free_mem_percent = emsesp::System::free_mem(); // added by proddy
|
|
||||||
|
|
||||||
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_ESP_STATUS_SIZE);
|
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_ESP_STATUS_SIZE);
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
@@ -40,8 +38,7 @@ void SystemStatus::systemStatus(AsyncWebServerRequest * request) {
|
|||||||
root["fs_used"] = fs_info.usedBytes;
|
root["fs_used"] = fs_info.usedBytes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); // proddy added
|
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); // proddy added
|
||||||
root["free_mem"] = free_mem_percent; // proddy added
|
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ void WiFiSettingsService::reconfigureWiFiConnection() {
|
|||||||
|
|
||||||
void WiFiSettingsService::loop() {
|
void WiFiSettingsService::loop() {
|
||||||
unsigned long currentMillis = millis();
|
unsigned long currentMillis = millis();
|
||||||
if (!_lastConnectionAttempt || (unsigned long)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) {
|
if (!_lastConnectionAttempt || (uint32_t)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) {
|
||||||
_lastConnectionAttempt = currentMillis;
|
_lastConnectionAttempt = currentMillis;
|
||||||
manageSTA();
|
manageSTA();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace uuid {
|
|||||||
|
|
||||||
namespace console {
|
namespace console {
|
||||||
|
|
||||||
static const char __pstr__logger_name[] __attribute__((__aligned__(sizeof(int)))) PROGMEM = "shell";
|
static const char __pstr__logger_name[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "shell";
|
||||||
const uuid::log::Logger Shell::logger_{reinterpret_cast<const __FlashStringHelper *>(__pstr__logger_name), uuid::log::Facility::LPR};
|
const uuid::log::Logger Shell::logger_{reinterpret_cast<const __FlashStringHelper *>(__pstr__logger_name), uuid::log::Facility::LPR};
|
||||||
|
|
||||||
Shell::QueuedLogMessage::QueuedLogMessage(unsigned long id, std::shared_ptr<uuid::log::Message> && content)
|
Shell::QueuedLogMessage::QueuedLogMessage(unsigned long id, std::shared_ptr<uuid::log::Message> && content)
|
||||||
|
|||||||
@@ -26,19 +26,19 @@ namespace uuid {
|
|||||||
|
|
||||||
namespace log {
|
namespace log {
|
||||||
|
|
||||||
static constexpr const char * pstr_level_lowercase_off __attribute__((__aligned__(sizeof(int)))) PROGMEM = "off";
|
static constexpr const char * pstr_level_lowercase_off __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "off";
|
||||||
static constexpr const char * pstr_level_lowercase_emerg __attribute__((__aligned__(sizeof(int)))) PROGMEM = "emerg";
|
static constexpr const char * pstr_level_lowercase_emerg __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "emerg";
|
||||||
static constexpr const char * pstr_level_lowercase_crit __attribute__((__aligned__(sizeof(int)))) PROGMEM = "crit";
|
static constexpr const char * pstr_level_lowercase_crit __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "crit";
|
||||||
static constexpr const char * pstr_level_lowercase_alert __attribute__((__aligned__(sizeof(int)))) PROGMEM = "alert";
|
static constexpr const char * pstr_level_lowercase_alert __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "alert";
|
||||||
static constexpr const char * pstr_level_lowercase_err __attribute__((__aligned__(sizeof(int)))) PROGMEM = "err";
|
static constexpr const char * pstr_level_lowercase_err __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "err";
|
||||||
static constexpr const char * pstr_level_lowercase_warning __attribute__((__aligned__(sizeof(int)))) PROGMEM = "warning";
|
static constexpr const char * pstr_level_lowercase_warning __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "warning";
|
||||||
static constexpr const char * pstr_level_lowercase_notice __attribute__((__aligned__(sizeof(int)))) PROGMEM = "notice";
|
static constexpr const char * pstr_level_lowercase_notice __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "notice";
|
||||||
static constexpr const char * pstr_level_lowercase_info __attribute__((__aligned__(sizeof(int)))) PROGMEM = "info";
|
static constexpr const char * pstr_level_lowercase_info __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "info";
|
||||||
static constexpr const char * pstr_level_lowercase_debug __attribute__((__aligned__(sizeof(int)))) PROGMEM = "debug";
|
static constexpr const char * pstr_level_lowercase_debug __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "debug";
|
||||||
static constexpr const char * pstr_level_lowercase_trace __attribute__((__aligned__(sizeof(int)))) PROGMEM = "trace";
|
static constexpr const char * pstr_level_lowercase_trace __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "trace";
|
||||||
static constexpr const char * pstr_level_lowercase_all __attribute__((__aligned__(sizeof(int)))) PROGMEM = "all";
|
static constexpr const char * pstr_level_lowercase_all __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "all";
|
||||||
|
|
||||||
static const __FlashStringHelper * log_level_lowercase[(int)Level::ALL - (int)Level::OFF + 1] __attribute__((__aligned__(sizeof(int))))
|
static const __FlashStringHelper * log_level_lowercase[(int)Level::ALL - (int)Level::OFF + 1] __attribute__((__aligned__(sizeof(uint32_t))))
|
||||||
PROGMEM = {reinterpret_cast<const __FlashStringHelper *>(pstr_level_lowercase_off),
|
PROGMEM = {reinterpret_cast<const __FlashStringHelper *>(pstr_level_lowercase_off),
|
||||||
reinterpret_cast<const __FlashStringHelper *>(pstr_level_lowercase_emerg),
|
reinterpret_cast<const __FlashStringHelper *>(pstr_level_lowercase_emerg),
|
||||||
reinterpret_cast<const __FlashStringHelper *>(pstr_level_lowercase_crit),
|
reinterpret_cast<const __FlashStringHelper *>(pstr_level_lowercase_crit),
|
||||||
|
|||||||
@@ -26,19 +26,19 @@ namespace uuid {
|
|||||||
|
|
||||||
namespace log {
|
namespace log {
|
||||||
|
|
||||||
static constexpr const char * pstr_level_uppercase_off __attribute__((__aligned__(sizeof(int)))) PROGMEM = "OFF";
|
static constexpr const char * pstr_level_uppercase_off __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "OFF";
|
||||||
static constexpr const char * pstr_level_uppercase_emerg __attribute__((__aligned__(sizeof(int)))) PROGMEM = "EMERG";
|
static constexpr const char * pstr_level_uppercase_emerg __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "EMERG";
|
||||||
static constexpr const char * pstr_level_uppercase_crit __attribute__((__aligned__(sizeof(int)))) PROGMEM = "CRIT";
|
static constexpr const char * pstr_level_uppercase_crit __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "CRIT";
|
||||||
static constexpr const char * pstr_level_uppercase_alert __attribute__((__aligned__(sizeof(int)))) PROGMEM = "ALERT";
|
static constexpr const char * pstr_level_uppercase_alert __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "ALERT";
|
||||||
static constexpr const char * pstr_level_uppercase_err __attribute__((__aligned__(sizeof(int)))) PROGMEM = "ERR";
|
static constexpr const char * pstr_level_uppercase_err __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "ERR";
|
||||||
static constexpr const char * pstr_level_uppercase_warning __attribute__((__aligned__(sizeof(int)))) PROGMEM = "WARNING";
|
static constexpr const char * pstr_level_uppercase_warning __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "WARNING";
|
||||||
static constexpr const char * pstr_level_uppercase_notice __attribute__((__aligned__(sizeof(int)))) PROGMEM = "NOTICE";
|
static constexpr const char * pstr_level_uppercase_notice __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "NOTICE";
|
||||||
static constexpr const char * pstr_level_uppercase_info __attribute__((__aligned__(sizeof(int)))) PROGMEM = "INFO";
|
static constexpr const char * pstr_level_uppercase_info __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "INFO";
|
||||||
static constexpr const char * pstr_level_uppercase_debug __attribute__((__aligned__(sizeof(int)))) PROGMEM = "DEBUG";
|
static constexpr const char * pstr_level_uppercase_debug __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "DEBUG";
|
||||||
static constexpr const char * pstr_level_uppercase_trace __attribute__((__aligned__(sizeof(int)))) PROGMEM = "TRACE";
|
static constexpr const char * pstr_level_uppercase_trace __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "TRACE";
|
||||||
static constexpr const char * pstr_level_uppercase_all __attribute__((__aligned__(sizeof(int)))) PROGMEM = "ALL";
|
static constexpr const char * pstr_level_uppercase_all __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "ALL";
|
||||||
|
|
||||||
static const __FlashStringHelper * log_level_uppercase[(int)Level::ALL - (int)Level::OFF + 1] __attribute__((__aligned__(sizeof(int))))
|
static const __FlashStringHelper * log_level_uppercase[(int)Level::ALL - (int)Level::OFF + 1] __attribute__((__aligned__(sizeof(uint32_t))))
|
||||||
PROGMEM = {reinterpret_cast<const __FlashStringHelper *>(pstr_level_uppercase_off),
|
PROGMEM = {reinterpret_cast<const __FlashStringHelper *>(pstr_level_uppercase_off),
|
||||||
reinterpret_cast<const __FlashStringHelper *>(pstr_level_uppercase_emerg),
|
reinterpret_cast<const __FlashStringHelper *>(pstr_level_uppercase_emerg),
|
||||||
reinterpret_cast<const __FlashStringHelper *>(pstr_level_uppercase_crit),
|
reinterpret_cast<const __FlashStringHelper *>(pstr_level_uppercase_crit),
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
#include <uuid/common.h>
|
#include <uuid/common.h>
|
||||||
#include <uuid/log.h>
|
#include <uuid/log.h>
|
||||||
|
|
||||||
static const char __pstr__logger_name[] __attribute__((__aligned__(sizeof(int)))) PROGMEM = "syslog";
|
static const char __pstr__logger_name[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "syslog";
|
||||||
|
|
||||||
namespace uuid {
|
namespace uuid {
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@ bool SyslogService::transmit(const QueuedLogMessage & message) {
|
|||||||
tm.tm_hour,
|
tm.tm_hour,
|
||||||
tm.tm_min,
|
tm.tm_min,
|
||||||
tm.tm_sec,
|
tm.tm_sec,
|
||||||
(unsigned long)message.time_.tv_usec);
|
(uint32_t)message.time_.tv_usec);
|
||||||
} else {
|
} else {
|
||||||
udp_.print('-');
|
udp_.print('-');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char __pstr__logger_name[] __attribute__((__aligned__(sizeof(int)))) PROGMEM = "telnet";
|
static const char __pstr__logger_name[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = "telnet";
|
||||||
|
|
||||||
namespace uuid {
|
namespace uuid {
|
||||||
|
|
||||||
|
|||||||
2
makefile
2
makefile
@@ -18,7 +18,7 @@ MAKEFLAGS+="j "
|
|||||||
TARGET := emsesp
|
TARGET := emsesp
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src lib_standalone lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src src/devices lib/ArduinoJson/src src/test
|
SOURCES := src lib_standalone lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src src/devices lib/ArduinoJson/src src/test
|
||||||
INCLUDES := lib/ArduinoJson/src lib_standalone lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/uuid-telnet/src lib/uuid-syslog/src src/devices src
|
INCLUDES := lib/ArduinoJson/src lib_standalone lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/uuid-telnet/src lib/uuid-syslog/src src/devices lib src
|
||||||
LIBRARIES :=
|
LIBRARIES :=
|
||||||
|
|
||||||
CPPCHECK = cppcheck
|
CPPCHECK = cppcheck
|
||||||
|
|||||||
@@ -10,6 +10,22 @@ extra_configs =
|
|||||||
pio_local.ini
|
pio_local.ini
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
|
; default platformio compile flags are: -fno-rtti -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functions=4 -ffunction-sections -fdata-sections -fno-exceptions -Wall
|
||||||
|
core_build_flags = -Wno-deprecated-declarations
|
||||||
|
-mtarget-align
|
||||||
|
-free
|
||||||
|
-fipa-pta
|
||||||
|
-Wreturn-type
|
||||||
|
-DCORE_DEBUG_LEVEL=0
|
||||||
|
-DNDEBUG
|
||||||
|
-DFP_IN_IROM
|
||||||
|
-DBEARSSL_SSL_BASIC
|
||||||
|
-DVTABLES_IN_FLASH
|
||||||
|
-DPSTR_ALIGN=1 ; remove the 4-bytes alignment for PSTR()
|
||||||
|
-std=c17
|
||||||
|
-std=c++17
|
||||||
|
-std=gnu++17
|
||||||
|
|
||||||
debug_flags =
|
debug_flags =
|
||||||
; -D EMSESP_DEBUG
|
; -D EMSESP_DEBUG
|
||||||
; -D EMSESP_UART_DEBUG
|
; -D EMSESP_UART_DEBUG
|
||||||
@@ -17,8 +33,8 @@ debug_flags =
|
|||||||
; -D EMSESP_FORCE_SERIAL
|
; -D EMSESP_FORCE_SERIAL
|
||||||
; -D ENABLE_CORS
|
; -D ENABLE_CORS
|
||||||
|
|
||||||
; default platformio compile flags are: -fno-rtti -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functions=4 -ffunction-sections -fdata-sections -fno-exceptions -Wall
|
|
||||||
build_flags =
|
build_flags =
|
||||||
|
${common.core_build_flags}
|
||||||
${factory_settings.build_flags}
|
${factory_settings.build_flags}
|
||||||
-D FT_PROJECT=1
|
-D FT_PROJECT=1
|
||||||
-D FT_SECURITY=1
|
-D FT_SECURITY=1
|
||||||
@@ -31,6 +47,10 @@ build_flags =
|
|||||||
-D ARDUINOJSON_ENABLE_STD_STRING=1
|
-D ARDUINOJSON_ENABLE_STD_STRING=1
|
||||||
-D PROGMEM_WWW
|
-D PROGMEM_WWW
|
||||||
-D CORS_ORIGIN=\"http://localhost:3000\"
|
-D CORS_ORIGIN=\"http://localhost:3000\"
|
||||||
|
|
||||||
|
build_unflags = -Wall
|
||||||
|
-Wdeprecated-declarations
|
||||||
|
-std=gnu++11
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
@@ -38,6 +58,7 @@ monitor_speed = 115200
|
|||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
build_type = release
|
build_type = release
|
||||||
lib_ldf_mode = chain+
|
lib_ldf_mode = chain+
|
||||||
|
; lib_compat_mode = strict
|
||||||
|
|
||||||
check_tool = cppcheck, clangtidy
|
check_tool = cppcheck, clangtidy
|
||||||
check_severity = high, medium
|
check_severity = high, medium
|
||||||
@@ -72,12 +93,20 @@ extra_scripts =
|
|||||||
scripts/rename_fw.py
|
scripts/rename_fw.py
|
||||||
board = esp12e ; https://github.com/platformio/platform-espressif8266/tree/master/boards
|
board = esp12e ; https://github.com/platformio/platform-espressif8266/tree/master/boards
|
||||||
platform = espressif8266 ; https://github.com/platformio/platform-espressif8266/releases
|
platform = espressif8266 ; https://github.com/platformio/platform-espressif8266/releases
|
||||||
|
platform_packages = platformio/framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git
|
||||||
|
; toolchain-xtensa @ ~2.100100.200706
|
||||||
|
; toolchain-xtensa @ 2.40802.200502
|
||||||
|
; toolchain-xtensa @ https://github.com/earlephilhower/esp-quick-toolchain/releases/download/3.0.0-gnu12/x86_64-linux-gnu.xtensa-lx106-elf-0474ae9.200706.tar.gz
|
||||||
|
; platformio/tool-esptool @ 1.413.0
|
||||||
|
; platformio/tool-esptoolpy @ ~1.30000.0
|
||||||
|
mcspr/toolchain-xtensa @ 5.100200.201223
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
board_build.f_cpu = 160000000L ; 160MHz
|
board_build.f_cpu = 160000000L ; 160MHz
|
||||||
; eagle.flash.4m1m.ld = 1019 KB sketch, 1000 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 2052 KB OTA & buffer
|
; eagle.flash.4m1m.ld = 1019 KB sketch, 1000 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 2052 KB OTA & buffer
|
||||||
; eagle.flash.4m2m.ld = 1019 KB sketch, 2024 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 1028 KB OTA & buffer
|
; eagle.flash.4m2m.ld = 1019 KB sketch, 2024 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 1028 KB OTA & buffer
|
||||||
; board_build.ldscript = eagle.flash.4m2m.ld
|
; board_build.ldscript = eagle.flash.4m2m.ld
|
||||||
build_flags = ${common.build_flags} ${common.debug_flags}
|
build_flags = ${common.build_flags} ${common.debug_flags}
|
||||||
|
build_unflags = ${common.build_unflags}
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
AsyncTCP
|
AsyncTCP
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WebAPIService.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "command.h"
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "system.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WebDevicesService.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WebSettingsService.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WebStatusService.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ namespace emsesp {
|
|||||||
|
|
||||||
uuid::log::Logger Command::logger_{F_(command), uuid::log::Facility::DAEMON};
|
uuid::log::Logger Command::logger_{F_(command), uuid::log::Facility::DAEMON};
|
||||||
|
|
||||||
std::vector<Command::CmdFunction> Command::cmdfunctions_;
|
static emsesp::array<Command::CmdFunction> cmdfunctions_(90, 255, 16); // reserve space for 90 commands
|
||||||
|
|
||||||
|
emsesp::array<Command::CmdFunction> * Command::commands() {
|
||||||
|
return &cmdfunctions_;
|
||||||
|
}
|
||||||
|
|
||||||
// calls a command
|
// calls a command
|
||||||
// id may be used to represent a heating circuit for example
|
// id may be used to represent a heating circuit for example
|
||||||
@@ -85,12 +89,19 @@ bool Command::call(const uint8_t device_type, const char * cmd, const char * val
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add a command to the list, which does not return json
|
// add a command to the list, which does not return json
|
||||||
void Command::add(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb) {
|
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb) {
|
||||||
// if the command already exists for that device type don't add it
|
// if the command already exists for that device type don't add it
|
||||||
if (find_command(device_type, uuid::read_flash_string(cmd).c_str()) != nullptr) {
|
if (find_command(device_type, uuid::read_flash_string(cmd).c_str()) != nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmdfunctions_.emplace_back(device_type, cmd, cb, nullptr);
|
|
||||||
|
CmdFunction cf;
|
||||||
|
cf.cmd_ = cmd;
|
||||||
|
cf.device_type_ = device_type;
|
||||||
|
cf.cmdfunction_json_ = nullptr; // empty
|
||||||
|
cf.cmdfunction_ = cb;
|
||||||
|
cmdfunctions_.push(cf);
|
||||||
|
// cmdfunctions_.emplace_back(device_type, cmd, cb, nullptr);
|
||||||
|
|
||||||
// see if we need to subscribe
|
// see if we need to subscribe
|
||||||
if (Mqtt::enabled()) {
|
if (Mqtt::enabled()) {
|
||||||
@@ -105,7 +116,14 @@ void Command::add_with_json(const uint8_t device_type, const __FlashStringHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdfunctions_.emplace_back(device_type, cmd, nullptr, cb); // add command
|
CmdFunction cf;
|
||||||
|
cf.cmd_ = cmd;
|
||||||
|
cf.device_type_ = device_type;
|
||||||
|
cf.cmdfunction_json_ = cb;
|
||||||
|
cf.cmdfunction_ = nullptr; // empty
|
||||||
|
cmdfunctions_.push(cf);
|
||||||
|
|
||||||
|
// cmdfunctions_.emplace_back(device_type, cmd, nullptr, cb); // add command
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if a command exists for that device type
|
// see if a command exists for that device type
|
||||||
@@ -132,11 +150,11 @@ Command::CmdFunction * Command::find_command(const uint8_t device_type, const ch
|
|||||||
|
|
||||||
// output list of all commands to console for a specific DeviceType
|
// output list of all commands to console for a specific DeviceType
|
||||||
void Command::show(uuid::console::Shell & shell, uint8_t device_type) {
|
void Command::show(uuid::console::Shell & shell, uint8_t device_type) {
|
||||||
if (commands().empty()) {
|
if (cmdfunctions_.empty()) {
|
||||||
shell.println(F("No commands"));
|
shell.println(F("No commands"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & cf : Command::commands()) {
|
for (const auto & cf : cmdfunctions_) {
|
||||||
if (cf.device_type_ == device_type) {
|
if (cf.device_type_ == device_type) {
|
||||||
shell.printf("%s ", uuid::read_flash_string(cf.cmd_).c_str());
|
shell.printf("%s ", uuid::read_flash_string(cf.cmd_).c_str());
|
||||||
}
|
}
|
||||||
@@ -162,7 +180,7 @@ bool Command::device_has_commands(const uint8_t device_type) {
|
|||||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||||
if ((emsdevice) && (emsdevice->device_type() == device_type)) {
|
if ((emsdevice) && (emsdevice->device_type() == device_type)) {
|
||||||
// device found, now see if it has any commands
|
// device found, now see if it has any commands
|
||||||
for (const auto & cf : Command::commands()) {
|
for (const auto & cf : cmdfunctions_) {
|
||||||
if (cf.device_type_ == device_type) {
|
if (cf.device_type_ == device_type) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include "containers.h"
|
||||||
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
#include <uuid/log.h>
|
#include <uuid/log.h>
|
||||||
@@ -44,22 +46,13 @@ class Command {
|
|||||||
const __FlashStringHelper * cmd_;
|
const __FlashStringHelper * cmd_;
|
||||||
cmdfunction_p cmdfunction_;
|
cmdfunction_p cmdfunction_;
|
||||||
cmdfunction_json_p cmdfunction_json_;
|
cmdfunction_json_p cmdfunction_json_;
|
||||||
|
|
||||||
CmdFunction(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cmdfunction, cmdfunction_json_p cmdfunction_json)
|
|
||||||
: device_type_(device_type)
|
|
||||||
, cmd_(cmd)
|
|
||||||
, cmdfunction_(cmdfunction)
|
|
||||||
, cmdfunction_json_(cmdfunction_json) {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<CmdFunction> commands() {
|
static emsesp::array<Command::CmdFunction> * commands();
|
||||||
return cmdfunctions_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & json);
|
static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & json);
|
||||||
static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id);
|
static bool call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id);
|
||||||
static void add(const uint8_t device_type, const uint8_t device_id, const __FlashStringHelper * cmd, cmdfunction_p cb);
|
static void add(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb);
|
||||||
static void add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb);
|
static void add_with_json(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_json_p cb);
|
||||||
static void show_all(uuid::console::Shell & shell);
|
static void show_all(uuid::console::Shell & shell);
|
||||||
static Command::CmdFunction * find_command(const uint8_t device_type, const char * cmd);
|
static Command::CmdFunction * find_command(const uint8_t device_type, const char * cmd);
|
||||||
@@ -68,8 +61,6 @@ class Command {
|
|||||||
static void show_devices(uuid::console::Shell & shell);
|
static void show_devices(uuid::console::Shell & shell);
|
||||||
static bool device_has_commands(const uint8_t device_type);
|
static bool device_has_commands(const uint8_t device_type);
|
||||||
|
|
||||||
static std::vector<CmdFunction> cmdfunctions_; // list of commands
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -422,7 +422,7 @@ void EMSESPShell::add_console_commands() {
|
|||||||
std::vector<std::string> command_list;
|
std::vector<std::string> command_list;
|
||||||
uint8_t device_type = EMSdevice::device_name_2_device_type(arguments[0].c_str());
|
uint8_t device_type = EMSdevice::device_name_2_device_type(arguments[0].c_str());
|
||||||
if (Command::device_has_commands(device_type)) {
|
if (Command::device_has_commands(device_type)) {
|
||||||
for (const auto & cf : Command::commands()) {
|
for (const auto & cf : *Command::commands()) {
|
||||||
if (cf.device_type_ == device_type) {
|
if (cf.device_type_ == device_type) {
|
||||||
command_list.emplace_back(uuid::read_flash_string(cf.cmd_));
|
command_list.emplace_back(uuid::read_flash_string(cf.cmd_));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,9 +46,11 @@ using uuid::log::Level;
|
|||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// strings stored 32 bit aligned on ESP8266/ESP32
|
// strings stored 32 bit aligned on ESP8266/ESP32
|
||||||
#define MAKE_PSTR(string_name, string_literal) static const char __pstr__##string_name[] __attribute__((__aligned__(sizeof(int)))) PROGMEM = string_literal;
|
#define MAKE_PSTR(string_name, string_literal) static const char __pstr__##string_name[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = string_literal;
|
||||||
#define MAKE_PSTR_WORD(string_name) MAKE_PSTR(string_name, #string_name)
|
#define MAKE_PSTR_WORD(string_name) MAKE_PSTR(string_name, #string_name)
|
||||||
#define F_(string_name) FPSTR(__pstr__##string_name)
|
#define F_(string_name) FPSTR(__pstr__##string_name)
|
||||||
|
#define MAKE_PSTR_LIST(list_name, ...) static const __FlashStringHelper * const __pstr__##list_name[] PROGMEM = {__VA_ARGS__, nullptr};
|
||||||
|
#define FL_(list_name) (__pstr__##list_name)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// localizations
|
// localizations
|
||||||
@@ -58,7 +60,7 @@ using uuid::log::Level;
|
|||||||
#undef LOCAL
|
#undef LOCAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static constexpr uint32_t INVALID_PASSWORD_DELAY_MS = 3000;
|
static constexpr uint32_t INVALID_PASSWORD_DELAY_MS = 2000;
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
448
src/containers.h
Normal file
448
src/containers.h
Normal file
@@ -0,0 +1,448 @@
|
|||||||
|
/*
|
||||||
|
* EMS-ESP - https://github.com/proddy/EMS-ESP
|
||||||
|
* Copyright 2020 Paul Derbyshire
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lightweight queue & array
|
||||||
|
* Based ideas from https://github.com/muwerk/ustd
|
||||||
|
* Limits to max 255 entries
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMSESP_CONTAINERS_H
|
||||||
|
#define EMSESP_CONTAINERS_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if defined EMSESP_ASSERT
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace emsesp {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class queueIterator {
|
||||||
|
public:
|
||||||
|
queueIterator(T * values_ptr, uint8_t p)
|
||||||
|
: values_ptr_{values_ptr}
|
||||||
|
, position_{p} {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const queueIterator<T> & other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const queueIterator<T> & other) const {
|
||||||
|
return position_ == other.position_;
|
||||||
|
}
|
||||||
|
|
||||||
|
queueIterator & operator++() {
|
||||||
|
++position_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator*() const {
|
||||||
|
return *(values_ptr_ + position_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T * values_ptr_;
|
||||||
|
uint8_t position_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class queue {
|
||||||
|
private:
|
||||||
|
T * que_;
|
||||||
|
uint8_t peakSize_;
|
||||||
|
uint8_t maxSize_;
|
||||||
|
uint8_t size_;
|
||||||
|
uint8_t quePtrFront_; // back
|
||||||
|
uint8_t quePtrBack_; // front
|
||||||
|
T bad_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructs a queue object with the maximum number of <T> pointer entries
|
||||||
|
queue(uint8_t maxQueueSize)
|
||||||
|
: maxSize_(maxQueueSize) {
|
||||||
|
memset(&bad_, 0, sizeof(bad_));
|
||||||
|
quePtrFront_ = 0;
|
||||||
|
quePtrBack_ = 0;
|
||||||
|
size_ = 0;
|
||||||
|
peakSize_ = 0;
|
||||||
|
que_ = (T *)malloc(sizeof(T) * maxSize_);
|
||||||
|
if (que_ == nullptr)
|
||||||
|
maxSize_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deallocate the queue structure
|
||||||
|
~queue() {
|
||||||
|
if (que_ != nullptr) {
|
||||||
|
free(que_);
|
||||||
|
que_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push a new entry into the queue.
|
||||||
|
// true on success, false if queue is full, then the element is relaced with the front one
|
||||||
|
bool push(T ent) {
|
||||||
|
// Serial.print("quePtrFront_: ");
|
||||||
|
// Serial.print(quePtrFront_);
|
||||||
|
// Serial.print(" quePtrBack_: ");
|
||||||
|
// Serial.print(quePtrBack_);
|
||||||
|
// Serial.println();
|
||||||
|
if (size_ >= maxSize_) {
|
||||||
|
// que_[quePtrFront_] = ent;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
que_[quePtrBack_] = ent;
|
||||||
|
quePtrBack_ = (quePtrBack_ + 1) % maxSize_;
|
||||||
|
++size_;
|
||||||
|
if (size_ > peakSize_) {
|
||||||
|
peakSize_ = size_;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool push_back(T ent) {
|
||||||
|
return push(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push a new entry into the front of queue, moving the rest down
|
||||||
|
// true on success, false if queue is full
|
||||||
|
// there are no good checks for overflow
|
||||||
|
bool push_front(T ent) {
|
||||||
|
if (size_ >= maxSize_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Serial.print("quePtrFront_: ");
|
||||||
|
// Serial.print(quePtrFront_);
|
||||||
|
// Serial.print(" quePtrBack_: ");
|
||||||
|
// Serial.print(quePtrBack_);
|
||||||
|
// Serial.println();
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i <= size_; i++) {
|
||||||
|
que_[quePtrBack_ - i + 1] = que_[quePtrBack_ - i]; // move the rest up 1
|
||||||
|
}
|
||||||
|
que_[quePtrFront_] = ent; // add the new one
|
||||||
|
quePtrBack_ = (quePtrBack_ + 1) % maxSize_;
|
||||||
|
++size_;
|
||||||
|
if (size_ > peakSize_) {
|
||||||
|
peakSize_ = size_;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator[](uint8_t i) {
|
||||||
|
return que_[i + quePtrFront_];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop the oldest entry from the queue
|
||||||
|
T pop() {
|
||||||
|
if (size_ == 0)
|
||||||
|
return bad_;
|
||||||
|
T ent = que_[quePtrFront_];
|
||||||
|
quePtrFront_ = (quePtrFront_ + 1) % maxSize_;
|
||||||
|
--size_;
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alias pop_front to keep backwards compatibility with std::list/queue
|
||||||
|
T pop_front() {
|
||||||
|
return pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
T front() {
|
||||||
|
return que_[quePtrFront_];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t front_i() {
|
||||||
|
return quePtrFront_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T * front_p() {
|
||||||
|
return &que_[quePtrFront_];
|
||||||
|
}
|
||||||
|
|
||||||
|
T back() {
|
||||||
|
return que_[quePtrBack_];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the value for <T>entry that's given back, if read from an empty
|
||||||
|
// queue is requested. By default, an entry all memset to zero is given
|
||||||
|
// back. Using this function, the value of an invalid read can be configured
|
||||||
|
void setInvalidValue(T & entryInvalidValue) {
|
||||||
|
bad_ = entryInvalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns true: queue empty, false: not empty
|
||||||
|
bool empty() {
|
||||||
|
if (size_ == 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns number of entries in the queue
|
||||||
|
uint8_t size() {
|
||||||
|
return (size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// max number of queue entries that have been in the queue
|
||||||
|
uint8_t peak() {
|
||||||
|
return (peakSize_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterators
|
||||||
|
queueIterator<T> begin() {
|
||||||
|
return queueIterator<T>(que_, quePtrFront_);
|
||||||
|
}
|
||||||
|
queueIterator<T> end() {
|
||||||
|
return queueIterator<T>(que_, quePtrFront_ + size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
queueIterator<const T> begin() const {
|
||||||
|
return queueIterator<const T>(que_, quePtrFront_);
|
||||||
|
}
|
||||||
|
|
||||||
|
queueIterator<const T> end() const {
|
||||||
|
return queueIterator<const T>(que_, quePtrFront_ + size_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class arrayIterator {
|
||||||
|
public:
|
||||||
|
arrayIterator(T * values_ptr)
|
||||||
|
: values_ptr_{values_ptr}
|
||||||
|
, position_{0} {
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayIterator(T * values_ptr, size_t size_)
|
||||||
|
: values_ptr_{values_ptr}
|
||||||
|
, position_{size_} {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const arrayIterator<T> & other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const arrayIterator<T> & other) const {
|
||||||
|
return position_ == other.position_;
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayIterator & operator++() {
|
||||||
|
++position_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator*() const {
|
||||||
|
return *(values_ptr_ + position_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T * values_ptr_;
|
||||||
|
size_t position_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ARRAY_INIT_SIZE 16
|
||||||
|
#define ARRAY_MAX_SIZE 255 // fixed for uint8_t
|
||||||
|
#define ARRAY_INC_SIZE 16
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class array {
|
||||||
|
private:
|
||||||
|
T * arr_;
|
||||||
|
uint8_t startSize_;
|
||||||
|
uint8_t maxSize_;
|
||||||
|
uint8_t incSize_ = ARRAY_INC_SIZE;
|
||||||
|
uint8_t allocSize_;
|
||||||
|
uint8_t size_;
|
||||||
|
T bad_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructs an array object. All allocation-hints are optional, the
|
||||||
|
// array class will allocate memory as needed during writes, if
|
||||||
|
// startSize_!=maxSize_.
|
||||||
|
// @param startSize_ The number of array entries that are allocated
|
||||||
|
// during object creation
|
||||||
|
// @param maxSize_ The maximal limit of records that will be allocated.
|
||||||
|
// If startSize_ < maxSize_, the array size_ will grow automatically as
|
||||||
|
// needed.
|
||||||
|
// @param incSize_ The number of array entries that are allocated as a
|
||||||
|
// chunk if the array needs to grow
|
||||||
|
array(uint8_t startSize_ = ARRAY_INIT_SIZE, uint8_t maxSize_ = ARRAY_MAX_SIZE, uint8_t incSize_ = ARRAY_INC_SIZE)
|
||||||
|
: startSize_(startSize_)
|
||||||
|
, maxSize_(maxSize_)
|
||||||
|
, incSize_(incSize_) {
|
||||||
|
size_ = 0;
|
||||||
|
memset(&bad_, 0, sizeof(bad_));
|
||||||
|
if (maxSize_ < startSize_)
|
||||||
|
maxSize_ = startSize_;
|
||||||
|
allocSize_ = startSize_;
|
||||||
|
arr_ = new T[allocSize_];
|
||||||
|
}
|
||||||
|
|
||||||
|
~array() {
|
||||||
|
/*! Free resources */
|
||||||
|
if (arr_ != nullptr) {
|
||||||
|
delete[] arr_;
|
||||||
|
arr_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the array allocation size_. the new number of array entries, corresponding memory is allocated/free'd as necessary.
|
||||||
|
bool resize(uint8_t newSize) {
|
||||||
|
uint8_t mv = newSize;
|
||||||
|
if (newSize > maxSize_) {
|
||||||
|
if (maxSize_ == allocSize_)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
newSize = maxSize_;
|
||||||
|
}
|
||||||
|
if (newSize <= allocSize_)
|
||||||
|
return true;
|
||||||
|
T * arrn = new T[newSize];
|
||||||
|
if (arrn == nullptr)
|
||||||
|
return false;
|
||||||
|
for (uint8_t i = 0; i < mv; i++) {
|
||||||
|
arrn[i] = arr_[i];
|
||||||
|
}
|
||||||
|
delete[] arr_;
|
||||||
|
arr_ = arrn;
|
||||||
|
allocSize_ = newSize;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the value for <T>entry that's given back,
|
||||||
|
// if read of an invalid index is requested.
|
||||||
|
// By default, an entry all memset to zero is given
|
||||||
|
// back. Using this function, the value of an invalid read can be configured.
|
||||||
|
// returns the value that is given back in case an invalid operation (e.g. read out of bounds) is tried
|
||||||
|
void setInvalidValue(T & entryInvalidValue) {
|
||||||
|
bad_ = entryInvalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append an array element after the current end of the array
|
||||||
|
// takes entry array element that is appended after the last current
|
||||||
|
// entry. The new array size_ must be smaller than maxSize_ as defined
|
||||||
|
// during array creation. New array memory is automatically allocated if
|
||||||
|
// within maxSize_ boundaries
|
||||||
|
int push(T & entry) {
|
||||||
|
if (size_ >= allocSize_) {
|
||||||
|
if (incSize_ == 0)
|
||||||
|
return -1;
|
||||||
|
if (!resize(allocSize_ + incSize_))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
arr_[size_] = entry;
|
||||||
|
++size_;
|
||||||
|
return size_ - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign content of array element at i for const's
|
||||||
|
T operator[](uint8_t i) const {
|
||||||
|
if (i >= allocSize_) {
|
||||||
|
if (incSize_ == 0) {
|
||||||
|
#ifdef EMSESP_ASSERT
|
||||||
|
assert(i < allocSize_);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!resize(allocSize_ + incSize_)) {
|
||||||
|
#ifdef EMSESP_ASSERT
|
||||||
|
assert(i < allocSize_);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= size_ && i <= allocSize_)
|
||||||
|
size_ = i + 1;
|
||||||
|
if (i >= allocSize_) {
|
||||||
|
return bad_;
|
||||||
|
}
|
||||||
|
return arr_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign content of array element at i
|
||||||
|
T & operator[](uint8_t i) {
|
||||||
|
if (i >= allocSize_) {
|
||||||
|
if (incSize_ == 0) {
|
||||||
|
#ifdef EMSESP_ASSERT
|
||||||
|
assert(i < allocSize_);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!resize(allocSize_ + incSize_)) {
|
||||||
|
#ifdef EMSESP_ASSERT
|
||||||
|
assert(i < allocSize_);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= size_ && i <= allocSize_)
|
||||||
|
size_ = i + 1;
|
||||||
|
if (i >= allocSize_) {
|
||||||
|
return bad_;
|
||||||
|
}
|
||||||
|
return arr_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// true if array empty, false otherwise
|
||||||
|
bool empty() const {
|
||||||
|
if (size_ == 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return number of array elements
|
||||||
|
uint8_t size() const {
|
||||||
|
return (size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns number of allocated entries which can be larger than the length of the array
|
||||||
|
uint8_t alloclen() const {
|
||||||
|
return (allocSize_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// emplace
|
||||||
|
// template <typename... Args>
|
||||||
|
// void emplace1(Args... args) {
|
||||||
|
// add(args...);
|
||||||
|
// };
|
||||||
|
// template <class... Args>
|
||||||
|
// void emplace(Args &&... args) {
|
||||||
|
// add(T(std::forward<Args>(args)...));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// iterators
|
||||||
|
arrayIterator<T> begin() {
|
||||||
|
return arrayIterator<T>(arr_);
|
||||||
|
}
|
||||||
|
arrayIterator<T> end() {
|
||||||
|
return arrayIterator<T>(arr_, size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayIterator<const T> begin() const {
|
||||||
|
return arrayIterator<const T>(arr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayIterator<const T> end() const {
|
||||||
|
return arrayIterator<const T>(arr_, size_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace emsesp
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -26,11 +26,11 @@ uuid::log::Logger Boiler::logger_{F_(boiler), uuid::log::Facility::CONSOLE};
|
|||||||
|
|
||||||
Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||||
reserve_mem(20); // reserve some space for the telegram registries, to avoid memory fragmentation
|
|
||||||
|
|
||||||
LOG_DEBUG(F("Adding new Boiler with device ID 0x%02X"), device_id);
|
LOG_DEBUG(F("Adding new Boiler with device ID 0x%02X"), device_id);
|
||||||
|
|
||||||
System::show_mem("starting boiler regs"); // TODO remove debug
|
reserve_telgram_functions(25); // reserve some space for the telegram registries, to avoid memory fragmentation
|
||||||
|
|
||||||
|
System::show_mem("starting boiler regs");
|
||||||
|
|
||||||
// the telegram handlers...
|
// the telegram handlers...
|
||||||
register_telegram_type(0x10, F("UBAErrorMessage1"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAErrorMessage(t); });
|
register_telegram_type(0x10, F("UBAErrorMessage1"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAErrorMessage(t); });
|
||||||
@@ -60,7 +60,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
|||||||
EMSESP::send_read_request(0x11, device_id); // read last errorcode on start (only published on errors)
|
EMSESP::send_read_request(0x11, device_id); // read last errorcode on start (only published on errors)
|
||||||
EMSESP::send_read_request(0x15, device_id); // read maintenace data on start (only published on change)
|
EMSESP::send_read_request(0x15, device_id); // read maintenace data on start (only published on change)
|
||||||
|
|
||||||
System::show_mem("after telegram type reg"); // TODO remove debug
|
System::show_mem("after telegram type reg");
|
||||||
|
|
||||||
// MQTT commands for boiler topic
|
// MQTT commands for boiler topic
|
||||||
register_mqtt_cmd(F("comfort"), [&](const char * value, const int8_t id) { return set_warmwater_mode(value, id); });
|
register_mqtt_cmd(F("comfort"), [&](const char * value, const int8_t id) { return set_warmwater_mode(value, id); });
|
||||||
@@ -80,407 +80,438 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
|||||||
register_mqtt_cmd(F("boilhystoff"), [&](const char * value, const int8_t id) { return set_hyst_off(value, id); });
|
register_mqtt_cmd(F("boilhystoff"), [&](const char * value, const int8_t id) { return set_hyst_off(value, id); });
|
||||||
register_mqtt_cmd(F("burnperiod"), [&](const char * value, const int8_t id) { return set_burn_period(value, id); });
|
register_mqtt_cmd(F("burnperiod"), [&](const char * value, const int8_t id) { return set_burn_period(value, id); });
|
||||||
register_mqtt_cmd(F("pumpdelay"), [&](const char * value, const int8_t id) { return set_pump_delay(value, id); });
|
register_mqtt_cmd(F("pumpdelay"), [&](const char * value, const int8_t id) { return set_pump_delay(value, id); });
|
||||||
// register_mqtt_cmd(F("reset"), [&](const char * value, const int8_t id) { return set_reset(value, id); });
|
|
||||||
register_mqtt_cmd(F("maintenance"), [&](const char * value, const int8_t id) { return set_maintenance(value, id); });
|
register_mqtt_cmd(F("maintenance"), [&](const char * value, const int8_t id) { return set_maintenance(value, id); });
|
||||||
register_mqtt_cmd(F("pumpmodmax"), [&](const char * value, const int8_t id) { return set_max_pump(value, id); });
|
register_mqtt_cmd(F("pumpmodmax"), [&](const char * value, const int8_t id) { return set_max_pump(value, id); });
|
||||||
register_mqtt_cmd(F("pumpmodmin"), [&](const char * value, const int8_t id) { return set_min_pump(value, id); });
|
register_mqtt_cmd(F("pumpmodmin"), [&](const char * value, const int8_t id) { return set_min_pump(value, id); });
|
||||||
|
// register_mqtt_cmd(F("reset"), [&](const char * value, const int8_t id) { return set_reset(value, id); });
|
||||||
|
|
||||||
System::show_mem("after mqtt cmd reg"); // TODO remove debug
|
System::show_mem("after mqtt cmd reg");
|
||||||
|
|
||||||
// add values
|
// add values
|
||||||
|
reserve_device_values(50);
|
||||||
// init_devicevalues(30); // TODO reserve mem
|
|
||||||
|
|
||||||
// main - boiler_data topic
|
// main - boiler_data topic
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &heatingActive_, DeviceValueType::BOOL, {}, F("heatingActive"), F("Heating active"), DeviceValueUOM::NONE);
|
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &tapwaterActive_, DeviceValueType::BOOL, {}, F("tapwaterActive"), F("Warm water/DHW active"), DeviceValueUOM::NONE);
|
DeviceValueTAG::TAG_BOILER_DATA, &heatingActive_, DeviceValueType::BOOL, nullptr, F("heatingActive"), F("Heating active"), DeviceValueUOM::NONE);
|
||||||
register_device_value(
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &selFlowTemp_, DeviceValueType::UINT, {}, F("selFlowTemp"), F("Selected flow temperature"), DeviceValueUOM::DEGREES);
|
&tapwaterActive_,
|
||||||
register_device_value(
|
DeviceValueType::BOOL,
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &selBurnPow_, DeviceValueType::UINT, {}, F("selBurnPow"), F("Burner selected max power"), DeviceValueUOM::PERCENT);
|
nullptr,
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpMod_, DeviceValueType::UINT, {}, F("pumpMod"), F("Pump modulation"), DeviceValueUOM::PERCENT);
|
F("tapwaterActive"),
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpMod2_, DeviceValueType::UINT, {}, F("pumpMod2"), F("Heat pump modulation"), DeviceValueUOM::PERCENT);
|
F("Warm water/DHW active"),
|
||||||
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(TAG_BOILER_DATA,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
&outdoorTemp_,
|
&selFlowTemp_,
|
||||||
DeviceValueType::SHORT,
|
DeviceValueType::UINT,
|
||||||
flash_string_vector{F("10")},
|
nullptr,
|
||||||
F("outdoorTemp"),
|
F("selFlowTemp"),
|
||||||
F("Outside temperature"),
|
F("Selected flow temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
|
&selBurnPow_,
|
||||||
|
DeviceValueType::UINT,
|
||||||
|
nullptr,
|
||||||
|
F("selBurnPow"),
|
||||||
|
F("Burner selected max power"),
|
||||||
|
DeviceValueUOM::PERCENT);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpMod_, DeviceValueType::UINT, nullptr, F("pumpMod"), F("Pump modulation"), DeviceValueUOM::PERCENT);
|
||||||
|
register_device_value(
|
||||||
|
DeviceValueTAG::TAG_BOILER_DATA, &pumpMod2_, DeviceValueType::UINT, nullptr, F("pumpMod2"), F("Heat pump modulation"), DeviceValueUOM::PERCENT);
|
||||||
|
|
||||||
|
register_device_value(TAG_BOILER_DATA, &outdoorTemp_, DeviceValueType::SHORT, FL_(div10), F("outdoorTemp"), F("Outside temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
&curFlowTemp_,
|
&curFlowTemp_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("curFlowTemp"),
|
F("curFlowTemp"),
|
||||||
F("Current flow temperature"),
|
F("Current flow temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
register_device_value(
|
||||||
&retTemp_,
|
DeviceValueTAG::TAG_BOILER_DATA, &retTemp_, DeviceValueType::USHORT, FL_(div10), F("retTemp"), F("Return temperature"), DeviceValueUOM::DEGREES);
|
||||||
DeviceValueType::USHORT,
|
|
||||||
flash_string_vector{F("10")},
|
|
||||||
F("retTemp"),
|
|
||||||
F("Return temperature"),
|
|
||||||
DeviceValueUOM::DEGREES);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
&switchTemp_,
|
&switchTemp_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("switchTemp"),
|
F("switchTemp"),
|
||||||
F("Mixing switch temperature"),
|
F("Mixing switch temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &sysPress_, DeviceValueType::UINT, FL_(div10), F("sysPress"), F("System pressure"), DeviceValueUOM::BAR);
|
||||||
&sysPress_,
|
register_device_value(TAG_BOILER_DATA, &boilTemp_, DeviceValueType::USHORT, FL_(div10), F("boilTemp"), F("Max boiler temperature"), DeviceValueUOM::DEGREES);
|
||||||
DeviceValueType::UINT,
|
register_device_value(TAG_BOILER_DATA, &exhaustTemp_, DeviceValueType::USHORT, FL_(div10), F("exhaustTemp"), F("Exhaust temperature"), DeviceValueUOM::DEGREES);
|
||||||
flash_string_vector{F("10")},
|
|
||||||
F("sysPress"),
|
|
||||||
F("System pressure"),
|
|
||||||
DeviceValueUOM::BAR);
|
|
||||||
register_device_value(TAG_BOILER_DATA,
|
|
||||||
&boilTemp_,
|
|
||||||
DeviceValueType::USHORT,
|
|
||||||
flash_string_vector{F("10")},
|
|
||||||
F("boilTemp"),
|
|
||||||
F("Max boiler temperature"),
|
|
||||||
DeviceValueUOM::DEGREES);
|
|
||||||
register_device_value(TAG_BOILER_DATA,
|
|
||||||
&exhaustTemp_,
|
|
||||||
DeviceValueType::USHORT,
|
|
||||||
flash_string_vector{F("10")},
|
|
||||||
F("exhaustTemp"),
|
|
||||||
F("Exhaust temperature"),
|
|
||||||
DeviceValueUOM::DEGREES);
|
|
||||||
|
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnGas_, DeviceValueType::BOOL, {}, F("burnGas"), F("Gas"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnGas_, DeviceValueType::BOOL, nullptr, F("burnGas"), F("Gas"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &flameCurr_, DeviceValueType::USHORT, {F("10")}, F("flameCurr"), F("Flame current"), DeviceValueUOM::UA);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &flameCurr_, DeviceValueType::USHORT, FL_(div10), F("flameCurr"), F("Flame current"), DeviceValueUOM::UA);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &heatPump_, DeviceValueType::BOOL, {}, F("heatPump"), F("Heat pump"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &heatPump_, DeviceValueType::BOOL, nullptr, F("heatPump"), F("Heat pump"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &fanWork_, DeviceValueType::BOOL, {}, F("fanWork"), F("Fan"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &fanWork_, DeviceValueType::BOOL, nullptr, F("fanWork"), F("Fan"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &ignWork_, DeviceValueType::BOOL, {}, F("ignWork"), F("Ignition"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &ignWork_, DeviceValueType::BOOL, nullptr, F("ignWork"), F("Ignition"), DeviceValueUOM::NONE);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
|
&heatingActivated_,
|
||||||
|
DeviceValueType::BOOL,
|
||||||
|
nullptr,
|
||||||
|
F("heatingActivated"),
|
||||||
|
F("Heating activated"),
|
||||||
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &heatingActivated_, DeviceValueType::BOOL, {}, F("heatingActivated"), F("Heating activated"), DeviceValueUOM::NONE);
|
DeviceValueTAG::TAG_BOILER_DATA, &heatingTemp_, DeviceValueType::UINT, nullptr, F("heatingTemp"), F("Heating temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &heatingTemp_, DeviceValueType::UINT, {}, F("heatingTemp"), F("Heating temperature"), DeviceValueUOM::DEGREES);
|
DeviceValueTAG::TAG_BOILER_DATA, &pumpModMax_, DeviceValueType::UINT, nullptr, F("pumpModMax"), F("Burner pump max power"), DeviceValueUOM::PERCENT);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &pumpModMax_, DeviceValueType::UINT, {}, F("pumpModMax"), F("Burner pump max power"), DeviceValueUOM::PERCENT);
|
DeviceValueTAG::TAG_BOILER_DATA, &pumpModMin_, DeviceValueType::UINT, nullptr, F("pumpModMin"), F("Burner pump min power"), DeviceValueUOM::PERCENT);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpDelay_, DeviceValueType::UINT, nullptr, F("pumpDelay"), F("Pump delay"), DeviceValueUOM::MINUTES);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &pumpModMin_, DeviceValueType::UINT, {}, F("pumpModMin"), F("Burner pump min power"), DeviceValueUOM::PERCENT);
|
DeviceValueTAG::TAG_BOILER_DATA, &burnMinPeriod_, DeviceValueType::UINT, nullptr, F("burnMinPeriod"), F("Burner min period"), DeviceValueUOM::MINUTES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &pumpDelay_, DeviceValueType::UINT, {}, F("pumpDelay"), F("Pump delay"), DeviceValueUOM::MINUTES);
|
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &burnMinPeriod_, DeviceValueType::UINT, {}, F("burnMinPeriod"), F("Burner min period"), DeviceValueUOM::MINUTES);
|
DeviceValueTAG::TAG_BOILER_DATA, &burnMinPower_, DeviceValueType::UINT, nullptr, F("burnMinPower"), F("Burner min power"), DeviceValueUOM::PERCENT);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnMinPower_, DeviceValueType::UINT, {}, F("burnMinPower"), F("Burner min power"), DeviceValueUOM::PERCENT);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnMaxPower_, DeviceValueType::UINT, {}, F("burnMaxPower"), F("Burner max power"), DeviceValueUOM::PERCENT);
|
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &boilHystOn_, DeviceValueType::INT, {}, F("boilHystOn"), F("Hysteresis on temperature"), DeviceValueUOM::DEGREES);
|
DeviceValueTAG::TAG_BOILER_DATA, &burnMaxPower_, DeviceValueType::UINT, nullptr, F("burnMaxPower"), F("Burner max power"), DeviceValueUOM::PERCENT);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &boilHystOff_, DeviceValueType::INT, {}, F("boilHystOff"), F("Hysteresis off temperature"), DeviceValueUOM::DEGREES);
|
DeviceValueTAG::TAG_BOILER_DATA, &boilHystOn_, DeviceValueType::INT, nullptr, F("boilHystOn"), F("Hysteresis on temperature"), DeviceValueUOM::DEGREES);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
|
&boilHystOff_,
|
||||||
|
DeviceValueType::INT,
|
||||||
|
nullptr,
|
||||||
|
F("boilHystOff"),
|
||||||
|
F("Hysteresis off temperature"),
|
||||||
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &setFlowTemp_, DeviceValueType::UINT, {}, F("setFlowTemp"), F("Set flow temperature"), DeviceValueUOM::DEGREES);
|
DeviceValueTAG::TAG_BOILER_DATA, &setFlowTemp_, DeviceValueType::UINT, nullptr, F("setFlowTemp"), F("Set flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &setBurnPow_, DeviceValueType::UINT, {}, F("setBurnPow"), F("Burner set power"), DeviceValueUOM::PERCENT);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &curBurnPow_, DeviceValueType::UINT, {}, F("curBurnPow"), F("Burner current power"), DeviceValueUOM::PERCENT);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnStarts_, DeviceValueType::ULONG, {}, F("burnStarts"), F("Burner # starts"), DeviceValueUOM::NONE);
|
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &burnWorkMin_, DeviceValueType::TIME, {}, F("burnWorkMin"), F("Total burner operating time"), DeviceValueUOM::MINUTES);
|
DeviceValueTAG::TAG_BOILER_DATA, &setBurnPow_, DeviceValueType::UINT, nullptr, F("setBurnPow"), F("Burner set power"), DeviceValueUOM::PERCENT);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &heatWorkMin_, DeviceValueType::TIME, {}, F("heatWorkMin"), F("Total heat operating time"), DeviceValueUOM::MINUTES);
|
DeviceValueTAG::TAG_BOILER_DATA, &curBurnPow_, DeviceValueType::UINT, nullptr, F("curBurnPow"), F("Burner current power"), DeviceValueUOM::PERCENT);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &burnStarts_, DeviceValueType::ULONG, nullptr, F("burnStarts"), F("Burner # starts"), DeviceValueUOM::NONE);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
|
&burnWorkMin_,
|
||||||
|
DeviceValueType::TIME,
|
||||||
|
nullptr,
|
||||||
|
F("burnWorkMin"),
|
||||||
|
F("Total burner operating time"),
|
||||||
|
DeviceValueUOM::MINUTES);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
|
&heatWorkMin_,
|
||||||
|
DeviceValueType::TIME,
|
||||||
|
nullptr,
|
||||||
|
F("heatWorkMin"),
|
||||||
|
F("Total heat operating time"),
|
||||||
|
DeviceValueUOM::MINUTES);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA, &UBAuptime_, DeviceValueType::TIME, {}, F("UBAuptime"), F("Total UBA operating time"), DeviceValueUOM::MINUTES);
|
DeviceValueTAG::TAG_BOILER_DATA, &UBAuptime_, DeviceValueType::TIME, nullptr, F("UBAuptime"), F("Total UBA operating time"), DeviceValueUOM::MINUTES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &lastCode_, DeviceValueType::TEXT, {}, F("lastCode"), F("Last error code"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &lastCode_, DeviceValueType::TEXT, nullptr, F("lastCode"), F("Last error code"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &serviceCode_, DeviceValueType::TEXT, {}, F("serviceCode"), F("Service code"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA, &serviceCode_, DeviceValueType::TEXT, nullptr, F("serviceCode"), F("Service code"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA,
|
||||||
&serviceCodeNumber_,
|
&serviceCodeNumber_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
{},
|
nullptr,
|
||||||
F("serviceCodeNumber"),
|
F("serviceCodeNumber"),
|
||||||
F("Service code number"),
|
F("Service code number"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
|
|
||||||
System::show_mem("after device value reg"); // TODO remove debug
|
System::show_mem("after device value reg");
|
||||||
|
|
||||||
#ifdef EMSESP_FORCE_SERIAL
|
return; // TODO early exit for memory profiling on ESP8266
|
||||||
return; // TODO remove early exit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ww - boiler_data_ww topic
|
// ww - boiler_data_ww topic
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWSelTemp_,
|
&wWSelTemp_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{},
|
nullptr,
|
||||||
F("wWSelTemp"),
|
F("wWSelTemp"),
|
||||||
F("Warm Water selected temperature"),
|
F("Warm Water selected temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(
|
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWSetTemp_, DeviceValueType::UINT, {}, F("wWSetTemp"), F("Warm water set temperature"), DeviceValueUOM::DEGREES);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWType_,
|
&wWSetTemp_,
|
||||||
DeviceValueType::ENUM,
|
DeviceValueType::UINT,
|
||||||
flash_string_vector{F("off"), F("flow"), F("buffered flow"), F("buffer"), F("layered buffer")},
|
nullptr,
|
||||||
F("wWType"),
|
F("wWSetTemp"),
|
||||||
F("Warm water type"),
|
F("Warm water set temperature"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::DEGREES);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWType_, DeviceValueType::ENUM, FL_(enum_flow), F("wWType"), F("Warm water type"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWComfort_,
|
&wWComfort_,
|
||||||
DeviceValueType::ENUM,
|
DeviceValueType::ENUM,
|
||||||
flash_string_vector{F("hot"), F("eco"), F("intelligent")},
|
FL_(enum_comfort),
|
||||||
F("wWComfort"),
|
F("wWComfort"),
|
||||||
F("Warm water comfort"),
|
F("Warm water comfort"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWCircPump_,
|
&wWCircPump_,
|
||||||
DeviceValueType::BOOL,
|
DeviceValueType::BOOL,
|
||||||
{},
|
nullptr,
|
||||||
F("wWCircPump"),
|
F("wWCircPump"),
|
||||||
F("Warm water circulation pump available"),
|
F("Warm water circulation pump available"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWChargeType_,
|
&wWChargeType_,
|
||||||
DeviceValueType::BOOL,
|
DeviceValueType::BOOL,
|
||||||
flash_string_vector{F("3-way valve"), F("charge pump")},
|
FL_(enum_charge),
|
||||||
F("wWChargeType"),
|
F("wWChargeType"),
|
||||||
F("Warm Water charging type"),
|
F("Warm Water charging type"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWDisinfectionTemp_,
|
&wWDisinfectionTemp_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{},
|
nullptr,
|
||||||
F("wWDisinfectionTemp"),
|
F("wWDisinfectionTemp"),
|
||||||
F("Warm Water disinfection temperature"),
|
F("Warm Water disinfection temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWCircPumpMode_,
|
&wWCircPumpMode_,
|
||||||
DeviceValueType::ENUM,
|
DeviceValueType::ENUM,
|
||||||
flash_string_vector{F("off"), F("1x3min"), F("2x3min"), F("3x3min"), F("4x3min"), F("5x3min"), F("6x3min"), F("continuos")},
|
FL_(enum_freq),
|
||||||
F("wWCircPumpMode"),
|
F("wWCircPumpMode"),
|
||||||
F("Warm water circulation pump freq"),
|
F("Warm water circulation pump freq"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCirc_, DeviceValueType::BOOL, {}, F("wWCirc"), F("Warm Water circulation active"), DeviceValueUOM::NONE);
|
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCirc_, DeviceValueType::BOOL, nullptr, F("wWCirc"), F("Warm Water circulation active"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWCurTemp_,
|
&wWCurTemp_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
{F("10")},
|
FL_(div10),
|
||||||
F("wWCurTemp"),
|
F("wWCurTemp"),
|
||||||
F("Warm Water current temperature (intern)"),
|
F("Warm Water current temperature (intern)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWCurTemp2_,
|
&wWCurTemp2_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("wWCurTemp2"),
|
F("wWCurTemp2"),
|
||||||
F("Warm Water current temperature (extern)"),
|
F("Warm Water current temperature (extern)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWCurFlow_,
|
&wWCurFlow_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{F("10")},
|
FL_(div10),
|
||||||
F("wWCurFlow"),
|
F("wWCurFlow"),
|
||||||
F("Warm Water current tap water flow"),
|
F("Warm Water current tap water flow"),
|
||||||
DeviceValueUOM::LMIN);
|
DeviceValueUOM::LMIN);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wwStorageTemp1_,
|
&wwStorageTemp1_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("wwStorageTemp1"),
|
F("wwStorageTemp1"),
|
||||||
F("Warm water storage temperature (intern)"),
|
F("Warm water storage temperature (intern)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wwStorageTemp2_,
|
&wwStorageTemp2_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("wwStorageTemp2"),
|
F("wwStorageTemp2"),
|
||||||
F("Warm water storage temperature (extern)"),
|
F("Warm water storage temperature (extern)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWActivated_, DeviceValueType::BOOL, {}, F("wWActivated"), F("Warm Water activated"), DeviceValueUOM::NONE);
|
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWActivated_, DeviceValueType::BOOL, nullptr, F("wWActivated"), F("Warm Water activated"), DeviceValueUOM::NONE);
|
||||||
register_device_value(
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWOneTime_, DeviceValueType::BOOL, {}, F("wWOneTime"), F("Warm Water one time charging"), DeviceValueUOM::NONE);
|
&wWOneTime_,
|
||||||
|
DeviceValueType::BOOL,
|
||||||
|
nullptr,
|
||||||
|
F("wWOneTime"),
|
||||||
|
F("Warm Water one time charging"),
|
||||||
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWDisinfecting_,
|
&wWDisinfecting_,
|
||||||
DeviceValueType::BOOL,
|
DeviceValueType::BOOL,
|
||||||
{},
|
nullptr,
|
||||||
F("wWDisinfecting"),
|
F("wWDisinfecting"),
|
||||||
F("Warm Water disinfecting"),
|
F("Warm Water disinfecting"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCharging_, DeviceValueType::BOOL, {}, F("wWCharging"), F("Warm Water charging"), DeviceValueUOM::NONE);
|
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWRecharging_, DeviceValueType::BOOL, {}, F("wWRecharging"), F("Warm Water recharging"), DeviceValueUOM::NONE);
|
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWCharging_, DeviceValueType::BOOL, nullptr, F("wWCharging"), F("Warm Water charging"), DeviceValueUOM::NONE);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
|
&wWRecharging_,
|
||||||
|
DeviceValueType::BOOL,
|
||||||
|
nullptr,
|
||||||
|
F("wWRecharging"),
|
||||||
|
F("Warm Water recharging"),
|
||||||
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWTempOK_, DeviceValueType::BOOL, {}, F("wWTempOK"), F("Warm Water temperature ok"), DeviceValueUOM::NONE);
|
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWTempOK_, DeviceValueType::BOOL, nullptr, F("wWTempOK"), F("Warm Water temperature ok"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWActive_, DeviceValueType::BOOL, {}, F("wWActive"), F("Warm Water active"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWActive_, DeviceValueType::BOOL, nullptr, F("wWActive"), F("Warm Water active"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWHeat_, DeviceValueType::BOOL, {}, F("wWHeat"), F("Warm Water heating"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWHeat_, DeviceValueType::BOOL, nullptr, F("wWHeat"), F("Warm Water heating"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wWSetPumpPower_,
|
&wWSetPumpPower_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{},
|
nullptr,
|
||||||
F("wWSetPumpPower"),
|
F("wWSetPumpPower"),
|
||||||
F("Warm Water pump set power"),
|
F("Warm Water pump set power"),
|
||||||
DeviceValueUOM::PERCENT);
|
DeviceValueUOM::PERCENT);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wwMixTemperature_,
|
&wwMixTemperature_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
{},
|
nullptr,
|
||||||
F("wwMixTemperature"),
|
F("wwMixTemperature"),
|
||||||
F("Warm Water mix temperature"),
|
F("Warm Water mix temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
&wwBufferTemperature_,
|
&wwBufferTemperature_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
{},
|
nullptr,
|
||||||
F("wwBufferTemperature"),
|
F("wwBufferTemperature"),
|
||||||
F("Warm Water buffer boiler temperature"),
|
F("Warm Water buffer boiler temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWStarts_, DeviceValueType::ULONG, {}, F("wWStarts"), F("Warm Water # starts"), DeviceValueUOM::NONE);
|
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWStarts2_, DeviceValueType::ULONG, {}, F("wWStarts2"), F("Warm Water # starts (control)"), DeviceValueUOM::NONE);
|
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWStarts_, DeviceValueType::ULONG, nullptr, F("wWStarts"), F("Warm Water # starts"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wWWorkM_, DeviceValueType::TIME, {}, F("wWWorkM"), F("Warm Water active time"), DeviceValueUOM::MINUTES);
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||||
|
&wWStarts2_,
|
||||||
|
DeviceValueType::ULONG,
|
||||||
|
nullptr,
|
||||||
|
F("wWStarts2"),
|
||||||
|
F("Warm Water # starts (control)"),
|
||||||
|
DeviceValueUOM::NONE);
|
||||||
|
register_device_value(
|
||||||
|
DeviceValueTAG::TAG_BOILER_DATA_WW, &wWWorkM_, DeviceValueType::TIME, nullptr, F("wWWorkM"), F("Warm Water active time"), DeviceValueUOM::MINUTES);
|
||||||
|
|
||||||
// info - boiler_data_info topic
|
// info - boiler_data_info topic
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&upTimeControl_,
|
&upTimeControl_,
|
||||||
DeviceValueType::TIME,
|
DeviceValueType::TIME,
|
||||||
flash_string_vector{F("60")},
|
FL_(div60),
|
||||||
F("upTimeControl"),
|
F("upTimeControl"),
|
||||||
F("Operating time total heat"),
|
F("Operating time total heat"),
|
||||||
DeviceValueUOM::MINUTES);
|
DeviceValueUOM::MINUTES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&upTimeCompHeating_,
|
&upTimeCompHeating_,
|
||||||
DeviceValueType::TIME,
|
DeviceValueType::TIME,
|
||||||
flash_string_vector{F("60")},
|
FL_(div60),
|
||||||
F("upTimeCompHeating"),
|
F("upTimeCompHeating"),
|
||||||
F("Operating time compressor heating"),
|
F("Operating time compressor heating"),
|
||||||
DeviceValueUOM::MINUTES);
|
DeviceValueUOM::MINUTES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&upTimeCompCooling_,
|
&upTimeCompCooling_,
|
||||||
DeviceValueType::TIME,
|
DeviceValueType::TIME,
|
||||||
flash_string_vector{F("60")},
|
FL_(div60),
|
||||||
F("upTimeCompCooling"),
|
F("upTimeCompCooling"),
|
||||||
F("Operating time compressor cooling"),
|
F("Operating time compressor cooling"),
|
||||||
DeviceValueUOM::MINUTES);
|
DeviceValueUOM::MINUTES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&upTimeCompWw_,
|
&upTimeCompWw_,
|
||||||
DeviceValueType::TIME,
|
DeviceValueType::TIME,
|
||||||
flash_string_vector{F("60")},
|
FL_(div60),
|
||||||
F("upTimeCompWw"),
|
F("upTimeCompWw"),
|
||||||
F("Operating time compressor warm water"),
|
F("Operating time compressor warm water"),
|
||||||
DeviceValueUOM::MINUTES);
|
DeviceValueUOM::MINUTES);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&heatingStarts_,
|
&heatingStarts_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("heatingStarts"),
|
F("heatingStarts"),
|
||||||
F("# heating starts (control)"),
|
F("# heating starts (control)"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&coolingStarts_,
|
&coolingStarts_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("coolingStarts"),
|
F("coolingStarts"),
|
||||||
F("# cooling starts (control)"),
|
F("# cooling starts (control)"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgConsTotal_,
|
&nrgConsTotal_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgConsTotal"),
|
F("nrgConsTotal"),
|
||||||
F("Total energy consumption"),
|
F("Total energy consumption"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgConsCompTotal_,
|
&nrgConsCompTotal_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgConsCompTotal"),
|
F("nrgConsCompTotal"),
|
||||||
F("Energy consumption compressor total"),
|
F("Energy consumption compressor total"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgConsCompHeating_,
|
&nrgConsCompHeating_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgConsCompHeating"),
|
F("nrgConsCompHeating"),
|
||||||
F("Energy consumption compressor heating"),
|
F("Energy consumption compressor heating"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgConsCompWw_,
|
&nrgConsCompWw_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgConsCompWw"),
|
F("nrgConsCompWw"),
|
||||||
F("Energy consumption compressor warm water"),
|
F("Energy consumption compressor warm water"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgConsCompCooling_,
|
&nrgConsCompCooling_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgConsCompCooling"),
|
F("nrgConsCompCooling"),
|
||||||
F("Energy consumption compressor cooling"),
|
F("Energy consumption compressor cooling"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
DeviceValueTAG::TAG_BOILER_DATA_INFO, &nrgSuppTotal_, DeviceValueType::ULONG, {}, F("nrgSuppTotal"), F("Total energy supplied"), DeviceValueUOM::NONE);
|
&nrgSuppTotal_,
|
||||||
|
DeviceValueType::ULONG,
|
||||||
|
nullptr,
|
||||||
|
F("nrgSuppTotal"),
|
||||||
|
F("Total energy supplied"),
|
||||||
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgSuppHeating_,
|
&nrgSuppHeating_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgSuppHeating"),
|
F("nrgSuppHeating"),
|
||||||
F("Total energy supplied heating"),
|
F("Total energy supplied heating"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgSuppWw_,
|
&nrgSuppWw_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgSuppWw"),
|
F("nrgSuppWw"),
|
||||||
F("Total energy warm supplied warm water"),
|
F("Total energy warm supplied warm water"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&nrgSuppCooling_,
|
&nrgSuppCooling_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("nrgSuppCooling"),
|
F("nrgSuppCooling"),
|
||||||
F("Total energy supplied cooling"),
|
F("Total energy supplied cooling"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&auxElecHeatNrgConsTotal_,
|
&auxElecHeatNrgConsTotal_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("auxElecHeatNrgConsTotal"),
|
F("auxElecHeatNrgConsTotal"),
|
||||||
F("Auxiliary electrical heater energy consumption total"),
|
F("Auxiliary electrical heater energy consumption total"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&auxElecHeatNrgConsHeating_,
|
&auxElecHeatNrgConsHeating_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("auxElecHeatNrgConsHeating"),
|
F("auxElecHeatNrgConsHeating"),
|
||||||
F("Auxiliary electrical heater energy consumption heating"),
|
F("Auxiliary electrical heater energy consumption heating"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&auxElecHeatNrgConsDHW_,
|
&auxElecHeatNrgConsDHW_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::ULONG,
|
||||||
{},
|
nullptr,
|
||||||
F("auxElecHeatNrgConsDHW"),
|
F("auxElecHeatNrgConsDHW"),
|
||||||
F("Auxiliary electrical heater energy consumption DHW"),
|
F("Auxiliary electrical heater energy consumption DHW"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&maintenanceMessage_,
|
&maintenanceMessage_,
|
||||||
DeviceValueType::TEXT,
|
DeviceValueType::TEXT,
|
||||||
{},
|
nullptr,
|
||||||
F("maintenanceMessage"),
|
F("maintenanceMessage"),
|
||||||
F("Maintenance message"),
|
F("Maintenance message"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&maintenanceDate_,
|
&maintenanceDate_,
|
||||||
DeviceValueType::TEXT,
|
DeviceValueType::TEXT,
|
||||||
{},
|
nullptr,
|
||||||
F("maintenanceDate"),
|
F("maintenanceDate"),
|
||||||
F("Maintenance set date"),
|
F("Maintenance set date"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&maintenanceType_,
|
&maintenanceType_,
|
||||||
DeviceValueType::ENUM,
|
DeviceValueType::ENUM,
|
||||||
flash_string_vector{F("off"), F("time"), F("date")},
|
FL_(enum_off_time_date),
|
||||||
F("maintenanceType"),
|
F("maintenanceType"),
|
||||||
F("Scheduled maintenance"),
|
F("Scheduled maintenance"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_INFO,
|
||||||
&maintenanceTime_,
|
&maintenanceTime_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{},
|
nullptr,
|
||||||
F("maintenanceTime"),
|
F("maintenanceTime"),
|
||||||
F("Maintenance set time"),
|
F("Maintenance set time"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
@@ -680,11 +711,12 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram
|
|||||||
has_update(telegram->read_value(serviceCodeNumber_, 4));
|
has_update(telegram->read_value(serviceCodeNumber_, 4));
|
||||||
|
|
||||||
// at this point do a quick check to see if the hot water or heating is active
|
// at this point do a quick check to see if the hot water or heating is active
|
||||||
uint8_t state = 0;
|
uint8_t state = EMS_VALUE_UINT_NOTSET;
|
||||||
telegram->read_value(state, 11);
|
if (telegram->read_value(state, 11)) {
|
||||||
boilerState_ = state & 0x01 ? 0x08 : 0;
|
boilerState_ = state & 0x01 ? 0x08 : 0;
|
||||||
boilerState_ |= state & 0x02 ? 0x01 : 0;
|
boilerState_ |= state & 0x02 ? 0x01 : 0;
|
||||||
boilerState_ |= state & 0x04 ? 0x02 : 0;
|
boilerState_ |= state & 0x04 ? 0x02 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
check_active(); // do a quick check to see if the hot water or heating is active
|
check_active(); // do a quick check to see if the hot water or heating is active
|
||||||
}
|
}
|
||||||
@@ -870,6 +902,9 @@ void Boiler::process_UBAMaintenanceStatus(std::shared_ptr<const Telegram> telegr
|
|||||||
|
|
||||||
// 0x10, 0x11
|
// 0x10, 0x11
|
||||||
void Boiler::process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
void Boiler::process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
if (telegram->offset > 0 || telegram->message_length < 9) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr
|
// data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr
|
||||||
if (telegram->message_data[4] & 0x80) { // valid date
|
if (telegram->message_data[4] & 0x80) { // valid date
|
||||||
|
|
||||||
@@ -896,6 +931,9 @@ void Boiler::process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
|||||||
|
|
||||||
// 0x15
|
// 0x15
|
||||||
void Boiler::process_UBAMaintenanceData(std::shared_ptr<const Telegram> telegram) {
|
void Boiler::process_UBAMaintenanceData(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
if (telegram->offset > 0 || telegram->message_length < 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// first byte: Maintenance messages (0 = none, 1 = by operating hours, 2 = by date)
|
// first byte: Maintenance messages (0 = none, 1 = by operating hours, 2 = by date)
|
||||||
|
|
||||||
telegram->read_value(maintenanceType_, 0);
|
telegram->read_value(maintenanceType_, 0);
|
||||||
|
|||||||
@@ -19,18 +19,7 @@
|
|||||||
#ifndef EMSESP_BOILER_H
|
#ifndef EMSESP_BOILER_H
|
||||||
#define EMSESP_BOILER_H
|
#define EMSESP_BOILER_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -19,15 +19,7 @@
|
|||||||
#ifndef EMSESP_CONNECT_H
|
#ifndef EMSESP_CONNECT_H
|
||||||
#define EMSESP_CONNECT_H
|
#define EMSESP_CONNECT_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "emsesp.h"
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -19,15 +19,7 @@
|
|||||||
#ifndef EMSESP_CONTROLLER_H
|
#ifndef EMSESP_CONTROLLER_H
|
||||||
#define EMSESP_CONTROLLER_H
|
#define EMSESP_CONTROLLER_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "emsesp.h"
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -19,15 +19,7 @@
|
|||||||
#ifndef EMSESP_GATEWAY_H
|
#ifndef EMSESP_GATEWAY_H
|
||||||
#define EMSESP_GATEWAY_H
|
#define EMSESP_GATEWAY_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "emsesp.h"
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -19,15 +19,7 @@
|
|||||||
#ifndef EMSESP_GENERIC_H
|
#ifndef EMSESP_GENERIC_H
|
||||||
#define EMSESP_GENERIC_H
|
#define EMSESP_GENERIC_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "emsesp.h"
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,11 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c
|
|||||||
register_telegram_type(0x042B, F("HP1"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor1(t); });
|
register_telegram_type(0x042B, F("HP1"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor1(t); });
|
||||||
register_telegram_type(0x047B, F("HP2"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor2(t); });
|
register_telegram_type(0x047B, F("HP2"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor2(t); });
|
||||||
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &airHumidity_, DeviceValueType::UINT, flash_string_vector{F("2")}, F("airHumidity"), F("Relative air humidity"), DeviceValueUOM::NONE);
|
// device values
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &dewTemperature_, DeviceValueType::UINT, {}, F("dewTemperature"), F("Dew point temperature"), DeviceValueUOM::NONE);
|
register_device_value(
|
||||||
|
DeviceValueTAG::TAG_NONE, &airHumidity_, DeviceValueType::UINT, FL_(div2), F("airHumidity"), F("Relative air humidity"), DeviceValueUOM::NONE);
|
||||||
|
register_device_value(
|
||||||
|
DeviceValueTAG::TAG_NONE, &dewTemperature_, DeviceValueType::UINT, nullptr, F("dewTemperature"), F("Dew point temperature"), DeviceValueUOM::NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish HA config
|
// publish HA config
|
||||||
|
|||||||
@@ -19,16 +19,7 @@
|
|||||||
#ifndef EMSESP_HEATPUMP_H
|
#ifndef EMSESP_HEATPUMP_H
|
||||||
#define EMSESP_HEATPUMP_H
|
#define EMSESP_HEATPUMP_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
|||||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||||
register_telegram_type(0x010C, F("IPMSetMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_IPMStatusMessage(t); });
|
register_telegram_type(0x010C, F("IPMSetMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_IPMStatusMessage(t); });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -74,10 +75,10 @@ void Mixer::register_values(const Type type, uint16_t hc) {
|
|||||||
tag = DeviceValueTAG::TAG_WWC1 + hc - 1;
|
tag = DeviceValueTAG::TAG_WWC1 + hc - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
register_device_value(tag, &flowTemp_, DeviceValueType::USHORT, flash_string_vector{F("10")}, F("flowTemp"), F("Current flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &flowTemp_, DeviceValueType::USHORT, FL_(div10), F("flowTemp"), F("Current flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, {}, F("flowSetTemp"), F("Setpoint flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, F("flowSetTemp"), F("Setpoint flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, {}, F("pumpStatus"), F("Pump/Valve status"), DeviceValueUOM::NONE);
|
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, F("pumpStatus"), F("Pump/Valve status"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &status_, DeviceValueType::INT, {}, F("status"), F("Current status"), DeviceValueUOM::NONE);
|
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, F("status"), F("Current status"), DeviceValueUOM::NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,16 +19,7 @@
|
|||||||
#ifndef EMSESP_MIXER_H
|
#ifndef EMSESP_MIXER_H
|
||||||
#define EMSESP_MIXER_H
|
#define EMSESP_MIXER_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -60,37 +60,39 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
|||||||
register_telegram_type(0x0101, F("ISM1Set"), false, [&](std::shared_ptr<const Telegram> t) { process_ISM1Set(t); });
|
register_telegram_type(0x0101, F("ISM1Set"), false, [&](std::shared_ptr<const Telegram> t) { process_ISM1Set(t); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// device values...
|
||||||
|
|
||||||
// special case for a device_id with 0x2A where it's not actual a solar module
|
// special case for a device_id with 0x2A where it's not actual a solar module
|
||||||
if (device_id == 0x2A) {
|
if (device_id == 0x2A) {
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &type_, DeviceValueType::TEXT, {}, F("type"), F("Type"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_NONE, &type_, DeviceValueType::TEXT, nullptr, F("type"), F("Type"), DeviceValueUOM::NONE);
|
||||||
strncpy(type_, "warm water circuit", sizeof(type_));
|
strncpy(type_, "warm water circuit", sizeof(type_));
|
||||||
}
|
}
|
||||||
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&collectorTemp_,
|
&collectorTemp_,
|
||||||
DeviceValueType::SHORT,
|
DeviceValueType::SHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("collectorTemp"),
|
F("collectorTemp"),
|
||||||
F("Collector temperature (TS1)"),
|
F("Collector temperature (TS1)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&tankBottomTemp_,
|
&tankBottomTemp_,
|
||||||
DeviceValueType::SHORT,
|
DeviceValueType::SHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("tankBottomTemp"),
|
F("tankBottomTemp"),
|
||||||
F("Bottom temperature (TS2)"),
|
F("Bottom temperature (TS2)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&tankBottomTemp2_,
|
&tankBottomTemp2_,
|
||||||
DeviceValueType::SHORT,
|
DeviceValueType::SHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("tankBottomTemp2"),
|
F("tankBottomTemp2"),
|
||||||
F("Bottom temperature (TS5)"),
|
F("Bottom temperature (TS5)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&heatExchangerTemp_,
|
&heatExchangerTemp_,
|
||||||
DeviceValueType::SHORT,
|
DeviceValueType::SHORT,
|
||||||
{F("10")},
|
FL_(div10),
|
||||||
F("heatExchangerTemp"),
|
F("heatExchangerTemp"),
|
||||||
F("Heat exchanger temperature (TS6)"),
|
F("Heat exchanger temperature (TS6)"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
@@ -98,43 +100,37 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
|||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&tank1MaxTempCurrent_,
|
&tank1MaxTempCurrent_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{},
|
nullptr,
|
||||||
F("tank1MaxTempCurrent"),
|
F("tank1MaxTempCurrent"),
|
||||||
F("Maximum Tank temperature"),
|
F("Maximum Tank temperature"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&solarPumpModulation_,
|
&solarPumpModulation_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{},
|
nullptr,
|
||||||
F("solarPumpModulation"),
|
F("solarPumpModulation"),
|
||||||
F("Solar pump modulation (PS1)"),
|
F("Solar pump modulation (PS1)"),
|
||||||
DeviceValueUOM::PERCENT);
|
DeviceValueUOM::PERCENT);
|
||||||
register_device_value(
|
|
||||||
DeviceValueTAG::TAG_NONE, &cylinderPumpModulation_, DeviceValueType::UINT, {}, F("cylinderPumpModulation"), F("Cylinder pump modulation (PS5)"), DeviceValueUOM::PERCENT);
|
|
||||||
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &solarPump_, DeviceValueType::BOOL, {}, F("solarPump"), F("Solar pump (PS1) active"), DeviceValueUOM::NONE);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &valveStatus_, DeviceValueType::BOOL, {}, F("valveStatus"), F("Valve status"), DeviceValueUOM::NONE);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &tankHeated_, DeviceValueType::BOOL, {}, F("tankHeated"), F("Tank heated"), DeviceValueUOM::NONE);
|
|
||||||
register_device_value(
|
|
||||||
DeviceValueTAG::TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, {}, F("collectorShutdown"), F("Collector shutdown"), DeviceValueUOM::NONE);
|
|
||||||
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &pumpWorkMin_, DeviceValueType::TIME, {}, F("pumpWorkMin"), F("Pump working time"), DeviceValueUOM::MINUTES);
|
|
||||||
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&energyLastHour_,
|
&cylinderPumpModulation_,
|
||||||
DeviceValueType::ULONG,
|
DeviceValueType::UINT,
|
||||||
flash_string_vector{F("10")},
|
nullptr,
|
||||||
F("energyLastHour"),
|
F("cylinderPumpModulation"),
|
||||||
F("Energy last hour"),
|
F("Cylinder pump modulation (PS5)"),
|
||||||
DeviceValueUOM::WH);
|
DeviceValueUOM::PERCENT);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
|
||||||
&energyTotal_,
|
register_device_value(DeviceValueTAG::TAG_NONE, &solarPump_, DeviceValueType::BOOL, nullptr, F("solarPump"), F("Solar pump (PS1) active"), DeviceValueUOM::NONE);
|
||||||
DeviceValueType::ULONG,
|
register_device_value(DeviceValueTAG::TAG_NONE, &valveStatus_, DeviceValueType::BOOL, nullptr, F("valveStatus"), F("Valve status"), DeviceValueUOM::NONE);
|
||||||
flash_string_vector{F("10")},
|
register_device_value(DeviceValueTAG::TAG_NONE, &tankHeated_, DeviceValueType::BOOL, nullptr, F("tankHeated"), F("Tank heated"), DeviceValueUOM::NONE);
|
||||||
F("energyTotal"),
|
register_device_value(
|
||||||
F("Energy total"),
|
DeviceValueTAG::TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, F("collectorShutdown"), F("Collector shutdown"), DeviceValueUOM::NONE);
|
||||||
DeviceValueUOM::KWH);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &energyToday_, DeviceValueType::ULONG, {}, F("energyToday"), F("Energy today"), DeviceValueUOM::WH);
|
register_device_value(DeviceValueTAG::TAG_NONE, &pumpWorkMin_, DeviceValueType::TIME, nullptr, F("pumpWorkMin"), F("Pump working time"), DeviceValueUOM::MINUTES);
|
||||||
|
|
||||||
|
register_device_value(
|
||||||
|
DeviceValueTAG::TAG_NONE, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), F("energyLastHour"), F("Energy last hour"), DeviceValueUOM::WH);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_NONE, &energyTotal_, DeviceValueType::ULONG, FL_(div10), F("energyTotal"), F("Energy total"), DeviceValueUOM::KWH);
|
||||||
|
register_device_value(DeviceValueTAG::TAG_NONE, &energyToday_, DeviceValueType::ULONG, nullptr, F("energyToday"), F("Energy today"), DeviceValueUOM::WH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish HA config
|
// publish HA config
|
||||||
|
|||||||
@@ -19,16 +19,7 @@
|
|||||||
#ifndef EMSESP_SOLAR_H
|
#ifndef EMSESP_SOLAR_H
|
||||||
#define EMSESP_SOLAR_H
|
#define EMSESP_SOLAR_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -34,15 +34,10 @@ Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const
|
|||||||
register_telegram_type(0x9D, F("WM10SetMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_WM10SetMessage(t); });
|
register_telegram_type(0x9D, F("WM10SetMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_WM10SetMessage(t); });
|
||||||
register_telegram_type(0x1E, F("WM10TempMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_WM10TempMessage(t); });
|
register_telegram_type(0x1E, F("WM10TempMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_WM10TempMessage(t); });
|
||||||
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &activated_, DeviceValueType::BOOL, {}, F("activated"), F("Activated"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_NONE, &activated_, DeviceValueType::BOOL, nullptr, F("activated"), F("Activated"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(
|
||||||
&flowTemp_,
|
DeviceValueTAG::TAG_NONE, &flowTemp_, DeviceValueType::USHORT, FL_(div10), F("flowTemp"), F("Current flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
DeviceValueType::USHORT,
|
register_device_value(DeviceValueTAG::TAG_NONE, &status_, DeviceValueType::INT, nullptr, F("status"), F("Status"), DeviceValueUOM::NONE);
|
||||||
flash_string_vector{F("10")},
|
|
||||||
F("flowTemp"),
|
|
||||||
F("Current flow temperature"),
|
|
||||||
DeviceValueUOM::DEGREES);
|
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &status_, DeviceValueType::INT, {}, F("status"), F("Status"), DeviceValueUOM::NONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish HA config
|
// publish HA config
|
||||||
|
|||||||
@@ -19,16 +19,7 @@
|
|||||||
#ifndef EMSESP_SWITCH_H
|
#ifndef EMSESP_SWITCH_H
|
||||||
#define EMSESP_SWITCH_H
|
#define EMSESP_SWITCH_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "telegram.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
&& ((actual_master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) || (device_id < actual_master_thermostat)))) {
|
&& ((actual_master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) || (device_id < actual_master_thermostat)))) {
|
||||||
EMSESP::actual_master_thermostat(device_id);
|
EMSESP::actual_master_thermostat(device_id);
|
||||||
actual_master_thermostat = device_id;
|
actual_master_thermostat = device_id;
|
||||||
reserve_mem(25); // reserve some space for the telegram registries, to avoid memory fragmentation
|
reserve_telgram_functions(25); // reserve some space for the telegram registries, to avoid memory fragmentation
|
||||||
|
|
||||||
// common telegram handlers
|
// common telegram handlers
|
||||||
register_telegram_type(EMS_TYPE_RCOutdoorTemp, F("RCOutdoorTemp"), false, [&](std::shared_ptr<const Telegram> t) { process_RCOutdoorTemp(t); });
|
register_telegram_type(EMS_TYPE_RCOutdoorTemp, F("RCOutdoorTemp"), false, [&](std::shared_ptr<const Telegram> t) { process_RCOutdoorTemp(t); });
|
||||||
@@ -868,6 +868,10 @@ void Thermostat::process_RC35Monitor(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// exit if the 15th byte (second from last) is 0x00, which I think is calculated flow setpoint temperature
|
// exit if the 15th byte (second from last) is 0x00, which I think is calculated flow setpoint temperature
|
||||||
// with weather controlled RC35s this value is >=5, otherwise can be zero and our setpoint temps will be incorrect
|
// with weather controlled RC35s this value is >=5, otherwise can be zero and our setpoint temps will be incorrect
|
||||||
// see https://github.com/proddy/EMS-ESP/issues/373#issuecomment-627907301
|
// see https://github.com/proddy/EMS-ESP/issues/373#issuecomment-627907301
|
||||||
|
if (telegram->offset > 0 || telegram->message_length < 15) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (telegram->message_data[14] == 0x00) {
|
if (telegram->message_data[14] == 0x00) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -890,7 +894,7 @@ void Thermostat::process_RC35Monitor(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// type 0x3D (HC1), 0x47 (HC2), 0x51 (HC3), 0x5B (HC4) - Working Mode Heating - for reading the mode from the RC35 thermostat (0x10)
|
// type 0x3D (HC1), 0x47 (HC2), 0x51 (HC3), 0x5B (HC4) - Working Mode Heating - for reading the mode from the RC35 thermostat (0x10)
|
||||||
void Thermostat::process_RC35Set(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RC35Set(std::shared_ptr<const Telegram> telegram) {
|
||||||
// check to see we have a valid type. heating: 1 radiator, 2 convectors, 3 floors, 4 room supply
|
// check to see we have a valid type. heating: 1 radiator, 2 convectors, 3 floors, 4 room supply
|
||||||
if (telegram->message_data[0] == 0x00) {
|
if (telegram->offset == 0 && telegram->message_data[0] == 0x00) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,6 +939,10 @@ void Thermostat::process_RC35Timer(std::shared_ptr<const Telegram> telegram) {
|
|||||||
|
|
||||||
// process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long
|
// process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long
|
||||||
void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
if (telegram->offset > 0 || telegram->message_length < 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags() == EMS_DEVICE_FLAG_EASY) {
|
if (flags() == EMS_DEVICE_FLAG_EASY) {
|
||||||
return; // not supported
|
return; // not supported
|
||||||
}
|
}
|
||||||
@@ -975,6 +983,10 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// 10 00 A2 00 41 32 32 03 30 00 02 00 00 00 00 00 00 02 CRC
|
// 10 00 A2 00 41 32 32 03 30 00 02 00 00 00 00 00 00 02 CRC
|
||||||
// A 2 2 816
|
// A 2 2 816
|
||||||
void Thermostat::process_RCError(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RCError(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
if (telegram->offset > 0 || telegram->message_length < 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char buf[4];
|
char buf[4];
|
||||||
buf[0] = telegram->message_data[0];
|
buf[0] = telegram->message_data[0];
|
||||||
buf[1] = telegram->message_data[1];
|
buf[1] = telegram->message_data[1];
|
||||||
@@ -986,6 +998,10 @@ void Thermostat::process_RCError(std::shared_ptr<const Telegram> telegram) {
|
|||||||
|
|
||||||
// 0x12 error log
|
// 0x12 error log
|
||||||
void Thermostat::process_RCErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RCErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
if (telegram->offset > 0 || telegram->message_length < 12) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr
|
// data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr
|
||||||
if (telegram->message_data[4] & 0x80) { // valid date
|
if (telegram->message_data[4] & 0x80) { // valid date
|
||||||
char code[3];
|
char code[3];
|
||||||
@@ -1011,7 +1027,7 @@ bool Thermostat::set_minexttemp(const char * value, const int8_t id) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(F("Setting min external temperature to %d"), mt);
|
LOG_INFO(F("Setting min external temperature to %d C"), mt);
|
||||||
if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) {
|
if ((model() == EMS_DEVICE_FLAG_RC300) || (model() == EMS_DEVICE_FLAG_RC100)) {
|
||||||
write_command(0x240, 10, mt, 0x240);
|
write_command(0x240, 10, mt, 0x240);
|
||||||
} else {
|
} else {
|
||||||
@@ -1128,7 +1144,7 @@ bool Thermostat::set_control(const char * value, const int8_t id) {
|
|||||||
|
|
||||||
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
|
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
|
||||||
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(hc_num);
|
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(hc_num);
|
||||||
if (hc == nullptr || ctrl > 2) {
|
if (hc == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1238,12 +1254,20 @@ bool Thermostat::set_holiday(const char * value, const int8_t id) {
|
|||||||
data[0] = (hd[0] - '0') * 10 + (hd[1] - '0');
|
data[0] = (hd[0] - '0') * 10 + (hd[1] - '0');
|
||||||
data[1] = (hd[3] - '0') * 10 + (hd[4] - '0');
|
data[1] = (hd[3] - '0') * 10 + (hd[4] - '0');
|
||||||
data[2] = (hd[7] - '0') * 100 + (hd[8] - '0') * 10 + (hd[9] - '0');
|
data[2] = (hd[7] - '0') * 100 + (hd[8] - '0') * 10 + (hd[9] - '0');
|
||||||
data[3] = (hd[11] - '0') * 10 + (hd[11] - '0');
|
data[3] = (hd[11] - '0') * 10 + (hd[12] - '0');
|
||||||
data[4] = (hd[14] - '0') * 10 + (hd[15] - '0');
|
data[4] = (hd[14] - '0') * 10 + (hd[15] - '0');
|
||||||
data[5] = (hd[18] - '0') * 100 + (hd[19] - '0') * 10 + (hd[20] - '0');
|
data[5] = (hd[18] - '0') * 100 + (hd[19] - '0') * 10 + (hd[20] - '0');
|
||||||
|
|
||||||
LOG_INFO(F("Setting holiday for hc %d"), hc->hc_num());
|
if (hd[10] == '-') {
|
||||||
write_command(timer_typeids[hc->hc_num() - 1], 87, data, 6, 0);
|
LOG_INFO(F("Setting holiday away from home for hc %d"), hc->hc_num());
|
||||||
|
write_command(timer_typeids[hc->hc_num() - 1], 87, data, 6, 0);
|
||||||
|
} else if (hd[10] == '+') {
|
||||||
|
LOG_INFO(F("Setting holiday at home for hc %d"), hc->hc_num());
|
||||||
|
write_command(timer_typeids[hc->hc_num() - 1], 93, data, 6, 0);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(F("Set holiday: Invalid"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2004,6 +2028,7 @@ void Thermostat::add_commands() {
|
|||||||
register_mqtt_cmd(F("clockoffset"), [&](const char * value, const int8_t id) { return set_clockoffset(value, id); });
|
register_mqtt_cmd(F("clockoffset"), [&](const char * value, const int8_t id) { return set_clockoffset(value, id); });
|
||||||
register_mqtt_cmd(F("language"), [&](const char * value, const int8_t id) { return set_language(value, id); });
|
register_mqtt_cmd(F("language"), [&](const char * value, const int8_t id) { return set_language(value, id); });
|
||||||
register_mqtt_cmd(F("display"), [&](const char * value, const int8_t id) { return set_display(value, id); });
|
register_mqtt_cmd(F("display"), [&](const char * value, const int8_t id) { return set_display(value, id); });
|
||||||
|
break;
|
||||||
case EMS_DEVICE_FLAG_RC35: // RC30 and RC35
|
case EMS_DEVICE_FLAG_RC35: // RC30 and RC35
|
||||||
register_mqtt_cmd(F("nighttemp"), [&](const char * value, const int8_t id) { return set_nighttemp(value, id); });
|
register_mqtt_cmd(F("nighttemp"), [&](const char * value, const int8_t id) { return set_nighttemp(value, id); });
|
||||||
register_mqtt_cmd(F("daytemp"), [&](const char * value, const int8_t id) { return set_daytemp(value, id); });
|
register_mqtt_cmd(F("daytemp"), [&](const char * value, const int8_t id) { return set_daytemp(value, id); });
|
||||||
@@ -2042,41 +2067,43 @@ void Thermostat::add_commands() {
|
|||||||
|
|
||||||
// register main device values, top level for all thermostats (non heating circuit)
|
// register main device values, top level for all thermostats (non heating circuit)
|
||||||
void Thermostat::register_device_values() {
|
void Thermostat::register_device_values() {
|
||||||
|
/*
|
||||||
|
|
||||||
uint8_t model = this->model();
|
uint8_t model = this->model();
|
||||||
|
|
||||||
// Common for all thermostats
|
// Common for all thermostats
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &dateTime_, DeviceValueType::TEXT, {}, F("dateTime"), F("Date/Time"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_NONE, &dateTime_, DeviceValueType::TEXT,nullptr, F("dateTime"), F("Date/Time"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &errorCode_, DeviceValueType::TEXT, {}, F("errorCode"), F("Error code"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_NONE, &errorCode_, DeviceValueType::TEXT,nullptr, F("errorCode"), F("Error code"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &lastCode_, DeviceValueType::TEXT, {}, F("lastCode"), F("Last error"), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_NONE, &lastCode_, DeviceValueType::TEXT,nullptr, F("lastCode"), F("Last error"), DeviceValueUOM::NONE);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &wwTemp_, DeviceValueType::UINT, {}, F("wwTemp"), F("Warm water high temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(DeviceValueTAG::TAG_NONE, &wwTemp_, DeviceValueType::UINT,nullptr, F("wwTemp"), F("Warm water high temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &wwTempLow_, DeviceValueType::UINT, {}, F("wwTempLow"), F("Warm water low temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(DeviceValueTAG::TAG_NONE, &wwTempLow_, DeviceValueType::UINT,nullptr, F("wwTempLow"), F("Warm water low temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &wwExtra1_, DeviceValueType::UINT, {}, F("wwExtra1"), F("Warm water circuit 1 extra"), DeviceValueUOM::DEGREES);
|
register_device_value(DeviceValueTAG::TAG_NONE, &wwExtra1_, DeviceValueType::UINT,nullptr, F("wwExtra1"), F("Warm water circuit 1 extra"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE, &wwExtra2_, DeviceValueType::UINT, {}, F("wwExtra2"), F("Warm water circuit 2 extra"), DeviceValueUOM::DEGREES);
|
register_device_value(DeviceValueTAG::TAG_NONE, &wwExtra2_, DeviceValueType::UINT,nullptr, F("wwExtra2"), F("Warm water circuit 2 extra"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&tempsensor1_,
|
&tempsensor1_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("inttemp1"),
|
F("inttemp1"),
|
||||||
F("Temperature sensor 1"),
|
F("Temperature sensor 1"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&tempsensor2_,
|
&tempsensor2_,
|
||||||
DeviceValueType::USHORT,
|
DeviceValueType::USHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("inttemp2"),
|
F("inttemp2"),
|
||||||
F("Temperature sensor 2"),
|
F("Temperature sensor 2"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&ibaCalIntTemperature_,
|
&ibaCalIntTemperature_,
|
||||||
DeviceValueType::INT,
|
DeviceValueType::INT,
|
||||||
flash_string_vector{F("2")},
|
FL_(div2),
|
||||||
F("intoffset"),
|
F("intoffset"),
|
||||||
F("Offset int. temperature"),
|
F("Offset int. temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&ibaMinExtTemperature_,
|
&ibaMinExtTemperature_,
|
||||||
DeviceValueType::INT,
|
DeviceValueType::INT,
|
||||||
{},
|
nullptr,
|
||||||
F("minexttemp"),
|
F("minexttemp"),
|
||||||
F("Min ext. temperature"),
|
F("Min ext. temperature"),
|
||||||
DeviceValueUOM::DEGREES); // min ext temp for heating curve, in deg.
|
DeviceValueUOM::DEGREES); // min ext temp for heating curve, in deg.
|
||||||
@@ -2108,7 +2135,7 @@ void Thermostat::register_device_values() {
|
|||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&ibaClockOffset_,
|
&ibaClockOffset_,
|
||||||
DeviceValueType::UINT,
|
DeviceValueType::UINT,
|
||||||
{},
|
nullptr,
|
||||||
F("ibaClockOffset"),
|
F("ibaClockOffset"),
|
||||||
F("Clock offset"),
|
F("Clock offset"),
|
||||||
DeviceValueUOM::NONE); // offset (in sec) to clock, 0xff=-1s, 0x02=2s
|
DeviceValueUOM::NONE); // offset (in sec) to clock, 0xff=-1s, 0x02=2s
|
||||||
@@ -2126,12 +2153,12 @@ void Thermostat::register_device_values() {
|
|||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&dampedoutdoortemp2_,
|
&dampedoutdoortemp2_,
|
||||||
DeviceValueType::SHORT,
|
DeviceValueType::SHORT,
|
||||||
flash_string_vector{F("10")},
|
FL_(div10),
|
||||||
F("dampedtemp"),
|
F("dampedtemp"),
|
||||||
F("Damped outdoor temperature"),
|
F("Damped outdoor temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
DeviceValueTAG::TAG_NONE, &floordrytemp_, DeviceValueType::UINT, {}, F("floordrytemp"), F("Floor drying temperature"), DeviceValueUOM::DEGREES);
|
DeviceValueTAG::TAG_NONE, &floordrytemp_, DeviceValueType::UINT,nullptr, F("floordrytemp"), F("Floor drying temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&ibaBuildingType_,
|
&ibaBuildingType_,
|
||||||
DeviceValueType::ENUM,
|
DeviceValueType::ENUM,
|
||||||
@@ -2160,7 +2187,7 @@ void Thermostat::register_device_values() {
|
|||||||
register_device_value(DeviceValueTAG::TAG_NONE,
|
register_device_value(DeviceValueTAG::TAG_NONE,
|
||||||
&dampedoutdoortemp_,
|
&dampedoutdoortemp_,
|
||||||
DeviceValueType::SHORT,
|
DeviceValueType::SHORT,
|
||||||
{},
|
nullptr,
|
||||||
F("dampedtemp"),
|
F("dampedtemp"),
|
||||||
F("Damped outdoor temperature"),
|
F("Damped outdoor temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
@@ -2186,10 +2213,12 @@ void Thermostat::register_device_values() {
|
|||||||
F("Warm water circulation mode"),
|
F("Warm water circulation mode"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// registers the values for a heating circuit
|
// registers the values for a heating circuit
|
||||||
void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::HeatingCircuit> hc) {
|
void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::HeatingCircuit> hc) {
|
||||||
|
/*
|
||||||
uint8_t model = hc->get_model();
|
uint8_t model = hc->get_model();
|
||||||
|
|
||||||
// heating circuit
|
// heating circuit
|
||||||
@@ -2198,14 +2227,14 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
// different logic on how temperature values are stored, depending on model
|
// different logic on how temperature values are stored, depending on model
|
||||||
flash_string_vector setpoint_temp_divider, curr_temp_divider;
|
flash_string_vector setpoint_temp_divider, curr_temp_divider;
|
||||||
if (model == EMS_DEVICE_FLAG_EASY) {
|
if (model == EMS_DEVICE_FLAG_EASY) {
|
||||||
setpoint_temp_divider = flash_string_vector{F("100")};
|
setpoint_temp_divider = FL_(div100);
|
||||||
curr_temp_divider = flash_string_vector{F("100")};
|
curr_temp_divider = FL_(div100);
|
||||||
} else if (model == EMS_DEVICE_FLAG_JUNKERS) {
|
} else if (model == EMS_DEVICE_FLAG_JUNKERS) {
|
||||||
setpoint_temp_divider = flash_string_vector{F("10")};
|
setpoint_temp_divider = FL_(div10);
|
||||||
curr_temp_divider = flash_string_vector{F("10")};
|
curr_temp_divider = FL_(div10);
|
||||||
} else {
|
} else {
|
||||||
setpoint_temp_divider = flash_string_vector{F("2")};
|
setpoint_temp_divider = FL_(div2);
|
||||||
curr_temp_divider = flash_string_vector{F("10")};
|
curr_temp_divider = FL_(div10);
|
||||||
}
|
}
|
||||||
register_device_value(
|
register_device_value(
|
||||||
tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, F("seltemp"), F("Setpoint room temperature"), DeviceValueUOM::DEGREES);
|
tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, F("seltemp"), F("Setpoint room temperature"), DeviceValueUOM::DEGREES);
|
||||||
@@ -2226,7 +2255,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
F("HA current room temperature"),
|
F("HA current room temperature"),
|
||||||
DeviceValueUOM::DEGREES);
|
DeviceValueUOM::DEGREES);
|
||||||
} else if (option == Mqtt::HA_Climate_Format::ZERO) {
|
} else if (option == Mqtt::HA_Climate_Format::ZERO) {
|
||||||
register_device_value(tag, &zero_value_, DeviceValueType::UINT, {}, F("hatemp"), nullptr, DeviceValueUOM::DEGREES);
|
register_device_value(tag, &zero_value_, DeviceValueType::UINT,nullptr, F("hatemp"), nullptr, DeviceValueUOM::DEGREES);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're sending to HA the only valid mode types are heat, auto and off
|
// if we're sending to HA the only valid mode types are heat, auto and off
|
||||||
@@ -2250,14 +2279,14 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
register_device_value(tag, &hc->manualtemp, DeviceValueType::UINT, {F("2")}, F("manualtemp"), F("Manual temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->manualtemp, DeviceValueType::UINT, {F("2")}, F("manualtemp"), F("Manual temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("comforttemp"), F("Comfort temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("comforttemp"), F("Comfort temperature"), DeviceValueUOM::DEGREES);
|
||||||
|
|
||||||
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, {}, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT,nullptr, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, {}, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT,nullptr, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, {}, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT,nullptr, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, {}, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT,nullptr, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, {}, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT,nullptr, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, {}, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT,nullptr, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, {}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT,nullptr, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, {}, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT,nullptr, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag,
|
register_device_value(tag,
|
||||||
&hc->heatingtype,
|
&hc->heatingtype,
|
||||||
DeviceValueType::ENUM,
|
DeviceValueType::ENUM,
|
||||||
@@ -2279,7 +2308,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
F("controlmode"),
|
F("controlmode"),
|
||||||
F("Control mode"),
|
F("Control mode"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->program, DeviceValueType::UINT,nullptr, F("program"), F("Program"), DeviceValueUOM::NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model == EMS_DEVICE_FLAG_RC20) {
|
if (model == EMS_DEVICE_FLAG_RC20) {
|
||||||
@@ -2290,9 +2319,9 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
if (model == EMS_DEVICE_FLAG_RC20_2) {
|
if (model == EMS_DEVICE_FLAG_RC20_2) {
|
||||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, flash_string_vector{F("off"), F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, flash_string_vector{F("off"), F("manual"), F("auto")}, F("mode"), F("Mode"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, flash_string_vector{F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, flash_string_vector{F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->program, DeviceValueType::UINT,nullptr, F("program"), F("Program"), DeviceValueUOM::NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) {
|
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) {
|
||||||
@@ -2300,18 +2329,18 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, {F("night"), F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, {F("night"), F("day")}, F("modetype"), F("Mode type"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, {F("2")}, F("daytemp"), F("Day temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, {F("2")}, F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, {F("2")}, F("nighttemp"), F("Night temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, {}, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT,nullptr, F("designtemp"), F("Design temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, {F("2")}, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, {F("2")}, F("offsettemp"), F("Offset temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->holidaytemp, DeviceValueType::UINT, {F("2")}, F("holidaytemp"), F("Holiday temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->holidaytemp, DeviceValueType::UINT, {F("2")}, F("holidaytemp"), F("Holiday temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, {}, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT,nullptr, F("targetflowtemp"), F("Target flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, {}, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT,nullptr, F("summertemp"), F("Summer temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->summermode, DeviceValueType::BOOL, {}, F("summermode"), F("Summer mode"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->summermode, DeviceValueType::BOOL,nullptr, F("summermode"), F("Summer mode"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL, {}, F("holidaymode"), F("Holiday mode"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL,nullptr, F("holidaymode"), F("Holiday mode"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, {}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT,nullptr, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, {}, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT,nullptr, F("roominfluence"), F("Room influence"), DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, {}, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT,nullptr, F("minflowtemp"), F("Min flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, {}, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT,nullptr, F("maxflowtemp"), F("Max flow temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT, {}, F("flowtempoffset"), F("Flow temperature offset"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT,nullptr, F("flowtempoffset"), F("Flow temperature offset"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag,
|
register_device_value(tag,
|
||||||
&hc->heatingtype,
|
&hc->heatingtype,
|
||||||
DeviceValueType::ENUM,
|
DeviceValueType::ENUM,
|
||||||
@@ -2333,7 +2362,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
F("controlmode"),
|
F("controlmode"),
|
||||||
F("Control mode"),
|
F("Control mode"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, {}, F("program"), F("Program"), DeviceValueUOM::NONE);
|
register_device_value(tag, &hc->program, DeviceValueType::UINT,nullptr, F("program"), F("Program"), DeviceValueUOM::NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||||
@@ -2346,11 +2375,12 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
|||||||
F("modetype"),
|
F("modetype"),
|
||||||
F("Mode type"),
|
F("Mode type"),
|
||||||
DeviceValueUOM::NONE);
|
DeviceValueUOM::NONE);
|
||||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("heattemp"), F("Heat temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), F("heattemp"), F("Heat temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, flash_string_vector{F("2")}, F("ecotemp"), F("Eco temperature"), DeviceValueUOM::DEGREES);
|
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), F("ecotemp"), F("Eco temperature"), DeviceValueUOM::DEGREES);
|
||||||
register_device_value(
|
register_device_value(
|
||||||
tag, &hc->nofrosttemp, DeviceValueType::INT, flash_string_vector{F("2")}, F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES);
|
tag, &hc->nofrosttemp, DeviceValueType::INT, FL_(div2), F("nofrosttemp"), F("Nofrost temperature"), DeviceValueUOM::DEGREES);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -19,19 +19,7 @@
|
|||||||
#ifndef EMSESP_THERMOSTAT_H
|
#ifndef EMSESP_THERMOSTAT_H
|
||||||
#define EMSESP_THERMOSTAT_H
|
#define EMSESP_THERMOSTAT_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "helpers.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace emsesp {
|
|||||||
|
|
||||||
// mapping of UOM, to match order in DeviceValueUOM enum emsdevice.h
|
// mapping of UOM, to match order in DeviceValueUOM enum emsdevice.h
|
||||||
// must be an int of 4 bytes, 32bit aligned
|
// must be an int of 4 bytes, 32bit aligned
|
||||||
static const __FlashStringHelper * DeviceValueUOM_s[] __attribute__((__aligned__(sizeof(int)))) PROGMEM = {
|
static const __FlashStringHelper * DeviceValueUOM_s[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = {
|
||||||
|
|
||||||
F_(degrees),
|
F_(degrees),
|
||||||
F_(percent),
|
F_(percent),
|
||||||
@@ -69,10 +69,6 @@ const std::string EMSdevice::tag_to_string(uint8_t tag) {
|
|||||||
return uuid::read_flash_string(DeviceValueTAG_s[tag - 1]); // offset by 1 to account for NONE
|
return uuid::read_flash_string(DeviceValueTAG_s[tag - 1]); // offset by 1 to account for NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<EMSdevice::DeviceValue> EMSdevice::devicevalues() const {
|
|
||||||
return devicevalues_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EMSdevice::brand_to_string() const {
|
std::string EMSdevice::brand_to_string() const {
|
||||||
switch (brand_) {
|
switch (brand_) {
|
||||||
case EMSdevice::Brand::BOSCH:
|
case EMSdevice::Brand::BOSCH:
|
||||||
@@ -264,7 +260,7 @@ std::string EMSdevice::to_string_short() const {
|
|||||||
void EMSdevice::fetch_values() {
|
void EMSdevice::fetch_values() {
|
||||||
EMSESP::logger().debug(F("Fetching values for device ID 0x%02X"), device_id());
|
EMSESP::logger().debug(F("Fetching values for device ID 0x%02X"), device_id());
|
||||||
|
|
||||||
for (const auto & tf : telegram_functions_) {
|
for (const auto & tf : *telegram_functions_) {
|
||||||
if (tf.fetch_) {
|
if (tf.fetch_) {
|
||||||
read_command(tf.telegram_type_id_);
|
read_command(tf.telegram_type_id_);
|
||||||
}
|
}
|
||||||
@@ -275,7 +271,7 @@ void EMSdevice::fetch_values() {
|
|||||||
void EMSdevice::toggle_fetch(uint16_t telegram_id, bool toggle) {
|
void EMSdevice::toggle_fetch(uint16_t telegram_id, bool toggle) {
|
||||||
EMSESP::logger().debug(F("Toggling fetch for device ID 0x%02X, telegram ID 0x%02X to %d"), device_id(), telegram_id, toggle);
|
EMSESP::logger().debug(F("Toggling fetch for device ID 0x%02X, telegram ID 0x%02X to %d"), device_id(), telegram_id, toggle);
|
||||||
|
|
||||||
for (auto & tf : telegram_functions_) {
|
for (auto & tf : *telegram_functions_) {
|
||||||
if (tf.telegram_type_id_ == telegram_id) {
|
if (tf.telegram_type_id_ == telegram_id) {
|
||||||
tf.fetch_ = toggle;
|
tf.fetch_ = toggle;
|
||||||
}
|
}
|
||||||
@@ -284,7 +280,7 @@ void EMSdevice::toggle_fetch(uint16_t telegram_id, bool toggle) {
|
|||||||
|
|
||||||
// get status of automatic fetch for a telegram id
|
// get status of automatic fetch for a telegram id
|
||||||
bool EMSdevice::get_toggle_fetch(uint16_t telegram_id) {
|
bool EMSdevice::get_toggle_fetch(uint16_t telegram_id) {
|
||||||
for (auto & tf : telegram_functions_) {
|
for (auto & tf : *telegram_functions_) {
|
||||||
if (tf.telegram_type_id_ == telegram_id) {
|
if (tf.telegram_type_id_ == telegram_id) {
|
||||||
return tf.fetch_;
|
return tf.fetch_;
|
||||||
}
|
}
|
||||||
@@ -292,15 +288,33 @@ bool EMSdevice::get_toggle_fetch(uint16_t telegram_id) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// list device values
|
||||||
|
void EMSdevice::show_device_values(uuid::console::Shell & shell) {
|
||||||
|
size_t total_s = 0;
|
||||||
|
uint8_t count = 0;
|
||||||
|
for (const auto & dv : *devicevalues_) {
|
||||||
|
size_t s = sizeof(dv);
|
||||||
|
if (dv.full_name) {
|
||||||
|
shell.printfln("[%s] %d", uuid::read_flash_string(dv.full_name).c_str(), s);
|
||||||
|
} else {
|
||||||
|
shell.printfln("[%s]* %d", uuid::read_flash_string(dv.short_name).c_str(), s);
|
||||||
|
}
|
||||||
|
total_s += s;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
shell.printfln("Total size of %d elements: %d", count, total_s);
|
||||||
|
shell.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// list all the telegram type IDs for this device
|
// list all the telegram type IDs for this device
|
||||||
void EMSdevice::show_telegram_handlers(uuid::console::Shell & shell) {
|
void EMSdevice::show_telegram_handlers(uuid::console::Shell & shell) {
|
||||||
if (telegram_functions_.size() == 0) {
|
if (telegram_functions_->size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shell.printf(F(" This %s will respond to telegram type IDs: "), device_type_name().c_str());
|
shell.printf(F(" This %s will respond to telegram type IDs: "), device_type_name().c_str());
|
||||||
for (const auto & tf : telegram_functions_) {
|
for (const auto & tf : *telegram_functions_) {
|
||||||
shell.printf(F("0x%02X "), tf.telegram_type_id_);
|
shell.printf(F("0x%02X "), tf.telegram_type_id_);
|
||||||
}
|
}
|
||||||
shell.println();
|
shell.println();
|
||||||
@@ -308,16 +322,17 @@ void EMSdevice::show_telegram_handlers(uuid::console::Shell & shell) {
|
|||||||
|
|
||||||
// list all the telegram type IDs for this device, outputting to a string (max size 200)
|
// list all the telegram type IDs for this device, outputting to a string (max size 200)
|
||||||
char * EMSdevice::show_telegram_handlers(char * result) {
|
char * EMSdevice::show_telegram_handlers(char * result) {
|
||||||
|
uint8_t size = telegram_functions_->size();
|
||||||
|
|
||||||
strlcpy(result, "", 200);
|
strlcpy(result, "", 200);
|
||||||
|
|
||||||
if (telegram_functions_.size() == 0) {
|
if (!size) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char str[10];
|
char str[10];
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
size_t size = telegram_functions_.size();
|
for (const auto & tf : *telegram_functions_) {
|
||||||
for (const auto & tf : telegram_functions_) {
|
|
||||||
snprintf_P(str, sizeof(str), PSTR("0x%02X"), tf.telegram_type_id_);
|
snprintf_P(str, sizeof(str), PSTR("0x%02X"), tf.telegram_type_id_);
|
||||||
strlcat(result, str, 200);
|
strlcat(result, str, 200);
|
||||||
if (++i < size) {
|
if (++i < size) {
|
||||||
@@ -339,12 +354,26 @@ void EMSdevice::register_mqtt_topic(const std::string & topic, mqtt_subfunction_
|
|||||||
|
|
||||||
// add command to library
|
// add command to library
|
||||||
void EMSdevice::register_mqtt_cmd(const __FlashStringHelper * cmd, cmdfunction_p f) {
|
void EMSdevice::register_mqtt_cmd(const __FlashStringHelper * cmd, cmdfunction_p f) {
|
||||||
Command::add(device_type_, device_id_, cmd, f);
|
Command::add(device_type_, cmd, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// register a call back function for a specific telegram type
|
// register a call back function for a specific telegram type
|
||||||
void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, process_function_p f) {
|
void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, process_function_p f) {
|
||||||
telegram_functions_.emplace_back(telegram_type_id, telegram_type_name, fetch, f);
|
TelegramFunction tf;
|
||||||
|
tf.fetch_ = fetch;
|
||||||
|
tf.process_function_ = f;
|
||||||
|
tf.telegram_type_id_ = telegram_type_id;
|
||||||
|
tf.telegram_type_name_ = telegram_type_name;
|
||||||
|
telegram_functions_->push(tf);
|
||||||
|
|
||||||
|
// TelegramFunction(uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, process_function_p process_function)
|
||||||
|
// : telegram_type_id_(telegram_type_id)
|
||||||
|
// , telegram_type_name_(telegram_type_name)
|
||||||
|
// , fetch_(fetch)
|
||||||
|
// , process_function_(process_function) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// telegram_functions_.emplace_back(telegram_type_id, telegram_type_name, fetch, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add to device value library
|
// add to device value library
|
||||||
@@ -357,14 +386,13 @@ void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __
|
|||||||
// full name: used in Web and Console
|
// full name: used in Web and Console
|
||||||
// uom: unit of measure from DeviceValueUOM
|
// uom: unit of measure from DeviceValueUOM
|
||||||
// icon (optional): the HA mdi icon to use, from locale_*.h file
|
// icon (optional): the HA mdi icon to use, from locale_*.h file
|
||||||
void EMSdevice::register_device_value(uint8_t tag,
|
void EMSdevice::register_device_value(uint8_t tag,
|
||||||
void * value_p,
|
void * value_p,
|
||||||
uint8_t type,
|
uint8_t type,
|
||||||
const flash_string_vector & options,
|
const __FlashStringHelper * const * options,
|
||||||
const __FlashStringHelper * short_name,
|
const __FlashStringHelper * short_name,
|
||||||
const __FlashStringHelper * full_name,
|
const __FlashStringHelper * full_name,
|
||||||
uint8_t uom,
|
uint8_t uom) {
|
||||||
const __FlashStringHelper * icon) {
|
|
||||||
// init the value depending on it's type
|
// init the value depending on it's type
|
||||||
if (type == DeviceValueType::TEXT) {
|
if (type == DeviceValueType::TEXT) {
|
||||||
*(char *)(value_p) = {'\0'};
|
*(char *)(value_p) = {'\0'};
|
||||||
@@ -382,7 +410,26 @@ void EMSdevice::register_device_value(uint8_t tag,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add to our library
|
// add to our library
|
||||||
devicevalues_.emplace_back(device_type_, tag, value_p, type, options, short_name, full_name, uom, icon);
|
DeviceValue dv;
|
||||||
|
dv.device_type = device_type_;
|
||||||
|
dv.tag = tag;
|
||||||
|
dv.value_p = value_p;
|
||||||
|
dv.type = type;
|
||||||
|
dv.short_name = short_name;
|
||||||
|
dv.full_name = full_name;
|
||||||
|
dv.uom = uom;
|
||||||
|
|
||||||
|
dv.options = options;
|
||||||
|
dv.options_size = 0;
|
||||||
|
// count #options
|
||||||
|
if (options != nullptr) {
|
||||||
|
uint8_t i = 0;
|
||||||
|
while (options[i++]) {
|
||||||
|
dv.options_size++;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
devicevalues_->push(dv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// looks up the uom (suffix) for a given key from the device value table
|
// looks up the uom (suffix) for a given key from the device value table
|
||||||
@@ -397,7 +444,10 @@ std::string EMSdevice::get_value_uom(const char * key) {
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & dv : devicevalues_) {
|
// find the key (p) in the name
|
||||||
|
// because the new container is not multi-threaded can't use the iterator
|
||||||
|
for (uint8_t i = 0; i < devicevalues_->size(); i++) {
|
||||||
|
auto dv = (*devicevalues_)[i];
|
||||||
if (dv.full_name != nullptr) {
|
if (dv.full_name != nullptr) {
|
||||||
if (uuid::read_flash_string(dv.full_name) == p) {
|
if (uuid::read_flash_string(dv.full_name) == p) {
|
||||||
// ignore TIME since "minutes" is already included
|
// ignore TIME since "minutes" is already included
|
||||||
@@ -419,13 +469,16 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
|||||||
JsonArray data = json.createNestedArray("data");
|
JsonArray data = json.createNestedArray("data");
|
||||||
|
|
||||||
uint8_t num_elements = 0;
|
uint8_t num_elements = 0;
|
||||||
for (const auto & dv : devicevalues_) {
|
for (uint8_t i = 0; i < devicevalues_->size(); i++) {
|
||||||
|
auto dv = (*devicevalues_)[i];
|
||||||
|
|
||||||
|
// for (const auto & dv : devicevalues()) {
|
||||||
// ignore if full_name empty
|
// ignore if full_name empty
|
||||||
if (dv.full_name != nullptr) {
|
if (dv.full_name != nullptr) {
|
||||||
// handle Booleans (true, false)
|
// handle Booleans (true, false)
|
||||||
if ((dv.type == DeviceValueType::BOOL) && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
if ((dv.type == DeviceValueType::BOOL) && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
||||||
// see if we have options for the bool's
|
// see if we have options for the bool's
|
||||||
if (dv.options.size() == 2) {
|
if (dv.options_size == 2) {
|
||||||
data.add(*(uint8_t *)(dv.value_p) ? dv.options[0] : dv.options[1]);
|
data.add(*(uint8_t *)(dv.value_p) ? dv.options[0] : dv.options[1]);
|
||||||
} else {
|
} else {
|
||||||
// see how to render the value depending on the setting
|
// see how to render the value depending on the setting
|
||||||
@@ -449,7 +502,7 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
|||||||
|
|
||||||
// handle ENUMs
|
// handle ENUMs
|
||||||
else if ((dv.type == DeviceValueType::ENUM) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
else if ((dv.type == DeviceValueType::ENUM) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
||||||
if (*(uint8_t *)(dv.value_p) < dv.options.size()) {
|
if (*(uint8_t *)(dv.value_p) < dv.options_size) {
|
||||||
data.add(dv.options[*(uint8_t *)(dv.value_p)]);
|
data.add(dv.options[*(uint8_t *)(dv.value_p)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -459,7 +512,7 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
|||||||
// If a divider is specified, do the division to 2 decimals places and send back as double/float
|
// If a divider is specified, do the division to 2 decimals places and send back as double/float
|
||||||
// otherwise force as an integer whole
|
// otherwise force as an integer whole
|
||||||
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
|
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
|
||||||
uint8_t divider = (dv.options.size() == 1) ? Helpers::atoint(uuid::read_flash_string(dv.options[0]).c_str()) : 0;
|
uint8_t divider = ((dv.options_size) == 1) ? Helpers::atoint(uuid::read_flash_string(dv.options[0]).c_str()) : 0;
|
||||||
|
|
||||||
// INT
|
// INT
|
||||||
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) {
|
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) {
|
||||||
@@ -536,7 +589,9 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter
|
|||||||
uint8_t old_tag = 255;
|
uint8_t old_tag = 255;
|
||||||
JsonObject json = root;
|
JsonObject json = root;
|
||||||
|
|
||||||
for (const auto & dv : devicevalues_) {
|
for (uint8_t i = 0; i < devicevalues_->size(); i++) {
|
||||||
|
auto dv = (*devicevalues_)[i];
|
||||||
|
// for (const auto & dv : devicevalues()) {
|
||||||
// only show if tag is either empty or matches a value, and don't show if full_name is empty unless we're outputing for mqtt payloads
|
// only show if tag is either empty or matches a value, and don't show if full_name is empty unless we're outputing for mqtt payloads
|
||||||
if (((tag_filter == DeviceValueTAG::TAG_NONE) || (tag_filter == dv.tag)) && (dv.full_name != nullptr || !verbose)) {
|
if (((tag_filter == DeviceValueTAG::TAG_NONE) || (tag_filter == dv.tag)) && (dv.full_name != nullptr || !verbose)) {
|
||||||
bool have_tag = ((dv.tag != DeviceValueTAG::TAG_NONE) && (dv.device_type != DeviceType::BOILER));
|
bool have_tag = ((dv.tag != DeviceValueTAG::TAG_NONE) && (dv.device_type != DeviceType::BOILER));
|
||||||
@@ -561,7 +616,7 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter
|
|||||||
// handle Booleans (true, false)
|
// handle Booleans (true, false)
|
||||||
if ((dv.type == DeviceValueType::BOOL) && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
if ((dv.type == DeviceValueType::BOOL) && Helpers::hasValue(*(uint8_t *)(dv.value_p), EMS_VALUE_BOOL)) {
|
||||||
// see if we have options for the bool's
|
// see if we have options for the bool's
|
||||||
if (dv.options.size() == 2) {
|
if (dv.options_size == 2) {
|
||||||
json[name] = *(uint8_t *)(dv.value_p) ? dv.options[0] : dv.options[1];
|
json[name] = *(uint8_t *)(dv.value_p) ? dv.options[0] : dv.options[1];
|
||||||
has_value = true;
|
has_value = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -590,7 +645,7 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter
|
|||||||
|
|
||||||
// handle ENUMs
|
// handle ENUMs
|
||||||
else if ((dv.type == DeviceValueType::ENUM) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
else if ((dv.type == DeviceValueType::ENUM) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
||||||
if (*(uint8_t *)(dv.value_p) < dv.options.size()) {
|
if (*(uint8_t *)(dv.value_p) < dv.options_size) {
|
||||||
json[name] = dv.options[*(uint8_t *)(dv.value_p)];
|
json[name] = dv.options[*(uint8_t *)(dv.value_p)];
|
||||||
has_value = true;
|
has_value = true;
|
||||||
}
|
}
|
||||||
@@ -601,7 +656,7 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter
|
|||||||
// If a divider is specified, do the division to 2 decimals places and send back as double/float
|
// If a divider is specified, do the division to 2 decimals places and send back as double/float
|
||||||
// otherwise force as an integer whole
|
// otherwise force as an integer whole
|
||||||
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
|
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
|
||||||
uint8_t divider = (dv.options.size() == 1) ? Helpers::atoint(uuid::read_flash_string(dv.options[0]).c_str()) : 0;
|
uint8_t divider = (dv.options_size == 1) ? Helpers::atoint(uuid::read_flash_string(dv.options[0]).c_str()) : 0;
|
||||||
|
|
||||||
// INT
|
// INT
|
||||||
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) {
|
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) {
|
||||||
@@ -658,6 +713,17 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter
|
|||||||
return has_value;
|
return has_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create the Home Assistant configs for each value as a sensor
|
||||||
|
void EMSdevice::publish_mqtt_ha_sensor() {
|
||||||
|
for (const auto & dv : *devicevalues_) {
|
||||||
|
Mqtt::register_mqtt_ha_sensor(dv.type, dv.tag, dv.full_name, device_type_, dv.short_name, dv.uom);
|
||||||
|
}
|
||||||
|
|
||||||
|
// publish it
|
||||||
|
bool ok = publish_ha_config();
|
||||||
|
ha_config_done(ok); // see if it worked
|
||||||
|
}
|
||||||
|
|
||||||
// return the name of the telegram type
|
// return the name of the telegram type
|
||||||
std::string EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> telegram) {
|
std::string EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> telegram) {
|
||||||
// see if it's one of the common ones, like Version
|
// see if it's one of the common ones, like Version
|
||||||
@@ -667,7 +733,7 @@ std::string EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> telegr
|
|||||||
return read_flash_string(F("UBADevices"));
|
return read_flash_string(F("UBADevices"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & tf : telegram_functions_) {
|
for (const auto & tf : *telegram_functions_) {
|
||||||
if ((tf.telegram_type_id_ == telegram->type_id) && (telegram->type_id != 0xFF)) {
|
if ((tf.telegram_type_id_ == telegram->type_id) && (telegram->type_id != 0xFF)) {
|
||||||
return uuid::read_flash_string(tf.telegram_type_name_);
|
return uuid::read_flash_string(tf.telegram_type_name_);
|
||||||
}
|
}
|
||||||
@@ -679,7 +745,7 @@ std::string EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> telegr
|
|||||||
// take a telegram_type_id and call the matching handler
|
// take a telegram_type_id and call the matching handler
|
||||||
// return true if match found
|
// return true if match found
|
||||||
bool EMSdevice::handle_telegram(std::shared_ptr<const Telegram> telegram) {
|
bool EMSdevice::handle_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||||
for (const auto & tf : telegram_functions_) {
|
for (const auto & tf : *telegram_functions_) {
|
||||||
if (tf.telegram_type_id_ == telegram->type_id) {
|
if (tf.telegram_type_id_ == telegram->type_id) {
|
||||||
// if the data block is empty, assume that this telegram is not recognized by the bus master
|
// if the data block is empty, assume that this telegram is not recognized by the bus master
|
||||||
// so remove it from the automatic fetch list
|
// so remove it from the automatic fetch list
|
||||||
@@ -689,7 +755,10 @@ bool EMSdevice::handle_telegram(std::shared_ptr<const Telegram> telegram) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tf.process_function_(telegram);
|
if (telegram->message_length > 0) {
|
||||||
|
tf.process_function_(telegram);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include "containers.h"
|
||||||
#include "emsfactory.h"
|
#include "emsfactory.h"
|
||||||
#include "telegram.h"
|
#include "telegram.h"
|
||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
@@ -212,10 +213,13 @@ class EMSdevice {
|
|||||||
std::string to_string_short() const;
|
std::string to_string_short() const;
|
||||||
|
|
||||||
void show_telegram_handlers(uuid::console::Shell & shell);
|
void show_telegram_handlers(uuid::console::Shell & shell);
|
||||||
|
void show_device_values(uuid::console::Shell & shell);
|
||||||
char * show_telegram_handlers(char * result);
|
char * show_telegram_handlers(char * result);
|
||||||
void show_mqtt_handlers(uuid::console::Shell & shell);
|
void show_mqtt_handlers(uuid::console::Shell & shell);
|
||||||
|
|
||||||
using process_function_p = std::function<void(std::shared_ptr<const Telegram>)>;
|
using process_function_p = std::function<void(std::shared_ptr<const Telegram>)>;
|
||||||
|
// using process_function_p = void (*)(std::shared_ptr<const Telegram>);
|
||||||
|
|
||||||
void register_telegram_type(const uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, process_function_p cb);
|
void register_telegram_type(const uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, process_function_p cb);
|
||||||
bool handle_telegram(std::shared_ptr<const Telegram> telegram);
|
bool handle_telegram(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
@@ -223,14 +227,13 @@ class EMSdevice {
|
|||||||
bool generate_values_json(JsonObject & json, const uint8_t tag_filter, const bool verbose = false);
|
bool generate_values_json(JsonObject & json, const uint8_t tag_filter, const bool verbose = false);
|
||||||
bool generate_values_json_web(JsonObject & json);
|
bool generate_values_json_web(JsonObject & json);
|
||||||
|
|
||||||
void register_device_value(uint8_t tag,
|
void register_device_value(uint8_t tag,
|
||||||
void * value_p,
|
void * value_p,
|
||||||
uint8_t type,
|
uint8_t type,
|
||||||
const flash_string_vector & options,
|
const __FlashStringHelper * const * options,
|
||||||
const __FlashStringHelper * short_name,
|
const __FlashStringHelper * short_name,
|
||||||
const __FlashStringHelper * full_name,
|
const __FlashStringHelper * full_name,
|
||||||
uint8_t uom,
|
uint8_t uom);
|
||||||
const __FlashStringHelper * icon = nullptr);
|
|
||||||
|
|
||||||
void write_command(const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid);
|
void write_command(const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid);
|
||||||
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid);
|
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid);
|
||||||
@@ -240,16 +243,14 @@ class EMSdevice {
|
|||||||
void register_mqtt_topic(const std::string & topic, mqtt_subfunction_p f);
|
void register_mqtt_topic(const std::string & topic, mqtt_subfunction_p f);
|
||||||
void register_mqtt_cmd(const __FlashStringHelper * cmd, cmdfunction_p f);
|
void register_mqtt_cmd(const __FlashStringHelper * cmd, cmdfunction_p f);
|
||||||
|
|
||||||
|
void publish_mqtt_ha_sensor();
|
||||||
|
|
||||||
std::string telegram_type_name(std::shared_ptr<const Telegram> telegram);
|
std::string telegram_type_name(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
void fetch_values();
|
void fetch_values();
|
||||||
void toggle_fetch(uint16_t telegram_id, bool toggle);
|
void toggle_fetch(uint16_t telegram_id, bool toggle);
|
||||||
bool get_toggle_fetch(uint16_t telegram_id);
|
bool get_toggle_fetch(uint16_t telegram_id);
|
||||||
|
|
||||||
void reserve_mem(size_t n) {
|
|
||||||
telegram_functions_.reserve(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ha_config_done() const {
|
bool ha_config_done() const {
|
||||||
return ha_config_done_;
|
return ha_config_done_;
|
||||||
}
|
}
|
||||||
@@ -318,41 +319,14 @@ class EMSdevice {
|
|||||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC100 = 9;
|
static constexpr uint8_t EMS_DEVICE_FLAG_RC100 = 9;
|
||||||
static constexpr uint8_t EMS_DEVICE_FLAG_JUNKERS = 10;
|
static constexpr uint8_t EMS_DEVICE_FLAG_JUNKERS = 10;
|
||||||
|
|
||||||
struct DeviceValue {
|
void reserve_device_values(uint8_t elements) {
|
||||||
uint8_t device_type; // EMSdevice::DeviceType
|
static auto dv_ = emsesp::array<DeviceValue>(elements, 255, 16);
|
||||||
uint8_t tag; // DeviceValueTAG::*
|
devicevalues_ = &dv_;
|
||||||
void * value_p; // pointer to variable of any type
|
}
|
||||||
uint8_t type; // DeviceValueType::*
|
|
||||||
const flash_string_vector options; // list of options for ENUM, or divider
|
|
||||||
const __FlashStringHelper * short_name; // used in MQTT
|
|
||||||
const __FlashStringHelper * full_name; // used in Web and Console
|
|
||||||
uint8_t uom; // DeviceValueUOM::*
|
|
||||||
const __FlashStringHelper * icon; // HA icon
|
|
||||||
|
|
||||||
DeviceValue(uint8_t device_type,
|
void reserve_telgram_functions(uint8_t elements) {
|
||||||
uint8_t tag,
|
static auto tf_ = emsesp::array<TelegramFunction>(elements, 255, 16);
|
||||||
void * value_p,
|
telegram_functions_ = &tf_;
|
||||||
uint8_t type,
|
|
||||||
const flash_string_vector options,
|
|
||||||
const __FlashStringHelper * short_name,
|
|
||||||
const __FlashStringHelper * full_name,
|
|
||||||
uint8_t uom,
|
|
||||||
const __FlashStringHelper * icon)
|
|
||||||
: device_type(device_type)
|
|
||||||
, tag(tag)
|
|
||||||
, value_p(value_p)
|
|
||||||
, type(type)
|
|
||||||
, options(options)
|
|
||||||
, short_name(short_name)
|
|
||||||
, full_name(full_name)
|
|
||||||
, uom(uom)
|
|
||||||
, icon(icon) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const std::vector<DeviceValue> devicevalues() const;
|
|
||||||
|
|
||||||
void init_devicevalues(uint8_t size) {
|
|
||||||
devicevalues_.reserve(size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -373,17 +347,21 @@ class EMSdevice {
|
|||||||
const __FlashStringHelper * telegram_type_name_; // e.g. RC20Message
|
const __FlashStringHelper * telegram_type_name_; // e.g. RC20Message
|
||||||
bool fetch_; // if this type_id be queried automatically
|
bool fetch_; // if this type_id be queried automatically
|
||||||
process_function_p process_function_;
|
process_function_p process_function_;
|
||||||
|
|
||||||
TelegramFunction(uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, process_function_p process_function)
|
|
||||||
: telegram_type_id_(telegram_type_id)
|
|
||||||
, telegram_type_name_(telegram_type_name)
|
|
||||||
, fetch_(fetch)
|
|
||||||
, process_function_(process_function) {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types
|
emsesp::array<TelegramFunction> * telegram_functions_; // each EMS device has its own set of registered telegram types
|
||||||
|
|
||||||
std::vector<DeviceValue> devicevalues_;
|
struct DeviceValue {
|
||||||
|
uint8_t device_type; // EMSdevice::DeviceType
|
||||||
|
uint8_t tag; // DeviceValueTAG::*
|
||||||
|
void * value_p; // pointer to variable of any type
|
||||||
|
uint8_t type; // DeviceValueType::*
|
||||||
|
const __FlashStringHelper * const * options; // options as a flash char array
|
||||||
|
uint8_t options_size; // # options in the char array, calculated
|
||||||
|
const __FlashStringHelper * short_name; // used in MQTT
|
||||||
|
const __FlashStringHelper * full_name; // used in Web and Console
|
||||||
|
uint8_t uom; // DeviceValueUOM::*
|
||||||
|
};
|
||||||
|
emsesp::array<DeviceValue> * devicevalues_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
100
src/emsesp.cpp
100
src/emsesp.cpp
@@ -20,6 +20,12 @@
|
|||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
#if defined(EMSESP_STANDALONE)
|
||||||
|
uint32_t heap_start = 0;
|
||||||
|
#else
|
||||||
|
uint32_t heap_start = ESP.getFreeHeap(); // get initial available heap memory
|
||||||
|
#endif
|
||||||
|
|
||||||
AsyncWebServer webServer(80);
|
AsyncWebServer webServer(80);
|
||||||
|
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
@@ -38,10 +44,11 @@ WebStatusService EMSESP::webStatusService = WebStatusService(&webServer, EMSES
|
|||||||
WebDevicesService EMSESP::webDevicesService = WebDevicesService(&webServer, EMSESP::esp8266React.getSecurityManager());
|
WebDevicesService EMSESP::webDevicesService = WebDevicesService(&webServer, EMSESP::esp8266React.getSecurityManager());
|
||||||
WebAPIService EMSESP::webAPIService = WebAPIService(&webServer);
|
WebAPIService EMSESP::webAPIService = WebAPIService(&webServer);
|
||||||
|
|
||||||
using DeviceFlags = emsesp::EMSdevice;
|
using DeviceFlags = EMSdevice;
|
||||||
using DeviceType = emsesp::EMSdevice::DeviceType;
|
using DeviceType = EMSdevice::DeviceType;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<EMSdevice>> EMSESP::emsdevices; // array of all the detected EMS devices
|
std::vector<std::unique_ptr<EMSdevice>> EMSESP::emsdevices; // array of all the detected EMS devices
|
||||||
std::vector<emsesp::EMSESP::Device_record> EMSESP::device_library_; // library of all our known EMS devices so far
|
std::vector<emsesp::EMSESP::Device_record> EMSESP::device_library_; // library of all our known EMS devices, in heap
|
||||||
|
|
||||||
uuid::log::Logger EMSESP::logger_{F_(emsesp), uuid::log::Facility::KERN};
|
uuid::log::Logger EMSESP::logger_{F_(emsesp), uuid::log::Facility::KERN};
|
||||||
|
|
||||||
@@ -410,16 +417,7 @@ void EMSESP::publish_device_values(uint8_t device_type) {
|
|||||||
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||||
// if we're using HA and it's not already done, send the config topics first. only do this once
|
// if we're using HA and it's not already done, send the config topics first. only do this once
|
||||||
if (Mqtt::ha_enabled() && (!emsdevice->ha_config_done())) {
|
if (Mqtt::ha_enabled() && (!emsdevice->ha_config_done())) {
|
||||||
// create the configs for each value as a sensor
|
emsdevice->publish_mqtt_ha_sensor(); // create the configs for each value as a sensor
|
||||||
for (const auto & dv : emsdevice->devicevalues()) {
|
|
||||||
if (dv.device_type == device_type) {
|
|
||||||
Mqtt::register_mqtt_ha_sensor(dv.type, dv.tag, dv.full_name, device_type, dv.short_name, dv.uom, dv.icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create HA device
|
|
||||||
// if this is done early, it may fail for some reason
|
|
||||||
emsdevice->ha_config_done(emsdevice->publish_ha_config());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if its a boiler, generate json for each group and publish it
|
// if its a boiler, generate json for each group and publish it
|
||||||
@@ -771,26 +769,14 @@ void EMSESP::show_devices(uuid::console::Shell & shell) {
|
|||||||
}
|
}
|
||||||
shell.println();
|
shell.println();
|
||||||
emsdevice->show_telegram_handlers(shell);
|
emsdevice->show_telegram_handlers(shell);
|
||||||
// emsdevice->show_mqtt_handlers(shell);
|
|
||||||
shell.println();
|
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined EMSESP_DEBUG
|
||||||
// TODO debug stuff - count size of objects
|
emsdevice->show_mqtt_handlers(shell);
|
||||||
size_t total_s = 0;
|
|
||||||
uint8_t count = 0;
|
|
||||||
for (const auto & dv : emsdevice->devicevalues()) {
|
|
||||||
size_t s = sizeof(dv);
|
|
||||||
if (dv.full_name) {
|
|
||||||
shell.printfln("[%s] %d", uuid::read_flash_string(dv.full_name).c_str(), s);
|
|
||||||
} else {
|
|
||||||
shell.printfln("[%s]* %d", uuid::read_flash_string(dv.short_name).c_str(), s);
|
|
||||||
}
|
|
||||||
total_s += s;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
shell.printfln("Total size of %d elements: %d", count, total_s);
|
|
||||||
shell.println();
|
shell.println();
|
||||||
|
emsdevice->show_device_values(shell);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shell.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1039,33 +1025,55 @@ void EMSESP::send_raw_telegram(const char * data) {
|
|||||||
// start all the core services
|
// start all the core services
|
||||||
// the services must be loaded in the correct order
|
// the services must be loaded in the correct order
|
||||||
void EMSESP::start() {
|
void EMSESP::start() {
|
||||||
// see if we need to migrate from previous versions
|
// start the file system. We use LittleFS for ESP8266.
|
||||||
if (!system_.check_upgrade()) {
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
SPIFFS.begin(true);
|
SPIFFS.begin(true);
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
LittleFS.begin();
|
LittleFS.begin();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
esp8266React.begin(); // loads system settings (wifi, mqtt, etc)
|
esp8266React.begin(); // loads system settings (wifi, mqtt, etc)
|
||||||
webSettingsService.begin(); // load EMS-ESP specific settings
|
webSettingsService.begin(); // load EMS-ESP specific settings
|
||||||
}
|
|
||||||
|
|
||||||
// Load our library of known devices into stack mem. Names are stored in Flash mem.
|
system_.check_upgrade(); // do any upgrades
|
||||||
// device_library_.reserve(80);
|
|
||||||
|
#if defined(EMSESP_DEBUG)
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
|
uint32_t tbefore = ESP.getFreeHeap();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Load our library of known devices into stack mem. Names are stored in Flash memory
|
||||||
|
// Still it takes up about 960bytes
|
||||||
|
device_library_.reserve(80);
|
||||||
device_library_ = {
|
device_library_ = {
|
||||||
#include "device_library.h"
|
#include "device_library.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
console_.start(); // telnet and serial console
|
#if defined(EMSESP_DEBUG)
|
||||||
mqtt_.start(); // mqtt init
|
#ifndef EMSESP_STANDALONE
|
||||||
system_.start(); // starts syslog, uart, sets version, initializes LED. Requires pre-loaded settings.
|
uint32_t tafter = ESP.getFreeHeap();
|
||||||
shower_.start(); // initialize shower timer and shower alert
|
#endif
|
||||||
dallassensor_.start(); // dallas external sensors
|
#endif
|
||||||
webServer.begin(); // start web server
|
|
||||||
|
console_.start(); // telnet and serial console
|
||||||
|
mqtt_.start(); // mqtt init
|
||||||
|
system_.start(heap_start); // starts syslog, uart, sets version, initializes LED. Requires pre-loaded settings.
|
||||||
|
shower_.start(); // initialize shower timer and shower alert
|
||||||
|
dallassensor_.start(); // dallas external sensors
|
||||||
|
webServer.begin(); // start web server
|
||||||
|
|
||||||
|
// emsdevices.reserve(5); // reserve space for initially 5 devices to avoid mem frag issues
|
||||||
|
|
||||||
emsdevices.reserve(5); // reserve space for initially 5 devices to avoid mem frag issues
|
|
||||||
LOG_INFO(F("EMS Device library loaded with %d records"), device_library_.size());
|
LOG_INFO(F("EMS Device library loaded with %d records"), device_library_.size());
|
||||||
|
|
||||||
|
#if defined(EMSESP_DEBUG)
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
|
LOG_INFO(F("Used %d mem for devices"), tbefore - tafter);
|
||||||
|
System::show_mem("after start()");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// main loop calling all services
|
// main loop calling all services
|
||||||
|
|||||||
@@ -22,9 +22,10 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <queue>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
#include <uuid/common.h>
|
#include <uuid/common.h>
|
||||||
#include <uuid/console.h>
|
#include <uuid/console.h>
|
||||||
#include <uuid/log.h>
|
#include <uuid/log.h>
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
#include "WebSettingsService.h"
|
#include "WebSettingsService.h"
|
||||||
#include "WebAPIService.h"
|
#include "WebAPIService.h"
|
||||||
|
|
||||||
|
#include "containers.h"
|
||||||
#include "emsdevice.h"
|
#include "emsdevice.h"
|
||||||
#include "emsfactory.h"
|
#include "emsfactory.h"
|
||||||
#include "telegram.h"
|
#include "telegram.h"
|
||||||
|
|||||||
@@ -355,8 +355,9 @@ double Helpers::round2(double value, const uint8_t divider) {
|
|||||||
return (int)((value / divider) * 100 + 0.5) / 100.0;
|
return (int)((value / divider) * 100 + 0.5) / 100.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Helpers::check_abs(const int32_t i) {
|
// abs of a signed 32-bit integer
|
||||||
return ((i < 0 ? -i : i) != 0xFFFFFF);
|
uint32_t Helpers::abs(const int32_t i) {
|
||||||
|
return (i < 0 ? -i : i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for booleans, use isBool true (EMS_VALUE_BOOL)
|
// for booleans, use isBool true (EMS_VALUE_BOOL)
|
||||||
@@ -467,6 +468,4 @@ bool Helpers::value2enum(const char * v, uint8_t & value, const flash_string_vec
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class Helpers {
|
|||||||
static uint32_t hextoint(const char * hex);
|
static uint32_t hextoint(const char * hex);
|
||||||
static uint16_t atoint(const char * value);
|
static uint16_t atoint(const char * value);
|
||||||
static bool check_abs(const int32_t i);
|
static bool check_abs(const int32_t i);
|
||||||
|
static uint32_t abs(const int32_t i);
|
||||||
static double round2(double value, const uint8_t divider);
|
static double round2(double value, const uint8_t divider);
|
||||||
static std::string toLower(std::string const & s);
|
static std::string toLower(std::string const & s);
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
// common words
|
// common words
|
||||||
MAKE_PSTR_WORD(exit)
|
MAKE_PSTR_WORD(exit)
|
||||||
MAKE_PSTR_WORD(help)
|
MAKE_PSTR_WORD(help)
|
||||||
@@ -125,3 +127,38 @@ MAKE_PSTR(new_password_prompt1, "Enter new password: ")
|
|||||||
MAKE_PSTR(new_password_prompt2, "Retype new password: ")
|
MAKE_PSTR(new_password_prompt2, "Retype new password: ")
|
||||||
MAKE_PSTR(password_prompt, "Password: ")
|
MAKE_PSTR(password_prompt, "Password: ")
|
||||||
MAKE_PSTR(unset, "<unset>")
|
MAKE_PSTR(unset, "<unset>")
|
||||||
|
|
||||||
|
MAKE_PSTR_WORD(2);
|
||||||
|
MAKE_PSTR_WORD(10);
|
||||||
|
MAKE_PSTR_WORD(100);
|
||||||
|
MAKE_PSTR_WORD(60);
|
||||||
|
|
||||||
|
MAKE_PSTR_LIST(div2, F_(2))
|
||||||
|
MAKE_PSTR_LIST(div10, F_(10))
|
||||||
|
MAKE_PSTR_LIST(div100, F_(100))
|
||||||
|
MAKE_PSTR_LIST(div60, F_(60))
|
||||||
|
|
||||||
|
MAKE_PSTR_WORD(time)
|
||||||
|
MAKE_PSTR_WORD(date)
|
||||||
|
MAKE_PSTR_WORD(1x3min)
|
||||||
|
MAKE_PSTR_WORD(2x3min)
|
||||||
|
MAKE_PSTR_WORD(3x3min)
|
||||||
|
MAKE_PSTR_WORD(4x3min)
|
||||||
|
MAKE_PSTR_WORD(5x3min)
|
||||||
|
MAKE_PSTR_WORD(6x3min)
|
||||||
|
MAKE_PSTR_WORD(continuos);
|
||||||
|
MAKE_PSTR(3wayvalve, "3-way valve")
|
||||||
|
MAKE_PSTR(chargepump, "charge pump")
|
||||||
|
MAKE_PSTR_WORD(hot)
|
||||||
|
MAKE_PSTR_WORD(eco)
|
||||||
|
MAKE_PSTR_WORD(intelligent)
|
||||||
|
MAKE_PSTR_WORD(flow)
|
||||||
|
MAKE_PSTR_WORD(buffer)
|
||||||
|
MAKE_PSTR(bufferedflow, "buffered flow")
|
||||||
|
MAKE_PSTR(layeredbuffer, "layered buffer")
|
||||||
|
|
||||||
|
MAKE_PSTR_LIST(enum_off_time_date, F_(off), F_(time), F_(date))
|
||||||
|
MAKE_PSTR_LIST(enum_freq, F_(off), F_(1x3min), F_(2x3min), F_(3x3min), F_(4x3min), F_(5x3min), F_(6x3min), F_(continuos))
|
||||||
|
MAKE_PSTR_LIST(enum_charge, F_(3wayvalve), F_(chargepump))
|
||||||
|
MAKE_PSTR_LIST(enum_comfort, F_(hot), F_(eco), F_(intelligent))
|
||||||
|
MAKE_PSTR_LIST(enum_flow, F_(off), F_(flow), F_(bufferedflow), F_(buffer), F_(layeredbuffer))
|
||||||
|
|||||||
72
src/mqtt.cpp
72
src/mqtt.cpp
@@ -24,6 +24,7 @@ namespace emsesp {
|
|||||||
|
|
||||||
AsyncMqttClient * Mqtt::mqttClient_;
|
AsyncMqttClient * Mqtt::mqttClient_;
|
||||||
|
|
||||||
|
|
||||||
// static parameters we make global
|
// static parameters we make global
|
||||||
std::string Mqtt::hostname_;
|
std::string Mqtt::hostname_;
|
||||||
uint8_t Mqtt::mqtt_qos_;
|
uint8_t Mqtt::mqtt_qos_;
|
||||||
@@ -39,15 +40,16 @@ uint8_t Mqtt::dallas_format_;
|
|||||||
uint8_t Mqtt::ha_climate_format_;
|
uint8_t Mqtt::ha_climate_format_;
|
||||||
bool Mqtt::ha_enabled_;
|
bool Mqtt::ha_enabled_;
|
||||||
|
|
||||||
|
static emsesp::queue<Mqtt::QueuedMqttMessage> mqtt_messages_ = emsesp::queue<Mqtt::QueuedMqttMessage>(MAX_MQTT_MESSAGES);
|
||||||
|
|
||||||
std::vector<Mqtt::MQTTSubFunction> Mqtt::mqtt_subfunctions_;
|
std::vector<Mqtt::MQTTSubFunction> Mqtt::mqtt_subfunctions_;
|
||||||
|
|
||||||
uint16_t Mqtt::mqtt_publish_fails_ = 0;
|
uint16_t Mqtt::mqtt_publish_fails_ = 0;
|
||||||
bool Mqtt::connecting_ = false;
|
bool Mqtt::connecting_ = false;
|
||||||
bool Mqtt::initialized_ = false;
|
bool Mqtt::initialized_ = false;
|
||||||
uint8_t Mqtt::connectcount_ = 0;
|
uint8_t Mqtt::connectcount_ = 0;
|
||||||
uint16_t Mqtt::mqtt_message_id_ = 0;
|
uint16_t Mqtt::mqtt_message_id_ = 0;
|
||||||
std::list<Mqtt::QueuedMqttMessage> Mqtt::mqtt_messages_;
|
char will_topic_[Mqtt::MQTT_TOPIC_MAX_SIZE]; // because MQTT library keeps only char pointer
|
||||||
char will_topic_[Mqtt::MQTT_TOPIC_MAX_SIZE]; // because MQTT library keeps only char pointer
|
|
||||||
|
|
||||||
uuid::log::Logger Mqtt::logger_{F_(mqtt), uuid::log::Facility::DAEMON};
|
uuid::log::Logger Mqtt::logger_{F_(mqtt), uuid::log::Facility::DAEMON};
|
||||||
|
|
||||||
@@ -506,17 +508,17 @@ void Mqtt::ha_status() {
|
|||||||
|
|
||||||
doc["uniq_id"] = FJSON("status");
|
doc["uniq_id"] = FJSON("status");
|
||||||
doc["~"] = System::hostname(); // default ems-esp
|
doc["~"] = System::hostname(); // default ems-esp
|
||||||
// doc["avty_t"] = FJSON("~/status");
|
// doc["avty_t"] = FJSON("~/status"); // commented out, as it causes errors in HA sometimes
|
||||||
doc["json_attr_t"] = FJSON("~/heartbeat");
|
doc["json_attr_t"] = FJSON("~/heartbeat");
|
||||||
doc["stat_t"] = FJSON("~/heartbeat");
|
doc["stat_t"] = FJSON("~/heartbeat");
|
||||||
doc["name"] = FJSON("EMS-ESP status");
|
doc["name"] = FJSON("EMS-ESP status");
|
||||||
doc["val_tpl"] = FJSON("{{value_json['status']}}");
|
doc["val_tpl"] = FJSON("{{value_json['status']}}");
|
||||||
|
|
||||||
JsonObject dev = doc.createNestedObject("dev");
|
JsonObject dev = doc.createNestedObject("dev");
|
||||||
dev["name"] = FJSON("EMS-ESP");
|
dev["name"] = F_(EMSESP); // "EMS-ESP"
|
||||||
dev["sw"] = EMSESP_APP_VERSION;
|
dev["sw"] = EMSESP_APP_VERSION;
|
||||||
dev["mf"] = FJSON("proddy");
|
dev["mf"] = FJSON("proddy");
|
||||||
dev["mdl"] = FJSON("EMS-ESP");
|
dev["mdl"] = F_(EMSESP); // "EMS-ESP"
|
||||||
JsonArray ids = dev.createNestedArray("ids");
|
JsonArray ids = dev.createNestedArray("ids");
|
||||||
ids.add("ems-esp");
|
ids.add("ems-esp");
|
||||||
|
|
||||||
@@ -545,11 +547,12 @@ std::shared_ptr<const MqttMessage> Mqtt::queue_message(const uint8_t operation,
|
|||||||
message = std::make_shared<MqttMessage>(operation, full_topic, payload, retain);
|
message = std::make_shared<MqttMessage>(operation, full_topic, payload, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the queue is full, make room but removing the last one
|
QueuedMqttMessage qmm;
|
||||||
if (mqtt_messages_.size() >= MAX_MQTT_MESSAGES) {
|
qmm.content_ = std::move(message);
|
||||||
mqtt_messages_.pop_front();
|
qmm.retry_count_ = 0;
|
||||||
}
|
qmm.packet_id_ = 0;
|
||||||
mqtt_messages_.emplace_back(mqtt_message_id_++, std::move(message));
|
qmm.id_ = mqtt_message_id_++;
|
||||||
|
mqtt_messages_.push_back(qmm);
|
||||||
|
|
||||||
return mqtt_messages_.back().content_; // this is because the message has been moved
|
return mqtt_messages_.back().content_; // this is because the message has been moved
|
||||||
}
|
}
|
||||||
@@ -706,7 +709,8 @@ void Mqtt::process_queue() {
|
|||||||
mqtt_messages_.pop_front(); // delete
|
mqtt_messages_.pop_front(); // delete
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
mqtt_messages_.front().retry_count_++;
|
// update the record
|
||||||
|
mqtt_messages_.front_p()->retry_count_++;
|
||||||
LOG_DEBUG(F("Failed to publish to %s. Trying again, #%d"), message->topic.c_str(), mqtt_message.retry_count_ + 1);
|
LOG_DEBUG(F("Failed to publish to %s. Trying again, #%d"), message->topic.c_str(), mqtt_message.retry_count_ + 1);
|
||||||
return; // leave on queue for next time so it gets republished
|
return; // leave on queue for next time so it gets republished
|
||||||
}
|
}
|
||||||
@@ -715,7 +719,7 @@ void Mqtt::process_queue() {
|
|||||||
// if we have ACK set with QOS 1 or 2, leave on queue and let the ACK process remove it
|
// if we have ACK set with QOS 1 or 2, leave on queue and let the ACK process remove it
|
||||||
// but add the packet_id so we can check it later
|
// but add the packet_id so we can check it later
|
||||||
if (mqtt_qos_ != 0) {
|
if (mqtt_qos_ != 0) {
|
||||||
mqtt_messages_.front().packet_id_ = packet_id;
|
mqtt_messages_.front_p()->packet_id_ = packet_id;
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
LOG_DEBUG(F("[DEBUG] Setting packetID for ACK to %d"), packet_id);
|
LOG_DEBUG(F("[DEBUG] Setting packetID for ACK to %d"), packet_id);
|
||||||
#endif
|
#endif
|
||||||
@@ -733,15 +737,13 @@ void Mqtt::register_mqtt_ha_sensor(uint8_t type, // device v
|
|||||||
const __FlashStringHelper * name,
|
const __FlashStringHelper * name,
|
||||||
const uint8_t device_type,
|
const uint8_t device_type,
|
||||||
const __FlashStringHelper * entity,
|
const __FlashStringHelper * entity,
|
||||||
const uint8_t uom,
|
const uint8_t uom) {
|
||||||
const __FlashStringHelper * icon) {
|
|
||||||
// ignore if name (fullname) is empty
|
// ignore if name (fullname) is empty
|
||||||
if (name == nullptr) {
|
if (name == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DynamicJsonDocument doc(EMSESP_JSON_SIZE_HA_CONFIG);
|
DynamicJsonDocument doc(EMSESP_JSON_SIZE_HA_CONFIG);
|
||||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc; // TODO see if this crashes ESP8266?
|
|
||||||
|
|
||||||
bool have_prefix = ((tag != DeviceValueTAG::TAG_NONE) && (device_type != EMSdevice::DeviceType::BOILER));
|
bool have_prefix = ((tag != DeviceValueTAG::TAG_NONE) && (device_type != EMSdevice::DeviceType::BOILER));
|
||||||
|
|
||||||
@@ -791,7 +793,7 @@ void Mqtt::register_mqtt_ha_sensor(uint8_t type, // device v
|
|||||||
// look at the device value type
|
// look at the device value type
|
||||||
if (type != DeviceValueType::BOOL) {
|
if (type != DeviceValueType::BOOL) {
|
||||||
//
|
//
|
||||||
// normal HA sensor
|
// normal HA sensor, not a boolean one
|
||||||
//
|
//
|
||||||
|
|
||||||
// topic
|
// topic
|
||||||
@@ -807,21 +809,17 @@ void Mqtt::register_mqtt_ha_sensor(uint8_t type, // device v
|
|||||||
doc["unit_of_meas"] = EMSdevice::uom_to_string(uom);
|
doc["unit_of_meas"] = EMSdevice::uom_to_string(uom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there was no icon supplied, resort to the default one
|
// map the HA icon
|
||||||
if (icon == nullptr) {
|
switch (uom) {
|
||||||
switch (uom) {
|
case DeviceValueUOM::DEGREES:
|
||||||
case DeviceValueUOM::DEGREES:
|
doc["ic"] = F_(icontemperature);
|
||||||
doc["ic"] = F_(icontemperature);
|
break;
|
||||||
break;
|
case DeviceValueUOM::PERCENT:
|
||||||
case DeviceValueUOM::PERCENT:
|
doc["ic"] = F_(iconpercent);
|
||||||
doc["ic"] = F_(iconpercent);
|
break;
|
||||||
break;
|
case DeviceValueUOM::NONE:
|
||||||
case DeviceValueUOM::NONE:
|
default:
|
||||||
default:
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
doc["ic"] = icon; // must be prefixed with mdi:
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
|
|||||||
47
src/mqtt.h
47
src/mqtt.h
@@ -38,8 +38,18 @@
|
|||||||
|
|
||||||
using uuid::console::Shell;
|
using uuid::console::Shell;
|
||||||
|
|
||||||
|
// time between HA publishes
|
||||||
#define MQTT_HA_PUBLISH_DELAY 50
|
#define MQTT_HA_PUBLISH_DELAY 50
|
||||||
|
|
||||||
|
// size of queue
|
||||||
|
#if defined(EMSESP_STANDALONE)
|
||||||
|
#define MAX_MQTT_MESSAGES 70
|
||||||
|
#elif defined(ESP32)
|
||||||
|
#define MAX_MQTT_MESSAGES 100
|
||||||
|
#else
|
||||||
|
#define MAX_MQTT_MESSAGES 20
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
using mqtt_subfunction_p = std::function<bool(const char * message)>;
|
using mqtt_subfunction_p = std::function<bool(const char * message)>;
|
||||||
@@ -103,8 +113,7 @@ class Mqtt {
|
|||||||
const __FlashStringHelper * name,
|
const __FlashStringHelper * name,
|
||||||
const uint8_t device_type,
|
const uint8_t device_type,
|
||||||
const __FlashStringHelper * entity,
|
const __FlashStringHelper * entity,
|
||||||
const uint8_t uom,
|
const uint8_t uom);
|
||||||
const __FlashStringHelper * icon);
|
|
||||||
static void register_command(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb);
|
static void register_command(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb);
|
||||||
|
|
||||||
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
||||||
@@ -174,37 +183,19 @@ class Mqtt {
|
|||||||
mqtt_retain_ = mqtt_retain;
|
mqtt_retain_ = mqtt_retain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct QueuedMqttMessage {
|
||||||
|
uint16_t id_;
|
||||||
|
std::shared_ptr<const MqttMessage> content_;
|
||||||
|
uint8_t retry_count_;
|
||||||
|
uint16_t packet_id_;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
class QueuedMqttMessage {
|
|
||||||
public:
|
|
||||||
const uint16_t id_;
|
|
||||||
const std::shared_ptr<const MqttMessage> content_;
|
|
||||||
uint8_t retry_count_;
|
|
||||||
uint16_t packet_id_;
|
|
||||||
|
|
||||||
~QueuedMqttMessage() = default;
|
|
||||||
QueuedMqttMessage(uint16_t id, std::shared_ptr<MqttMessage> && content)
|
|
||||||
: id_(id)
|
|
||||||
, content_(std::move(content)) {
|
|
||||||
retry_count_ = 0;
|
|
||||||
packet_id_ = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static std::list<QueuedMqttMessage> mqtt_messages_;
|
|
||||||
|
|
||||||
static AsyncMqttClient * mqttClient_;
|
static AsyncMqttClient * mqttClient_;
|
||||||
static uint16_t mqtt_message_id_;
|
static uint16_t mqtt_message_id_;
|
||||||
|
|
||||||
#if defined(EMSESP_STANDALONE)
|
|
||||||
static constexpr size_t MAX_MQTT_MESSAGES = 70; // size of queue
|
|
||||||
#elif defined(ESP32)
|
|
||||||
static constexpr size_t MAX_MQTT_MESSAGES = 100; // size of queue
|
|
||||||
#else
|
|
||||||
static constexpr size_t MAX_MQTT_MESSAGES = 20; // size of queue
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static constexpr uint32_t MQTT_PUBLISH_WAIT = 200; // delay between sending publishes, to account for large payloads
|
static constexpr uint32_t MQTT_PUBLISH_WAIT = 200; // delay between sending publishes, to account for large payloads
|
||||||
static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing
|
static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing
|
||||||
|
|
||||||
@@ -261,7 +252,7 @@ class Mqtt {
|
|||||||
static uint8_t dallas_format_;
|
static uint8_t dallas_format_;
|
||||||
static uint8_t ha_climate_format_;
|
static uint8_t ha_climate_format_;
|
||||||
static bool ha_enabled_;
|
static bool ha_enabled_;
|
||||||
};
|
}; // namespace emsesp
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|
||||||
|
|||||||
@@ -19,17 +19,8 @@
|
|||||||
#ifndef EMSESP_SHOWER_H
|
#ifndef EMSESP_SHOWER_H
|
||||||
#define EMSESP_SHOWER_H
|
#define EMSESP_SHOWER_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
#include "helpers.h"
|
|
||||||
#include "console.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
class Shower {
|
class Shower {
|
||||||
|
|||||||
@@ -130,17 +130,6 @@ void System::format(uuid::console::Shell & shell) {
|
|||||||
System::restart();
|
System::restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// return free heap mem as a percentage
|
|
||||||
uint8_t System::free_mem() {
|
|
||||||
#ifndef EMSESP_STANDALONE
|
|
||||||
uint32_t free_memory = ESP.getFreeHeap();
|
|
||||||
#else
|
|
||||||
uint32_t free_memory = 1000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (100 * free_memory / heap_start_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void System::syslog_init() {
|
void System::syslog_init() {
|
||||||
int8_t syslog_level_;
|
int8_t syslog_level_;
|
||||||
uint32_t syslog_mark_interval_;
|
uint32_t syslog_mark_interval_;
|
||||||
@@ -182,14 +171,10 @@ void System::syslog_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first call. Sets memory and starts up the UART Serial bridge
|
// first call. Sets memory and starts up the UART Serial bridge
|
||||||
void System::start() {
|
void System::start(uint32_t heap_start) {
|
||||||
// set the inital free mem
|
// set the inital free mem, only on first boot
|
||||||
if (heap_start_ < 2) {
|
if (heap_start_ < 2) {
|
||||||
#ifndef EMSESP_STANDALONE
|
heap_start_ = heap_start;
|
||||||
heap_start_ = ESP.getFreeHeap();
|
|
||||||
#else
|
|
||||||
heap_start_ = 2000;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
@@ -202,15 +187,15 @@ void System::start() {
|
|||||||
|
|
||||||
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
||||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(pin), System::command_pin);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(pin), System::command_pin);
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(send), System::command_send);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send);
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(publish), System::command_publish);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish);
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(fetch), System::command_fetch);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch);
|
||||||
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info);
|
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info);
|
||||||
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(settings), System::command_settings);
|
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(settings), System::command_settings);
|
||||||
|
|
||||||
#if defined(EMSESP_TEST)
|
#if defined(EMSESP_TEST)
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(test), System::command_test);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(test), System::command_test);
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -308,13 +293,12 @@ void System::show_mem(const char * note) {
|
|||||||
static uint8_t old_heap_frag = 0;
|
static uint8_t old_heap_frag = 0;
|
||||||
uint32_t free_heap = ESP.getFreeHeap();
|
uint32_t free_heap = ESP.getFreeHeap();
|
||||||
uint8_t heap_frag = ESP.getHeapFragmentation();
|
uint8_t heap_frag = ESP.getHeapFragmentation();
|
||||||
LOG_INFO(F("(%s) Free heap: %d%% (%lu) (~%lu), frag:%d%% (~%d)"),
|
LOG_INFO(F("(%s) Free heap: %lu (~%lu), frag:%d%% (~%d)"),
|
||||||
note,
|
note,
|
||||||
free_mem(),
|
|
||||||
free_heap,
|
free_heap,
|
||||||
(uint32_t)abs(free_heap - old_free_heap),
|
(uint32_t)Helpers::abs(free_heap - old_free_heap),
|
||||||
heap_frag,
|
heap_frag,
|
||||||
(uint8_t)abs(heap_frag - old_heap_frag));
|
(uint8_t)Helpers::abs(heap_frag - old_heap_frag));
|
||||||
old_free_heap = free_heap;
|
old_free_heap = free_heap;
|
||||||
old_heap_frag = heap_frag;
|
old_heap_frag = heap_frag;
|
||||||
#endif
|
#endif
|
||||||
@@ -329,8 +313,6 @@ void System::send_heartbeat() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t free_memory = free_mem();
|
|
||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
uint8_t frag_memory = ESP.getHeapFragmentation();
|
uint8_t frag_memory = ESP.getHeapFragmentation();
|
||||||
#endif
|
#endif
|
||||||
@@ -352,8 +334,8 @@ void System::send_heartbeat() {
|
|||||||
doc["mqttfails"] = Mqtt::publish_fails();
|
doc["mqttfails"] = Mqtt::publish_fails();
|
||||||
doc["txfails"] = EMSESP::txservice_.telegram_fail_count();
|
doc["txfails"] = EMSESP::txservice_.telegram_fail_count();
|
||||||
doc["rxfails"] = EMSESP::rxservice_.telegram_error_count();
|
doc["rxfails"] = EMSESP::rxservice_.telegram_error_count();
|
||||||
doc["freemem"] = free_memory;
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
|
doc["freemem"] = ESP.getFreeHeap();
|
||||||
doc["fragmem"] = frag_memory;
|
doc["fragmem"] = frag_memory;
|
||||||
#endif
|
#endif
|
||||||
if (analog_enabled_) {
|
if (analog_enabled_) {
|
||||||
@@ -508,12 +490,11 @@ void System::show_system(uuid::console::Shell & shell) {
|
|||||||
shell.printfln(F("CPU frequency: %u MHz"), ESP.getCpuFreqMHz());
|
shell.printfln(F("CPU frequency: %u MHz"), ESP.getCpuFreqMHz());
|
||||||
#endif
|
#endif
|
||||||
shell.printfln(F("Sketch size: %u bytes (%u bytes free)"), ESP.getSketchSize(), ESP.getFreeSketchSpace());
|
shell.printfln(F("Sketch size: %u bytes (%u bytes free)"), ESP.getSketchSize(), ESP.getFreeSketchSpace());
|
||||||
shell.printfln(F("Free heap: %lu bytes"), (unsigned long)ESP.getFreeHeap());
|
shell.printfln(F("Free heap: %lu bytes"), (uint32_t)ESP.getFreeHeap());
|
||||||
shell.printfln(F("Free mem: %d %%"), free_mem());
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
shell.printfln(F("Heap fragmentation: %u %%"), ESP.getHeapFragmentation());
|
shell.printfln(F("Heap fragmentation: %u %%"), ESP.getHeapFragmentation());
|
||||||
shell.printfln(F("Maximum free block size: %lu bytes"), (unsigned long)ESP.getMaxFreeBlockSize());
|
shell.printfln(F("Maximum free block size: %lu bytes"), (uint32_t)ESP.getMaxFreeBlockSize());
|
||||||
shell.printfln(F("Free continuations stack: %lu bytes"), (unsigned long)ESP.getFreeContStack());
|
shell.printfln(F("Free continuations stack: %lu bytes"), (uint32_t)ESP.getFreeContStack());
|
||||||
#endif
|
#endif
|
||||||
shell.println();
|
shell.println();
|
||||||
|
|
||||||
@@ -734,10 +715,10 @@ void System::console_commands(Shell & shell, unsigned int context) {
|
|||||||
Console::enter_custom_context(shell, context);
|
Console::enter_custom_context(shell, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// upgrade from previous versions of EMS-ESP, based on SPIFFS on an ESP8266
|
// upgrade from previous versions of EMS-ESP
|
||||||
// returns true if an upgrade was done
|
// returns true if an upgrade was done
|
||||||
// the logic is bit abnormal (loading both filesystems and testing) but this was the only way I could get it to work reliably
|
|
||||||
bool System::check_upgrade() {
|
bool System::check_upgrade() {
|
||||||
|
/*
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
LittleFSConfig l_cfg;
|
LittleFSConfig l_cfg;
|
||||||
l_cfg.setAutoFormat(false);
|
l_cfg.setAutoFormat(false);
|
||||||
@@ -923,6 +904,8 @@ bool System::check_upgrade() {
|
|||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// export all settings to JSON text
|
// export all settings to JSON text
|
||||||
@@ -1033,8 +1016,8 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & json
|
|||||||
|
|
||||||
node["version"] = EMSESP_APP_VERSION;
|
node["version"] = EMSESP_APP_VERSION;
|
||||||
node["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
node["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
||||||
node["freemem"] = free_mem();
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
|
node["freemem"] = ESP.getFreeHeap();
|
||||||
node["fragmem"] = ESP.getHeapFragmentation();
|
node["fragmem"] = ESP.getHeapFragmentation();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace emsesp {
|
|||||||
|
|
||||||
class System {
|
class System {
|
||||||
public:
|
public:
|
||||||
void start();
|
void start(uint32_t heap_start);
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
@@ -59,7 +59,6 @@ class System {
|
|||||||
static bool command_test(const char * value, const int8_t id);
|
static bool command_test(const char * value, const int8_t id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t free_mem();
|
|
||||||
static void upload_status(bool in_progress);
|
static void upload_status(bool in_progress);
|
||||||
static bool upload_status();
|
static bool upload_status();
|
||||||
static void show_mem(const char * note);
|
static void show_mem(const char * note);
|
||||||
|
|||||||
@@ -127,10 +127,10 @@ std::string Telegram::to_string_message() const {
|
|||||||
// checks if we have an Rx telegram that needs processing
|
// checks if we have an Rx telegram that needs processing
|
||||||
void RxService::loop() {
|
void RxService::loop() {
|
||||||
while (!rx_telegrams_.empty()) {
|
while (!rx_telegrams_.empty()) {
|
||||||
auto telegram = rx_telegrams_.front().telegram_;
|
auto telegram = rx_telegrams_.pop().telegram_;
|
||||||
(void)EMSESP::process_telegram(telegram); // further process the telegram
|
(void)EMSESP::process_telegram(telegram); // further process the telegram
|
||||||
increment_telegram_count(); // increase rx count
|
increment_telegram_count(); // increase rx count
|
||||||
rx_telegrams_.pop_front(); // remove it from the queue
|
// rx_telegrams_.pop_front(); // remove it from the queue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,25 +217,10 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
|||||||
// if we receive a hc2.. telegram from 0x19.. match it to master_thermostat if master is 0x18
|
// if we receive a hc2.. telegram from 0x19.. match it to master_thermostat if master is 0x18
|
||||||
src = EMSESP::check_master_device(src, type_id, true);
|
src = EMSESP::check_master_device(src, type_id, true);
|
||||||
|
|
||||||
// create the telegram
|
QueuedRxTelegram qrxt;
|
||||||
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length);
|
qrxt.telegram_ = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length);
|
||||||
|
qrxt.id_ = rx_telegram_id_++;
|
||||||
// check if queue is full, if so remove top item to make space
|
rx_telegrams_.push(qrxt);
|
||||||
if (rx_telegrams_.size() >= MAX_RX_TELEGRAMS) {
|
|
||||||
rx_telegrams_.pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
rx_telegrams_.emplace_back(rx_telegram_id_++, std::move(telegram)); // add to queue
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tx CODE starts here...
|
|
||||||
//
|
|
||||||
|
|
||||||
// empty queue, don't process
|
|
||||||
void TxService::flush_tx_queue() {
|
|
||||||
tx_telegrams_.clear();
|
|
||||||
tx_telegram_id_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start and initialize Tx
|
// start and initialize Tx
|
||||||
@@ -279,13 +264,13 @@ void TxService::send() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the Telegram, also removes from queue
|
||||||
|
auto telegram = tx_telegrams_.pop();
|
||||||
|
|
||||||
// if we're in read-only mode (tx_mode 0) forget the Tx call
|
// if we're in read-only mode (tx_mode 0) forget the Tx call
|
||||||
if (tx_mode() != 0) {
|
if (tx_mode() != 0) {
|
||||||
send_telegram(tx_telegrams_.front());
|
send_telegram(telegram);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tx_telegrams_.pop_front(); // remove the telegram from the queue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// process a Tx telegram
|
// process a Tx telegram
|
||||||
@@ -411,21 +396,19 @@ void TxService::add(const uint8_t operation,
|
|||||||
uint8_t * message_data,
|
uint8_t * message_data,
|
||||||
const uint8_t message_length,
|
const uint8_t message_length,
|
||||||
const bool front) {
|
const bool front) {
|
||||||
auto telegram = std::make_shared<Telegram>(operation, ems_bus_id(), dest, type_id, offset, message_data, message_length);
|
|
||||||
|
|
||||||
#ifdef EMSESP_DEBUG
|
#ifdef EMSESP_DEBUG
|
||||||
LOG_DEBUG(F("[DEBUG] New Tx [#%d] telegram, length %d"), tx_telegram_id_, message_length);
|
LOG_DEBUG(F("[DEBUG] New Tx [#%d] telegram, length %d"), tx_telegram_id_, message_length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// if the queue is full, make room but removing the last one
|
QueuedTxTelegram qtxt;
|
||||||
if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) {
|
qtxt.id_ = tx_telegram_id_++;
|
||||||
tx_telegrams_.pop_front();
|
qtxt.retry_ = false;
|
||||||
}
|
qtxt.telegram_ = std::make_shared<Telegram>(operation, ems_bus_id(), dest, type_id, offset, message_data, message_length);
|
||||||
|
|
||||||
if (front) {
|
if (front) {
|
||||||
tx_telegrams_.emplace_front(tx_telegram_id_++, std::move(telegram), false); // add to back of queue
|
tx_telegrams_.push_front(qtxt); // add to front of queue
|
||||||
} else {
|
} else {
|
||||||
tx_telegrams_.emplace_back(tx_telegram_id_++, std::move(telegram), false); // add to back of queue
|
tx_telegrams_.push_back(qtxt); // add to back of queue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,21 +467,19 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
|
|||||||
EMSESP::set_read_id(type_id);
|
EMSESP::set_read_id(type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length); // operation is TX_WRITE or TX_READ
|
|
||||||
|
|
||||||
// if the queue is full, make room but removing the last one
|
|
||||||
if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) {
|
|
||||||
tx_telegrams_.pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef EMSESP_DEBUG
|
#ifdef EMSESP_DEBUG
|
||||||
LOG_DEBUG(F("[DEBUG] New Tx [#%d] telegram, length %d"), tx_telegram_id_, message_length);
|
LOG_DEBUG(F("[DEBUG] New Tx [#%d] telegram, length %d"), tx_telegram_id_, message_length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QueuedTxTelegram qtxt;
|
||||||
|
qtxt.id_ = tx_telegram_id_++;
|
||||||
|
qtxt.retry_ = false;
|
||||||
|
qtxt.telegram_ = std::make_shared<Telegram>(operation, ems_bus_id(), dest, type_id, offset, message_data, message_length);
|
||||||
|
|
||||||
if (front) {
|
if (front) {
|
||||||
tx_telegrams_.emplace_front(tx_telegram_id_++, std::move(telegram), false); // add to back of queue
|
tx_telegrams_.push_front(qtxt); // add to front of queue
|
||||||
} else {
|
} else {
|
||||||
tx_telegrams_.emplace_back(tx_telegram_id_++, std::move(telegram), false); // add to back of queue
|
tx_telegrams_.push_back(qtxt); // add to back of queue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +529,7 @@ void TxService::send_raw(const char * telegram_data) {
|
|||||||
return; // nothing to send
|
return; // nothing to send
|
||||||
}
|
}
|
||||||
|
|
||||||
add(Telegram::Operation::TX_RAW, data, count + 1, true); // add to front of Tx queue
|
add(Telegram::Operation::TX_RAW, data, count + 1, true); // add to top/front of Tx queue
|
||||||
}
|
}
|
||||||
|
|
||||||
// add last Tx to tx queue and increment count
|
// add last Tx to tx queue and increment count
|
||||||
@@ -573,16 +554,15 @@ void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const ui
|
|||||||
Helpers::data_to_hex(data, length).c_str());
|
Helpers::data_to_hex(data, length).c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// add to the top of the queue
|
QueuedTxTelegram qtxt;
|
||||||
if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) {
|
qtxt.id_ = tx_telegram_id_++;
|
||||||
tx_telegrams_.pop_back();
|
qtxt.retry_ = true; // this time it is a retry
|
||||||
}
|
qtxt.telegram_ = telegram_last_;
|
||||||
|
tx_telegrams_.push_front(qtxt); // add to front of queue
|
||||||
tx_telegrams_.emplace_front(tx_telegram_id_++, std::move(telegram_last_), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t TxService::read_next_tx() {
|
uint16_t TxService::read_next_tx() {
|
||||||
// add to the top of the queue
|
// add to the top/front of the queue
|
||||||
uint8_t message_data[1] = {EMS_MAX_TELEGRAM_LENGTH}; // request all data, 32 bytes
|
uint8_t message_data[1] = {EMS_MAX_TELEGRAM_LENGTH}; // request all data, 32 bytes
|
||||||
add(Telegram::Operation::TX_READ, telegram_last_->dest, telegram_last_->type_id, telegram_last_->offset + 25, message_data, 1, true);
|
add(Telegram::Operation::TX_READ, telegram_last_->dest, telegram_last_->type_id, telegram_last_->offset + 25, message_data, 1, true);
|
||||||
return telegram_last_->type_id;
|
return telegram_last_->type_id;
|
||||||
@@ -606,8 +586,8 @@ uint16_t TxService::post_send_query() {
|
|||||||
uint8_t dest = (this->telegram_last_->dest & 0x7F);
|
uint8_t dest = (this->telegram_last_->dest & 0x7F);
|
||||||
// when set a value with large offset before and validate on same type, we have to add offset 0, 26, 52, ...
|
// when set a value with large offset before and validate on same type, we have to add offset 0, 26, 52, ...
|
||||||
uint8_t offset = (this->telegram_last_->type_id == post_typeid) ? ((this->telegram_last_->offset / 26) * 26) : 0;
|
uint8_t offset = (this->telegram_last_->type_id == post_typeid) ? ((this->telegram_last_->offset / 26) * 26) : 0;
|
||||||
uint8_t message_data[1] = {EMS_MAX_TELEGRAM_LENGTH}; // request all data, 32 bytes
|
uint8_t message_data[1] = {EMS_MAX_TELEGRAM_LENGTH}; // request all data, 32 bytes
|
||||||
this->add(Telegram::Operation::TX_READ, dest, post_typeid, offset, message_data, 1, true);
|
this->add(Telegram::Operation::TX_READ, dest, post_typeid, offset, message_data, 1, true); // add to top/front of queue
|
||||||
// read_request(telegram_last_post_send_query_, dest, 0); // no offset
|
// read_request(telegram_last_post_send_query_, dest, 0); // no offset
|
||||||
LOG_DEBUG(F("Sending post validate read, type ID 0x%02X to dest 0x%02X"), post_typeid, dest);
|
LOG_DEBUG(F("Sending post validate read, type ID 0x%02X to dest 0x%02X"), post_typeid, dest);
|
||||||
set_post_send_query(0); // reset
|
set_post_send_query(0); // reset
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#define EMSESP_TELEGRAM_H
|
#define EMSESP_TELEGRAM_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
|
||||||
|
|
||||||
// UART drivers
|
// UART drivers
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
@@ -33,8 +32,12 @@
|
|||||||
|
|
||||||
#include <uuid/log.h>
|
#include <uuid/log.h>
|
||||||
|
|
||||||
|
#include "containers.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
|
#define MAX_RX_TELEGRAMS 10 // size of Rx queue
|
||||||
|
#define MAX_TX_TELEGRAMS 30 // size of Tx queue
|
||||||
|
|
||||||
// default values for null values
|
// default values for null values
|
||||||
static constexpr uint8_t EMS_VALUE_BOOL = 0xFF; // used to mark that something is a boolean
|
static constexpr uint8_t EMS_VALUE_BOOL = 0xFF; // used to mark that something is a boolean
|
||||||
static constexpr uint8_t EMS_VALUE_BOOL_OFF = 0x00; // boolean false
|
static constexpr uint8_t EMS_VALUE_BOOL_OFF = 0x00; // boolean false
|
||||||
@@ -200,8 +203,6 @@ class EMSbus {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class RxService : public EMSbus {
|
class RxService : public EMSbus {
|
||||||
static constexpr size_t MAX_RX_TELEGRAMS = 10;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RxService() = default;
|
RxService() = default;
|
||||||
~RxService() = default;
|
~RxService() = default;
|
||||||
@@ -229,37 +230,29 @@ class RxService : public EMSbus {
|
|||||||
return (q <= EMS_BUS_QUALITY_RX_THRESHOLD ? 100 : 100 - q);
|
return (q <= EMS_BUS_QUALITY_RX_THRESHOLD ? 100 : 100 - q);
|
||||||
}
|
}
|
||||||
|
|
||||||
class QueuedRxTelegram {
|
struct QueuedRxTelegram {
|
||||||
public:
|
uint16_t id_;
|
||||||
const uint16_t id_;
|
std::shared_ptr<const Telegram> telegram_;
|
||||||
const std::shared_ptr<const Telegram> telegram_;
|
|
||||||
|
|
||||||
~QueuedRxTelegram() = default;
|
|
||||||
QueuedRxTelegram(uint16_t id, std::shared_ptr<Telegram> && telegram)
|
|
||||||
: id_(id)
|
|
||||||
, telegram_(std::move(telegram)) {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::list<QueuedRxTelegram> queue() const {
|
const emsesp::queue<QueuedRxTelegram> queue() const {
|
||||||
return rx_telegrams_;
|
return rx_telegrams_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint8_t EMS_BUS_QUALITY_RX_THRESHOLD = 5; // % threshold before reporting quality issues
|
static constexpr uint8_t EMS_BUS_QUALITY_RX_THRESHOLD = 5; // % threshold before reporting quality issues
|
||||||
|
|
||||||
uint8_t rx_telegram_id_ = 0; // queue counter
|
uint8_t rx_telegram_id_ = 0; // queue counter
|
||||||
uint32_t telegram_count_ = 0; // # Rx received
|
uint32_t telegram_count_ = 0; // # Rx received
|
||||||
uint32_t telegram_error_count_ = 0; // # Rx CRC errors
|
uint32_t telegram_error_count_ = 0; // # Rx CRC errors
|
||||||
std::shared_ptr<const Telegram> rx_telegram; // the incoming Rx telegram
|
std::shared_ptr<const Telegram> rx_telegram; // the incoming Rx telegram
|
||||||
std::list<QueuedRxTelegram> rx_telegrams_; // the Rx Queue
|
emsesp::queue<QueuedRxTelegram> rx_telegrams_ = emsesp::queue<QueuedRxTelegram>(MAX_RX_TELEGRAMS); // the Rx Queue
|
||||||
};
|
};
|
||||||
|
|
||||||
class TxService : public EMSbus {
|
class TxService : public EMSbus {
|
||||||
public:
|
public:
|
||||||
static constexpr size_t MAX_TX_TELEGRAMS = 30; // size of Tx queue
|
static constexpr uint8_t TX_WRITE_FAIL = 4; // EMS return code for fail
|
||||||
static constexpr uint8_t TX_WRITE_FAIL = 4; // EMS return code for fail
|
static constexpr uint8_t TX_WRITE_SUCCESS = 1; // EMS return code for success
|
||||||
static constexpr uint8_t TX_WRITE_SUCCESS = 1; // EMS return code for success
|
|
||||||
|
|
||||||
TxService() = default;
|
TxService() = default;
|
||||||
~TxService() = default;
|
~TxService() = default;
|
||||||
@@ -277,7 +270,6 @@ class TxService : public EMSbus {
|
|||||||
void read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0);
|
void read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0);
|
||||||
void send_raw(const char * telegram_data);
|
void send_raw(const char * telegram_data);
|
||||||
void send_poll();
|
void send_poll();
|
||||||
void flush_tx_queue();
|
|
||||||
void retry_tx(const uint8_t operation, const uint8_t * data, const uint8_t length);
|
void retry_tx(const uint8_t operation, const uint8_t * data, const uint8_t length);
|
||||||
bool is_last_tx(const uint8_t src, const uint8_t dest) const;
|
bool is_last_tx(const uint8_t src, const uint8_t dest) const;
|
||||||
uint16_t post_send_query();
|
uint16_t post_send_query();
|
||||||
@@ -342,21 +334,13 @@ class TxService : public EMSbus {
|
|||||||
telegram_write_count_++;
|
telegram_write_count_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
class QueuedTxTelegram {
|
struct QueuedTxTelegram {
|
||||||
public:
|
uint16_t id_;
|
||||||
const uint16_t id_;
|
std::shared_ptr<const Telegram> telegram_;
|
||||||
const std::shared_ptr<const Telegram> telegram_;
|
bool retry_; // true if its a retry
|
||||||
const bool retry_; // is a retry
|
|
||||||
|
|
||||||
~QueuedTxTelegram() = default;
|
|
||||||
QueuedTxTelegram(uint16_t id, std::shared_ptr<Telegram> && telegram, bool retry)
|
|
||||||
: id_(id)
|
|
||||||
, telegram_(std::move(telegram))
|
|
||||||
, retry_(retry) {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::list<QueuedTxTelegram> queue() const {
|
const emsesp::queue<QueuedTxTelegram> queue() const {
|
||||||
return tx_telegrams_;
|
return tx_telegrams_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +351,7 @@ class TxService : public EMSbus {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<QueuedTxTelegram> tx_telegrams_; // the Tx queue
|
emsesp::queue<QueuedTxTelegram> tx_telegrams_ = emsesp::queue<QueuedTxTelegram>(MAX_TX_TELEGRAMS); // the Tx Queue
|
||||||
|
|
||||||
uint32_t telegram_read_count_ = 0; // # Tx successful reads
|
uint32_t telegram_read_count_ = 0; // # Tx successful reads
|
||||||
uint32_t telegram_write_count_ = 0; // # Tx successful writes
|
uint32_t telegram_write_count_ = 0; // # Tx successful writes
|
||||||
|
|||||||
@@ -401,10 +401,11 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
|||||||
if (command == "boiler") {
|
if (command == "boiler") {
|
||||||
shell.printfln(F("Testing boiler..."));
|
shell.printfln(F("Testing boiler..."));
|
||||||
run_test("boiler");
|
run_test("boiler");
|
||||||
|
shell.invoke_command("show devices");
|
||||||
shell.invoke_command("show");
|
shell.invoke_command("show");
|
||||||
shell.invoke_command("call boiler info");
|
// shell.invoke_command("call boiler info");
|
||||||
shell.invoke_command("call system publish");
|
// shell.invoke_command("call system publish");
|
||||||
shell.invoke_command("show mqtt");
|
// shell.invoke_command("show mqtt");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "fr120") {
|
if (command == "fr120") {
|
||||||
@@ -558,7 +559,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
|||||||
uart_telegram("98 00 FF 00 01 A5 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03"); // without CRC
|
uart_telegram("98 00 FF 00 01 A5 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03"); // without CRC
|
||||||
uart_telegram_withCRC("98 00 FF 00 01 A6 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03 6B"); // with CRC
|
uart_telegram_withCRC("98 00 FF 00 01 A6 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03 6B"); // with CRC
|
||||||
|
|
||||||
EMSESP::txservice_.flush_tx_queue();
|
|
||||||
shell.loop_all();
|
shell.loop_all();
|
||||||
EMSESP::show_device_values(shell);
|
EMSESP::show_device_values(shell);
|
||||||
|
|
||||||
@@ -638,8 +638,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
|||||||
if (command == "tx") {
|
if (command == "tx") {
|
||||||
shell.printfln(F("Testing Tx..."));
|
shell.printfln(F("Testing Tx..."));
|
||||||
|
|
||||||
EMSESP::txservice_.flush_tx_queue();
|
|
||||||
|
|
||||||
// TX queue example - Me -> Thermostat, (0x91), telegram: 0B 17 91 05 44 45 46 47 (#data=4)
|
// TX queue example - Me -> Thermostat, (0x91), telegram: 0B 17 91 05 44 45 46 47 (#data=4)
|
||||||
uint8_t t11[] = {0x44, 0x45, 0x46, 0x47};
|
uint8_t t11[] = {0x44, 0x45, 0x46, 0x47};
|
||||||
EMSESP::txservice_.add(Telegram::Operation::TX_RAW, 0x17, 0x91, 0x05, t11, sizeof(t11));
|
EMSESP::txservice_.add(Telegram::Operation::TX_RAW, 0x17, 0x91, 0x05, t11, sizeof(t11));
|
||||||
@@ -672,16 +670,11 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
|||||||
for (uint8_t i = 0; i < 10; i++) {
|
for (uint8_t i = 0; i < 10; i++) {
|
||||||
EMSESP::txservice_.send(); // send it to UART
|
EMSESP::txservice_.send(); // send it to UART
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSESP::txservice_.flush_tx_queue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "poll") {
|
if (command == "poll") {
|
||||||
shell.printfln(F("Testing Poll..."));
|
shell.printfln(F("Testing Poll..."));
|
||||||
|
|
||||||
// check if sending works when a poll comes in, with retries
|
|
||||||
EMSESP::txservice_.flush_tx_queue();
|
|
||||||
|
|
||||||
// simulate sending a read request
|
// simulate sending a read request
|
||||||
// uint8_t t16[] = {0x44, 0x45, 0x46, 0x47}; // Me -> Thermostat, (0x91), telegram: 0B 17 91 05 44 45 46 47 (#data=4)
|
// uint8_t t16[] = {0x44, 0x45, 0x46, 0x47}; // Me -> Thermostat, (0x91), telegram: 0B 17 91 05 44 45 46 47 (#data=4)
|
||||||
// EMSESP::txservice_.add(Telegram::Operation::TX_RAW, 0x17, 0x91, 0x05, t16, sizeof(t16));
|
// EMSESP::txservice_.add(Telegram::Operation::TX_RAW, 0x17, 0x91, 0x05, t16, sizeof(t16));
|
||||||
@@ -702,8 +695,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
|||||||
uint8_t t2[] = {0x21, 0x22};
|
uint8_t t2[] = {0x21, 0x22};
|
||||||
EMSESP::send_write_request(0x91, 0x17, 0x00, t2, sizeof(t2), 0);
|
EMSESP::send_write_request(0x91, 0x17, 0x00, t2, sizeof(t2), 0);
|
||||||
EMSESP::show_ems(shell);
|
EMSESP::show_ems(shell);
|
||||||
|
|
||||||
EMSESP::txservice_.flush_tx_queue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "cmd") {
|
if (command == "cmd") {
|
||||||
@@ -759,10 +750,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
|||||||
char boiler_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
char boiler_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
char thermostat_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
char thermostat_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
char system_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
char system_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
|
|
||||||
// test publish and adding to queue
|
|
||||||
EMSESP::txservice_.flush_tx_queue();
|
|
||||||
|
|
||||||
EMSESP::EMSESP::mqtt_.publish("boiler", "test me");
|
EMSESP::EMSESP::mqtt_.publish("boiler", "test me");
|
||||||
Mqtt::show_mqtt(shell); // show queue
|
Mqtt::show_mqtt(shell); // show queue
|
||||||
|
|
||||||
@@ -816,7 +803,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
|||||||
EMSESP::incoming_telegram(poll, 1);
|
EMSESP::incoming_telegram(poll, 1);
|
||||||
|
|
||||||
EMSESP::show_ems(shell);
|
EMSESP::show_ems(shell);
|
||||||
EMSESP::txservice_.flush_tx_queue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == "rx2") {
|
if (command == "rx2") {
|
||||||
|
|||||||
@@ -21,21 +21,7 @@
|
|||||||
#ifndef EMSESP_TEST_H
|
#ifndef EMSESP_TEST_H
|
||||||
#define EMSESP_TEST_H
|
#define EMSESP_TEST_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <uuid/common.h>
|
|
||||||
#include <uuid/console.h>
|
|
||||||
#include <uuid/log.h>
|
|
||||||
|
|
||||||
#include "emsdevice.h"
|
|
||||||
#include "emsfactory.h"
|
|
||||||
#include "telegram.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "command.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user