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

This commit is contained in:
MichaelDvP
2020-01-12 09:59:51 +01:00
58 changed files with 161 additions and 8346 deletions

View File

@@ -17,8 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- set boiler warm water temp on Junkers/Bosch HT3
### Changed
- improved MQTT publishing to stop flooding
- improved MQTT publishing to stop flooding. `publish_time` must be at least 1 (second)
### Removed
- `autodetect scan`

View File

@@ -1,5 +1,4 @@
![logo](https://github.com/proddy/EMS-ESP/raw/master/doc/ems%20gateway/logo-proddy-fw.jpg)
# EMS-ESP
![logo](docs/_media/logo/EMS-ESP_logo_dark.png)
[![version](https://img.shields.io/github/release/proddy/EMS-ESP.svg?label=Latest%20Release)](https://github.com/proddy/EMS-ESP/blob/master/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)
@@ -10,12 +9,14 @@
[![downloads](https://img.shields.io/github/downloads/proddy/EMS-ESP/total.svg)](https://github.com/proddy/EMS-ESP/releases)
<br />
[![gitter](https://img.shields.io/gitter/room/EMS-ESP/EMS-ESP.svg)](https://gitter.im/EMS-ESP/community)
<br>
-------------
EMS-ESP is a open-source system to communicate with **EMS** (Energy Management System) based boilers, thermostats and other modules from manufacturers like Bosch, Buderus, Nefit, Junkers and Sieger.
The code is written for the Espressif **ESP8266** microcontroller and supports a telnet console for real-time monitoring and configuration and customizable MQTT support for publishing the information to a home automation system such as Home Assistant or Domoticz.
#### Please reference the [Wiki](https://github.com/proddy/EMS-ESP/wiki) for further details and instructions on how to build and configure the firmware.
#### Please reference the [Wiki](https://emsesp.github.io/docs) for further details and instructions on how to build and configure the firmware.
---
@@ -23,31 +24,28 @@ The code is written for the Espressif **ESP8266** microcontroller and supports a
#### A web interface for easy configuration and real-time monitoring of the EMS bus
| ![web menu](https://github.com/proddy/EMS-ESP/raw/master/doc/web/system_status.PNG) | ![web menu](https://github.com/proddy/EMS-ESP/raw/master/doc/web/ems_dashboard.PNG) |
| ![web menu](docs/_media/web/system_status.PNG) | ![web menu](docs/_media/web/ems_dashboard.PNG) |
| -------------------------------------------------------- | ---------------------------------------------------------- |
#### MQTT support for Home Assistant and Domoticz
![ha](https://github.com/proddy/EMS-ESP/raw/master/doc/home%20assistant/ha.png)
![ha](docs/_media/home%20assistant/ha.png)
#### Telnet for advanced configuration and verbose traffic logging
| ![telnet menu](https://github.com/proddy/EMS-ESP/raw/master/doc/telnet/telnet_menu.jpg) | ![telnet menu](https://github.com/proddy/EMS-ESP/raw/master/doc/telnet/telnet_stats.PNG) |
| ![telnet menu](docs/_media/telnet/telnet_menu.jpg) | ![telnet menu](docs/_media/telnet/telnet_stats.PNG) |
| ------------------------------------------------------------ | -------------------------------------------------------- |
## Supported EMS devices
More than **50** EMS devices are currently supported. See the [complete list](https://github.com/proddy/EMS-ESP/wiki/Supported-EMS-Devices) from the [Wiki](https://github.com/proddy/EMS-ESP/wiki).
More than **50** EMS 1.0 and 2.0 devices are currently supported. See the [complete list](https://proddy.github.io/EMS-ESP/#/Supported-EMS-Devices).
## Uploading the firmware
Latest stable firmware build can be found [here](https://github.com/proddy/EMS-ESP/releases/latest).
---
Follow [these instructions](https://github.com/proddy/EMS-ESP/wiki/Building-and-Uploading-the-Firmware) on how to upload to the ESP8266.
## Native compatibility with bbqkees' **EMS Gateway**
## Compatible with bbqkees' EMS Gateway
All firmware versions fully support BBQKees' [EMS Gateway](https://bbqkees-electronics.nl/) board with integrated Wemos D1 ESP8266.
The firmware fully supports BBQKees' [EMS Gateway](https://shop.hotgoodies.nl/ems/) board with integrated Wemos D1 ESP8266.
| ![on boiler](https://github.com/proddy/EMS-ESP/raw/master/doc/ems%20gateway/on-boiler.jpg) | ![kit](https://github.com/proddy/EMS-ESP/raw/master/doc/ems%20gateway/ems-kit-2.jpg) | ![basic circuit](https://github.com/proddy/EMS-ESP/raw/master/doc/ems%20gateway/ems-board-white.jpg) |
| ![on boiler](docs/_media/ems%20gateway/on-boiler.jpg) | ![kit](docs/_media/ems%20gateway/ems-kit-2.jpg) | ![basic circuit](docs/_media/ems%20gateway/ems-board-white.jpg) |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -1,42 +0,0 @@
- id: ems-esp_offline
alias: See if ems-esp goes offline
initial_state: true
trigger:
platform: state
entity_id: sensor.ems_esp_status
to: offline
action:
- service: notify.admin_notify
data_template:
title: EMS-ESP
message: 'gone offline'
- id: emsesp_restart
alias: See if ems-esp restarts
initial_state: true
trigger:
platform: mqtt
topic: home/ems-esp/start
payload: start
action:
- service: notify.admin_notify
data_template:
title: ems-esp has booted
message: EMS-ESP
- service: mqtt.publish
data_template:
topic: home/ems-esp/start
payload: '{{ now().strftime("%H:%M:%S %-d/%b/%Y") }}'
- id: boiler_shower
alias: Alert shower time
initial_state: true
trigger:
platform: state
entity_id: sensor.last_shower_duration
action:
- service: notify.admin_notify
data_template:
title: Shower finished at {{states.sensor.time.state}}
message: "{{ states.sensor.last_shower_duration.state }}"

View File

@@ -1,12 +0,0 @@
- platform: mqtt
name: 'Tap Water'
state_topic: 'home/ems-esp/tapwater_active'
payload_on: "1"
payload_off: "0"
- platform: mqtt
name: 'Heating'
state_topic: 'home/ems-esp/heating_active'
payload_on: "1"
payload_off: "0"

View File

@@ -1,41 +0,0 @@
- platform: mqtt
name: Thermostat
modes:
- "auto"
- "heat"
- "off"
mode_command_topic: "home/ems-esp/thermostat_cmd_mode1"
temperature_command_topic: "home/ems-esp/thermostat_cmd_temp1"
mode_state_topic: "home/ems-esp/thermostat_data"
current_temperature_topic: "home/ems-esp/thermostat_data"
temperature_state_topic: "home/ems-esp/thermostat_data"
mode_state_template: "{% if value_json.hc1.mode in ['manual', 'day'] %} heat {% elif value_json.hc1.mode in ['night', 'off'] %} off {% else %} auto {% endif %}"
current_temperature_template: "{{ value_json.hc1.currtemp }}"
temperature_state_template: "{{ value_json.hc1.seltemp }}"
temp_step: 0.5
- platform: mqtt
name: boiler
modes:
- "auto"
- "off"
min_temp: 40
max_temp: 60
temp_step: 1
current_temperature_topic: "home/ems-esp/boiler_data"
temperature_state_topic: "home/ems-esp/boiler_data"
mode_state_topic: "home/ems-esp/boiler_data"
current_temperature_template: "{{ value_json.wWCurTmp }}"
temperature_state_template: "{{ value_json.wWSelTemp }}"
mode_state_template: "{% if value_json.wWActivated == 'off' %} off {% else %} auto {% endif %}"
temperature_command_topic: "home/ems-esp/boiler_cmd_wwtemp"
mode_command_topic: "home/ems-esp/boiler_cmd_wwactivated"

View File

@@ -1,12 +0,0 @@
sensor.boiler_boottime:
friendly_name: Controller last restart
icon: mdi:clock-start
sensor.showertime_time:
friendly_name: 'Last shower at'
icon: mdi:timelapse
sensor.boiler_updated:
friendly_name: 'Data last received'
icon: mdi:clock-start

View File

@@ -1,16 +0,0 @@
- name: pushover
platform: pushover
api_key: !secret pushover_api_key
user_key: !secret pushover_user_key
- name: general_notify
platform: group
services:
- service: ios_pauls_iphone
- service: pushover
- name: admin_notify
platform: group
services:
- service: ios_pauls_iphone
- service: pushover

View File

@@ -1,8 +0,0 @@
# ems-esp
shower_coldshot:
sequence:
- service: mqtt.publish
data_template:
topic: 'home/ems-esp/generic_cmd'
payload: '{cmd:"coldshot"}'

View File

@@ -1,146 +0,0 @@
# thermostat HC1
- platform: mqtt
state_topic: 'home/ems-esp/thermostat_data'
name: 'Current Room Temperature'
unit_of_measurement: '°C'
value_template: "{{ value_json.hc1.currtemp }}"
- platform: mqtt
state_topic: 'home/ems-esp/thermostat_data'
name: 'Current Set Temperature'
unit_of_measurement: '°C'
value_template: "{{ value_json.hc1.seltemp }}"
- platform: mqtt
state_topic: 'home/ems-esp/thermostat_data'
name: 'Current Mode'
value_template: "{{ value_json.hc1.mode }}"
# boiler
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Warm Water selected temperature'
unit_of_measurement: '°C'
value_template: '{{ value_json.wWSelTemp }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Warm Water tapwater flow rate'
unit_of_measurement: 'l/min'
value_template: '{{ value_json.wWCurFlow }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Warm Water current temperature'
unit_of_measurement: '°C'
value_template: '{{ value_json.wWCurTmp }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Warm Water activated'
value_template: '{{ value_json.wWActivated }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Warm Water 3-way valve'
value_template: '{{ value_json.wWHeat }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Current flow temperature'
unit_of_measurement: '°C'
value_template: '{{ value_json.curFlowTemp }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Return temperature'
unit_of_measurement: '°C'
value_template: '{{ value_json.retTemp }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Gas'
value_template: '{{ value_json.burnGas }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Boiler pump'
value_template: '{{ value_json.heatPmp }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Fan'
value_template: '{{ value_json.fanWork }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Ignition'
value_template: '{{ value_json.ignWork }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Circulation pump'
value_template: '{{ value_json.wWCirc }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Burner max power'
unit_of_measurement: '%'
value_template: '{{ value_json.selBurnPow }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Burner max power'
unit_of_measurement: '%'
value_template: '{{ value_json.selBurnPow }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Burner current power'
unit_of_measurement: '%'
value_template: '{{ value_json.curBurnPow }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'System Pressure'
unit_of_measurement: 'bar'
value_template: '{{ value_json.sysPress }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Boiler temperature'
unit_of_measurement: '°C'
value_template: '{{ value_json.boilTemp }}'
- platform: mqtt
state_topic: 'home/ems-esp/boiler_data'
name: 'Pump modulation'
unit_of_measurement: '%'
value_template: '{{ value_json.pumpMod }}'
# shower time duration
- platform: mqtt
name: 'Last shower duration'
state_topic: "home/ems-esp/shower_data"
value_template: "{{ value_json.duration | is_defined }}"
- platform: template
sensors:
showertime_time:
value_template: '{{ as_timestamp(states.sensor.last_shower_duration.last_updated) | int | timestamp_custom("%-I:%M on %a %-d %b") }}'
boiler_updated:
value_template: '{{ as_timestamp(states.sensor.boiler_temperature.last_updated) | timestamp_custom("%H:%M on %d/%b") }}'
boiler_boottime:
value_template: '{{ as_timestamp(states.automation.see_if_boiler_restarts.attributes.last_triggered) | timestamp_custom("%H:%M:%S %d/%m/%y") }}'
# general
- platform: mqtt
state_topic: 'home/ems-esp/status'
name: 'ems-esp status'

View File

@@ -1,20 +0,0 @@
# EMS-ESP
- platform: mqtt
name: "Shower Timer"
state_topic: "home/ems-esp/shower_data"
value_template: "{{ value_json.timer }}"
command_topic: "home/ems-esp/shower_data"
payload_on: '{"timer":"1"}'
payload_off: '{"timer":"0"}'
state_on: "1"
state_off: "0"
- platform: mqtt
name: "Long Shower Alert"
state_topic: "home/ems-esp/shower_data"
value_template: "{{ value_json.alert }}"
command_topic: "home/ems-esp/shower_data"
payload_on: '{"alert":"1"}'
payload_off: '{"alert":"0"}'
state_on: "1"
state_off: "0"

View File

@@ -1,75 +0,0 @@
- id: ems-esp_id0
title: Heating
cards:
- id: ems-esp_id1
type: glance
entities:
- entity: binary_sensor.tap_water
icon: mdi:fire
- entity: binary_sensor.heating
icon: mdi:radiator
- id: ems-esp_id2
type: entities
title: Boiler
show_header_toggle: false
entities:
- sensor.boiler_boottime
- sensor.boiler_updated
- sensor.ems_esp_status
- type: divider
- sensor.warm_water_selected_temperature
- sensor.warm_water_current_temperature
- sensor.warm_water_activated
- sensor.warm_water_3_way_valve
- type: divider
- sensor.boiler_temperature
- sensor.return_temperature
- sensor.current_flow_temperature
- sensor.pump_modulation
- sensor.ignition
- sensor.gas
- sensor.fan
- sensor.boiler_pump
- sensor.system_pressure
- sensor.burner_max_power
- sensor.burner_current_power
- id: ems-esp_id3
type: vertical-stack
cards:
- type: entities
title: Shower Monitor
show_header_toggle: false
entities:
- switch.shower_timer
- switch.long_shower_alert
- type: divider
- sensor.last_shower_duration
- sensor.showertime_time
- type: entity-button
icon: mdi:shower-head
name: send a cold shot of shower water
entity: script.shower_coldshot
tap_action:
action: call-service
service: script.turn_on
service_data:
entity_id: script.shower_coldshot
- type: history-graph
entities:
- sensor.ems_esp_wifi
- sensor.ems_esp_freemem
- id: ems-esp_id4
type: vertical-stack
cards:
- type: history-graph
entities:
- sensor.pc_room_sensor_temperature
- sensor.current_room_temperature
- sensor.dark_sky_temperature
- type: thermostat
entity: climate.thermostat
- type: thermostat
entity: climate.boiler

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/_media/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1 @@
<svg id="Capa_1" enable-background="new 0 0 511.728 511.728" height="512" viewBox="0 0 511.728 511.728" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m228.871 504.5v-50.088l-29.153-6.478v56.566z" fill="#878b91"/><path d="m312.01 504.5v-56.566l-29.153 6.478v50.088z" fill="#878b91"/><path d="m102.542 50.49c0-11.848 7.837-22.269 19.228-25.532 24.567-7.037 71.513-17.458 134.094-17.458 64.244 0 110.286 10.267 134.291 17.3 11.296 3.31 19.031 13.704 19.031 25.473v327.727c0 11.848-7.837 22.269-19.228 25.532-24.566 7.037-71.513 17.458-134.094 17.458-64.244 0-110.286-10.267-134.291-17.3-11.296-3.31-19.031-13.704-19.031-25.473z" fill="#e2faff"/><path d="m390.155 24.8c-24.005-7.033-70.047-17.3-134.291-17.3-5.539 0-10.949.085-16.238.239 55.521 1.571 95.667 10.655 117.529 17.061 11.296 3.31 19.031 13.704 19.031 25.473v327.727c0 11.848-7.837 22.269-19.228 25.532-22.392 6.414-63.385 15.636-117.855 17.219 5.443.154 11.026.239 16.762.239 62.581 0 109.527-10.421 134.094-17.458 11.391-3.263 19.228-13.684 19.228-25.532v-327.727c-.002-11.769-7.736-22.163-19.032-25.473z" fill="#cbf4ff"/><path d="m363.05 400.273v34.338c0 7.466-4.905 14.058-12.07 16.159-16.762 4.913-50.172 12.602-95.116 12.602-46.074 0-78.756-7.553-95.152-12.471-7.14-2.141-12.034-8.695-12.034-16.148v-34.479h214.372z" fill="#82d5f2"/><path d="m330.05 400.273v34.338c0 7.466-4.905 14.058-12.07 16.159-14.672 4.301-42.1 10.728-78.854 12.264 5.364.219 10.945.338 16.738.338 44.944 0 78.354-7.689 95.116-12.602 7.165-2.1 12.07-8.693 12.07-16.159v-34.338z" fill="#67c6e4"/><ellipse cx="255.864" cy="131.961" fill="#82d5f2" rx="49.872" ry="49.866"/><path d="m102.542 308.121v70.094c0 11.77 7.735 22.164 19.031 25.473 24.005 7.033 70.047 17.3 134.291 17.3 62.581 0 109.527-10.421 134.094-17.458 11.391-3.263 19.228-13.684 19.228-25.532v-69.878h-306.644z" fill="#baeefc"/><path d="m376.185 308.121v69.879c0 11.848-7.837 22.269-19.228 25.532-22.392 6.414-63.385 15.636-117.855 17.219 5.443.154 11.026.239 16.762.239 62.581 0 109.527-10.421 134.094-17.458 11.391-3.263 19.228-13.684 19.228-25.532v-69.878h-33.001z" fill="#a2e1f8"/><path d="m313.235 131.961c0-31.632-25.737-57.366-57.372-57.366s-57.372 25.734-57.372 57.366 25.737 57.366 57.372 57.366 57.372-25.734 57.372-57.366zm-99.743 0c0-23.361 19.008-42.366 42.372-42.366s42.372 19.005 42.372 42.366-19.008 42.366-42.372 42.366-42.372-19.005-42.372-42.366z"/><path d="m275.702 122.48c6.81-6.809-3.786-17.427-10.605-10.607l-15.037 15.035c-6.713 6.712 3.738 17.475 10.605 10.607z"/><path d="m416.686 50.273c0-15.023-10.043-28.458-24.422-32.67-22.437-6.574-69.991-17.603-136.4-17.603-15.982 0-32.011.681-47.642 2.023-9.595.824-8.324 15.772 1.283 14.945 15.206-1.306 30.803-1.968 46.359-1.968 64.536 0 110.517 10.649 132.182 16.998 8.031 2.353 13.64 9.868 13.64 18.276v250.348h-291.644v-250.132c0-8.461 5.672-15.996 13.793-18.322 11.309-3.239 23.561-6.107 36.416-8.525 9.464-1.78 6.705-16.528-2.773-14.741-13.31 2.503-26.019 5.48-37.772 8.847-14.521 4.159-24.663 17.623-24.663 32.742v327.726c0 15.023 10.043 28.458 24.422 32.67 5.667 1.661 12.942 3.605 21.713 5.585v18.281c0 10.837 6.984 20.214 17.38 23.333 7.447 2.233 18.809 5.175 33.661 7.673v38.741c0 9.63 15 9.644 15 0v-36.56c4.486.556 9.207 1.055 14.153 1.478v35.082c0 9.63 15 9.644 15 0v-34.09c6.213.293 12.708.461 19.493.461 6.55 0 13.051-.16 19.493-.475v34.104c0 9.63 15 9.644 15 0v-35.135c4.758-.42 9.477-.929 14.153-1.525v36.66c0 9.63 15 9.644 15 0v-38.899c3.651-.626 7.275-1.3 10.862-2.036 9.434-1.936 6.432-16.631-3.016-14.693-53.191 10.916-112.262 10.508-164.49-5.155-4.001-1.2-6.689-4.803-6.689-8.965v-15.181c25.125 4.743 58.83 8.919 99.687 8.919 40.222 0 74.192-4.317 99.687-9.174v15.295c0 9.63 15 9.644 15 0v-18.411c8.587-1.936 15.796-3.833 21.472-5.458 14.521-4.159 24.663-17.623 24.663-32.742v-327.727zm-28.793 346.048c-22.385 6.412-69.304 17.168-132.029 17.168-64.536 0-110.517-10.649-132.182-16.998-8.031-2.353-13.64-9.868-13.64-18.276v-62.595h291.644v62.38c0 8.461-5.672 15.995-13.793 18.321z"/><path d="m203.737 351.74c-9.652 0-9.668 15 0 15 9.651 0 9.667-15 0-15z"/><path d="m255.864 351.74c-9.652 0-9.668 15 0 15 9.652 0 9.668-15 0-15z"/><path d="m307.991 351.74c-9.652 0-9.668 15 0 15 9.652 0 9.668-15 0-15z"/></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 166 KiB

View File

Before

Width:  |  Height:  |  Size: 423 KiB

After

Width:  |  Height:  |  Size: 423 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 200 KiB

View File

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 189 KiB

View File

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -7,7 +7,7 @@ Import("env")
def build_web():
print("** Building web...")
env.Execute(
"node ./tools/webfilesbuilder/node_modules/gulp/bin/gulp.js --cwd ./tools/webfilesbuilder")
"node ./tools/webfilesbuilder/node_modules/gulp/bin/gulp.js --silent --cwd ./tools/webfilesbuilder")
def code_check(source, target, env):
print("** Starting cppcheck...")

View File

@@ -1474,13 +1474,13 @@ void MyESP::_heartbeatCheck(bool force) {
StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc;
JsonObject rootHeartbeat = doc.to<JsonObject>();
rootHeartbeat["version"] = _app_version;
rootHeartbeat["IP"] = WiFi.localIP().toString();
//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();
//rootHeartbeat["MQTTdisconnects"] = _getSystemDropoutCounter();
char data[300] = {0};
serializeJson(doc, data, sizeof(data));

View File

@@ -9,7 +9,7 @@
#ifndef MyESP_h
#define MyESP_h
#define MYESP_VERSION "1.2.22"
#define MYESP_VERSION "1.2.23"
#include <ArduinoJson.h>
#include <ArduinoOTA.h>

View File

@@ -114,7 +114,7 @@
<div class="row form-group">
<label class="col-xs-3">Publish Time<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
data-content="How often to send MQTT topics with stats. 0 is automatic. (in seconds)"></i></label>
data-content="How often to send the MQTT topics in seconds. Must be at least 1"></i></label>
<span class="col-xs-9">
<input class="form-control input-sm" placeholder="0" value="" style="display:inline;max-width:185px"
id="publish_time" type="text">

View File

@@ -8,7 +8,7 @@ var custom_config = {
"listen_mode": false,
"shower_timer": false,
"shower_alert": false,
"publish_time": 0,
"publish_time": 10,
"tx_mode": 1
}
};

View File

@@ -18,24 +18,28 @@ DS18::DS18() {
}
DS18::~DS18() {
if (_wire)
if (_wire) {
delete _wire;
}
}
// init
uint8_t DS18::setup(uint8_t gpio, bool parasite) {
uint8_t count;
void DS18::setup(uint8_t gpio, bool parasite) {
_gpio = gpio;
_parasite = (parasite ? 1 : 0);
// OneWire
if (_wire)
if (_wire) {
delete _wire;
}
_wire = new OneWire(_gpio);
}
// Search devices
count = loadDevices();
// clear list and scan for devices
uint8_t DS18::scan() {
_devices.clear();
uint8_t count = loadDevices(); // start the search
// If no devices found check again pulling up the line
if (count == 0) {
@@ -48,30 +52,30 @@ uint8_t DS18::setup(uint8_t gpio, bool parasite) {
return count;
}
// scan every 2 seconds
void DS18::loop() {
static uint32_t last = 0;
if (millis() - last < DS18_READ_INTERVAL)
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, _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;
_devices[index].data[0] = _devices[index].data[0] + 1; // Force a CRC check error
return;
}
// Read each scratchpad
_wire->select(_devices[index].address);
_wire->write(DS18_CMD_READ_SCRATCHPAD);
@@ -81,8 +85,7 @@ void DS18::loop() {
}
if (_wire->reset() != 1) {
// Force a CRC check error
_devices[index].data[0] = _devices[index].data[0] + 1;
_devices[index].data[0] = _devices[index].data[0] + 1; // Force a CRC check error
return;
}
@@ -153,8 +156,9 @@ char * DS18::getDeviceString(char * buffer, unsigned char index) {
byte 8: SCRATCHPAD_CRC
*/
int16_t DS18::getRawValue(unsigned char index) {
if (index >= _count)
if (index >= _count) {
return 0;
}
uint8_t * data = _devices[index].data;
@@ -170,23 +174,35 @@ int16_t DS18::getRawValue(unsigned char index) {
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00)
if (cfg == 0x00) {
raw = raw & ~7; // 9 bit res, 93.75 ms
else if (cfg == 0x20)
} else if (cfg == 0x20) {
raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40)
} else if (cfg == 0x40) {
raw = raw & ~1; // 11 bit res, 375 ms
// 12 bit res, 750 ms
}
}
return raw;
}
// return real value as a float
// The raw temperature data is in units of sixteenths of a degree, so the value must be divided by 16 in order to convert it to degrees.
// return real value as a float, rounded to 2 decimal places
float DS18::getValue(unsigned char index) {
float value = (float)getRawValue(index) / 16.0;
return value;
int16_t raw_value = getRawValue(index);
// check if valid
if ((raw_value == DS18_CRC_ERROR) || (raw_value == DS18_DISCONNECTED)) {
return (float)DS18_DISCONNECTED;
}
// The raw temperature data is in units of sixteenths of a degree,
// so the value must first be divided by 16 in order to convert it to degrees.
float new_value = (float)(raw_value / 16.0);
// round to 2 decimal places
// https://arduinojson.org/v6/faq/how-to-configure-the-serialization-of-floats/
return (int)(new_value * 100 + 0.5) / 100.0;
}
// check for a supported DS chip version
@@ -196,8 +212,9 @@ bool DS18::validateID(unsigned char id) {
// return the type
unsigned char DS18::chip(unsigned char index) {
if (index < _count)
if (index < _count) {
return _devices[index].address[0];
}
return 0;
}
@@ -206,6 +223,7 @@ 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]) {

View File

@@ -36,7 +36,8 @@ class DS18 {
DS18();
~DS18();
uint8_t setup(uint8_t gpio, bool parasite);
void setup(uint8_t gpio, bool parasite);
uint8_t scan();
void loop();
char * getDeviceString(char * s, unsigned char index);
float getValue(unsigned char index);

View File

@@ -98,9 +98,9 @@ static const command_t project_cmds[] PROGMEM = {
{true, "listen_mode <on | off>", "when set to on all automatic Tx are disabled"},
{true, "shower_timer <on | off>", "send MQTT notification on all shower durations"},
{true, "shower_alert <on | off>", "stop hot water to send 3 cold burst warnings after max shower time is exceeded"},
{true, "publish_time <seconds>", "set frequency for publishing data to MQTT (0=automatic)"},
{true, "publish_time <seconds>", "set frequency for publishing data to MQTT"},
{true, "tx_mode <n>", "changes Tx logic. 1=EMS generic, 2=EMS+, 3=HT3"},
{true, "master_thermostat [product id]", "product id to use as the master thermostat. Use no args for list."},
{true, "master_thermostat [product id]", "set default thermostat to use. Omit [product id] to show options."},
{false, "info", "show current values deciphered from the EMS messages"},
{false, "log <n | b | t | s | r | j | v | w [type ID]", "set logging to none, basic, thermostat, solar module, raw, jabber, verbose or watch a specific type"},
@@ -113,7 +113,7 @@ static const command_t project_cmds[] PROGMEM = {
{false, "refresh", "fetch values from the EMS devices"},
{false, "devices", "list detected EMS devices"},
{false, "queue", "show current Tx queue"},
{false, "autodetect", "detect EMS devices and attempt to automatically set boiler and thermostat types"},
{false, "autodetect", "scan for EMS devices and external sensors"},
{false, "send XX ...", "send raw telegram data to EMS bus (XX are hex values)"},
{false, "thermostat read <type ID>", "send read request to the thermostat for heating circuit hc 1-4"},
{false, "thermostat temp [hc] <degrees>", "set current thermostat temperature"},
@@ -505,13 +505,27 @@ void showInfo() {
char valuestr[8] = {0}; // for formatting temp
myDebug_P(PSTR("%sExternal temperature sensors:%s"), COLOR_BOLD_ON, COLOR_BOLD_OFF);
for (uint8_t i = 0; i < EMSESP_Settings.dallas_sensors; i++) {
myDebug_P(PSTR(" Sensor #%d %s: %s C"), i + 1, ds18.getDeviceString(buffer, i), _float_to_char(valuestr, ds18.getValue(i)));
float sensorValue = ds18.getValue(i);
if (sensorValue != DS18_DISCONNECTED) {
myDebug_P(PSTR(" Sensor #%d %s: %s C"), i + 1, ds18.getDeviceString(buffer, i), _float_to_char(valuestr, sensorValue));
}
}
}
myDebug_P(PSTR("")); // newline
}
// scan for external Dallas sensors and display
void scanDallas() {
EMSESP_Settings.dallas_sensors = ds18.scan();
if (EMSESP_Settings.dallas_sensors) {
char buffer[128] = {0};
for (uint8_t i = 0; i < EMSESP_Settings.dallas_sensors; i++) {
myDebug_P(PSTR("External temperature sensor %s found"), ds18.getDeviceString(buffer, i));
}
}
}
// send all dallas sensor values as a JSON package to MQTT
void publishSensorValues() {
// don't send if MQTT is connected
@@ -531,9 +545,8 @@ void publishSensorValues() {
// see if the sensor values have changed, if so send it on
for (uint8_t i = 0; i < EMSESP_Settings.dallas_sensors; i++) {
// round to 2 decimal places. from https://arduinojson.org/v6/faq/how-to-configure-the-serialization-of-floats/
float sensorValue = (int)(ds18.getValue(i) * 100 + 0.5) / 100.0;
if (sensorValue != DS18_DISCONNECTED && sensorValue != DS18_CRC_ERROR) {
float sensorValue = ds18.getValue(i);
if (sensorValue != DS18_DISCONNECTED) {
sprintf(label, PAYLOAD_EXTERNAL_SENSORS, (i + 1));
sensors[label] = sensorValue;
hasdata = true;
@@ -1083,8 +1096,13 @@ bool SetListCallback(MYESP_FSACTION_t action, uint8_t wc, const char * setting,
// publish_time
if ((strcmp(setting, "publish_time") == 0) && (wc == 2)) {
int16_t val = atoi(value);
if (val > 0) {
EMSESP_Settings.publish_time = atoi(value);
ok = true;
} else {
myDebug_P(PSTR("Error. time must be at least 1 second"));
}
}
// tx_mode
@@ -1133,12 +1151,7 @@ bool SetListCallback(MYESP_FSACTION_t action, uint8_t wc, const char * setting,
myDebug_P(PSTR(" listen_mode=%s"), EMSESP_Settings.listen_mode ? "on" : "off");
myDebug_P(PSTR(" shower_timer=%s"), EMSESP_Settings.shower_timer ? "on" : "off");
myDebug_P(PSTR(" shower_alert=%s"), EMSESP_Settings.shower_alert ? "on" : "off");
if (EMSESP_Settings.publish_time) {
myDebug_P(PSTR(" publish_time=%d"), EMSESP_Settings.publish_time);
} else {
myDebug_P(PSTR(" publish_time=0 (always publish on data received)"), EMSESP_Settings.publish_time);
}
if (EMSESP_Settings.master_thermostat) {
myDebug_P(PSTR(" master_thermostat=%d"), EMSESP_Settings.master_thermostat);
@@ -1188,9 +1201,9 @@ void _showCommands(uint8_t event) {
// we set the logging here
void TelnetCallback(uint8_t event) {
if (event == TELNET_EVENT_CONNECT) {
ems_setLogging(EMS_SYS_LOGGING_DEFAULT);
ems_setLogging(EMS_SYS_LOGGING_DEFAULT, true);
} else if (event == TELNET_EVENT_DISCONNECT) {
ems_setLogging(EMS_SYS_LOGGING_NONE);
ems_setLogging(EMS_SYS_LOGGING_NONE, true);
} else if ((event == TELNET_EVENT_SHOWCMD) || (event == TELNET_EVENT_SHOWSET)) {
_showCommands(event);
}
@@ -1229,6 +1242,8 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
}
if (strcmp(first_cmd, "autodetect") == 0) {
myDebug("Scanning for new EMS devices and attached external sensors...");
scanDallas();
ems_clearDeviceList();
ems_doReadCommand(EMS_TYPE_UBADevices, EMS_Boiler.device_id);
ok = true;
@@ -1464,15 +1479,19 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
const char * shower_alert = doc[TOPIC_SHOWER_ALERT];
if (shower_alert) {
EMSESP_Settings.shower_alert = ((shower_alert[0] - MYESP_MQTT_PAYLOAD_OFF) == 1);
if (ems_getLogging() != EMS_SYS_LOGGING_NONE) {
myDebug_P(PSTR("Shower alert has been set to %s"), EMSESP_Settings.shower_alert ? "enabled" : "disabled");
}
}
// assumes payload is "1" or "0"
const char * shower_timer = doc[TOPIC_SHOWER_TIMER];
if (shower_timer) {
EMSESP_Settings.shower_timer = ((shower_timer[0] - MYESP_MQTT_PAYLOAD_OFF) == 1);
if (ems_getLogging() != EMS_SYS_LOGGING_NONE) {
myDebug_P(PSTR("Shower timer has been set to %s"), EMSESP_Settings.shower_timer ? "enabled" : "disabled");
}
}
return;
}
@@ -1940,7 +1959,7 @@ void setup() {
regularUpdatesTimer.attach(REGULARUPDATES_TIME, do_regularUpdates); // regular reads from the EMS
}
// set timers for MQTT publish, only if publish_time is not 0 (automatic mode)
// set timers for MQTT publish
if (EMSESP_Settings.publish_time) {
publishValuesTimer.attach(EMSESP_Settings.publish_time, do_publishValues); // post MQTT EMS values
}
@@ -1956,7 +1975,8 @@ void setup() {
systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if EMS is reachable
// check for Dallas sensors
EMSESP_Settings.dallas_sensors = ds18.setup(EMSESP_Settings.dallas_gpio, EMSESP_Settings.dallas_parasite); // returns #sensors
ds18.setup(EMSESP_Settings.dallas_gpio, EMSESP_Settings.dallas_parasite);
scanDallas();
}
//
@@ -1970,11 +1990,6 @@ void loop() {
ds18.loop();
}
// publish EMS data to MQTT, only if in automatic mode (publish_time=0) otherwise it'll use the timer
if (EMSESP_Settings.publish_time == 0) {
publishEMSValues(false);
}
// if we have an EMS connect go and fetch some data and MQTT publish it
if (_need_first_publish) {
publishEMSValues(false);

View File

@@ -210,7 +210,7 @@ void ems_init() {
strlcpy(EMS_Thermostat.version, "?", sizeof(EMS_Thermostat.version));
// default logging is none
ems_setLogging(EMS_SYS_LOGGING_DEFAULT);
ems_setLogging(EMS_SYS_LOGGING_DEFAULT, true);
}
// Getters and Setters for parameters
@@ -282,9 +282,17 @@ _EMS_SYS_LOGGING ems_getLogging() {
}
void ems_setLogging(_EMS_SYS_LOGGING loglevel, uint16_t type_id) {
if (loglevel <= EMS_SYS_LOGGING_JABBER) {
EMS_Sys_Status.emsLogging_typeID = type_id;
ems_setLogging(EMS_SYS_LOGGING_WATCH, false);
}
void ems_setLogging(_EMS_SYS_LOGGING loglevel, bool quiet) {
EMS_Sys_Status.emsLogging = loglevel;
if (quiet) {
return; // no reporting to console
}
if (loglevel == EMS_SYS_LOGGING_NONE) {
myDebug_P(PSTR("System Logging set to None"));
} else if (loglevel == EMS_SYS_LOGGING_BASIC) {
@@ -300,11 +308,9 @@ void ems_setLogging(_EMS_SYS_LOGGING loglevel, uint16_t type_id) {
} else if (loglevel == EMS_SYS_LOGGING_JABBER) {
myDebug_P(PSTR("System Logging set to Jabber mode"));
} else if (loglevel == EMS_SYS_LOGGING_WATCH) {
EMS_Sys_Status.emsLogging_typeID = type_id;
myDebug_P(PSTR("System Logging set to Watch mode"));
}
}
}
/**
* send a poll acknowledge
@@ -2135,6 +2141,17 @@ void ems_printDevices() {
have_unknowns = true;
}
if ((it->device_type == EMS_DEVICE_TYPE_THERMOSTAT) && (EMS_Sys_Status.emsMasterThermostat == it->product_id)) {
myDebug_P(PSTR(" %s: %s%s%s (DeviceID:0x%02X ProductID:%d Version:%s) [master]"),
device_type,
COLOR_BOLD_ON,
device_string,
COLOR_BOLD_OFF,
it->device_id,
it->product_id,
it->version);
} else {
myDebug_P(PSTR(" %s: %s%s%s (DeviceID:0x%02X ProductID:%d Version:%s)"),
device_type,
COLOR_BOLD_ON,
@@ -2144,12 +2161,11 @@ void ems_printDevices() {
it->product_id,
it->version);
}
}
myDebug_P(PSTR("")); // newline
if (have_unknowns) {
myDebug_P(
PSTR("You have a device is that is not yet known by EMS-ESP. Please report this as a GitHub issue so we can expand the EMS device library."));
myDebug_P(PSTR("One or more devices are not recognized by EMS-ESP. Please report this in GitHub."));
}
} else {
myDebug_P(PSTR("No were devices recognized. This may be because Tx is disabled or failing."));

View File

@@ -434,7 +434,8 @@ void ems_setWarmWaterActivated(bool activated);
void ems_setWarmWaterOnetime(bool activated);
void ems_setWarmTapWaterActivated(bool activated);
void ems_setPoll(bool b);
void ems_setLogging(_EMS_SYS_LOGGING loglevel, uint16_t type_id = 0);
void ems_setLogging(_EMS_SYS_LOGGING loglevel, uint16_t type_id);
void ems_setLogging(_EMS_SYS_LOGGING loglevel, bool quiet = false);
void ems_setWarmWaterModeComfort(uint8_t comfort);
void ems_setModels();
void ems_setTxDisabled(bool b);

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.5b16"
#define APP_VERSION "1.9.5b17"

View File

@@ -97,7 +97,7 @@ var custom_configfile = {
"listen_mode": false,
"shower_timer": true,
"shower_alert": false,
"publish_time": 0,
"publish_time": 10,
"tx_mode": 1
}
};