Skip to content

Commit

Permalink
1.05b
Browse files Browse the repository at this point in the history
Fix for heating/cooling devices (systemMode/fanMode)
  • Loading branch information
fashberg committed Mar 31, 2020
1 parent 4d20c1c commit 8847edc
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 41 deletions.
4 changes: 4 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Version 1.05b
* Fix for heating/cooling devices (systemMode/fanMode)
* by Folke Ashberg <folke@ashberg.de>

## Version 1.04b
* moved webthings-page to /webthings (DNS-Discovery adopted)
* root-page is now config-page
Expand Down
42 changes: 36 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,53 @@
# ThermostatBecaWifi
Replaces original Tuya firmware on Beca thermostat with ESP8266 wifi module. The firmware is tested with following devices:
* BHT-002-GBLW, BHT-6000 (floor heating)
* BAC-002-ALW (heater, cooling, ventilation)
* BHT-002-GALW (Water/Gas heating)
* BHT-002-GCLW (Water/Gas Boiler)
* BAC-002-ALW (heater, cooling, ventilation)

Also selled by Moes or Qiumi.

![homeassistant](docs/bac-002-wifi.jpg)

### Hardware differences
GA/GB/GC differs only on relais-outputs. You need WiFi Version! (W in product Name).

* GA - Water-Heating
* Two Relais for opening and closing valve
* Only one Relais will be closed at the same time
* Closing Relais PIN 1 - PIN 3 (N or L)
* Opening Relais PIN 2 - PIN 3 (N or L)
* Product Spec says Max Power: 3 A
* GB - Electric-Heating
* Connect Heating between PIN 1 and PIN 2
* Product Spec says Max Power: 16 A
* GC - Water/Gas Boiler
* One Relais - potential free
* Relaise on PIN 1 - PIN 2 (dry contacts)
* Product Spec says Max Power: 3 A

## Features
* Enables thermostat to communicate via MQTT and/or Mozilla Webthings
* Configuration of connection and devixe parameters via web interface
* Configuration of connection and device parameters via web interface
* NTP and time zone synchronisation to set the clock of thermostat
* Reading and setting of all parameters via MQTT
* Reading and setting of main parameters vie Webthing
* Only BHT-002-GBLW: actualFloorTemperature (external temperature sensor)
* Reading and setting of main parameters via Webthings
* Only BHT-002-GxLW: actualFloorTemperature (external temperature sensor)
* Only BAC-002-ALW: fanSpeed:auto|low|medium|high; systemMode:cooling|heating|ventilation
* Reading and setting of time schedules via MQTT

## Installation
To install the firmware, follow instructions here:
Flashing.md

## Initial configuration
To setup the device model, network options and other parameters, follow instrcution here:
Configuration.md
After initial setup, the device configuration is still available via `http://<device_ip>/config`
After initial setup, the device configuration is still available via `http://<device_ip>/`


![homeassistant](docs/Setup_Main.png)

## Integration in Webthings
Since version 0.96 this firmware supports Mozilla Webthings directly. With webthings you can control the thermostat via the Gateway - inside and also outside of your home network. No clunky VPN, dynDNS solutions needed to access your home devices. I recommend to run the gateway in parallel to an MQTT server and for example Node-Red. Via MQTT you can control the thermostat completely and logic can be done by Node-Red. Webthings is used for outside control of main parameters.
Add the device to the gateway via '+' icon. After that you have the new nice and shiny icon in the dashboard:
Expand Down Expand Up @@ -75,7 +104,8 @@ Firmware provides 3 different json messages:
"floorTemperature":20, //only_BHT-002-GBLW
"fanMode":"auto|low|medium|high", //only_BAC-002-ALW
"systemMode":"cool|heat|fan_only", //only_BAC-002-ALW
"mode":"off|auto|heat|cool|fan_only" // combine Mode for better home assistant support. cool|fan_only only_BAC-002-AL
"mode":"off|auto|heat" // BHT-002: combined Mode for better home assistant support.
"mode":"off|autoheat|autocool|autofan|heat|cool|fan_only" // BAC-002-ALW
}
```
### 2. Schedules
Expand Down
113 changes: 80 additions & 33 deletions WThermostat/WBecaDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ const char* FAN_MODE_MEDIUM = "medium";
const char* FAN_MODE_HIGH = "high";
const char* MODE_OFF = "off";
const char* MODE_AUTO = "auto";
const char* MODE_AUTOHEAT = "autoheat";
const char* MODE_AUTOCOOL = "autocool";
const char* MODE_AUTOFAN = "autofan";
const char* MODE_HEAT = "heat";
const char* MODE_COOL = "cool";
const char* MODE_FAN = "fan_only";
Expand Down Expand Up @@ -132,15 +135,15 @@ class WBecaDevice: public WDevice {
this->systemMode->addEnumString(SYSTEM_MODE_COOL);
this->systemMode->addEnumString(SYSTEM_MODE_HEAT);
this->systemMode->addEnumString(SYSTEM_MODE_FAN);
this->systemMode->setString(SYSTEM_MODE_NONE);
this->systemMode->setOnChange(std::bind(&WBecaDevice::systemModeToMcu, this, std::placeholders::_1));
this->addProperty(systemMode);
this->fanMode = new WProperty("fanMode", "Fan", STRING);
this->fanMode->setAtType("FanModeProperty");
this->fanMode->addEnumString(FAN_MODE_NONE);
this->fanMode->addEnumString(FAN_MODE_LOW);
this->fanMode->addEnumString(FAN_MODE_MEDIUM);
this->fanMode->addEnumString(FAN_MODE_HIGH);
this->fanMode->setString(FAN_MODE_NONE);
this->fanMode->setOnChange(std::bind(&WBecaDevice::fanModeToMcu, this, std::placeholders::_1));
this->addProperty(fanMode);
}
/*
Expand All @@ -152,12 +155,17 @@ class WBecaDevice: public WDevice {
this->mode = new WProperty("mode", "Mode", STRING);
this->mode->setAtType("ThermostatModeProperty");
this->mode->addEnumString(MODE_OFF);
this->mode->addEnumString(MODE_AUTO);
this->mode->addEnumString(MODE_HEAT);
//if (getThermostatModel() == MODEL_BAC_002_ALW) {
// this->mode->addEnumString(MODE_COOL);
// this->mode->addEnumString(MODE_FAN);
//}
if (getThermostatModel() == MODEL_BHT_002_GBLW) {
this->mode->addEnumString(MODE_AUTO);
}
if (getThermostatModel() == MODEL_BAC_002_ALW) {
this->mode->addEnumString(MODE_AUTOHEAT);
this->mode->addEnumString(MODE_AUTOCOOL);
this->mode->addEnumString(MODE_AUTOFAN);
this->mode->addEnumString(MODE_COOL);
this->mode->addEnumString(MODE_FAN);
}
this->mode->addEnumString(MODE_HEAT);
this->mode->setOnChange(std::bind(&WBecaDevice::modeToMcu, this, std::placeholders::_1));
this->mode->setOnValueRequest([this](WProperty* p) {updateMode();});
this->addProperty(mode);
Expand Down Expand Up @@ -646,8 +654,9 @@ class WBecaDevice: public WDevice {
}
}

void fanModeToMcu() {
void fanModeToMcu(WProperty* property) {
if ((fanMode != nullptr) && (!this->receivingDataFromMcu)) {
network->log()->notice(F("fanModeToMcu"));
byte dt = this->getFanModeAsByte();
if (dt != 0xFF) {
//send to device
Expand Down Expand Up @@ -682,8 +691,9 @@ class WBecaDevice: public WDevice {
}
}

void systemModeToMcu() {
void systemModeToMcu(WProperty* property) {
if ((systemMode != nullptr) && (!this->receivingDataFromMcu)) {
network->log()->notice(F("systemModeToMcu"));
byte dt = this->getSystemModeAsByte();
if (dt != 0xFF) {
//send to device
Expand Down Expand Up @@ -1099,30 +1109,51 @@ class WBecaDevice: public WDevice {
}
}
void modeToMcu(WProperty* property) {
network->log()->notice(F("modeToMcu %s"), property->c_str());
if (this->mode->equalsString(MODE_AUTO)){
this->deviceOn->setBoolean(true);
this->schedulesMode->setString(SCHEDULES_MODE_AUTO);
if (getThermostatModel() == MODEL_BAC_002_ALW){
// FIXME: this->systemMode->setString( coo; )
}
network->log()->trace(F("modeToMcu %s"), property->c_str());

} else {
this->schedulesMode->setString(SCHEDULES_MODE_OFF);
if (getThermostatModel() == MODEL_BHT_002_GBLW) {
if (this->mode->equalsString(MODE_OFF)){
this->deviceOn->setBoolean(false);
this->schedulesMode->setString(SCHEDULES_MODE_OFF);
} else {
this->deviceOn->setBoolean(true);
if (this->mode->equalsString(MODE_AUTO)){
this->schedulesMode->setString(SCHEDULES_MODE_AUTO);
this->schedulesMode->setString(SCHEDULES_MODE_AUTO);
} else if (this->mode->equalsString(MODE_HEAT)){
this->schedulesMode->setString(SCHEDULES_MODE_OFF);
} else {
network->log()->warning(F("modeToMcu unknown mode %s"), property->c_str());
}
}
}
if (getThermostatModel() == MODEL_BAC_002_ALW){
if (this->mode->equalsString(MODE_OFF)){
this->schedulesMode->setString(SCHEDULES_MODE_OFF);
this->deviceOn->setBoolean(false);
} else {
this->deviceOn->setBoolean(true);
this->fanMode->setString(FAN_MODE_AUTO);
if (this->mode->equalsString(MODE_HEAT)){
// deviceOn + schedules Off = heat
}
if (getThermostatModel() == MODEL_BAC_002_ALW) {
if (this->mode->equalsString(MODE_HEAT)){
} else if (this->mode->equalsString(MODE_COOL)){
this->systemMode->setString(SYSTEM_MODE_COOL);
} else if (this->mode->equalsString(MODE_FAN)){
this->systemMode->setString(SYSTEM_MODE_FAN);
}
this->schedulesMode->setString(SCHEDULES_MODE_OFF);
this->systemMode->setString(SYSTEM_MODE_HEAT);
} else if (this->mode->equalsString(MODE_COOL)){
this->schedulesMode->setString(SCHEDULES_MODE_OFF);
this->systemMode->setString(SYSTEM_MODE_COOL);
} else if (this->mode->equalsString(MODE_FAN)){
this->schedulesMode->setString(SCHEDULES_MODE_OFF);
this->systemMode->setString(SYSTEM_MODE_FAN);
} else if (this->mode->equalsString(MODE_AUTOHEAT)){
this->schedulesMode->setString(SCHEDULES_MODE_AUTO);
this->systemMode->setString(SYSTEM_MODE_HEAT);
} else if (this->mode->equalsString(MODE_AUTOCOOL)){
this->schedulesMode->setString(SCHEDULES_MODE_AUTO);
this->systemMode->setString(SYSTEM_MODE_COOL);
} else if (this->mode->equalsString(MODE_AUTOFAN)){
this->schedulesMode->setString(SCHEDULES_MODE_AUTO);
this->systemMode->setString(SYSTEM_MODE_FAN);
} else {
network->log()->warning(F("modeToMcu unknown mode %s"), property->c_str());
}
}
}
Expand All @@ -1133,16 +1164,32 @@ class WBecaDevice: public WDevice {
if (!this->deviceOn->getBoolean()){
this->mode->setString(MODE_OFF);
} else if (this->schedulesMode->equalsString(SCHEDULES_MODE_AUTO)){
this->mode->setString(MODE_AUTO);
if (getThermostatModel() == MODEL_BAC_002_ALW){
if (this->systemMode->equalsString(SYSTEM_MODE_HEAT)){
this->mode->setString(MODE_AUTOHEAT);
} else if (this->systemMode->equalsString(SYSTEM_MODE_COOL)){
this->mode->setString(MODE_AUTOCOOL);
} else if (this->systemMode->equalsString(SYSTEM_MODE_FAN)){
this->mode->setString(MODE_AUTOFAN);
}
} else if (getThermostatModel() == MODEL_BHT_002_GBLW) {
this->mode->setString(MODE_AUTO);
} else {
network->log()->error(F("Bug. Can't find mode (on+auto+?)"));
}
} else if (getThermostatModel() == MODEL_BAC_002_ALW) {
if (this->systemMode->equalsString(MODE_COOL)){
if (this->systemMode->equalsString(SYSTEM_MODE_HEAT)){
this->mode->setString(MODE_HEAT);
} else if (this->systemMode->equalsString(SYSTEM_MODE_COOL)){
this->mode->setString(MODE_COOL);
} else if (this->systemMode->equalsString(SYSTEM_MODE_FAN)){
this->mode->setString(MODE_FAN);
}
} else {
}
} else if (getThermostatModel() == MODEL_BHT_002_GBLW){
this->mode->setString(MODE_HEAT);
}
} else {
network->log()->error(F("Bug. Can't find mode (on+noauto+?)"));
}
}

void lockedToMcu(WProperty* property) {
Expand Down
2 changes: 1 addition & 1 deletion WThermostat/WClock.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class WClock : public WDevice {
RtcTime.year = tmpTime.year;
Rtc.daylight_saving_time = RuleToTime(this->timeRuleDst, RtcTime.year);
Rtc.standard_time = RuleToTime(this->timeRuleStd, RtcTime.year);
network->log()->notice(F("NTP time synced: (%04d-%02d-%02d %02d:%02d:%02d, Weekday: %d, Epoch: %d, Dst: %d, Std: %d, Diff: )"),
network->log()->notice(F("NTP time synced: (%04d-%02d-%02d %02d:%02d:%02d, Weekday: %d, Epoch: %d, Dst: %d, Std: %d, Diff: %d)"),
tmpTime.year, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second, tmpTime.day_of_week,
ntpTime, Rtc.daylight_saving_time, Rtc.standard_time, ntpTime - oldutc );

Expand Down
2 changes: 1 addition & 1 deletion WThermostat/WThermostat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "WLogDevice.h"

#define APPLICATION "Thermostat Beca"
#define VERSION "1.04b"
#define VERSION "1.05b"

#ifdef DEBUG // use platform.io environment to activate/deactive
#define SERIALDEBUG true // enables logging to serial console
Expand Down
Binary file renamed WThermostat_1.04b.bin → WThermostat_1.05b.bin
Binary file not shown.
Binary file added docs/BAC-1000-Manual.pdf
Binary file not shown.
Binary file added docs/BHT-002-Manual.pdf
Binary file not shown.
Binary file modified docs/Setup_Main.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/device.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8847edc

Please sign in to comment.