mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
prepare for ems plujs updates
This commit is contained in:
@@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [1.7.0 dev] 2019-03-
|
## [1.6.1 dev] 2019-03-
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- EMS Plus support
|
- Buderus Logamax plus
|
||||||
|
|
||||||
## [1.6.0] 2019-03-24
|
## [1.6.0] 2019-03-24
|
||||||
|
|
||||||
|
|||||||
@@ -155,8 +155,6 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) {
|
|||||||
// finally if we don't want Serial anymore, turn it off
|
// finally if we don't want Serial anymore, turn it off
|
||||||
if (!_use_serial) {
|
if (!_use_serial) {
|
||||||
myDebug_P(PSTR("Disabling serial port"));
|
myDebug_P(PSTR("Disabling serial port"));
|
||||||
Serial.flush();
|
|
||||||
Serial.end();
|
|
||||||
SerialAndTelnet.setSerial(NULL);
|
SerialAndTelnet.setSerial(NULL);
|
||||||
} else {
|
} else {
|
||||||
myDebug_P(PSTR("Using serial port output"));
|
myDebug_P(PSTR("Using serial port output"));
|
||||||
@@ -679,6 +677,19 @@ bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value)
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// force the serial on/off
|
||||||
|
void MyESP::setUseSerial(bool toggle) {
|
||||||
|
//(void)fs_saveConfig(); // save the setting for next reboot
|
||||||
|
|
||||||
|
if (toggle) {
|
||||||
|
SerialAndTelnet.setSerial(&Serial);
|
||||||
|
_use_serial = true;
|
||||||
|
} else {
|
||||||
|
SerialAndTelnet.setSerial(NULL);
|
||||||
|
_use_serial = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MyESP::_telnetCommand(char * commandLine) {
|
void MyESP::_telnetCommand(char * commandLine) {
|
||||||
char * str = commandLine;
|
char * str = commandLine;
|
||||||
bool state = false;
|
bool state = false;
|
||||||
@@ -792,14 +803,14 @@ String MyESP::_buildTime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns system uptime in seconds - copied for espurna. see (c)
|
// returns system uptime in seconds - copied for espurna. see (c)
|
||||||
unsigned long MyESP::_getUptime() {
|
uint32_t MyESP::_getUptime() {
|
||||||
static unsigned long last_uptime = 0;
|
static uint32_t last_uptime = 0;
|
||||||
static unsigned char uptime_overflows = 0;
|
static unsigned char uptime_overflows = 0;
|
||||||
|
|
||||||
if (millis() < last_uptime)
|
if (millis() < last_uptime)
|
||||||
++uptime_overflows;
|
++uptime_overflows;
|
||||||
last_uptime = millis();
|
last_uptime = millis();
|
||||||
unsigned long uptime_seconds = uptime_overflows * (UPTIME_OVERFLOW / 1000) + (last_uptime / 1000);
|
uint32_t uptime_seconds = uptime_overflows * (UPTIME_OVERFLOW / 1000) + (last_uptime / 1000);
|
||||||
|
|
||||||
return uptime_seconds;
|
return uptime_seconds;
|
||||||
}
|
}
|
||||||
@@ -884,9 +895,7 @@ void MyESP::showSystemStats() {
|
|||||||
myDebug_P(PSTR(" [MEM] Max OTA size: %d"), (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
myDebug_P(PSTR(" [MEM] Max OTA size: %d"), (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
||||||
myDebug_P(PSTR(" [MEM] OTA Reserved: %d"), 4 * SPI_FLASH_SEC_SIZE);
|
myDebug_P(PSTR(" [MEM] OTA Reserved: %d"), 4 * SPI_FLASH_SEC_SIZE);
|
||||||
myDebug_P(PSTR(" [MEM] Free Heap: %d"), ESP.getFreeHeap());
|
myDebug_P(PSTR(" [MEM] Free Heap: %d"), ESP.getFreeHeap());
|
||||||
#if defined(ESP8266)
|
|
||||||
myDebug_P(PSTR(" [MEM] Stack: %d"), ESP.getFreeContStack());
|
|
||||||
#endif
|
|
||||||
myDebug_P(PSTR(""));
|
myDebug_P(PSTR(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1019,8 +1028,8 @@ void MyESP::setMQTT(const char * mqtt_host,
|
|||||||
const char * mqtt_username,
|
const char * mqtt_username,
|
||||||
const char * mqtt_password,
|
const char * mqtt_password,
|
||||||
const char * mqtt_base,
|
const char * mqtt_base,
|
||||||
unsigned long mqtt_keepalive,
|
uint32_t mqtt_keepalive,
|
||||||
unsigned char mqtt_qos,
|
uint8_t mqtt_qos,
|
||||||
bool mqtt_retain,
|
bool mqtt_retain,
|
||||||
const char * mqtt_will_topic,
|
const char * mqtt_will_topic,
|
||||||
const char * mqtt_will_online_payload,
|
const char * mqtt_will_online_payload,
|
||||||
@@ -1155,7 +1164,7 @@ bool MyESP::_fs_loadConfig() {
|
|||||||
// Deserialize the JSON document
|
// Deserialize the JSON document
|
||||||
DeserializationError error = deserializeJson(doc, configFile);
|
DeserializationError error = deserializeJson(doc, configFile);
|
||||||
if (error) {
|
if (error) {
|
||||||
Serial.println(F("[FS] Failed to read file"));
|
myDebug_P(PSTR("[FS] Failed to read config file"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1264,13 +1273,13 @@ uint16_t MyESP::getSystemLoadAverage() {
|
|||||||
|
|
||||||
// calculate load average
|
// calculate load average
|
||||||
void MyESP::_calculateLoad() {
|
void MyESP::_calculateLoad() {
|
||||||
static unsigned long last_loadcheck = 0;
|
static uint32_t last_loadcheck = 0;
|
||||||
static unsigned long load_counter_temp = 0;
|
static uint32_t load_counter_temp = 0;
|
||||||
load_counter_temp++;
|
load_counter_temp++;
|
||||||
|
|
||||||
if (millis() - last_loadcheck > LOADAVG_INTERVAL) {
|
if (millis() - last_loadcheck > LOADAVG_INTERVAL) {
|
||||||
static unsigned long load_counter = 0;
|
static uint32_t load_counter = 0;
|
||||||
static unsigned long load_counter_max = 1;
|
static uint32_t load_counter_max = 1;
|
||||||
|
|
||||||
load_counter = load_counter_temp;
|
load_counter = load_counter_temp;
|
||||||
load_counter_temp = 0;
|
load_counter_temp = 0;
|
||||||
@@ -1478,7 +1487,7 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char *
|
|||||||
_eeprom_setup(); // set up eeprom for storing crash data
|
_eeprom_setup(); // set up eeprom for storing crash data
|
||||||
_fs_setup(); // SPIFFS setup, do this first to get values
|
_fs_setup(); // SPIFFS setup, do this first to get values
|
||||||
_wifi_setup(); // WIFI setup
|
_wifi_setup(); // WIFI setup
|
||||||
_ota_setup();
|
_ota_setup(); // init OTA
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1490,12 +1499,10 @@ void MyESP::loop() {
|
|||||||
|
|
||||||
jw.loop(); // WiFi
|
jw.loop(); // WiFi
|
||||||
|
|
||||||
/*
|
|
||||||
// do nothing else until we've got a wifi connection
|
// do nothing else until we've got a wifi connection
|
||||||
if (WiFi.getMode() & WIFI_AP) {
|
if (WiFi.getMode() & WIFI_AP) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
ArduinoOTA.handle(); // OTA
|
ArduinoOTA.handle(); // OTA
|
||||||
_mqttConnect(); // MQTT
|
_mqttConnect(); // MQTT
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#ifndef MyEMS_h
|
#ifndef MyEMS_h
|
||||||
#define MyEMS_h
|
#define MyEMS_h
|
||||||
|
|
||||||
#define MYESP_VERSION "1.1.6"
|
#define MYESP_VERSION "1.1.7"
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <ArduinoOTA.h>
|
#include <ArduinoOTA.h>
|
||||||
@@ -50,7 +50,6 @@ void custom_crash_callback(struct rst_info *, uint32_t, uint32_t);
|
|||||||
#define MQTT_RECONNECT_DELAY_MIN 2000 // Try to reconnect in 3 seconds upon disconnection
|
#define MQTT_RECONNECT_DELAY_MIN 2000 // Try to reconnect in 3 seconds upon disconnection
|
||||||
#define MQTT_RECONNECT_DELAY_STEP 3000 // Increase the reconnect delay in 3 seconds after each failed attempt
|
#define MQTT_RECONNECT_DELAY_STEP 3000 // Increase the reconnect delay in 3 seconds after each failed attempt
|
||||||
#define MQTT_RECONNECT_DELAY_MAX 120000 // Set reconnect time to 2 minutes at most
|
#define MQTT_RECONNECT_DELAY_MAX 120000 // Set reconnect time to 2 minutes at most
|
||||||
#define MQTT_MAX_SIZE 600 // max length of MQTT message
|
|
||||||
#define MQTT_MAX_TOPIC_SIZE 50 // max length of MQTT message
|
#define MQTT_MAX_TOPIC_SIZE 50 // max length of MQTT message
|
||||||
|
|
||||||
// Internal MQTT events
|
// Internal MQTT events
|
||||||
@@ -155,7 +154,7 @@ class MyESP {
|
|||||||
const char * mqtt_username,
|
const char * mqtt_username,
|
||||||
const char * mqtt_password,
|
const char * mqtt_password,
|
||||||
const char * mqtt_base,
|
const char * mqtt_base,
|
||||||
unsigned long mqtt_keepalive,
|
uint32_t mqtt_keepalive,
|
||||||
unsigned char mqtt_qos,
|
unsigned char mqtt_qos,
|
||||||
bool mqtt_retain,
|
bool mqtt_retain,
|
||||||
const char * mqtt_will_topic,
|
const char * mqtt_will_topic,
|
||||||
@@ -171,6 +170,7 @@ class MyESP {
|
|||||||
void myDebug_P(PGM_P format_P, ...);
|
void myDebug_P(PGM_P format_P, ...);
|
||||||
void setTelnet(command_t * cmds, uint8_t count, telnetcommand_callback_f callback_cmd, telnet_callback_f callback);
|
void setTelnet(command_t * cmds, uint8_t count, telnetcommand_callback_f callback_cmd, telnet_callback_f callback);
|
||||||
bool getUseSerial();
|
bool getUseSerial();
|
||||||
|
void setUseSerial(bool toggle);
|
||||||
|
|
||||||
// FS
|
// FS
|
||||||
void setSettings(fs_callback_f callback, fs_settings_callback_f fs_settings_callback);
|
void setSettings(fs_callback_f callback, fs_settings_callback_f fs_settings_callback);
|
||||||
@@ -195,7 +195,7 @@ class MyESP {
|
|||||||
private:
|
private:
|
||||||
// mqtt
|
// mqtt
|
||||||
AsyncMqttClient mqttClient;
|
AsyncMqttClient mqttClient;
|
||||||
unsigned long _mqtt_reconnect_delay;
|
uint32_t _mqtt_reconnect_delay;
|
||||||
void _mqttOnMessage(char * topic, char * payload, size_t len);
|
void _mqttOnMessage(char * topic, char * payload, size_t len);
|
||||||
void _mqttConnect();
|
void _mqttConnect();
|
||||||
void _mqtt_setup();
|
void _mqtt_setup();
|
||||||
@@ -207,14 +207,14 @@ class MyESP {
|
|||||||
char * _mqtt_username;
|
char * _mqtt_username;
|
||||||
char * _mqtt_password;
|
char * _mqtt_password;
|
||||||
char * _mqtt_base;
|
char * _mqtt_base;
|
||||||
unsigned long _mqtt_keepalive;
|
uint32_t _mqtt_keepalive;
|
||||||
unsigned char _mqtt_qos;
|
uint8_t _mqtt_qos;
|
||||||
bool _mqtt_retain;
|
bool _mqtt_retain;
|
||||||
char * _mqtt_will_topic;
|
char * _mqtt_will_topic;
|
||||||
char * _mqtt_will_online_payload;
|
char * _mqtt_will_online_payload;
|
||||||
char * _mqtt_will_offline_payload;
|
char * _mqtt_will_offline_payload;
|
||||||
char * _mqtt_topic;
|
char * _mqtt_topic;
|
||||||
unsigned long _mqtt_last_connection;
|
uint32_t _mqtt_last_connection;
|
||||||
bool _mqtt_connecting;
|
bool _mqtt_connecting;
|
||||||
|
|
||||||
// wifi
|
// wifi
|
||||||
@@ -264,14 +264,14 @@ class MyESP {
|
|||||||
void _printSetCommands();
|
void _printSetCommands();
|
||||||
|
|
||||||
// general
|
// general
|
||||||
char * _app_hostname;
|
char * _app_hostname;
|
||||||
char * _app_name;
|
char * _app_name;
|
||||||
char * _app_version;
|
char * _app_version;
|
||||||
char * _boottime;
|
char * _boottime;
|
||||||
bool _suspendOutput;
|
bool _suspendOutput;
|
||||||
bool _use_serial;
|
bool _use_serial;
|
||||||
unsigned long _getUptime();
|
uint32_t _getUptime();
|
||||||
String _buildTime();
|
String _buildTime();
|
||||||
|
|
||||||
// load average (0..100)
|
// load average (0..100)
|
||||||
void _calculateLoad();
|
void _calculateLoad();
|
||||||
|
|||||||
@@ -343,9 +343,11 @@ void TelnetSpy::flush(void) {
|
|||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
|
|
||||||
void TelnetSpy::begin(unsigned long baud, SerialConfig config, SerialMode mode, uint8_t tx_pin) {
|
void TelnetSpy::begin(unsigned long baud, SerialConfig config, SerialMode mode, uint8_t tx_pin) {
|
||||||
|
|
||||||
if (usedSer) {
|
if (usedSer) {
|
||||||
usedSer->begin(baud, config, mode, tx_pin);
|
usedSer->begin(baud, config, mode, tx_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,6 +435,7 @@ TelnetSpy::operator bool() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TelnetSpy::setDebugOutput(bool en) {
|
void TelnetSpy::setDebugOutput(bool en) {
|
||||||
|
|
||||||
debugOutput = en;
|
debugOutput = en;
|
||||||
|
|
||||||
// TODO: figure out how to disable system printing for the ESP32
|
// TODO: figure out how to disable system printing for the ESP32
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ uint8_t DS18::setup(uint8_t gpio, bool parasite) {
|
|||||||
|
|
||||||
// scan every 2 seconds
|
// scan every 2 seconds
|
||||||
void DS18::loop() {
|
void DS18::loop() {
|
||||||
static unsigned long last = 0;
|
static uint32_t last = 0;
|
||||||
if (millis() - last < DS18_READ_INTERVAL)
|
if (millis() - last < DS18_READ_INTERVAL)
|
||||||
return;
|
return;
|
||||||
last = millis();
|
last = millis();
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ Ticker showerColdShotStopTimer;
|
|||||||
#define SHOWER_MAX_DURATION 420000 // in ms. 7 minutes, before trigger a shot of cold water
|
#define SHOWER_MAX_DURATION 420000 // in ms. 7 minutes, before trigger a shot of cold water
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long timestamp; // for internal timings, via millis()
|
uint32_t timestamp; // for internal timings, via millis()
|
||||||
uint8_t dallas_sensors; // count of dallas sensors
|
uint8_t dallas_sensors; // count of dallas sensors
|
||||||
|
|
||||||
// custom params
|
// custom params
|
||||||
bool shower_timer; // true if we want to report back on shower times
|
bool shower_timer; // true if we want to report back on shower times
|
||||||
@@ -78,11 +78,11 @@ typedef struct {
|
|||||||
} _EMSESP_Status;
|
} _EMSESP_Status;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool showerOn;
|
bool showerOn;
|
||||||
unsigned long timerStart; // ms
|
uint32_t timerStart; // ms
|
||||||
unsigned long timerPause; // ms
|
uint32_t timerPause; // ms
|
||||||
unsigned long duration; // ms
|
uint32_t duration; // ms
|
||||||
bool doingColdShot; // true if we've just sent a jolt of cold water
|
bool doingColdShot; // true if we've just sent a jolt of cold water
|
||||||
} _EMSESP_Shower;
|
} _EMSESP_Shower;
|
||||||
|
|
||||||
command_t PROGMEM project_cmds[] = {
|
command_t PROGMEM project_cmds[] = {
|
||||||
@@ -312,7 +312,9 @@ void showInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
myDebug(" LED is %s, Silent mode is %s", EMSESP_Status.led ? "on" : "off", EMSESP_Status.silent_mode ? "on" : "off");
|
myDebug(" LED is %s, Silent mode is %s", EMSESP_Status.led ? "on" : "off", EMSESP_Status.silent_mode ? "on" : "off");
|
||||||
myDebug(" %d external temperature sensor%s connected", EMSESP_Status.dallas_sensors, (EMSESP_Status.dallas_sensors > 1) ? "s" : "");
|
if (EMSESP_Status.dallas_sensors > 0) {
|
||||||
|
myDebug(" %d external temperature sensor%s connected", EMSESP_Status.dallas_sensors, (EMSESP_Status.dallas_sensors == 1) ? "" : "s");
|
||||||
|
}
|
||||||
|
|
||||||
myDebug(" Thermostat is %s, Boiler is %s, Shower Timer is %s, Shower Alert is %s",
|
myDebug(" Thermostat is %s, Boiler is %s, Shower Timer is %s, Shower Alert is %s",
|
||||||
(ems_getThermostatEnabled() ? "enabled" : "disabled"),
|
(ems_getThermostatEnabled() ? "enabled" : "disabled"),
|
||||||
@@ -321,12 +323,23 @@ void showInfo() {
|
|||||||
((EMSESP_Status.shower_alert) ? "enabled" : "disabled"));
|
((EMSESP_Status.shower_alert) ? "enabled" : "disabled"));
|
||||||
|
|
||||||
myDebug("\n%sEMS Bus stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
myDebug("\n%sEMS Bus stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
||||||
myDebug(" Bus Connected=%s, Tx is %s, # Rx telegrams=%d, # Tx telegrams=%d, # Crc Errors=%d",
|
|
||||||
(ems_getBusConnected() ? "yes" : "no"),
|
if (ems_getBusConnected()) {
|
||||||
(ems_getTxCapable() ? "active" : "not active"),
|
myDebug(" Bus is connected");
|
||||||
EMS_Sys_Status.emsRxPgks,
|
|
||||||
EMS_Sys_Status.emsTxPkgs,
|
myDebug(" Rx: Poll=%d ms, # Rx telegrams read=%d, # Crc Errors=%d",
|
||||||
EMS_Sys_Status.emxCrcErr);
|
ems_getPollFrequency(),
|
||||||
|
EMS_Sys_Status.emsRxPgks,
|
||||||
|
EMS_Sys_Status.emxCrcErr);
|
||||||
|
|
||||||
|
if (ems_getTxCapable()) {
|
||||||
|
myDebug(" Tx: available, # Tx telegrams sent=%d", EMS_Sys_Status.emsTxPkgs);
|
||||||
|
} else {
|
||||||
|
myDebug(" Tx: no signal");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
myDebug(" No connection can be made to the EMS bus");
|
||||||
|
}
|
||||||
|
|
||||||
myDebug("");
|
myDebug("");
|
||||||
myDebug("%sBoiler stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
myDebug("%sBoiler stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
||||||
@@ -493,8 +506,8 @@ void showInfo() {
|
|||||||
|
|
||||||
// send all dallas sensor values as a JSON package to MQTT
|
// send all dallas sensor values as a JSON package to MQTT
|
||||||
void publishSensorValues() {
|
void publishSensorValues() {
|
||||||
StaticJsonDocument<MQTT_MAX_SIZE> doc;
|
StaticJsonDocument<200> doc;
|
||||||
JsonObject sensors = doc.to<JsonObject>();
|
JsonObject sensors = doc.to<JsonObject>();
|
||||||
|
|
||||||
bool hasdata = false;
|
bool hasdata = false;
|
||||||
char label[8] = {0};
|
char label[8] = {0};
|
||||||
@@ -511,7 +524,7 @@ void publishSensorValues() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasdata) {
|
if (hasdata) {
|
||||||
char data[MQTT_MAX_SIZE] = {0};
|
char data[200] = {0};
|
||||||
serializeJson(doc, data, sizeof(data));
|
serializeJson(doc, data, sizeof(data));
|
||||||
myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, data);
|
myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, data);
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/ems.cpp
38
src/ems.cpp
@@ -157,9 +157,9 @@ const uint8_t ems_crc_table[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
|
|||||||
0xCD, 0xCF, 0xC1, 0xC3, 0xC5, 0xC7, 0xF9, 0xFB, 0xFD, 0xFF, 0xF1, 0xF3, 0xF5, 0xF7, 0xE9, 0xEB, 0xED, 0xEF,
|
0xCD, 0xCF, 0xC1, 0xC3, 0xC5, 0xC7, 0xF9, 0xFB, 0xFD, 0xFF, 0xF1, 0xF3, 0xF5, 0xF7, 0xE9, 0xEB, 0xED, 0xEF,
|
||||||
0xE1, 0xE3, 0xE5, 0xE7};
|
0xE1, 0xE3, 0xE5, 0xE7};
|
||||||
|
|
||||||
const uint8_t TX_WRITE_TIMEOUT_COUNT = 2; // 3 retries before timeout
|
const uint8_t TX_WRITE_TIMEOUT_COUNT = 2; // 3 retries before timeout
|
||||||
const unsigned long EMS_BUS_TIMEOUT = 15000; // timeout in ms before recognizing the ems bus is offline (15 seconds)
|
const uint32_t EMS_BUS_TIMEOUT = 15000; // timeout in ms before recognizing the ems bus is offline (15 seconds)
|
||||||
const unsigned long EMS_POLL_TIMEOUT = 5000; // timeout in ms before recognizing the ems bus is offline (5 seconds)
|
const uint32_t EMS_POLL_TIMEOUT = 5000; // timeout in ms before recognizing the ems bus is offline (5 seconds)
|
||||||
|
|
||||||
// init stats and counters and buffers
|
// init stats and counters and buffers
|
||||||
// uses -255 or 255 for values that haven't been set yet (EMS_VALUE_INT_NOTSET and EMS_VALUE_FLOAT_NOTSET)
|
// uses -255 or 255 for values that haven't been set yet (EMS_VALUE_INT_NOTSET and EMS_VALUE_FLOAT_NOTSET)
|
||||||
@@ -176,7 +176,7 @@ void ems_init() {
|
|||||||
EMS_Sys_Status.emsRxTimestamp = 0;
|
EMS_Sys_Status.emsRxTimestamp = 0;
|
||||||
EMS_Sys_Status.emsTxCapable = false;
|
EMS_Sys_Status.emsTxCapable = false;
|
||||||
EMS_Sys_Status.emsTxDisabled = false;
|
EMS_Sys_Status.emsTxDisabled = false;
|
||||||
EMS_Sys_Status.emsPollTimestamp = 0;
|
EMS_Sys_Status.emsPollFrequency = 0;
|
||||||
EMS_Sys_Status.txRetryCount = 0;
|
EMS_Sys_Status.txRetryCount = 0;
|
||||||
|
|
||||||
// thermostat
|
// thermostat
|
||||||
@@ -302,8 +302,12 @@ void ems_setTxDisabled(bool b) {
|
|||||||
EMS_Sys_Status.emsTxDisabled = b;
|
EMS_Sys_Status.emsTxDisabled = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ems_getPollFrequency() {
|
||||||
|
return EMS_Sys_Status.emsPollFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
bool ems_getTxCapable() {
|
bool ems_getTxCapable() {
|
||||||
if ((millis() - EMS_Sys_Status.emsPollTimestamp) > EMS_POLL_TIMEOUT) {
|
if ((EMS_Sys_Status.emsPollFrequency == 0) || (EMS_Sys_Status.emsPollFrequency > EMS_POLL_TIMEOUT)) {
|
||||||
EMS_Sys_Status.emsTxCapable = false;
|
EMS_Sys_Status.emsTxCapable = false;
|
||||||
}
|
}
|
||||||
return EMS_Sys_Status.emsTxCapable;
|
return EMS_Sys_Status.emsTxCapable;
|
||||||
@@ -577,7 +581,6 @@ void _createValidate() {
|
|||||||
EMS_TxQueue.unshift(new_EMS_TxTelegram); // add back to queue making it first to be picked up next (FIFO)
|
EMS_TxQueue.unshift(new_EMS_TxTelegram); // add back to queue making it first to be picked up next (FIFO)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point triggered by an interrupt in emsuart.cpp
|
* Entry point triggered by an interrupt in emsuart.cpp
|
||||||
* length is only data bytes, excluding the BRK
|
* length is only data bytes, excluding the BRK
|
||||||
@@ -588,9 +591,9 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
|||||||
if ((length != 0) && (telegram[0] != 0x00)) {
|
if ((length != 0) && (telegram[0] != 0x00)) {
|
||||||
_ems_readTelegram(telegram, length);
|
_ems_readTelegram(telegram, length);
|
||||||
}
|
}
|
||||||
// now clear the Rx buffer just be safe and prevent duplicates
|
|
||||||
for (uint8_t i = 0; i < EMS_MAXBUFFERSIZE; telegram[i++] = 0x00)
|
// clear the Rx buffer just be safe and prevent duplicates
|
||||||
;
|
memset(telegram, 0, EMS_MAXBUFFERSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -600,9 +603,10 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
|||||||
void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
|
void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
|
||||||
// create the Rx package
|
// create the Rx package
|
||||||
static _EMS_RxTelegram EMS_RxTelegram;
|
static _EMS_RxTelegram EMS_RxTelegram;
|
||||||
EMS_RxTelegram.length = length;
|
static uint32_t _last_emsPollFrequency = 0;
|
||||||
EMS_RxTelegram.telegram = telegram;
|
EMS_RxTelegram.length = length;
|
||||||
EMS_RxTelegram.timestamp = millis();
|
EMS_RxTelegram.telegram = telegram;
|
||||||
|
EMS_RxTelegram.timestamp = millis();
|
||||||
|
|
||||||
// check if we just received a single byte
|
// check if we just received a single byte
|
||||||
// it could well be a Poll request from the boiler for us, which will have a value of 0x8B (0x0B | 0x80)
|
// it could well be a Poll request from the boiler for us, which will have a value of 0x8B (0x0B | 0x80)
|
||||||
@@ -610,10 +614,12 @@ void _ems_readTelegram(uint8_t * telegram, uint8_t length) {
|
|||||||
if (length == 1) {
|
if (length == 1) {
|
||||||
uint8_t value = telegram[0]; // 1st byte of data package
|
uint8_t value = telegram[0]; // 1st byte of data package
|
||||||
|
|
||||||
|
EMS_Sys_Status.emsPollFrequency = (EMS_RxTelegram.timestamp - _last_emsPollFrequency);
|
||||||
|
_last_emsPollFrequency = EMS_RxTelegram.timestamp;
|
||||||
|
|
||||||
// check first for a Poll for us
|
// check first for a Poll for us
|
||||||
if (value == (EMS_ID_ME | 0x80)) {
|
if (value == (EMS_ID_ME | 0x80)) {
|
||||||
EMS_Sys_Status.emsPollTimestamp = EMS_RxTelegram.timestamp; // store when we received a last poll
|
EMS_Sys_Status.emsTxCapable = true;
|
||||||
EMS_Sys_Status.emsTxCapable = true;
|
|
||||||
|
|
||||||
// do we have something to send thats waiting in the Tx queue?
|
// do we have something to send thats waiting in the Tx queue?
|
||||||
// if so send it if the Queue is not in a wait state
|
// if so send it if the Queue is not in a wait state
|
||||||
@@ -1396,8 +1402,8 @@ void ems_printTxQueue() {
|
|||||||
strlcpy(sType, "?", sizeof(sType));
|
strlcpy(sType, "?", sizeof(sType));
|
||||||
}
|
}
|
||||||
|
|
||||||
char addedTime[15] = {0};
|
char addedTime[15] = {0};
|
||||||
unsigned long upt = EMS_TxTelegram.timestamp;
|
uint32_t upt = EMS_TxTelegram.timestamp;
|
||||||
snprintf(addedTime,
|
snprintf(addedTime,
|
||||||
sizeof(addedTime),
|
sizeof(addedTime),
|
||||||
"(%02d:%02d:%02d)",
|
"(%02d:%02d:%02d)",
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ typedef struct {
|
|||||||
_EMS_SYS_LOGGING emsLogging; // logging
|
_EMS_SYS_LOGGING emsLogging; // logging
|
||||||
bool emsRefreshed; // fresh data, needs to be pushed out to MQTT
|
bool emsRefreshed; // fresh data, needs to be pushed out to MQTT
|
||||||
bool emsBusConnected; // is there an active bus
|
bool emsBusConnected; // is there an active bus
|
||||||
unsigned long emsRxTimestamp; // timestamp of last EMS message received
|
uint32_t emsRxTimestamp; // timestamp of last EMS message received
|
||||||
unsigned long emsPollTimestamp; // timestamp of last EMS poll sent to us
|
uint32_t emsPollFrequency; // time between EMS polls
|
||||||
bool emsTxCapable; // able to send via Tx
|
bool emsTxCapable; // able to send via Tx
|
||||||
bool emsTxDisabled; // true to prevent all Tx
|
bool emsTxDisabled; // true to prevent all Tx
|
||||||
uint8_t txRetryCount; // # times the last Tx was re-sent
|
uint8_t txRetryCount; // # times the last Tx was re-sent
|
||||||
@@ -109,7 +109,7 @@ typedef struct {
|
|||||||
uint8_t comparisonOffset; // offset of where the byte is we want to compare too later
|
uint8_t comparisonOffset; // offset of where the byte is we want to compare too later
|
||||||
uint8_t comparisonPostRead; // after a successful write call this to read
|
uint8_t comparisonPostRead; // after a successful write call this to read
|
||||||
bool forceRefresh; // should we send to MQTT after a successful Tx?
|
bool forceRefresh; // should we send to MQTT after a successful Tx?
|
||||||
unsigned long timestamp; // when created
|
uint32_t timestamp; // when created
|
||||||
uint8_t data[EMS_MAX_TELEGRAM_LENGTH];
|
uint8_t data[EMS_MAX_TELEGRAM_LENGTH];
|
||||||
} _EMS_TxTelegram;
|
} _EMS_TxTelegram;
|
||||||
|
|
||||||
@@ -120,7 +120,6 @@ typedef struct {
|
|||||||
uint8_t length; // length in bytes
|
uint8_t length; // length in bytes
|
||||||
} _EMS_RxTelegram;
|
} _EMS_RxTelegram;
|
||||||
|
|
||||||
|
|
||||||
// default empty Tx
|
// default empty Tx
|
||||||
const _EMS_TxTelegram EMS_TX_TELEGRAM_NEW = {
|
const _EMS_TxTelegram EMS_TX_TELEGRAM_NEW = {
|
||||||
EMS_TX_TELEGRAM_INIT, // action
|
EMS_TX_TELEGRAM_INIT, // action
|
||||||
@@ -297,6 +296,7 @@ bool ems_getEmsRefreshed();
|
|||||||
uint8_t ems_getThermostatModel();
|
uint8_t ems_getThermostatModel();
|
||||||
void ems_discoverModels();
|
void ems_discoverModels();
|
||||||
bool ems_getTxCapable();
|
bool ems_getTxCapable();
|
||||||
|
uint32_t ems_getPollFrequency();
|
||||||
|
|
||||||
void ems_scanDevices();
|
void ems_scanDevices();
|
||||||
void ems_printAllTypes();
|
void ems_printAllTypes();
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ const _Boiler_Type Boiler_Types[] = {
|
|||||||
{EMS_MODEL_UBA, 123, 0x08, "Buderus GB172/Nefit Trendline"},
|
{EMS_MODEL_UBA, 123, 0x08, "Buderus GB172/Nefit Trendline"},
|
||||||
{EMS_MODEL_UBA, 115, 0x08, "Nefit Topline Compact"},
|
{EMS_MODEL_UBA, 115, 0x08, "Nefit Topline Compact"},
|
||||||
{EMS_MODEL_UBA, 203, 0x08, "Buderus Logamax U122"},
|
{EMS_MODEL_UBA, 203, 0x08, "Buderus Logamax U122"},
|
||||||
|
{EMS_MODEL_UBA, 208, 0x08, "Buderus Logamax plus"},
|
||||||
{EMS_MODEL_UBA, 64, 0x08, "Sieger BK15 Boiler/Nefit Smartline"},
|
{EMS_MODEL_UBA, 64, 0x08, "Sieger BK15 Boiler/Nefit Smartline"},
|
||||||
{EMS_MODEL_UBA, 95, 0x08, "Bosch Condens 2500"}
|
{EMS_MODEL_UBA, 95, 0x08, "Bosch Condens 2500"}
|
||||||
|
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ void ICACHE_FLASH_ATTR emsuart_tx_brk() {
|
|||||||
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
USF(EMSUART_UART) = buf[i];
|
USF(EMSUART_UART) = buf[i];
|
||||||
|
//delayMicroseconds(EMS_TX_BRK_WAIT);
|
||||||
}
|
}
|
||||||
emsuart_tx_brk();
|
emsuart_tx_brk();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#define MQTT_RETAIN false
|
#define MQTT_RETAIN false
|
||||||
#define MQTT_KEEPALIVE 120 // 2 minutes
|
#define MQTT_KEEPALIVE 120 // 2 minutes
|
||||||
#define MQTT_QOS 1
|
#define MQTT_QOS 1
|
||||||
|
#define MQTT_MAX_SIZE 700 // max size of a JSON object. See https://arduinojson.org/v6/assistant/
|
||||||
|
|
||||||
// MQTT for thermostat
|
// MQTT for thermostat
|
||||||
#define TOPIC_THERMOSTAT_DATA "thermostat_data" // for sending thermostat values to MQTT
|
#define TOPIC_THERMOSTAT_DATA "thermostat_data" // for sending thermostat values to MQTT
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define APP_NAME "EMS-ESP"
|
#define APP_NAME "EMS-ESP"
|
||||||
#define APP_VERSION "1.7.0b1"
|
#define APP_VERSION "1.6.1b1"
|
||||||
#define APP_HOSTNAME "ems-esp"
|
#define APP_HOSTNAME "ems-esp"
|
||||||
|
|||||||
Reference in New Issue
Block a user