Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
hpanther
2020-10-30 14:38:31 +01:00
26 changed files with 389 additions and 282 deletions

View File

@@ -29,7 +29,7 @@ assignees: ''
*If applicable, add screenshots to help explain your problem.*
**Device information**
*Copy-paste here the information as it is outputted by the device. You can get this information by from the telnet session using the `system` command and `info`.*
*Copy-paste here the information as it is outputted by the device. You can get this information by from http://ems-esp.local/api?device=system&cmd=report.*
**Additional context**
*Add any other context about the problem here.*

View File

@@ -23,7 +23,7 @@ assignees: ''
*If applicable, add screenshots to help explain your problem.*
**Device information**
*Copy-paste here the information as it is outputted by the device. You can get this information by from the telnet session with the logging set to Verbose mode.*
*Copy-paste here the information as it is outputted by the device. You can get this information from http://ems-esp.local/api?device=system&cmd=report.*
**Additional context**
*Add any other context about the problem here.*

View File

@@ -1,33 +0,0 @@
name: EMS-ESP CI
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
#on:
# push:
# branches: [ main ]
# pull_request:
# branches: [ main ]
on:
pull_request:
jobs:
emsesp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up Python
uses: actions/setup-python@v1
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -U platformio
# platformio upgrade --dev
platformio upgrade
platformio update
- name: Run PlatformIO
run: |
platformio run

View File

@@ -1,88 +0,0 @@
name: Build_firmware
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
#on:
# push:
# branches: [ main ]
# pull_request:
# branches: [ main ]
on:
push:
branches: [ dev ]
jobs:
# emsesp_pull:
# runs-on: ubuntu-latest
# continue-on-error: true
# steps:
# - uses: actions/checkout@v1
# - name: Use latest EMS-ESP development
# run: |
# git config --local user.name "Platformio BUILD"
# git switch -c main
# git remote add -f EMS-ESP "https://github.com/proddy/EMS-ESP.git"
# git merge EMS-ESP/dev --allow-unrelated-histories
# - name: Push EMS-ESP # Push updates of latest EMS-ESP development to repo
# uses: ad-m/github-push-action@master
# with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
# branch: 'dev'
# force: true
emsesp:
# needs: emsesp_pull
runs-on: ubuntu-latest
# continue-on-error: true
steps:
- uses: actions/checkout@v1
- name: Set up Python
uses: actions/setup-python@v1
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -U platformio
# platformio upgrade --dev
platformio upgrade
platformio update
- name: Run PlatformIO
run: |
platformio run
- uses: actions/upload-artifact@v2
with:
name: firmware
path: ./build/firmware
Upload:
needs: [emsesp]
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v1
- uses: actions/download-artifact@v2
with:
name: firmware
path: ./mv_firmware
- name: Display structure of downloaded files
run: ls -R
working-directory: ./mv_firmware
- name: Move firmware files in sub-folders
run: |
mkdir -p ./firmware
[ ! -f ./mv_firmware/*.bin ] || mv ./mv_firmware/EMS-ESP*.* ./firmware/
[ ! -f ./FIRMWARE.md ] || mv -f ./FIRMWARE.md ./README.md
- name: Commit files # transfer the new binaries back into the repository
run: |
git config --local user.name "Platformio BUILD"
git rm -r --cached .
git add ./README.md
git add -f ./firmware/*.*
git commit -m "EMS-ESP binaries"
- name: Push changes # push the firmware files to branch firmware
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: 'firmware'
force: true

View File

@@ -1,20 +0,0 @@
name: EMS-ESP C++ make
on:
push:
# branches: [ dev ]
pull_request:
# branches: [ dev ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: make clean
run: make clean
- name: make
run: make

71
.github/workflows/build_firmware.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: Build Firmware
on:
push:
branches:
- dev
tags:
# - '*.*.*'
paths:
- 'CHANGELOG_LATEST.md'
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Version
id: fetch_version
run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk '{print $3}' | sed 's/"//g'`
echo "::set-output name=s::$version"
- name: Setup Python
uses: actions/setup-python@v1
- name: Install
run: |
python -m pip install --upgrade pip
pip install -U platformio
platformio upgrade
platformio update
- name: Build web
run: |
cd interface
npm install
npm run build
- name: Build images
run: |
platformio run -e esp8266
platformio run -e esp32
- name: Delete
uses: dev-drprasad/delete-tag-and-release@v0.1.2
# if: startsWith(github.ref, 'refs/tags/')
with:
delete_release: true
tag_name: dev
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Changelog
run: cat RELEASENOTES_DEV.md CHANGELOG_LATEST.md > BODY.txt
- name: Release
uses: softprops/action-gh-release@v1
# if: startsWith(github.ref, 'refs/tags/')
with:
body_path: BODY.txt
name: Development Build version ${{steps.fetch_version.outputs.s}}
tag_name: dev
prerelease: true
files: |
./build/firmware/*.*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,8 +1,10 @@
name: "EMS-ESP check code"
name: Code Check
on:
push:
branches: [dev]
paths:
- 'src/**'
pull_request:
# The branches below must be a subset of the branches above
branches: [dev]

56
.github/workflows/release_main.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: Release Main
on:
workflow_dispatch:
branches: [ main ]
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Version
id: fetch_version
run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk '{print $3}' | sed 's/"//g'`
echo "::set-output name=s::$version"
- name: Setup Python
uses: actions/setup-python@v1
- name: Install
run: |
python -m pip install --upgrade pip
pip install -U platformio
platformio upgrade
platformio update
- name: Build web
run: |
cd interface
npm install
npm run build
- name: Build images
run: |
platformio run -e esp8266
platformio run -e esp32
- name: Changelog
run: cat RELEASENOTES.md CHANGELOG_LATEST.md > BODY.txt
- name: Release
uses: softprops/action-gh-release@v1
with:
body_path: BODY.txt
name: EMS-ESP v${{steps.fetch_version.outputs.s}}
tag_name: v${{steps.fetch_version.outputs.s}}
prerelease: false
files: |
./build/firmware/*.*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

22
.github/workflows/standalone_build.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Standalone Build
on:
push:
branches: [ dev ]
paths:
- 'src/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: make clean
run: make clean
- name: make
run: make

View File

@@ -1,57 +1,10 @@
# EMS-ESP Changelog
# Changelog
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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.1]
### Added
- boiler `heatingactivated`, automatic select parameter telegrams for write
- boiler `wWType` parameter, in Console and MQTT
- support for uploading compressed firmware binaries in web UI
- setting to manually override the MQTT retain flag
- New API via HTTP REST API to read and set values. See https://emsesp.github.io/docs/#/API
- `show commands` command
- exporting of system settings using the `system info` command in Web and Console. Added link into the Web's Settings page.
- setting to change how booleans are rendered in MQTT (on/off, true/false, 1/0)
- enable ADC setting, add boiler circulation commands, add thermostat RC300 summermodes
- Added all device info to web UI for Thermostat and Boiler
- Added all device values to Home Assistant MQTT Discovery under separate devices and entities
- Show Rx and Tx quality in Console and Web UI
- Added button and tooltip to EMS Devices in Web
- wwtemp and wwtemplow to MQTT, Console and Web
- summer, winter modes for the CW400 thermostat
- new command under system called `report`. http://ems-esp/api?device=system&cmd=report to generate a report log for troubleshooting
- thermostat error codes
- Console command `publish ha` to also force the creation of the Home Assistant MQTT Discovery topics
- Heat pump values (dew temperature and relative air humidity)
### Fixed
- fix wwontime readback
- fixed support for RC300 via MQTT commands (#505)
- Some minor optimizations to memory handling in the MQTT service
- Prevent MQTT from publishing empty json payloads
- Accurate detection of warm water and heating (#515)
- Fix writing to the Junkers FR120 thermostat
- support for changing summermode
- added missing `heatingtype` to thermostat data
### Changed
- renamed wWCircPumpType to wWChargeType
- Installation and Configuration notes moved to the official EMS-ESP documentation site
- `call` commands can be done from the Console root for all devices
- Updated EMS-ESP official documentation (https://emsesp.github.io/docs/#/)
- JWT Secret renamed to Super User Password
- EMS Devices in Web UI shows button and tooltip to remind users they can click on a device
- MQTT topic name changes (see doc)
- Mixing renamed to Mixer
### Removed
- Console contexts for thermostat and boiler
- Removed option to enable/disable the MQTT Heartbeat. It's always on.
## [2.0.1] September 13 2020
### Added

51
CHANGELOG_LATEST.md Normal file
View File

@@ -0,0 +1,51 @@
# Changelog
### Added
- boiler `heatingactivated`, automatic select parameter telegrams for write
- boiler `wWType` parameter, in Console and MQTT
- support for uploading compressed firmware binaries in web UI
- setting to manually override the MQTT retain flag
- New API via HTTP REST API to read and set values. See https://emsesp.github.io/docs/#/API
- `show commands` command
- exporting of system settings using the `system info` command in Web and Console. Added link into the Web's Settings page.
- setting to change how booleans are rendered in MQTT (on/off, true/false, 1/0)
- enable ADC setting, add boiler circulation commands, add thermostat RC300 summermodes
- Added all device info to web UI for Thermostat and Boiler
- Added all device values to Home Assistant MQTT Discovery under separate devices and entities
- Show Rx and Tx quality in Console and Web UI
- Added button and tooltip to EMS Devices in Web
- wwtemp and wwtemplow to MQTT, Console and Web
- summer, winter modes for the CW400 thermostat
- new command under system called `report`. http://ems-esp/api?device=system&cmd=report to generate a report log for troubleshooting
- thermostat error codes
- Console command `publish ha` to also force the creation of the Home Assistant MQTT Discovery topics
- Heat pump values (dew temperature and relative air humidity)
- Console up key to repeat last command
- added RC300 floordrying, error, building, damped temperature
### Fixed
- fix wwontime readback
- fixed support for RC300 via MQTT commands (#505)
- Some minor optimizations to memory handling in the MQTT service
- Prevent MQTT from publishing empty json payloads
- Accurate detection of warm water and heating (#515)
- Fix writing to the Junkers FR120 thermostat
- support for changing summermode
- added missing `heatingtype` to thermostat data
- handle incomming ems+ read requests, ignore F7 telegrams with 3byte-id
- fix month for setting clock from NTP
### Changed
- renamed wWCircPumpType to wWChargeType
- Installation and Configuration notes moved to the official EMS-ESP documentation site
- `call` commands can be done from the Console root for all devices
- Updated EMS-ESP official documentation (https://emsesp.github.io/docs/#/)
- JWT Secret renamed to Super User Password
- EMS Devices in Web UI shows button and tooltip to remind users they can click on a device
- MQTT topic name changes (see doc)
- Mixing renamed to Mixer
### Removed
- Console contexts for thermostat and boiler
- Removed option to enable/disable the MQTT Heartbeat. It's always on.

View File

@@ -1,27 +0,0 @@
# ![logo](https://github.com/proddy/EMS-ESP/blob/main/media/EMS-ESP_logo_dark.png)
**EMS-ESP** is an open-source firmware for the Espressif ESP8266 and ESP32 microcontroller that communicates with **EMS** (Energy Management System) based equipment from manufacturers like Bosch, Buderus, Nefit, Junkers, Worcester and Sieger.
[![version](https://img.shields.io/github/release/proddy/EMS-ESP.svg?label=Latest%20Release)](https://github.com/proddy/EMS-ESP/blob/main/CHANGELOG.md)
[![release-date](https://img.shields.io/github/release-date/proddy/EMS-ESP.svg?label=Released)](https://github.com/proddy/EMS-ESP/commits/master)
[![license](https://img.shields.io/github/license/proddy/EMS-ESP.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b8880625bdf841d4adb2829732030887)](https://app.codacy.com/app/proddy/EMS-ESP?utm_source=github.com&utm_medium=referral&utm_content=proddy/EMS-ESP&utm_campaign=Badge_Grade_Settings)
[![Build Firmware](https://github.com/proddy/EMS-ESP/workflows/Build_firmware/badge.svg)](https://github.com/proddy/EMS-ESP/actions?query=workflow%3ABuild_firmware)
[![downloads](https://img.shields.io/github/downloads/proddy/EMS-ESP/total.svg)](https://github.com/proddy/EMS-ESP/releases)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/proddy/EMS-ESP.svg)](http://isitmaintained.com/project/proddy/EMS-ESP "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/proddy/EMS-ESP.svg)](http://isitmaintained.com/project/proddy/EMS-ESP "Percentage of issues still open")
<br/>
[![gitter](https://img.shields.io/gitter/room/EMS-ESP/EMS-ESP.svg)](https://gitter.im/EMS-ESP/community)
If you like **EMS-ESP**, please give it a star, or fork it and contribute!
[![GitHub stars](https://img.shields.io/github/stars/proddy/EMS-ESP.svg?style=social&label=Star)](https://github.com/proddy/EMS-ESP/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/proddy/EMS-ESP.svg?style=social&label=Fork)](https://github.com/proddy/EMS-ESP/network)
[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://www.paypal.com/paypalme/prderbyshire/2)
# Firmware Installation
Here you will find the latest development builds, under the [firmware](https://github.com/proddy/EMS-ESP/tree/firmware/firmware) folder. Follow the instructions in the [documentation](https://emsesp.github.io/docs) on how to install these binaries.
See also the [CHANGELOG](https://github.com/proddy/EMS-ESP/blob/dev/CHANGELOG.md) for any breaking changes between releases.

View File

@@ -5,7 +5,7 @@
[![version](https://img.shields.io/github/release/proddy/EMS-ESP.svg?label=Latest%20Release)](https://github.com/proddy/EMS-ESP/blob/main/CHANGELOG.md)
[![release-date](https://img.shields.io/github/release-date/proddy/EMS-ESP.svg?label=Released)](https://github.com/proddy/EMS-ESP/commits/master)
[![license](https://img.shields.io/github/license/proddy/EMS-ESP.svg)](LICENSE)
[![travis](https://travis-ci.com/proddy/EMS-ESP.svg?branch=dev)](https://travis-ci.com/proddy/EMS-ESP)
![Build Firmware](https://github.com/proddy/EMS-ESP/workflows/Build%20Firmware/badge.svg?branch=dev)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b8880625bdf841d4adb2829732030887)](https://app.codacy.com/app/proddy/EMS-ESP?utm_source=github.com&utm_medium=referral&utm_content=proddy/EMS-ESP&utm_campaign=Badge_Grade_Settings)
[![downloads](https://img.shields.io/github/downloads/proddy/EMS-ESP/total.svg)](https://github.com/proddy/EMS-ESP/releases)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/proddy/EMS-ESP.svg)](http://isitmaintained.com/project/proddy/EMS-ESP "Average time to resolve an issue")
@@ -89,7 +89,7 @@ You can contribute to EMS-ESP by
## **Credits**
A shout out to the people helping EMS-ESP get to where it is today...
- **@MichaelDvP** for all his amazing contributions and patience. Specifically the improved uart library, thermostat and mixer logic.
- **@MichaelDvP** for all his amazing contributions and patience. Specifically for the improved uart library, thermostat and mixer logic.
- **@BBQKees** for his endless testing and building the awesome circuit boards
- **@susisstrolch** for writing a first working version of the EMS bridge circuit which I used to design EMS-ESP version 0.1 back in August 2017
- plus everyone else providing suggestions, PRs and the odd donation that keep us motivated. Thanks!

6
RELEASENOTES.md Normal file
View File

@@ -0,0 +1,6 @@
# ![logo](https://github.com/proddy/EMS-ESP/blob/main/media/EMS-ESP_logo_dark.png)
# Firmware Installation
Follow the instructions in the [documentation](https://emsesp.github.io/docs) on how to install the firmware binaries in the Assets below.

8
RELEASENOTES_DEV.md Normal file
View File

@@ -0,0 +1,8 @@
# ![logo](https://github.com/proddy/EMS-ESP/blob/main/media/EMS-ESP_logo_dark.png)
This is a snapshot of the current "beta" development code and firmware binaries using the `dev` branch. It has all the latest features and fixes but please be aware that this is still experimental firmware used for testing and thus may contain the odd bug. Use at your own risk and remember to report an issue if you find something unusual.
# Firmware Installation
Follow the instructions in the [documentation](https://emsesp.github.io/docs) on how to install the firmware binaries in the Assets below.

View File

@@ -40,7 +40,7 @@ AsyncMqttClient::AsyncMqttClient()
_client.onPoll([](void * obj, AsyncClient * c) { (static_cast<AsyncMqttClient *>(obj))->_onPoll(c); }, this);
#ifdef ESP32
sprintf(_generatedClientId, "esp32%06x", ESP.getEfuseMac());
sprintf(_generatedClientId, "esp32%06x", (int)ESP.getEfuseMac());
_xSemaphore = xSemaphoreCreateMutex();
#elif defined(ESP8266)
sprintf(_generatedClientId, "esp8266%06x", ESP.getChipId());

View File

@@ -65,6 +65,8 @@ void Shell::start() {
#endif
line_buffer_.reserve(maximum_command_line_length_);
oldline_.reserve(maximum_command_line_length_);
oldline_.clear();
display_banner();
display_prompt();
shells_.insert(shared_from_this());
@@ -175,6 +177,9 @@ void Shell::loop_normal() {
case '\x0A':
// Line feed (^J)
if (previous_ != '\x0D') {
if (!line_buffer_.empty()) {
oldline_ = line_buffer_;
}
process_command();
}
break;
@@ -187,6 +192,9 @@ void Shell::loop_normal() {
break;
case '\x0D':
if (!line_buffer_.empty()) {
oldline_ = line_buffer_;
}
// Carriage return (^M)
process_command();
break;
@@ -211,6 +219,20 @@ void Shell::loop_normal() {
line_buffer_.push_back(c);
write((uint8_t)c);
}
// cursor up, get last command
if ((c == 'A') && (previous_ == '[')) {
erase_current_line();
prompt_displayed_ = false;
line_buffer_ = oldline_;
display_prompt();
}
// cursor back, forw or down: Delete line
if (((c == 'B') || (c == 'C') || (c == 'D')) && (previous_ == '[')) {
erase_current_line();
prompt_displayed_ = false;
line_buffer_.clear();
display_prompt();
}
}
break;
}

View File

@@ -905,6 +905,7 @@ class Shell : public std::enable_shared_from_this<Shell>, public uuid::log::Hand
std::string line_buffer_; /*!< Command line buffer. Limited to maximum_command_line_length() bytes. @since 0.1.0 */
size_t maximum_command_line_length_ = MAX_COMMAND_LINE_LENGTH; /*!< Maximum command line length in bytes. @since 0.6.0 */
unsigned char previous_ = 0; /*!< Previous character that was entered on the command line. Used to detect CRLF line endings. @since 0.1.0 */
std::string oldline_; /*!< old Command line buffer.*/
Mode mode_ = Mode::NORMAL; /*!< Current execution mode. @since 0.1.0 */
std::unique_ptr<ModeData> mode_data_ = nullptr; /*!< Data associated with the current execution mode. @since 0.1.0 */
bool stopped_ = false; /*!< Indicates that the shell has been stopped. @since 0.1.0 */

View File

@@ -1,8 +1,8 @@
; PlatformIO Project Configuration File for EMS-ESP
[platformio]
; default_envs = esp8266
; default_envs = esp32
default_envs = esp8266-local
; default_envs = esp32-local
# override any settings with your own local ones in pio_local.ini
extra_configs =
@@ -14,6 +14,7 @@ debug_flags =
; -D EMSESP_DEBUG
; -D EMSESP_UART_DEBUG
; -D EMSESP_FORCE_SERIAL
; -D ENABLE_CORS
; default platformio compile flags are: -fno-rtti -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functions=4 -ffunction-sections -fdata-sections -fno-exceptions -Wall
build_flags =
@@ -29,28 +30,12 @@ build_flags =
-D ARDUINOJSON_ENABLE_STD_STRING=1
-D PROGMEM_WWW
-D CORS_ORIGIN=\"http://localhost:3000\"
; Uncomment ENABLE_CORS to enable Cross-Origin Resource Sharing (required for local React development)
; -D ENABLE_CORS
libs_core =
; ArduinoJson
; ESPAsyncTCP
; AsyncTCP
; AsyncMqttClient
[env]
extra_scripts =
pre:scripts/build_interface.py
scripts/main_script.py
scripts/rename_fw.py
scripts/gzip_fw.py
framework = arduino
monitor_speed = 115200
; on OSX with non-native drivers use upload_speed = 115200
upload_speed = 921600
build_type = release
lib_ldf_mode = chain+
check_tool = cppcheck, clangtidy
@@ -60,24 +45,42 @@ check_flags =
clangtidy: --checks=-*,clang-analyzer-*,performance-*
[env:esp8266]
extra_scripts =
scripts/main_script.py
scripts/rename_fw.py
scripts/gzip_fw.py
board = esp12e
platform = espressif8266
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags}
[env:esp32]
extra_scripts =
scripts/rename_fw.py
scripts/gzip_fw.py
board = esp32dev
platform = espressif32
board_build.partitions = min_spiffs.csv
build_flags = ${common.build_flags}
[env:esp8266-local]
extra_scripts =
pre:scripts/build_interface.py
scripts/main_script.py
board = esp12e ; https://github.com/platformio/platform-espressif8266/tree/master/boards
build_type = release
platform = espressif8266 ; https://github.com/platformio/platform-espressif8266/releases
board_build.filesystem = littlefs
lib_deps = ${common.libs_core}
board_build.f_cpu = 160000000L ; 160MHz
; eagle.flash.4m1m.ld = 1019 KB sketch, 1000 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 2052 KB OTA & buffer
; eagle.flash.4m2m.ld = 1019 KB sketch, 2024 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 1028 KB OTA & buffer
; board_build.ldscript = eagle.flash.4m2m.ld
build_flags = ${common.build_flags} ${common.debug_flags}
lib_ignore =
AsyncTCP
[env:esp32]
[env:esp32-local]
extra_scripts =
pre:scripts/build_interface.py
board = esp32dev
build_type = release
platform = espressif32
; platform = https://github.com/platformio/platform-espressif32.git
board_build.partitions = min_spiffs.csv ; https://github.com/espressif/arduino-esp32/blob/master/tools/partitions/
lib_deps = ${common.libs_core}
build_flags = ${common.build_flags} ${common.debug_flags}

View File

@@ -123,6 +123,10 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
register_telegram_type(0x31B, F("RC300WWtemp"), true, [&](std::shared_ptr<const Telegram> t) { process_RC300WWtemp(t); });
register_telegram_type(0x31D, F("RC300WWmode2"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300WWmode2(t); });
register_telegram_type(0x31E, F("RC300WWmode2"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300WWmode2(t); });
register_telegram_type(0x23A, F("RC300OutdoorTemp"), true, [&](std::shared_ptr<const Telegram> t) { process_RC300OutdoorTemp(t); });
register_telegram_type(0x267, F("RC300Floordry"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300Floordry(t); });
register_telegram_type(0x240, F("RC300Settings"), true, [&](std::shared_ptr<const Telegram> t) { process_RC300Settings(t); });
register_telegram_type(0xBF, F("RC300Error"), false, [&](std::shared_ptr<const Telegram> t) { process_RC300Error(t); });
// JUNKERS/HT3
} else if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
@@ -186,6 +190,8 @@ void Thermostat::device_info_web(JsonArray & root) {
print_value_json(root, F("intoffset"), nullptr, F_(intoffset), nullptr, json_main);
print_value_json(root, F("minexttemp"), nullptr, F_(minexttemp), F_(degrees), json_main);
print_value_json(root, F("building"), nullptr, F_(building), nullptr, json_main);
print_value_json(root, F("floordry"), nullptr, F_(floordry), nullptr, json_main);
print_value_json(root, F("floordrytemp"), nullptr, F_(floordrytemp), F_(degrees), json_main);
print_value_json(root, F("wwmode"), nullptr, F_(wwmode), nullptr, json_main);
print_value_json(root, F("wwtemp"), nullptr, F_(wwtemp), nullptr, json_main);
print_value_json(root, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, json_main);
@@ -268,6 +274,8 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
print_value_json(shell, F("intoffset"), nullptr, F_(intoffset), nullptr, json_main);
print_value_json(shell, F("minexttemp"), nullptr, F_(minexttemp), F_(degrees), json_main);
print_value_json(shell, F("building"), nullptr, F_(building), nullptr, json_main);
print_value_json(shell, F("floordry"), nullptr, F_(floordry), nullptr, json_main);
print_value_json(shell, F("floordrytemp"), nullptr, F_(floordrytemp), F_(degrees), json_main);
print_value_json(shell, F("wwmode"), nullptr, F_(wwmode), nullptr, json_main);
print_value_json(shell, F("wwtemp"), nullptr, F_(wwtemp), nullptr, json_main);
print_value_json(shell, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, json_main);
@@ -399,11 +407,23 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
}
}
// Damped outdoor temperature
// Damped outdoor temperature (RC35)
if (Helpers::hasValue(dampedoutdoortemp_)) {
rootThermostat["dampedtemp"] = dampedoutdoortemp_;
}
// Damped outdoor temperature (RC300)
if (Helpers::hasValue(dampedoutdoortemp2_)) {
rootThermostat["dampedtemp"] = (float)dampedoutdoortemp2_ / 10;
}
// Floordry
if (Helpers::hasValue(floordrystatus_) && Helpers::hasValue(floordrytemp_) && (floordrytemp_ > 0)) {
char s[10];
rootThermostat["floordry"] = Helpers::render_enum(s, {"off", "start", "heat", "hold", "cool", "end"}, floordrystatus_);
rootThermostat["floordrytemp"] = floordrytemp_;
}
// Temp sensor 1
if (Helpers::hasValue(tempsensor1_)) {
rootThermostat["inttemp1"] = (float)tempsensor1_ / 10;
@@ -427,8 +447,12 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
// Building
if (Helpers::hasValue(ibaBuildingType_)) {
char s[10];
if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) {
rootThermostat["building"] = Helpers::render_enum(s, {"light", "medium", "heavy"}, ibaBuildingType_ - 1);
} else {
rootThermostat["building"] = Helpers::render_enum(s, {"light", "medium", "heavy"}, ibaBuildingType_);
}
}
// Warm water mode
if (Helpers::hasValue(wwMode_)) {
@@ -773,7 +797,7 @@ void Thermostat::register_mqtt_ha_config() {
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/thermostat/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(time), this->device_type(), "time", nullptr, nullptr);
// Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(error), this->device_type(), "errorcode", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(error), this->device_type(), "errorcode", nullptr, nullptr);
uint8_t model = this->model();
@@ -782,7 +806,16 @@ void Thermostat::register_mqtt_ha_config() {
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(language), this->device_type(), "language", nullptr, nullptr);
}
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC35) {
if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) {
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(dampedtemp), this->device_type(), "dampedtemp", F_(degrees), F_(icontemperature));
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(building), this->device_type(), "building", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(floordry), this->device_type(), "floordry", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(floordrytemp), this->device_type(), "floordrytemp", F_(degrees), F_(icontemperature));
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(wwmode), this->device_type(), "wwmode", nullptr, nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(wwtemp), this->device_type(), "wwtemp", F_(degrees), F_(icontemperature));
}
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) {
// excluding inttemp1, inttemp2, intoffset, minexttemp
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(dampedtemp), this->device_type(), "dampedtemp", F_(degrees), F_(icontemperature));
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(building), this->device_type(), "building", nullptr, nullptr);
@@ -1266,6 +1299,37 @@ void Thermostat::process_RC300WWmode2(std::shared_ptr<const Telegram> telegram)
// pos 3 = current status of DHW circulation pump
}
// 0x23A damped outdoor temp
void Thermostat::process_RC300OutdoorTemp(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(dampedoutdoortemp2_, 0); // is *10
}
// 0x240 RC300 parameter
void Thermostat::process_RC300Settings(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(ibaBuildingType_ , 9); // 1=light, 2=medium, 3=heavy
}
// 0x267 RC300 floordrying
void Thermostat::process_RC300Floordry(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(floordrystatus_ , 0);
changed_ |= telegram->read_value(floordrytemp_ , 1);
}
// 0xBF RC300 Errormessage
void Thermostat::process_RC300Error(std::shared_ptr<const Telegram> telegram) {
if (errorCode_.empty()) {
errorCode_.resize(10, '\0');
}
char buf[4];
buf[0] = telegram->message_data[5];
buf[1] = telegram->message_data[6];
buf[2] = telegram->message_data[7];
buf[3] = 0;
changed_ |= telegram->read_value(errorNumber_, 8);
snprintf_P(&errorCode_[0], errorCode_.capacity() + 1, PSTR("%s(%d)"), buf, errorNumber_);
}
// type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long
void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) {
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
@@ -1472,7 +1536,12 @@ bool Thermostat::set_building(const char * value, const int8_t id) {
}
LOG_INFO(F("Setting building to %s"), value);
if ((this->model() == EMS_DEVICE_FLAG_RC300) || (this->model() == EMS_DEVICE_FLAG_RC100)) {
write_command(0x240, 9, bd + 1, 0x240);
} else {
write_command(EMS_TYPE_IBASettings, 6, bd, EMS_TYPE_IBASettings);
}
return true;
}
@@ -1676,7 +1745,7 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
}
data[0] = tm_->tm_year - 100; // Bosch counts from 2000
data[1] = tm_->tm_mon;
data[1] = tm_->tm_mon + 1;
data[2] = tm_->tm_hour;
data[3] = tm_->tm_mday;
data[4] = tm_->tm_min;
@@ -2197,6 +2266,7 @@ void Thermostat::add_commands() {
register_mqtt_cmd(F("wwmode"), [&](const char * value, const int8_t id) { return set_wwmode(value, id); });
register_mqtt_cmd(F("wwtemp"), [&](const char * value, const int8_t id) { return set_wwtemp(value, id); });
register_mqtt_cmd(F("wwtemplow"), [&](const char * value, const int8_t id) { return set_wwtemplow(value, id); });
register_mqtt_cmd(F("building"), [&](const char * value, const int8_t id) { return set_building(value, id); });
break;
case EMS_DEVICE_FLAG_RC20_2:
register_mqtt_cmd(F("nighttemp"), [&](const char * value, const int8_t id) { return set_nighttemp(value, id); });

View File

@@ -151,6 +151,9 @@ class Thermostat : public EMSdevice {
int8_t dampedoutdoortemp_ = EMS_VALUE_INT_NOTSET;
uint16_t tempsensor1_ = EMS_VALUE_USHORT_NOTSET;
uint16_t tempsensor2_ = EMS_VALUE_USHORT_NOTSET;
int16_t dampedoutdoortemp2_ = EMS_VALUE_SHORT_NOTSET;
uint8_t floordrystatus_ = EMS_VALUE_UINT_NOTSET;
uint8_t floordrytemp_ = EMS_VALUE_UINT_NOTSET;
uint8_t wwExtra1_ = EMS_VALUE_UINT_NOTSET; // wwExtra active for wwSystem 1
uint8_t wwExtra2_ = EMS_VALUE_UINT_NOTSET;
@@ -267,6 +270,10 @@ class Thermostat : public EMSdevice {
void process_RC300WWmode(std::shared_ptr<const Telegram> telegram);
void process_RC300WWmode2(std::shared_ptr<const Telegram> telegram);
void process_RC300WWtemp(std::shared_ptr<const Telegram> telegram);
void process_RC300OutdoorTemp(std::shared_ptr<const Telegram> telegram);
void process_RC300Settings(std::shared_ptr<const Telegram> telegram);
void process_RC300Error(std::shared_ptr<const Telegram> telegram);
void process_RC300Floordry(std::shared_ptr<const Telegram> telegram);
void process_JunkersMonitor(std::shared_ptr<const Telegram> telegram);
void process_JunkersSet(std::shared_ptr<const Telegram> telegram);
void process_JunkersSet2(std::shared_ptr<const Telegram> telegram);

View File

@@ -311,7 +311,7 @@ std::string EMSdevice::telegram_type_name(std::shared_ptr<const Telegram> telegr
}
for (const auto & tf : telegram_functions_) {
if ((tf.telegram_type_id_ == telegram->type_id) && ((telegram->type_id & 0xFFF0) != 0xF0)) {
if ((tf.telegram_type_id_ == telegram->type_id) && (telegram->type_id != 0xFF)) {
return uuid::read_flash_string(tf.telegram_type_name_);
}
}

View File

@@ -239,6 +239,9 @@ MAKE_PSTR(inttemp2, "Temperature sensor 2")
MAKE_PSTR(intoffset, "Offset int. temperature")
MAKE_PSTR(minexttemp, "Min ext. temperature")
MAKE_PSTR(building, "Building")
MAKE_PSTR(floordry, "Floordrying")
MAKE_PSTR(floordrytemp, "Floordrying temperature")
MAKE_PSTR(wwmode, "Warm water mode")
MAKE_PSTR(wwtemp, "Warm water high temperature")
MAKE_PSTR(wwtemplow, "Warm water low temperature")

View File

@@ -796,9 +796,9 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix,
// name
char new_name[50];
if (prefix != nullptr) {
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s %s"), device_name.c_str(), prefix, name);
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s %s"), device_name.c_str(), prefix, uuid::read_flash_string(name).c_str());
} else {
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s"), device_name.c_str(), name);
snprintf_P(new_name, sizeof(new_name), PSTR("%s %s"), device_name.c_str(), uuid::read_flash_string(name).c_str());
}
new_name[0] = toupper(new_name[0]); // capitalize first letter

View File

@@ -171,21 +171,22 @@ void RxService::add(uint8_t * data, uint8_t length) {
// EMS 1 has type_id always in data[2], if it gets a ems+ inquiry it will reply with FF but short length
// i.e. sending 0B A1 FF 00 01 D8 20 CRC to a MM10 Mixer (ems1.0), the reply is 21 0B FF 00 CRC
// see: https://github.com/proddy/EMS-ESP/issues/380#issuecomment-633663007
if (data[2] < 0xF0 || length < 6) {
if (data[2] != 0xFF || length < 6) {
// EMS 1.0
// also handle F7, F9 as EMS 1.0, see https://github.com/proddy/EMS-ESP/issues/109#issuecomment-492781044
type_id = data[2];
message_data = data + 4;
message_length = length - 5;
} else if (data[1] & 0x80) {
// EMS 2.0 read request
type_id = (data[5] << 8) + data[6] + 256;
message_data = data + 4; // only data is the requested length
message_length = 1;
} else {
// EMS 2.0 / EMS+
uint8_t shift = 0; // default when data[2] is 0xFF
if (data[2] != 0xFF) {
// its F9 or F7, re-calculate shift. If the 5th byte is not 0xFF then telegram is 1 byte longer
shift = (data[4] != 0xFF) ? 2 : 1;
}
type_id = (data[4 + shift] << 8) + data[5 + shift] + 256;
message_data = data + 6 + shift;
message_length = length - 7 - shift;
type_id = (data[4] << 8) + data[5] + 256;
message_data = data + 6;
message_length = length - 7;
}
// if we're watching and "raw" print out actual telegram as bytes to the console
@@ -439,21 +440,20 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
// work out depending on the type, where the data message block starts and the message length
// same logic as in RxService::add(), but adjusted for no appended CRC
if (data[2] < 0xF0) {
if (data[2] != 0xFF) {
// EMS 1.0
type_id = data[2];
message_data = data + 4;
message_length = length - 4;
} else if (data[1] & 0x80) {
type_id = (data[5] << 8) + data[6] + 256;
message_data = data + 4;
message_length = 1;
} else {
// EMS 2.0 / EMS+
uint8_t shift = 0; // default when data[2] is 0xFF
if (data[2] != 0xFF) {
// its F9 or F7, re-calculate shift. If the 5th byte is not 0xFF then telegram is 1 byte longer
shift = (data[4] != 0xFF) ? 2 : 1;
}
type_id = (data[4 + shift] << 8) + data[5 + shift] + 256;
message_data = data + 6 + shift;
message_length = length - 6 - shift;
type_id = (data[4] << 8) + data[5] + 256;
message_data = data + 6;
message_length = length - 6;
}
// if we don't have a type_id or empty data block, exit

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "2.1.0b12"
#define EMSESP_APP_VERSION "2.1.0b13"