version 1.9.3 - merge with dev branch

This commit is contained in:
Paul
2019-10-26 12:04:51 +02:00
14 changed files with 340 additions and 68 deletions

View File

@@ -5,6 +5,23 @@ 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.9.3] 2019-10-26
### Added
- Report # TCP dropouts in the `system` command. These could be due to WiFI or MQTT disconnected.
- Added temp and mode to the MQTT `thermostat_cmd` topic
- build scripts for automated CI with TravisCI
### Fixed
- vertical bar showing in WebUI sidebar menu using FireFox
### Changed
- Heartbeat MQTT payload is now in JSON
- platformio.ini targets. Use `debug` for custom builds.
## [1.9.2] 2019-10-19 ## [1.9.2] 2019-10-19
#### Important! This build has breaking changes: #### Important! This build has breaking changes:
@@ -31,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- All MQTT topics for the Thermostat have the Heating Circuit appended (e.g. `thermostat_data1`). This includes the commands. - All MQTT topics for the Thermostat have the Heating Circuit appended (e.g. `thermostat_data1`). This includes the commands.
- Shower timer and shower alert and not MQTT published at boot up - Shower timer and shower alert and not MQTT published at boot up
- Heating Active logic change to use Selected Flow Temp of min 30 instead of 70 (https://github.com/proddy/EMS-ESP/issues/193) - Heating Active logic change to use Selected Flow Temp of min 30 instead of 70 (https://github.com/proddy/EMS-ESP/issues/193)
- Cleaned up Telnet messages during bootup to only show key information.
### Removed ### Removed

View File

@@ -3,8 +3,7 @@
; ;
[platformio] [platformio]
default_envs = release default_envs = debug
;default_envs = debug
[common] [common]
; custom build options are: ; custom build options are:
@@ -12,17 +11,12 @@ default_envs = release
; -DTESTS ; -DTESTS
; -DCRASH ; -DCRASH
; -DFORCE_SERIAL ; -DFORCE_SERIAL
; -DLOGICANALYZER
custom_flags = custom_flags =
;general_flags = -DNO_GLOBAL_EEPROM -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -DBEARSSL_SSL_BASIC ;general_flags = -DNO_GLOBAL_EEPROM -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -DBEARSSL_SSL_BASIC
general_flags = -DNO_GLOBAL_EEPROM general_flags = -DNO_GLOBAL_EEPROM
[env] [env]
; board = esp12e
; board = nodemcu
; board = nodemcu2
board = d1_mini
framework = arduino framework = arduino
platform = espressif8266 platform = espressif8266
lib_deps = lib_deps =
@@ -47,20 +41,31 @@ monitor_speed = 115200
upload_protocol = espota upload_protocol = espota
upload_port = ems-esp.local upload_port = ems-esp.local
[env:debug] # Special build for CI test
build_type = debug [env:travis]
build_flags = ${common.general_flags} ${common.custom_flags} -DTESTS board = esp12e
extra_scripts = build_flags = ${common.general_flags}
pre:scripts/rename_fw.py
pre:scripts/buildweb.py
[env:release] [env:esp12e]
board = esp12e
build_flags = ${common.general_flags}
[env:d1_mini]
board = d1_mini
build_flags = ${common.general_flags}
[env:nodemcuv2]
board = nodemcuv2
build_flags = ${common.general_flags}
[env:nodemcu]
board = nodemcu
build_flags = ${common.general_flags}
[env:debug]
board = d1_mini
build_type = debug
build_flags = ${common.general_flags} ${common.custom_flags} build_flags = ${common.general_flags} ${common.custom_flags}
extra_scripts = extra_scripts =
pre:scripts/rename_fw.py pre:scripts/rename_fw.py
pre:scripts/buildweb.py pre:scripts/buildweb.py
[env:checkcode]
build_type = debug
build_flags = ${common.general_flags} -Wall
extra_scripts = scripts/checkcode.py

192
scripts/build.sh Normal file
View File

@@ -0,0 +1,192 @@
#!/bin/bash
set -e
### Functions
is_git() {
command -v git >/dev/null 2>&1 || return 1
command git rev-parse >/dev/null 2>&1 || return 1
return 0
}
stat_bytes() {
echo "size is:"
case "$(uname -s)" in
Darwin) stat -f %z "$1";;
*) stat -c %s "$1";;
esac
}
# Available environments
list_envs() {
grep env: ../platformio.ini | sed 's/\[env:\(.*\)\]/\1/g'
}
print_available() {
echo "--------------------------------------------------------------"
echo "Available environments:"
for environment in $available; do
echo "-> $environment"
done
}
print_environments() {
echo "--------------------------------------------------------------"
echo "Current environments:"
for environment in $environments; do
echo "-> $environment"
done
}
set_default_environments() {
# Hook to build in parallel when using travis
if [[ "${TRAVIS_BUILD_STAGE_NAME}" = "Release" ]] && ${par_build}; then
environments=$(echo ${available} | \
awk -v par_thread=${par_thread} -v par_total_threads=${par_total_threads} \
'{ for (i = 1; i <= NF; i++) if (++j % par_total_threads == par_thread ) print $i; }')
return
fi
# Only build travis target
if [[ "${TRAVIS_BUILD_STAGE_NAME}" = "Test" ]]; then
environments=$travis
return
fi
# Fallback to all available environments
environments=$available
}
build_webui() {
cd ../tools/webfilesbuilder
# Build system uses gulpscript.js to build web interface
if [ ! -e node_modules/gulp/bin/gulp.js ]; then
echo "--------------------------------------------------------------"
echo "Installing dependencies..."
npm ci
fi
# Recreate web interface - "node ./tools/webfilesbuilder/node_modules/gulp/bin/gulp.js --cwd ./tools/webfilesbuilder"
echo "--------------------------------------------------------------"
echo "Building web interface..."
node node_modules/gulp/bin/gulp.js || exit
# TODO: do something if webui files are different
# for now, just print in travis log
if ${TRAVIS:-false}; then
git --no-pager diff --stat
fi
cd ../..
}
build_environments() {
echo "--------------------------------------------------------------"
echo "Building firmware images..."
mkdir -p $destination/EMS-ESP-$version
for environment in $environments; do
echo -n "* EMS-ESP-$version-$environment.bin --- "
platformio run --silent --environment $environment || exit 1
stat_bytes .pio/build/$environment/firmware.bin
[[ "${TRAVIS_BUILD_STAGE_NAME}" = "Test" ]] || \
mv .pio/build/$environment/firmware.bin $destination/EMS-ESP-$version/EMS-ESP-$version-$environment.bin
done
echo "--------------------------------------------------------------"
}
####### MAIN
destination=firmware
version_file=../src/version.h
version=$(grep -E '^#define APP_VERSION' $version_file | awk '{print $3}' | sed 's/"//g')
if ${TRAVIS:-false}; then
git_revision=${TRAVIS_COMMIT::7}
git_tag=${TRAVIS_TAG}
elif is_git; then
git_revision=$(git rev-parse --short HEAD)
git_tag=$(git tag --contains HEAD)
else
git_revision=unknown
git_tag=
fi
if [[ -n $git_tag ]]; then
new_version=${version/-*}
sed -i -e "s@$version@$new_version@" $version_file
version=$new_version
trap "git checkout -- $version_file" EXIT
fi
par_build=false
par_thread=${BUILDER_THREAD:-0}
par_total_threads=${BUILDER_TOTAL_THREADS:-4}
if [ ${par_thread} -ne ${par_thread} -o \
${par_total_threads} -ne ${par_total_threads} ]; then
echo "Parallel threads should be a number."
exit
fi
if [ ${par_thread} -ge ${par_total_threads} ]; then
echo "Current thread is greater than total threads. Doesn't make sense"
exit
fi
# travis platformio target is used for nightly Test
travis=$(list_envs | grep travis | sort)
# get all taregts, excluding travis and debug
available=$(list_envs | grep -Ev -- 'travis|debug' | sort)
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS}"
# get command line Parameters
# l prints environments
# 2 does parallel builds
# d uses next arg as destination folder
while getopts "lpd:" opt; do
case $opt in
l)
print_available
exit
;;
p)
par_build=true
;;
d)
destination=$OPTARG
;;
esac
done
shift $((OPTIND-1))
# Welcome message
echo "--------------------------------------------------------------"
echo "EMS-ESP FIRMWARE BUILDER"
echo "Building for version ${version}" ${git_revision:+($git_revision)}
# Environments to build
environments=$@
if [ $# -eq 0 ]; then
set_default_environments
fi
if ${CI:-false}; then
print_environments
fi
# for debugging
echo "* git_revision = $git_revision"
echo "* git_tag = $git_tag"
echo "* TRAVIS_EVENT_TYPE = $TRAVIS_EVENT_TYPE"
echo "* TRAVIS_TAG = $TRAVIS_TAG"
echo "* TRAVIS_BRANCH = $TRAVIS_BRANCH"
echo "* TRAVIS_BUILD_STAGE_NAME = $TRAVIS_BUILD_STAGE_NAME"
build_webui
build_environments

View File

@@ -40,7 +40,7 @@ env.AddPreAction("buildprog", build_web)
# build filename, replacing . with _ for the version # build filename, replacing . with _ for the version
#env.Replace(PROGNAME="firmware_%s" % branch + "_" + app_version.replace(".", "_")) #env.Replace(PROGNAME="firmware_%s" % branch + "_" + app_version.replace(".", "_"))
env.Replace(PROGNAME=app_name + "-" + app_version.replace(".", "_") + "-" + board + "-" + branch) #env.Replace(PROGNAME=app_name + "-" + app_version.replace(".", "_") + "-" + board + "-" + branch)
#env.Replace(PROGNAME=app_name + "-" + app_version) env.Replace(PROGNAME=app_name + "-" + app_version.replace(".", "_") + "-" + board)

View File

@@ -18,7 +18,7 @@ union system_rtcmem_t {
uint8_t stability_counter; uint8_t stability_counter;
uint8_t reset_reason; uint8_t reset_reason;
uint8_t boot_status; uint8_t boot_status;
uint8_t _reserved_; uint8_t dropout_counter;
} parts; } parts;
uint32_t value; uint32_t value;
}; };
@@ -200,6 +200,12 @@ uint32_t MyESP::_getInitialFreeHeap() {
// called when WiFi is connected, and used to start OTA, MQTT // called when WiFi is connected, and used to start OTA, MQTT
void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) { void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) {
if (code == MESSAGE_CONNECTED) { if (code == MESSAGE_CONNECTED) {
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP); // added to possibly fix wifi dropouts in arduino core 2.5.0
#endif
jw.enableAPFallback(false); // Disable AP mode after initial connect was successful - test for https://github.com/proddy/EMS-ESP/issues/187
myDebug_P(PSTR("[WIFI] Connected to SSID %s (hostname: %s, IP: %s)"), WiFi.SSID().c_str(), _getESPhostname().c_str(), WiFi.localIP().toString().c_str()); myDebug_P(PSTR("[WIFI] Connected to SSID %s (hostname: %s, IP: %s)"), WiFi.SSID().c_str(), _getESPhostname().c_str(), WiFi.localIP().toString().c_str());
/* /*
@@ -243,8 +249,6 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) {
myDebug_P(PSTR("[SYSTEM] Serial port communication is enabled")); myDebug_P(PSTR("[SYSTEM] Serial port communication is enabled"));
} }
_wifi_connected = true;
// NTP now that we have a WiFi connection // NTP now that we have a WiFi connection
if (_ntp_enabled) { if (_ntp_enabled) {
NTP.Ntp(_ntp_server, _ntp_interval); // set up NTP server NTP.Ntp(_ntp_server, _ntp_interval); // set up NTP server
@@ -256,7 +260,7 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) {
_wifi_callback_f(); _wifi_callback_f();
} }
// jw.enableAPFallback(false); // Disable AP mode after initial connect was successful - test for https://github.com/proddy/EMS-ESP/issues/187 _wifi_connected = true;
} }
if (code == MESSAGE_ACCESSPOINT_CREATED) { if (code == MESSAGE_ACCESSPOINT_CREATED) {
@@ -294,6 +298,7 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) {
if (code == MESSAGE_DISCONNECTED) { if (code == MESSAGE_DISCONNECTED) {
myDebug_P(PSTR("[WIFI] Disconnected")); myDebug_P(PSTR("[WIFI] Disconnected"));
_increaseSystemDropoutCounter(); // +1 to number of disconnects
_wifi_connected = false; _wifi_connected = false;
} }
@@ -457,6 +462,7 @@ void MyESP::_mqtt_setup() {
mqttClient.onDisconnect([this](AsyncMqttClientDisconnectReason reason) { mqttClient.onDisconnect([this](AsyncMqttClientDisconnectReason reason) {
if (reason == AsyncMqttClientDisconnectReason::TCP_DISCONNECTED) { if (reason == AsyncMqttClientDisconnectReason::TCP_DISCONNECTED) {
myDebug_P(PSTR("[MQTT] TCP Disconnected")); myDebug_P(PSTR("[MQTT] TCP Disconnected"));
_increaseSystemDropoutCounter(); // +1 to number of disconnects
(_mqtt_callback_f)(MQTT_DISCONNECT_EVENT, nullptr, nullptr); // call callback with disconnect (_mqtt_callback_f)(MQTT_DISCONNECT_EVENT, nullptr, nullptr); // call callback with disconnect
} }
if (reason == AsyncMqttClientDisconnectReason::MQTT_IDENTIFIER_REJECTED) { if (reason == AsyncMqttClientDisconnectReason::MQTT_IDENTIFIER_REJECTED) {
@@ -504,10 +510,6 @@ void MyESP::_wifi_setup() {
jw.enableScan(false); // Configure it to not scan available networks and connect in order of dBm jw.enableScan(false); // Configure it to not scan available networks and connect in order of dBm
jw.cleanNetworks(); // Clean existing network configuration jw.cleanNetworks(); // Clean existing network configuration
jw.addNetwork(_network_ssid, _network_password); // Add a network jw.addNetwork(_network_ssid, _network_password); // Add a network
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP); // added to possibly fix wifi dropouts in arduino core 2.5.0
#endif
} }
// set the callback function for the OTA onstart // set the callback function for the OTA onstart
@@ -747,7 +749,7 @@ void MyESP::_printSetCommands() {
} }
myDebug_P(PSTR(" mqtt_port=%d"), _mqtt_port); myDebug_P(PSTR(" mqtt_port=%d"), _mqtt_port);
myDebug_P(PSTR(" mqtt_keepalive=%d"), _mqtt_keepalive); myDebug_P(PSTR(" mqtt_keepalive=%d"), _mqtt_keepalive);
myDebug_P(PSTR(" mqtt_retain=%d"), (_mqtt_retain) ? "on" : "off"); myDebug_P(PSTR(" mqtt_retain=%s"), (_mqtt_retain) ? "on" : "off");
myDebug_P(PSTR(" mqtt_qos=%d"), _mqtt_qos); myDebug_P(PSTR(" mqtt_qos=%d"), _mqtt_qos);
myDebug_P(PSTR(" mqtt_heartbeat=%s"), (_mqtt_heartbeat) ? "on" : "off"); myDebug_P(PSTR(" mqtt_heartbeat=%s"), (_mqtt_heartbeat) ? "on" : "off");
@@ -1068,6 +1070,12 @@ uint8_t MyESP::_getSystemStabilityCounter() {
return data.parts.stability_counter; return data.parts.stability_counter;
} }
uint8_t MyESP::_getSystemDropoutCounter() {
system_rtcmem_t data;
data.value = Rtcmem->sys;
return data.parts.dropout_counter;
}
void MyESP::_setSystemStabilityCounter(uint8_t counter) { void MyESP::_setSystemStabilityCounter(uint8_t counter) {
system_rtcmem_t data; system_rtcmem_t data;
data.value = Rtcmem->sys; data.value = Rtcmem->sys;
@@ -1075,6 +1083,20 @@ void MyESP::_setSystemStabilityCounter(uint8_t counter) {
Rtcmem->sys = data.value; Rtcmem->sys = data.value;
} }
void MyESP::_setSystemDropoutCounter(uint8_t counter) {
system_rtcmem_t data;
data.value = Rtcmem->sys;
data.parts.dropout_counter = counter;
Rtcmem->sys = data.value;
}
void MyESP::_increaseSystemDropoutCounter() {
system_rtcmem_t data;
data.value = Rtcmem->sys;
data.parts.dropout_counter++;
Rtcmem->sys = data.value;
}
uint8_t MyESP::_getSystemResetReason() { uint8_t MyESP::_getSystemResetReason() {
system_rtcmem_t data; system_rtcmem_t data;
data.value = Rtcmem->sys; data.value = Rtcmem->sys;
@@ -1302,6 +1324,7 @@ void MyESP::showSystemStats() {
myDebug_P(PSTR(" [SYSTEM] Last reset info: %s"), (char *)ESP.getResetInfo().c_str()); myDebug_P(PSTR(" [SYSTEM] Last reset info: %s"), (char *)ESP.getResetInfo().c_str());
} }
myDebug_P(PSTR(" [SYSTEM] Restart count: %d"), _getSystemStabilityCounter()); myDebug_P(PSTR(" [SYSTEM] Restart count: %d"), _getSystemStabilityCounter());
myDebug_P(PSTR(" [SYSTEM] # TCP disconnects: %d"), _getSystemDropoutCounter());
myDebug_P(PSTR(" [SYSTEM] rtcmem status: blocks:%u addr:0x%p"), RtcmemSize, Rtcmem); myDebug_P(PSTR(" [SYSTEM] rtcmem status: blocks:%u addr:0x%p"), RtcmemSize, Rtcmem);
for (uint8_t block = 0; block < RtcmemSize; ++block) { for (uint8_t block = 0; block < RtcmemSize; ++block) {
@@ -1356,23 +1379,23 @@ void MyESP::_heartbeatCheck(bool force = false) {
uint32_t free_memory = ESP.getFreeHeap(); uint32_t free_memory = ESP.getFreeHeap();
uint8_t mem_available = 100 * free_memory / total_memory; // as a % uint8_t mem_available = 100 * free_memory / total_memory; // as a %
char payload[300] = {0}; StaticJsonDocument<200> doc;
char s[10]; JsonObject rootHeartbeat = doc.to<JsonObject>();
strlcpy(payload, "version=", sizeof(payload));
strlcat(payload, _app_version, sizeof(payload)); // version
strlcat(payload, ", IP=", sizeof(payload));
strlcat(payload, WiFi.localIP().toString().c_str(), sizeof(payload)); // IP address
strlcat(payload, ", rssid=", sizeof(payload));
strlcat(payload, itoa(getWifiQuality(), s, 10), sizeof(payload)); // rssi %
strlcat(payload, "%, load=", sizeof(payload));
strlcat(payload, ltoa(getSystemLoadAverage(), s, 10), sizeof(payload)); // load
strlcat(payload, "%, uptime=", sizeof(payload));
strlcat(payload, ltoa(_getUptime(), s, 10), sizeof(payload)); // uptime in secs
strlcat(payload, "secs, freemem=", sizeof(payload));
strlcat(payload, itoa(mem_available, s, 10), sizeof(payload)); // free mem as a %
strlcat(payload, "%", sizeof(payload));
mqttPublish(MQTT_TOPIC_HEARTBEAT, payload, false); // send to MQTT with retain off rootHeartbeat["version"] = _app_version;
rootHeartbeat["IP"] = WiFi.localIP().toString();
rootHeartbeat["rssid"] = getWifiQuality();
rootHeartbeat["load"] = getSystemLoadAverage();
rootHeartbeat["uptime"] = _getUptime();
rootHeartbeat["freemem"] = mem_available;
rootHeartbeat["MQTTdisconnects"] = _getSystemDropoutCounter();
char data[300] = {0};
serializeJson(doc, data, sizeof(data));
// myDebugLog("Publishing hearbeat via MQTT");
(void)mqttPublish(MQTT_TOPIC_HEARTBEAT, data, false); // send to MQTT with retain off
} }
} }
@@ -2918,6 +2941,8 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char *
_setSystemCheck(false); // reset system check _setSystemCheck(false); // reset system check
_heartbeatCheck(true); // force heartbeat _heartbeatCheck(true); // force heartbeat
_setSystemDropoutCounter(0); // reset # TCP dropouts
SerialAndTelnet.flush(); SerialAndTelnet.flush();
} }

View File

@@ -431,6 +431,10 @@ class MyESP {
uint8_t _getSystemStabilityCounter(); uint8_t _getSystemStabilityCounter();
void _setSystemStabilityCounter(uint8_t counter); void _setSystemStabilityCounter(uint8_t counter);
uint8_t _getSystemDropoutCounter();
void _setSystemDropoutCounter(uint8_t counter);
void _increaseSystemDropoutCounter();
void _setSystemResetReason(uint8_t reason); void _setSystemResetReason(uint8_t reason);
uint8_t _getCustomResetReason(); uint8_t _getCustomResetReason();
void _setCustomResetReason(uint8_t reason); void _setCustomResetReason(uint8_t reason);

View File

@@ -69,15 +69,10 @@ Ticker showerColdShotStopTimer;
#define SHOWER_COLDSHOT_DURATION 10 // in seconds. 10 seconds for cold water before turning back hot water #define SHOWER_COLDSHOT_DURATION 10 // in seconds. 10 seconds for cold water before turning back hot water
#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
#ifdef LOGICANALYZER
#define EMSESP_DALLAS_GPIO D1
#define EMSESP_DALLAS_PARASITE false
#else
// set this if using an external temperature sensor like a DS18B20 // set this if using an external temperature sensor like a DS18B20
// D5 is the default on a bbqkees board // D5 is the default on a bbqkees board
#define EMSESP_DALLAS_GPIO D5 #define EMSESP_DALLAS_GPIO D5
#define EMSESP_DALLAS_PARASITE false #define EMSESP_DALLAS_PARASITE false
#endif
// Set LED pin used for showing the EMS bus connection status. Solid means EMS bus working, flashing is an error // Set LED pin used for showing the EMS bus connection status. Solid means EMS bus working, flashing is an error
// can be either the onboard LED on the ESP8266 (LED_BULLETIN) or external via an external pull-up LED (e.g. D1 on a bbqkees' board) // can be either the onboard LED on the ESP8266 (LED_BULLETIN) or external via an external pull-up LED (e.g. D1 on a bbqkees' board)
@@ -1611,7 +1606,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
uint8_t hc; uint8_t hc;
// thermostat temp changes // thermostat temp changes
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_TEMP, topic); hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_TEMP_HA, topic);
if (hc) { if (hc) {
float f = strtof((char *)message, 0); float f = strtof((char *)message, 0);
ems_setThermostatTemp(f, hc); ems_setThermostatTemp(f, hc);
@@ -1620,7 +1615,7 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
} }
// thermostat mode changes // thermostat mode changes
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_MODE, topic); hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_MODE_HA, topic);
if (hc) { if (hc) {
if (strncmp(message, "auto", 4) == 0) { if (strncmp(message, "auto", 4) == 0) {
ems_setThermostatMode(2, hc); ems_setThermostatMode(2, hc);
@@ -1643,6 +1638,29 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
} }
const char * command = doc["cmd"]; const char * command = doc["cmd"];
// thermostat temp changes
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_TEMP, command);
if (hc) {
float f = doc["data"];
ems_setThermostatTemp(f, hc);
publishValues(true); // publish back immediately
return;
}
// thermostat mode changes
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_MODE, command);
if (hc) {
const char * data_cmd = doc["data"];
if (strncmp(data_cmd, "auto", 4) == 0) {
ems_setThermostatMode(2, hc);
} else if ((strncmp(data_cmd, "day", 4) == 0) || (strncmp(data_cmd, "manual", 6) == 0) || (strncmp(data_cmd, "heat", 4) == 0)) {
ems_setThermostatMode(1, hc);
} else if ((strncmp(data_cmd, "night", 5) == 0) || (strncmp(data_cmd, "off", 3) == 0)) {
ems_setThermostatMode(0, hc);
}
return;
}
// set night temp value // set night temp value
hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_NIGHTTEMP, command); hc = _hasHCspecified(TOPIC_THERMOSTAT_CMD_NIGHTTEMP, command);
if (hc) { if (hc) {

View File

@@ -1755,7 +1755,7 @@ void _process_SM100Energy(_EMS_RxTelegram * EMS_RxTelegram) {
* Type 0xE3 - HeatPump Monitor 1 * Type 0xE3 - HeatPump Monitor 1
*/ */
void _process_HPMonitor1(_EMS_RxTelegram * EMS_RxTelegram) { void _process_HPMonitor1(_EMS_RxTelegram * EMS_RxTelegram) {
EMS_HeatPump.HPModulation = _toByte(14); // modulation % EMS_HeatPump.HPModulation = _toByte(13); // modulation %
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
} }

View File

@@ -197,10 +197,11 @@ const _Boiler_Device Boiler_Devices[] = {
{72, "MC10 Module"}, {72, "MC10 Module"},
{123, "Buderus GBx72/Nefit Trendline/Junkers Cerapur/Worcester Greenstar Si"}, {123, "Buderus GBx72/Nefit Trendline/Junkers Cerapur/Worcester Greenstar Si"},
{133, "Buderus GB125"},
{115, "Nefit Topline/Buderus GB162"}, {115, "Nefit Topline/Buderus GB162"},
{203, "Buderus Logamax U122/Junkers Cerapur"}, {203, "Buderus Logamax U122/Junkers Cerapur"},
{208, "Buderus Logamax plus/GB192/Bosch Condens GC9000"}, {208, "Buderus Logamax plus/GB192/Bosch Condens GC9000"},
{64, "Sieger BK15/Nefit Smartline/Buderus GB152"}, {64, "Sieger BK13,BK15/Nefit Smartline/Buderus GB1x2"},
{95, "Bosch Condens 2500/Buderus Logamax GB062/Junkers Heatronic 3"}, {95, "Bosch Condens 2500/Buderus Logamax GB062/Junkers Heatronic 3"},
{122, "Nefit Proline"}, {122, "Nefit Proline"},
{170, "Buderus Logano GB212"}, {170, "Buderus Logano GB212"},
@@ -244,6 +245,7 @@ const _Other_Device Other_Devices[] = {
{125, 0x09, "BC25 Base Controller"}, {125, 0x09, "BC25 Base Controller"},
{169, 0x09, "BC40 Base Controller"}, {169, 0x09, "BC40 Base Controller"},
{152, 0x09, "Junkers Controller"}, {152, 0x09, "Junkers Controller"},
{230, 0x09, "BC Base Controller"},
{205, 0x02, "Nefit Moduline Easy Connect"}, {205, 0x02, "Nefit Moduline Easy Connect"},
{206, 0x02, "Bosch Easy Connect"}, {206, 0x02, "Bosch Easy Connect"},
@@ -277,6 +279,7 @@ const _Thermostat_Device Thermostat_Devices[] = {
{EMS_MODEL_RC10, 79, 0x17, "RC10/Moduline 100", EMS_THERMOSTAT_WRITE_YES}, {EMS_MODEL_RC10, 79, 0x17, "RC10/Moduline 100", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC20, 77, 0x17, "RC20/Moduline 300", EMS_THERMOSTAT_WRITE_YES}, {EMS_MODEL_RC20, 77, 0x17, "RC20/Moduline 300", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_WRITE_YES}, {EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC30, 67, 0x10, "RC30", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC30, 78, 0x10, "RC30/Moduline 400", EMS_THERMOSTAT_WRITE_YES}, {EMS_MODEL_RC30, 78, 0x10, "RC30/Moduline 400", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_WRITE_YES}, {EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_WRITE_YES},
{EMS_MODEL_RC300, 158, 0x10, "RC300/RC310/Moduline 3000/Bosch CW400", EMS_THERMOSTAT_WRITE_YES}, {EMS_MODEL_RC300, 158, 0x10, "RC300/RC310/Moduline 3000/Bosch CW400", EMS_THERMOSTAT_WRITE_YES},

View File

@@ -18,12 +18,14 @@
// these topics can be suffixed with a Heating Circuit number, e.g. thermostat_cmd_temp1 and thermostat_data1 // these topics can be suffixed with a Heating Circuit number, e.g. thermostat_cmd_temp1 and thermostat_data1
#define TOPIC_THERMOSTAT_DATA "thermostat_data" // for sending thermostat values to MQTT #define TOPIC_THERMOSTAT_DATA "thermostat_data" // for sending thermostat values to MQTT
#define TOPIC_THERMOSTAT_CMD "thermostat_cmd" // for receiving thermostat commands via MQTT #define TOPIC_THERMOSTAT_CMD "thermostat_cmd" // for receiving thermostat commands via MQTT
#define TOPIC_THERMOSTAT_CMD_TEMP "thermostat_cmd_temp" // temp changes via MQTT #define TOPIC_THERMOSTAT_CMD_TEMP_HA "thermostat_cmd_temp" // temp changes via MQTT, for HA climate component
#define TOPIC_THERMOSTAT_CMD_MODE "thermostat_cmd_mode" // mode changes via MQTT #define TOPIC_THERMOSTAT_CMD_MODE_HA "thermostat_cmd_mode" // mode changes via MQTT, for HA climate component
#define TOPIC_THERMOSTAT_CMD_DAYTEMP "daytemp" // day temp (RC35 specific) #define TOPIC_THERMOSTAT_CMD_TEMP "temp" // temp changes via MQTT
#define TOPIC_THERMOSTAT_CMD_NIGHTTEMP "nighttemp" // night temp (RC35 specific) #define TOPIC_THERMOSTAT_CMD_MODE "mode" // mode changes via MQTT
#define TOPIC_THERMOSTAT_CMD_HOLIDAYTEMP "holidayttemp" // holiday temp (RC35 specific) #define TOPIC_THERMOSTAT_CMD_DAYTEMP "daytemp" // day temp (RC35 specific)
#define TOPIC_THERMOSTAT_CMD_NIGHTTEMP "nighttemp" // night temp (RC35 specific)
#define TOPIC_THERMOSTAT_CMD_HOLIDAYTEMP "holidayttemp" // holiday temp (RC35 specific)
#define THERMOSTAT_CURRTEMP "currtemp" // current temperature #define THERMOSTAT_CURRTEMP "currtemp" // current temperature
#define THERMOSTAT_SELTEMP "seltemp" // selected temperature #define THERMOSTAT_SELTEMP "seltemp" // selected temperature

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.2" #define APP_VERSION "1.9.3b5"

View File

@@ -80,7 +80,7 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-xs-3"> <div class="col-xs-3">
<div style="position:fixed; top:0; bottom:40px; overflow-y:scroll; float:none;"> <div style="position:fixed; top:0; bottom:40px; float:none;">
<hr> <hr>
</hr> </hr>
<footer style="position:fixed; bottom: 0; height:40px;"><a id="appurl" <footer style="position:fixed; bottom: 0; height:40px;"><a id="appurl"

View File

@@ -38,11 +38,18 @@ var buildHeader = function (name) {
var filename = parts[parts.length - 1]; var filename = parts[parts.length - 1];
var extension = filename.split('.')[1]; var extension = filename.split('.')[1];
console.info('Creating file: ' + filename);
// var safename = name.split('.').join('_'); // var safename = name.split('.').join('_');
var safename = name.replace(/\.|-/g, "_"); var safename = name.replace(/\.|-/g, "_");
var destination = "../../src/webh/" + filename + ".h"; var destination = "../../src/webh/" + filename + ".h";
// check for woff files which should be fonts
if (extension === "woff") {
extension = "fonts";
}
// html files go into root // html files go into root
if (extension === "html") { if (extension === "html") {
var source = "../../src/websrc/temp/gzipped/" + name + ".gz"; var source = "../../src/websrc/temp/gzipped/" + name + ".gz";
@@ -50,8 +57,6 @@ var buildHeader = function (name) {
var source = "../../src/websrc/temp/gzipped/" + extension + "/" + name + ".gz"; var source = "../../src/websrc/temp/gzipped/" + extension + "/" + name + ".gz";
} }
console.info('Creating file: ' + filename + ' Extension: ' + extension);
var wstream = fs.createWriteStream(destination); var wstream = fs.createWriteStream(destination);
wstream.on('error', function (err) { wstream.on('error', function (err) {
console.log(err); console.log(err);
@@ -128,12 +133,12 @@ gulp.task('requiredcss', function () {
}); });
gulp.task("fontwoff", function () { gulp.task("fontwoff", function () {
return gulp.src("../../src/websrc/3rdparty/woff/*.*") return gulp.src("../../src/websrc/3rdparty/fonts/*.*")
.pipe(gulp.dest("../../src/websrc/temp/woff/")) .pipe(gulp.dest("../../src/websrc/temp/fonts/"))
.pipe(gzip({ .pipe(gzip({
append: true append: true
})) }))
.pipe(gulp.dest('../../src/websrc/temp/gzipped/woff/')) .pipe(gulp.dest('../../src/websrc/temp/gzipped/fonts/'))
.pipe(buildHeader('glyphicons-halflings-regular.woff')); .pipe(buildHeader('glyphicons-halflings-regular.woff'));
}); });