mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-09 01:09:51 +03:00
version 1.4.0. See ChangeLog
This commit is contained in:
221
src/ds18.cpp
Normal file
221
src/ds18.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Dallas support for external settings
|
||||
* Copied from Espurna - Copyright (C) 2017-2018 by Xose Pérez <xose dot perez at gmail dot com>
|
||||
*
|
||||
* Paul Derbyshire - https://github.com/proddy/EMS-ESP
|
||||
*
|
||||
* See ChangeLog.md for history
|
||||
* See README.md for Acknowledgments
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ds18.h"
|
||||
|
||||
std::vector<ds_device_t> _devices;
|
||||
|
||||
DS18::DS18() {
|
||||
_wire = NULL;
|
||||
_count = 0;
|
||||
_gpio = GPIO_NONE;
|
||||
}
|
||||
|
||||
DS18::~DS18() {
|
||||
if (_wire)
|
||||
delete _wire;
|
||||
}
|
||||
|
||||
// init
|
||||
uint8_t DS18::setup(uint8_t gpio) {
|
||||
uint8_t count;
|
||||
|
||||
_gpio = gpio;
|
||||
|
||||
// OneWire
|
||||
if (_wire)
|
||||
delete _wire;
|
||||
_wire = new OneWire(_gpio);
|
||||
|
||||
// Search devices
|
||||
count = loadDevices();
|
||||
|
||||
// If no devices found check again pulling up the line
|
||||
if (count == 0) {
|
||||
pinMode(_gpio, INPUT_PULLUP);
|
||||
count = loadDevices();
|
||||
}
|
||||
|
||||
_count = count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// scan every 2 seconds
|
||||
void DS18::loop() {
|
||||
static unsigned long last = 0;
|
||||
if (millis() - last < DS18_READ_INTERVAL)
|
||||
return;
|
||||
last = millis();
|
||||
|
||||
// Every second we either start a conversion or read the scratchpad
|
||||
static bool conversion = true;
|
||||
if (conversion) {
|
||||
// Start conversion
|
||||
_wire->reset();
|
||||
_wire->skip();
|
||||
_wire->write(DS18_CMD_START_CONVERSION, DS18_PARASITE);
|
||||
|
||||
} else {
|
||||
// Read scratchpads
|
||||
for (unsigned char index = 0; index < _devices.size(); index++) {
|
||||
// Read scratchpad
|
||||
if (_wire->reset() == 0) {
|
||||
// Force a CRC check error
|
||||
_devices[index].data[0] = _devices[index].data[0] + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
_wire->select(_devices[index].address);
|
||||
_wire->write(DS18_CMD_READ_SCRATCHPAD);
|
||||
|
||||
uint8_t data[DS18_DATA_SIZE];
|
||||
for (unsigned char i = 0; i < DS18_DATA_SIZE; i++) {
|
||||
data[i] = _wire->read();
|
||||
}
|
||||
|
||||
if (_wire->reset() != 1) {
|
||||
// Force a CRC check error
|
||||
_devices[index].data[0] = _devices[index].data[0] + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(_devices[index].data, data, DS18_DATA_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
conversion = !conversion;
|
||||
}
|
||||
|
||||
// return string of the device, with name and address
|
||||
char * DS18::getDeviceString(char * buffer, unsigned char index) {
|
||||
uint8_t size = 128;
|
||||
if (index < _count) {
|
||||
uint8_t * address = _devices[index].address;
|
||||
|
||||
unsigned char chip_id = chip(index);
|
||||
if (chip_id == DS18_CHIP_DS18S20) {
|
||||
strlcpy(buffer, "DS18S20", size);
|
||||
} else if (chip_id == DS18_CHIP_DS18B20) {
|
||||
strlcpy(buffer, "DS18B20", size);
|
||||
} else if (chip_id == DS18_CHIP_DS1822) {
|
||||
strlcpy(buffer, "DS1822", size);
|
||||
} else if (chip_id == DS18_CHIP_DS1825) {
|
||||
strlcpy(buffer, "DS1825", size);
|
||||
} else {
|
||||
strlcpy(buffer, "Unknown", size);
|
||||
}
|
||||
|
||||
char a[30] = {0};
|
||||
snprintf(a,
|
||||
sizeof(a),
|
||||
"(%02X%02X%02X%02X%02X%02X%02X%02X) @ GPIO%d",
|
||||
address[0],
|
||||
address[1],
|
||||
address[2],
|
||||
address[3],
|
||||
address[4],
|
||||
address[5],
|
||||
address[6],
|
||||
address[7],
|
||||
_gpio);
|
||||
|
||||
strlcat(buffer, a, size);
|
||||
} else {
|
||||
strlcpy(buffer, "invalid", size);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read sensor values
|
||||
*
|
||||
* Registers:
|
||||
byte 0: temperature LSB
|
||||
byte 1: temperature MSB
|
||||
byte 2: high alarm temp
|
||||
byte 3: low alarm temp
|
||||
byte 4: DS18S20: store for crc
|
||||
DS18B20 & DS1822: configuration register
|
||||
byte 5: internal use & crc
|
||||
byte 6: DS18S20: COUNT_REMAIN
|
||||
DS18B20 & DS1822: store for crc
|
||||
byte 7: DS18S20: COUNT_PER_C
|
||||
DS18B20 & DS1822: store for crc
|
||||
byte 8: SCRATCHPAD_CRC
|
||||
*/
|
||||
double DS18::getValue(unsigned char index) {
|
||||
if (index >= _count)
|
||||
return 0;
|
||||
|
||||
uint8_t * data = _devices[index].data;
|
||||
|
||||
if (OneWire::crc8(data, DS18_DATA_SIZE - 1) != data[DS18_DATA_SIZE - 1]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t raw = (data[1] << 8) | data[0];
|
||||
if (chip(index) == DS18_CHIP_DS18S20) {
|
||||
raw = raw << 3; // 9 bit resolution default
|
||||
if (data[7] == 0x10) {
|
||||
raw = (raw & 0xFFF0) + 12 - data[6]; // "count remain" gives full 12 bit resolution
|
||||
}
|
||||
} else {
|
||||
byte cfg = (data[4] & 0x60);
|
||||
if (cfg == 0x00)
|
||||
raw = raw & ~7; // 9 bit res, 93.75 ms
|
||||
else if (cfg == 0x20)
|
||||
raw = raw & ~3; // 10 bit res, 187.5 ms
|
||||
else if (cfg == 0x40)
|
||||
raw = raw & ~1; // 11 bit res, 375 ms
|
||||
// 12 bit res, 750 ms
|
||||
}
|
||||
|
||||
double value = (float)raw / 16.0;
|
||||
if (value == DS18_DISCONNECTED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// check for a supported DS chip version
|
||||
bool DS18::validateID(unsigned char id) {
|
||||
return (id == DS18_CHIP_DS18S20) || (id == DS18_CHIP_DS18B20) || (id == DS18_CHIP_DS1822) || (id == DS18_CHIP_DS1825);
|
||||
}
|
||||
|
||||
// return the type
|
||||
unsigned char DS18::chip(unsigned char index) {
|
||||
if (index < _count)
|
||||
return _devices[index].address[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// scan for DS sensors and load into the vector
|
||||
uint8_t DS18::loadDevices() {
|
||||
uint8_t address[8];
|
||||
_wire->reset();
|
||||
_wire->reset_search();
|
||||
while (_wire->search(address)) {
|
||||
// Check CRC
|
||||
if (_wire->crc8(address, 7) == address[7]) {
|
||||
// Check ID
|
||||
if (validateID(address[0])) {
|
||||
ds_device_t device;
|
||||
memcpy(device.address, address, 8);
|
||||
_devices.push_back(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (_devices.size());
|
||||
}
|
||||
55
src/ds18.h
Normal file
55
src/ds18.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Dallas support for external temperature sensors
|
||||
* Copyright (C) 2017-2018 by Xose Pérez <xose dot perez at gmail dot com>
|
||||
*
|
||||
* Paul Derbyshire - https://github.com/proddy/EMS-ESP
|
||||
*
|
||||
* See ChangeLog.md for history
|
||||
* See README.md for Acknowledgments
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OneWire.h>
|
||||
#include <vector>
|
||||
|
||||
#define DS18_CHIP_DS18S20 0x10
|
||||
#define DS18_CHIP_DS1822 0x22
|
||||
#define DS18_CHIP_DS18B20 0x28
|
||||
#define DS18_CHIP_DS1825 0x3B
|
||||
|
||||
#define DS18_DATA_SIZE 9
|
||||
#define DS18_PARASITE 1
|
||||
#define DS18_DISCONNECTED -127
|
||||
|
||||
#define GPIO_NONE 0x99
|
||||
#define DS18_READ_INTERVAL 2000 // Force sensor read & cache every 2 seconds
|
||||
|
||||
#define DS18_CMD_START_CONVERSION 0x44
|
||||
#define DS18_CMD_READ_SCRATCHPAD 0xBE
|
||||
|
||||
typedef struct {
|
||||
uint8_t address[8];
|
||||
uint8_t data[DS18_DATA_SIZE];
|
||||
} ds_device_t;
|
||||
|
||||
class DS18 {
|
||||
public:
|
||||
DS18();
|
||||
~DS18();
|
||||
|
||||
uint8_t setup(uint8_t gpio);
|
||||
void loop();
|
||||
char * getDeviceString(char * s, unsigned char index);
|
||||
double getValue(unsigned char index);
|
||||
|
||||
protected:
|
||||
bool validateID(unsigned char id);
|
||||
unsigned char chip(unsigned char index);
|
||||
uint8_t loadDevices();
|
||||
|
||||
OneWire * _wire;
|
||||
uint8_t _count; // # devices
|
||||
uint8_t _gpio; // the sensor pin
|
||||
};
|
||||
@@ -8,13 +8,17 @@
|
||||
*/
|
||||
|
||||
// local libraries
|
||||
#include "ds18.h"
|
||||
#include "ems.h"
|
||||
#include "ems_devices.h"
|
||||
#include "emsuart.h"
|
||||
#include "my_config.h"
|
||||
#include "version.h"
|
||||
|
||||
// my libraries
|
||||
// Dallas external temp sensors
|
||||
DS18 ds18;
|
||||
|
||||
// shared libraries
|
||||
#include <MyESP.h>
|
||||
|
||||
// public libraries
|
||||
@@ -74,10 +78,11 @@ Ticker showerColdShotStopTimer;
|
||||
#define SHOWER_COLDSHOT_DURATION 10 // in seconds. 10 seconds for cold water before turning back hot water
|
||||
|
||||
typedef struct {
|
||||
bool shower_timer; // true if we want to report back on shower times
|
||||
bool shower_alert; // true if we want the alert of cold water
|
||||
bool led_enabled; // LED on/off
|
||||
unsigned long timestamp; // for internal timings, via millis()
|
||||
bool shower_timer; // true if we want to report back on shower times
|
||||
bool shower_alert; // true if we want the alert of cold water
|
||||
bool led_enabled; // LED on/off
|
||||
unsigned long timestamp; // for internal timings, via millis()
|
||||
uint8_t dallas_sensors; // count of dallas sensors
|
||||
} _EMSESP_Status;
|
||||
|
||||
typedef struct {
|
||||
@@ -122,7 +127,7 @@ void myDebugLog(const char * s) {
|
||||
}
|
||||
|
||||
// convert float to char
|
||||
char * _float_to_char(char * a, float f, uint8_t precision = 1) {
|
||||
char * _float_to_char(char * a, float f, uint8_t precision = 2) {
|
||||
long p[] = {0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
|
||||
|
||||
char * ret = a;
|
||||
@@ -202,14 +207,20 @@ void _renderIntfractionalValue(const char * prefix, const char * postfix, uint8_
|
||||
strlcpy(buffer, " ", sizeof(buffer));
|
||||
strlcat(buffer, prefix, sizeof(buffer));
|
||||
strlcat(buffer, ": ", sizeof(buffer));
|
||||
strlcat(buffer, _int_to_char(s, value / (decimals * 10)), sizeof(buffer));
|
||||
strlcat(buffer, ".", sizeof(buffer));
|
||||
strlcat(buffer, _int_to_char(s, value % (decimals * 10)), sizeof(buffer));
|
||||
|
||||
if (value == EMS_VALUE_INT_NOTSET) {
|
||||
strlcat(buffer, "?", sizeof(buffer));
|
||||
} else {
|
||||
strlcat(buffer, _int_to_char(s, value / (decimals * 10)), sizeof(buffer));
|
||||
strlcat(buffer, ".", sizeof(buffer));
|
||||
strlcat(buffer, _int_to_char(s, value % (decimals * 10)), sizeof(buffer));
|
||||
}
|
||||
|
||||
if (postfix != NULL) {
|
||||
strlcat(buffer, " ", sizeof(buffer));
|
||||
strlcat(buffer, postfix, sizeof(buffer));
|
||||
}
|
||||
|
||||
myDebug(buffer);
|
||||
}
|
||||
|
||||
@@ -266,6 +277,8 @@ void showInfo() {
|
||||
|
||||
myDebug(" LED is %s", EMSESP_Status.led_enabled ? "on" : "off");
|
||||
|
||||
myDebug(" # connected Dallas temperature sensors = %d", EMSESP_Status.dallas_sensors);
|
||||
|
||||
myDebug(" Thermostat is %s, Boiler is %s, Poll is %s, Tx is %s, Shower Timer is %s, Shower Alert is %s",
|
||||
(ems_getThermostatEnabled() ? "enabled" : "disabled"),
|
||||
(ems_getBoilerEnabled() ? "enabled" : "disabled"),
|
||||
@@ -291,8 +304,10 @@ void showInfo() {
|
||||
myDebug(" Boiler type: %s", ems_getBoilerDescription(buffer_type));
|
||||
|
||||
// active stats
|
||||
myDebug(" Hot tap water is %s", (EMS_Boiler.tapwaterActive ? "running" : "off"));
|
||||
myDebug(" Central Heating is %s", (EMS_Boiler.heatingActive ? "active" : "off"));
|
||||
if (ems_getBusConnected()) {
|
||||
myDebug(" Hot tap water is %s", (EMS_Boiler.tapwaterActive ? "running" : "off"));
|
||||
myDebug(" Central Heating is %s", (EMS_Boiler.heatingActive ? "active" : "off"));
|
||||
}
|
||||
|
||||
// UBAParameterWW
|
||||
_renderBoolValue("Warm Water activated", EMS_Boiler.wWActivated);
|
||||
@@ -328,6 +343,11 @@ void showInfo() {
|
||||
_renderFloatValue("System pressure", "bar", EMS_Boiler.sysPress);
|
||||
myDebug(" Current System Service Code: %s", EMS_Boiler.serviceCodeChar);
|
||||
|
||||
// UBAParametersMessage
|
||||
_renderIntValue("Heating temperature setting on the boiler", "C", EMS_Boiler.heating_temp);
|
||||
_renderIntValue("Boiler circuit pump modulation max. power", "%", EMS_Boiler.pump_mod_max);
|
||||
_renderIntValue("Boiler circuit pump modulation min. power", "%", EMS_Boiler.pump_mod_min);
|
||||
|
||||
// UBAMonitorSlow
|
||||
_renderFloatValue("Outside temperature", "C", EMS_Boiler.extTemp);
|
||||
_renderFloatValue("Boiler temperature", "C", EMS_Boiler.boilTemp);
|
||||
@@ -383,9 +403,21 @@ void showInfo() {
|
||||
|
||||
myDebug(""); // newline
|
||||
|
||||
// Dallas
|
||||
if (EMSESP_Status.dallas_sensors != 0) {
|
||||
myDebug("%sExternal temperature sensors:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
||||
for (uint8_t i = 0; i < EMSESP_Status.dallas_sensors; i++) {
|
||||
char s[80] = {0};
|
||||
snprintf(s, sizeof(s), "Sensor #%d", i + 1);
|
||||
_renderFloatValue(s, "C", ds18.getValue(i));
|
||||
}
|
||||
}
|
||||
|
||||
myDebug(""); // newline
|
||||
|
||||
// show the Shower Info
|
||||
if (EMSESP_Status.shower_timer) {
|
||||
myDebug("%s Shower stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
||||
myDebug("%sShower stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
||||
myDebug(" Shower Timer is %s", (EMSESP_Shower.showerOn ? "active" : "off"));
|
||||
}
|
||||
}
|
||||
@@ -597,7 +629,7 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c
|
||||
// we set the logging here
|
||||
void TelnetCallback(uint8_t event) {
|
||||
if (event == TELNET_EVENT_CONNECT) {
|
||||
ems_setLogging(EMS_SYS_LOGGING_BASIC);
|
||||
ems_setLogging(EMS_SYS_LOGGING_NONE);
|
||||
} else if (event == TELNET_EVENT_DISCONNECT) {
|
||||
ems_setLogging(EMS_SYS_LOGGING_NONE);
|
||||
}
|
||||
@@ -838,10 +870,11 @@ void WIFICallback() {
|
||||
// Initialize the boiler settings and shower settings
|
||||
void initEMSESP() {
|
||||
// general settings
|
||||
EMSESP_Status.shower_timer = BOILER_SHOWER_TIMER;
|
||||
EMSESP_Status.shower_alert = BOILER_SHOWER_ALERT;
|
||||
EMSESP_Status.led_enabled = false;
|
||||
EMSESP_Status.timestamp = millis();
|
||||
EMSESP_Status.shower_timer = BOILER_SHOWER_TIMER;
|
||||
EMSESP_Status.shower_alert = BOILER_SHOWER_ALERT;
|
||||
EMSESP_Status.led_enabled = false;
|
||||
EMSESP_Status.timestamp = millis();
|
||||
EMSESP_Status.dallas_sensors = 0;
|
||||
|
||||
// shower settings
|
||||
EMSESP_Shower.timerStart = 0;
|
||||
@@ -888,18 +921,22 @@ void do_systemCheck() {
|
||||
// force calls to get data from EMS for the types that aren't sent as broadcasts
|
||||
// only if we have a EMS connection
|
||||
void do_regularUpdates() {
|
||||
myDebugLog("Calling scheduled data refresh from EMS devices..");
|
||||
ems_getThermostatValues();
|
||||
ems_getBoilerValues();
|
||||
if (ems_getBusConnected()) {
|
||||
myDebugLog("Calling scheduled data refresh from EMS devices..");
|
||||
ems_getThermostatValues();
|
||||
ems_getBoilerValues();
|
||||
}
|
||||
}
|
||||
|
||||
// turn off hot water to send a shot of cold
|
||||
void _showerColdShotStart() {
|
||||
myDebugLog("[Shower] doing a shot of cold water");
|
||||
ems_setWarmTapWaterActivated(false);
|
||||
EMSESP_Shower.doingColdShot = true;
|
||||
// start the timer for n seconds which will reset the water back to hot
|
||||
showerColdShotStopTimer.attach(SHOWER_COLDSHOT_DURATION, _showerColdShotStop);
|
||||
if (EMSESP_Status.shower_alert) {
|
||||
myDebugLog("[Shower] doing a shot of cold water");
|
||||
ems_setWarmTapWaterActivated(false);
|
||||
EMSESP_Shower.doingColdShot = true;
|
||||
// start the timer for n seconds which will reset the water back to hot
|
||||
showerColdShotStopTimer.attach(SHOWER_COLDSHOT_DURATION, _showerColdShotStop);
|
||||
}
|
||||
}
|
||||
|
||||
// turn back on the hot water for the shower
|
||||
@@ -1006,6 +1043,9 @@ void setup() {
|
||||
digitalWrite(BOILER_LED, (BOILER_LED == LED_BUILTIN) ? HIGH : LOW); // light off. For onboard high=off
|
||||
ledcheckTimer.attach(LEDCHECK_TIME, do_ledcheck); // blink heartbeat LED
|
||||
|
||||
// check for Dallas sensors
|
||||
EMSESP_Status.dallas_sensors = ds18.setup(TEMPERATURE_SENSOR_PIN);
|
||||
|
||||
// init the EMS bus
|
||||
// call ems.cpp's init function to set all the internal params
|
||||
ems_init(MY_THERMOSTAT_MODELID);
|
||||
@@ -1020,6 +1060,11 @@ void loop() {
|
||||
// the main loop
|
||||
myESP.loop();
|
||||
|
||||
// check Dallas sensors
|
||||
if (EMSESP_Status.dallas_sensors != 0) {
|
||||
ds18.loop();
|
||||
}
|
||||
|
||||
// publish the values to MQTT, regardless if the values haven't changed
|
||||
// we don't want to publish when doing a deep scan of the thermostat
|
||||
if (ems_getEmsRefreshed() && (scanThermostat_count == 0)) {
|
||||
|
||||
34
src/ems.cpp
34
src/ems.cpp
@@ -22,16 +22,20 @@ _EMS_Sys_Status EMS_Sys_Status; // EMS Status
|
||||
CircularBuffer<_EMS_TxTelegram, EMS_TX_TELEGRAM_QUEUE_MAX> EMS_TxQueue; // FIFO queue for Tx send buffer
|
||||
|
||||
// callbacks per type
|
||||
// Boiler and Buderus devices
|
||||
|
||||
// generic
|
||||
void _process_Version(uint8_t * data, uint8_t length);
|
||||
|
||||
// Boiler and Buderus devices
|
||||
void _process_UBAMonitorFast(uint8_t * data, uint8_t length);
|
||||
void _process_UBAMonitorSlow(uint8_t * data, uint8_t length);
|
||||
void _process_UBAMonitorWWMessage(uint8_t * data, uint8_t length);
|
||||
void _process_UBAParameterWW(uint8_t * data, uint8_t length);
|
||||
void _process_UBATotalUptimeMessage(uint8_t * data, uint8_t length);
|
||||
void _process_UBAParametersMessage(uint8_t * data, uint8_t length);
|
||||
void _process_SetPoints(uint8_t * data, uint8_t length);
|
||||
|
||||
// Common for most thermostats
|
||||
void _process_SetPoints(uint8_t * data, uint8_t length);
|
||||
void _process_RCTime(uint8_t * data, uint8_t length);
|
||||
void _process_RCOutdoorTempMessage(uint8_t * data, uint8_t length);
|
||||
|
||||
@@ -66,8 +70,7 @@ const _EMS_Type EMS_Types[] = {
|
||||
{EMS_MODEL_UBA, EMS_TYPE_UBAParameterWW, "UBAParameterWW", _process_UBAParameterWW},
|
||||
{EMS_MODEL_UBA, EMS_TYPE_UBATotalUptimeMessage, "UBATotalUptimeMessage", _process_UBATotalUptimeMessage},
|
||||
{EMS_MODEL_UBA, EMS_TYPE_UBAMaintenanceSettingsMessage, "UBAMaintenanceSettingsMessage", NULL},
|
||||
{EMS_MODEL_UBA, EMS_TYPE_UBAParametersMessage, "UBAParametersMessage", NULL},
|
||||
{EMS_MODEL_UBA, EMS_TYPE_UBAMaintenanceStatusMessage, "UBAMaintenanceStatusMessage", NULL},
|
||||
{EMS_MODEL_UBA, EMS_TYPE_UBAParametersMessage, "UBAParametersMessage", _process_UBAParametersMessage},
|
||||
{EMS_MODEL_UBA, EMS_TYPE_UBASetPoints, "UBASetPoints", _process_SetPoints},
|
||||
|
||||
// RC20 and RC20F
|
||||
@@ -212,6 +215,12 @@ void ems_init(uint8_t thermostat_modelid) {
|
||||
// UBATotalUptimeMessage
|
||||
EMS_Boiler.UBAuptime = EMS_VALUE_LONG_NOTSET; // Total UBA working hours
|
||||
|
||||
// UBAParametersMessage
|
||||
EMS_Boiler.heating_temp = EMS_VALUE_INT_NOTSET; // Heating temperature setting on the boiler
|
||||
EMS_Boiler.pump_mod_max = EMS_VALUE_INT_NOTSET; // Boiler circuit pump modulation max. power
|
||||
EMS_Boiler.pump_mod_min = EMS_VALUE_INT_NOTSET; // Boiler circuit pump modulation min. power
|
||||
|
||||
// calculated values
|
||||
EMS_Boiler.tapwaterActive = EMS_VALUE_INT_NOTSET; // Hot tap water is on/off
|
||||
EMS_Boiler.heatingActive = EMS_VALUE_INT_NOTSET; // Central heating is on/off
|
||||
|
||||
@@ -569,11 +578,6 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) {
|
||||
if (length == 1) {
|
||||
uint8_t value = telegram[0]; // 1st byte of data package
|
||||
|
||||
// TODO: remove, only for debugging why some people can't do a Tx
|
||||
//if ((value & 0x80) == 0x80) {
|
||||
// myDebug("Poll: %02X", value);
|
||||
//}
|
||||
|
||||
// check first for a Poll for us
|
||||
if (value == (EMS_ID_ME | 0x80)) {
|
||||
// store when we received a last poll
|
||||
@@ -886,6 +890,15 @@ void _process_UBATotalUptimeMessage(uint8_t * data, uint8_t length) {
|
||||
EMS_Sys_Status.emsRefreshed = true; // when we receieve this, lets force an MQTT publish
|
||||
}
|
||||
|
||||
/*
|
||||
* UBAParametersMessage - type 0x16
|
||||
*/
|
||||
void _process_UBAParametersMessage(uint8_t * data, uint8_t length) {
|
||||
EMS_Boiler.heating_temp = data[1];
|
||||
EMS_Boiler.pump_mod_max = data[9];
|
||||
EMS_Boiler.pump_mod_min = data[10];
|
||||
}
|
||||
|
||||
/**
|
||||
* UBAMonitorWWMessage - type 0x34 - warm water monitor. 19 bytes long
|
||||
* received every 10 seconds
|
||||
@@ -1298,6 +1311,7 @@ void ems_getBoilerValues() {
|
||||
ems_doReadCommand(EMS_TYPE_UBAMonitorFast, EMS_Boiler.type_id); // get boiler stats, instead of waiting 10secs for the broadcast
|
||||
ems_doReadCommand(EMS_TYPE_UBAMonitorSlow, EMS_Boiler.type_id); // get more boiler stats, instead of waiting 60secs for the broadcast
|
||||
ems_doReadCommand(EMS_TYPE_UBAParameterWW, EMS_Boiler.type_id); // get Warm Water values
|
||||
ems_doReadCommand(EMS_TYPE_UBAParametersMessage, EMS_Boiler.type_id); // get MC10 boiler values
|
||||
ems_doReadCommand(EMS_TYPE_UBATotalUptimeMessage, EMS_Boiler.type_id); // get Warm Water values
|
||||
}
|
||||
|
||||
@@ -1381,7 +1395,7 @@ char * ems_getBoilerDescription(char * buffer) {
|
||||
* Find the versions of our connected devices
|
||||
*/
|
||||
void ems_scanDevices() {
|
||||
myDebug("Scanning EMS bus for devices. This may take a few seconds...");
|
||||
myDebug("Scanning EMS bus for devices...");
|
||||
|
||||
// start refresh when scanning and forget anything devices we may have already set
|
||||
EMS_Thermostat.type_id = EMS_ID_NONE; // forget thermostat
|
||||
|
||||
@@ -203,6 +203,11 @@ typedef struct { // UBAParameterWW
|
||||
// UBATotalUptimeMessage
|
||||
uint32_t UBAuptime; // Total UBA working hours
|
||||
|
||||
// UBAParametersMessage
|
||||
uint8_t heating_temp; // Heating temperature setting on the boiler
|
||||
uint8_t pump_mod_max; // Boiler circuit pump modulation max. power
|
||||
uint8_t pump_mod_min; // Boiler circuit pump modulation min. power
|
||||
|
||||
// calculated values
|
||||
uint8_t tapwaterActive; // Hot tap water is on/off
|
||||
uint8_t heatingActive; // Central heating is on/off
|
||||
|
||||
@@ -97,7 +97,7 @@ const _Boiler_Type Boiler_Types[] = {
|
||||
|
||||
// various boilers and buderus type devices
|
||||
{EMS_MODEL_UBA, 72, 0x08, "MC10"},
|
||||
{EMS_MODEL_UBA, 123, 0x08, "Nefit Trendline"},
|
||||
{EMS_MODEL_UBA, 123, 0x08, "Buderus GB172/Nefit Trendline"},
|
||||
{EMS_MODEL_UBA, 115, 0x08, "Nefit Topline Compact"},
|
||||
{EMS_MODEL_UBA, 64, 0x08, "Sieger BK15 Boiler"},
|
||||
{EMS_MODEL_UBA, 190, 0x09, "BC10 Base Controller"},
|
||||
@@ -115,11 +115,11 @@ const _Boiler_Type Boiler_Types[] = {
|
||||
const _Thermostat_Type Thermostat_Types[] = {
|
||||
|
||||
{EMS_MODEL_ES73, 76, 0x10, "Sieger ES73", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC20, 77, 0x17, "RC20 (e.g. Nefit Moduline 300)", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC20, 77, 0x17, "RC20/Nefit Moduline 300)", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC30, 78, 0x10, "RC30 (e.g. Nefit Moduline 400)", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC30, 78, 0x10, "RC30/Nefit Moduline 400)", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_EASY, 202, 0x18, "TC100 (e.g. Nefit Easy or CT100)", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_EASY, 202, 0x18, "TC100/Nefit Easy", EMS_THERMOSTAT_READ_YES, EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_RC310, 158, 0x10, "RC310", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_CW100, 255, 0x18, "Bosch CW100", EMS_THERMOSTAT_READ_NO, EMS_THERMOSTAT_WRITE_NO}
|
||||
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
#pragma once
|
||||
|
||||
#define APP_NAME "EMS-ESP"
|
||||
#define APP_VERSION "1.3.2"
|
||||
#define APP_VERSION "1.4.0"
|
||||
#define APP_HOSTNAME "ems-esp"
|
||||
|
||||
Reference in New Issue
Block a user