Add-on support (#977)
Moved climate settings to an add-on. Updated documentation.
This commit is contained in:
@@ -7,7 +7,9 @@
|
|||||||
|
|
||||||
## General
|
## General
|
||||||
|
|
||||||
- Thanks for 600 stars.
|
First of all, we wanna say a big thanks to all of you who starred this project in GitHub. It's amazing how the number of stars keeps growing and is now around 650!!!
|
||||||
|
|
||||||
|
After a long wait since the latest big release, which we used to leave our desks for a while and enjoy some vacations time with our beloved ones, we are proud to introduce the version 4.0, which adds new screens and makes your panel more flexible and robust.
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
@@ -34,23 +36,33 @@ Since in this update lots of input to the blueprint changed, we highly recommend
|
|||||||
|
|
||||||
|
|
||||||
## Overview of all changes
|
## Overview of all changes
|
||||||
1. Alarm control panel
|
1. Add-ons support
|
||||||
2. Support to sensor display precision from Home Assistant (#880)
|
- Embedded thermostat/heater (#917)
|
||||||
3. Filtered device list (#881)
|
2. Alarm control panel
|
||||||
4. New language selector (#882)
|
3. Support to sensor display precision from Home Assistant (#880)
|
||||||
5. Removed `settings_entity` (#887)
|
4. Filtered device list (#881)
|
||||||
6. Support for US model on landscape mode (#890)
|
5. New language selector (#882)
|
||||||
7. API status indication on the panel ([#5ff5d35](https://github.com/Blackymas/NSPanel_HA_Blueprint/commit/5ff5d35833be1a1cf9ca0f570662456058980024))
|
6. Removed `settings_entity` (#887)
|
||||||
8. Light & cover settings pages will show only the supported features (#896)
|
7. Support for US model on landscape mode (#890)
|
||||||
9. New "Fan speed page" (#897)
|
8. API status indication on the panel ([#5ff5d35](https://github.com/Blackymas/NSPanel_HA_Blueprint/commit/5ff5d35833be1a1cf9ca0f570662456058980024))
|
||||||
10. Select wake-up page (#898)
|
9. Light & cover settings pages will show only the supported features (#896)
|
||||||
11. Panel's local control
|
10. New "Fan speed page" (#897)
|
||||||
12. Embedded thermostat/heater (#917)
|
11. Select wake-up page (#898)
|
||||||
|
12. Panel's local control
|
||||||
|
|
||||||
|
|
||||||
## Details of all changes
|
## Details of all changes
|
||||||
|
|
||||||
### 1. Alarm control panel
|
### 1. Support to add-ons
|
||||||
|
We are trying to make your panel more usefull and more robust by changing some of the functionalitites to run internally in the panel, even when the Wi-Fi network or Home Assistant are not available, however, every new functionality takes a bit from the ESP embedded in your panel and increases the complexity, and having a code cabaple to adapt to all the different user cases will be very complex and certainly will exceed the available memory.
|
||||||
|
|
||||||
|
The first add-on available is an **[embedded thermostat/heater](/docs/us/addon_climate.md)**, able to control it locally even when your Wi-Fi is out or Home Assistant is unavailable.
|
||||||
|
|
||||||
|
Please refeer to the [documentation](/docs/us/addon_climate.md) to get more details on how to enable this add-on.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 2. Alarm control panel
|
||||||
recommend api-encryption: https://esphome.io/components/api.html#configuration-variables
|
recommend api-encryption: https://esphome.io/components/api.html#configuration-variables
|
||||||
and, of course warn the user that this is a possible security issue.
|
and, of course warn the user that this is a possible security issue.
|
||||||
Anyways - this is also done with many other projects, AND it would require that a possible hacker is already inside the internal (or mayby iot) (W)LAN - and at this point....
|
Anyways - this is also done with many other projects, AND it would require that a possible hacker is already inside the internal (or mayby iot) (W)LAN - and at this point....
|
||||||
@@ -60,37 +72,37 @@ recommend to have a big warning, and that the user has to take care about e.g.:
|
|||||||
- enable api-encryption
|
- enable api-encryption
|
||||||
|
|
||||||
|
|
||||||
### 2. Support to sensor display precision from Home Assistant
|
### 3. Support to sensor display precision from Home Assistant
|
||||||
Now the values shown in your panel will follow the [sensor display precision](https://www.home-assistant.io/blog/2023/03/01/release-20233/#sensor-display-precision) provided by Home Assistant.
|
Now the values shown in your panel will follow the [sensor display precision](https://www.home-assistant.io/blog/2023/03/01/release-20233/#sensor-display-precision) provided by Home Assistant.
|
||||||
|
|
||||||
=> If you have problems with a value exceeding the available space in your panel, please reduce the number of decimals using Home Assistant [sensor display precision](https://www.home-assistant.io/blog/2023/03/01/release-20233/#sensor-display-precision).
|
=> If you have problems with a value exceeding the available space in your panel, please reduce the number of decimals using Home Assistant [sensor display precision](https://www.home-assistant.io/blog/2023/03/01/release-20233/#sensor-display-precision).
|
||||||
|
|
||||||
|
|
||||||
### 3. Filtered device list
|
### 4. Filtered device list
|
||||||
When selecting the NSPanel on the automation, only ESP32 devices will be shown, making easier to find your panel.
|
When selecting the NSPanel on the automation, only ESP32 devices will be shown, making easier to find your panel.
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
### 4. New language selector
|
### 5. New language selector
|
||||||
Starts using the new language selector release with HA 2023.5.0 and based on RFC 5646, which will increase reliability and standardization of the code.
|
Starts using the new language selector release with HA 2023.5.0 and based on RFC 5646, which will increase reliability and standardization of the code.
|
||||||
Althougt this is not visible for users at the first view, it will enable the use of more granualar language selections (like pt-BR vs pt-PT or en-US vs en-UK) if needed in the future.
|
Althougt this is not visible for users at the first view, it will enable the use of more granualar language selections (like pt-BR vs pt-PT or en-US vs en-UK) if needed in the future.
|
||||||
|
|
||||||
=> If you are an existing users, please remember to select your language again after the update, as the previous selection will be invalid.
|
=> If you are an existing users, please remember to select your language again after the update, as the previous selection will be invalid.
|
||||||
|
|
||||||
|
|
||||||
### 5. Removed `settings_entity`
|
### 6. Removed `settings_entity`
|
||||||
The entity `sensor.xxxxx_settings_entity` was previously used by ESPHome to to transfer information about the selected entity on the settings page to the Blueprint, enabling the transfer of settings from different instances of the blueprint with the use of service `esphome.xxxxx_set_settings_entity`. This mechanism was a bit fragile and not user friendly.
|
The entity `sensor.xxxxx_settings_entity` was previously used by ESPHome to to transfer information about the selected entity on the settings page to the Blueprint, enabling the transfer of settings from different instances of the blueprint with the use of service `esphome.xxxxx_set_settings_entity`. This mechanism was a bit fragile and not user friendly.
|
||||||
With this version the information about the entity shown will be part of the `sensor.xxxxx_nspanel_event` and the settings pages will be called with the service `esphome.xxxxx_open_entity_settings_page`.
|
With this version the information about the entity shown will be part of the `sensor.xxxxx_nspanel_event` and the settings pages will be called with the service `esphome.xxxxx_open_entity_settings_page`.
|
||||||
Apart of a cleaner device page, this change should be transparent for most users. If you have made automations based on the removed elements, please update it using the new service.
|
Apart of a cleaner device page, this change should be transparent for most users. If you have made automations based on the removed elements, please update it using the new service.
|
||||||
|
|
||||||
|
|
||||||
### 6. Support for US model on landscape mode
|
### 7. Support for US model on landscape mode
|
||||||
If you are using a panel model US in landscape mode, you can now use `nspanel_us_land.tft` where the bars related to the hardware buttons will be located at the right, closer to the respective buttons and fixing the offset on the touch screen when using `nspanel_eu.tft` into a US panel.
|
If you are using a panel model US in landscape mode, you can now use `nspanel_us_land.tft` where the bars related to the hardware buttons will be located at the right, closer to the respective buttons and fixing the offset on the touch screen when using `nspanel_eu.tft` into a US panel.
|
||||||
|
|
||||||
=> The hardware buttons labels are hidden in this format, as Nextion cannot support rotated text.
|
=> The hardware buttons labels are hidden in this format, as Nextion cannot support rotated text.
|
||||||
|
|
||||||
|
|
||||||
### 7. API status indication on the panel
|
### 8. API status indication on the panel
|
||||||
Now the Wi-Fi icon in the panel (at the right side of the time) will show one of 3 possible states:
|
Now the Wi-Fi icon in the panel (at the right side of the time) will show one of 3 possible states:
|
||||||
|
|
||||||
 The panel is connected to the Wi-Fi and the API is connected to Home Assistant (mdi:wifi)
|
 The panel is connected to the Wi-Fi and the API is connected to Home Assistant (mdi:wifi)
|
||||||
@@ -100,16 +112,16 @@ Now the Wi-Fi icon in the panel (at the right side of the time) will show one of
|
|||||||
 The panel is **NOT** connected to the Wi-Fi (mdi:wifi-off)
|
 The panel is **NOT** connected to the Wi-Fi (mdi:wifi-off)
|
||||||
|
|
||||||
|
|
||||||
### 8. Light & cover settings pages will show only the supported features
|
### 9. Light & cover settings pages will show only the supported features
|
||||||
Now when long press a button conneted to a light or a cover, the detailed light settings page will open only when the entity supports advanced control, and the detailed page will only show the controls supported by that entity.
|
Now when long press a button conneted to a light or a cover, the detailed light settings page will open only when the entity supports advanced control, and the detailed page will only show the controls supported by that entity.
|
||||||
|
|
||||||
|
|
||||||
### 9. New "Fan speed page"
|
### 10. New "Fan speed page"
|
||||||
If you have a connected fan supporting speed control, now you are able to control it's speed from your panel. Just add the new fan to one of the buttons pages or to the hardware buttons and a long press on those buttons will pop up the new "Fan speed page":
|
If you have a connected fan supporting speed control, now you are able to control it's speed from your panel. Just add the new fan to one of the buttons pages or to the hardware buttons and a long press on those buttons will pop up the new "Fan speed page":
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
### 10. Select wake-up page
|
### 11. Select wake-up page
|
||||||
Now you can select the wake-up page on the blueprint settings:
|
Now you can select the wake-up page on the blueprint settings:
|
||||||
|
|
||||||

|

|
||||||
@@ -117,32 +129,13 @@ Now you can select the wake-up page on the blueprint settings:
|
|||||||
This selected page will be shown after a boot (after the boot page) and with a touch in the screen when on screen saver page. After showing this wake-up page, all the previous behavior for closing the page (with a click or after a timeout) will be the same.
|
This selected page will be shown after a boot (after the boot page) and with a touch in the screen when on screen saver page. After showing this wake-up page, all the previous behavior for closing the page (with a click or after a timeout) will be the same.
|
||||||
|
|
||||||
|
|
||||||
### 11. Panel's local control
|
### 12. Panel's local control
|
||||||
We are trying to make your panel as autonomous as possible by moving some of the controls from the Blueprint to ESPHome. This will reduce the load in your network and Home Assistant, but also will make a more reliable system capable to do it's core functionality even when the network is unavailable or Home Assistant is restarting.
|
We are trying to make your panel as autonomous as possible by moving some of the controls from the Blueprint to ESPHome. This will reduce the load in your network and Home Assistant, but also will make a more reliable system capable to do it's core functionality even when the network is unavailable or Home Assistant is restarting.
|
||||||
With this version, the following engines have been moved to your panel (local control):
|
With this version, the following engines have been moved to your panel (local control):
|
||||||
- Time display
|
- Time display
|
||||||
- Physical relay control (when hardware left button is connected to relay 1 or right button to relay 2)
|
- Physical relay control (when hardware left button is connected to relay 1 or right button to relay 2)
|
||||||
- Embedded thermostat (see bellow)
|
- Embedded thermostat (see bellow)
|
||||||
|
|
||||||
|
|
||||||
### 12. Embedded thermostat/heater
|
|
||||||
Now you can use your panel to control a heater and let your ambient more confortable, and you will be able to control it locally even when your Wi-Fi is out or Home Assistant is unavailable.
|
|
||||||
|
|
||||||
in order to have this enable, add the following to your substitutions:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
substitutions:
|
|
||||||
embedded_thermostat_disabled: "false"
|
|
||||||
embedded_thermostat_heater_relay: "1" # Select 1 for "Relay 1" or 2 for "Relay 2"
|
|
||||||
```
|
|
||||||
|
|
||||||
For more advanced settings, please take a look at the full documentation.
|
|
||||||
|
|
||||||
===>>> Add documentation before release <<<===
|
|
||||||
- How to enable
|
|
||||||
- Substitutions
|
|
||||||
- etc
|
|
||||||
|
|
||||||
|
|
||||||
## Next topics we are currently working on
|
## Next topics we are currently working on
|
||||||
See here: https://github.com/Blackymas/NSPanel_HA_Blueprint/labels/roadmap
|
See here: https://github.com/Blackymas/NSPanel_HA_Blueprint/labels/roadmap
|
||||||
|
|||||||
95
docs/en/addon_climate.md
Normal file
95
docs/en/addon_climate.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# Add-on: Climate
|
||||||
|
|
||||||
|
## Description
|
||||||
|
This add-on enables the use of your panel's relays to act as a thermostat (heater only for now) using the internal temperature sensor and independent of the network availability.
|
||||||
|
|
||||||
|
### Attention
|
||||||
|
The NSPanel is limited to 2A per relay. Don't use it for directly power your heater if exceeding the panel specifications:
|
||||||
|
- 150W/110V/Gang, 300W/110V/Total
|
||||||
|
- 300W/220V/Gang, 600W/220V/Total
|
||||||
|
More details on the [Sonoff NSPanel's page](https://sonoff.tech/product/central-control-panel/nspanel/) and the [product specifications document](https://sonoff.tech/wp-content/uploads/2021/11/%E4%BA%A7%E5%93%81%E5%8F%82%E6%95%B0%E8%A1%A8-NSPanel-20210831.pdf).
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
You will need to add the reference to the `addon_climate` file on your ESPHome settings in the `package` section and after te `remote_package` (base code), as shown bellow:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
substitutions:
|
||||||
|
###### CHANGE ME START ######
|
||||||
|
device_name: "YOUR_NSPANEL_NAME"
|
||||||
|
wifi_ssid: !secret wifi_ssid
|
||||||
|
wifi_password: !secret wifi_password
|
||||||
|
|
||||||
|
nextion_update_url: "http://homeassistant.local:8123/local/nspanel_eu.tft"
|
||||||
|
|
||||||
|
addon_climate_heater_relay: "1"
|
||||||
|
##### CHANGE ME END #####
|
||||||
|
|
||||||
|
|
||||||
|
packages:
|
||||||
|
remote_package:
|
||||||
|
url: https://github.com/Blackymas/NSPanel_HA_Blueprint
|
||||||
|
ref: main
|
||||||
|
files: [nspanel_esphome.yaml]
|
||||||
|
refresh: 300s
|
||||||
|
|
||||||
|
addon_climate:
|
||||||
|
url: https://github.com/Blackymas/NSPanel_HA_Blueprint
|
||||||
|
ref: main
|
||||||
|
files: [nspanel_esphome_addon_climate.yaml]
|
||||||
|
refresh: 300s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The following keys are available to be used in your `substitutions`:
|
||||||
|
|
||||||
|
|Key|Required|Supported values|Default|Description|
|
||||||
|
|:-|:-:|:-:|:-:|:-|
|
||||||
|
|addon_climate_heater_relay|Mandatory|`1` or `2`|`0` (disabled)|Relay used for conrol the heater. User `1` for "Relay 1" or `2` for "Relay 2".|
|
||||||
|
|addon_climate_temp_units|Optional|`°C` or `°F`|`°C`|Temperature unit.|
|
||||||
|
|addon_climate_min_heating_off_time|Optional|Positive integer representing the number of seconds|`300`|Minimum duration (in seconds) the heating action must be disengaged before it may be engaged.|
|
||||||
|
|addon_climate_min_heating_run_time|Optional|Positive integer representing the number of seconds|`300`|Minimum duration (in seconds) the heating action must be engaged before it may be disengaged.|
|
||||||
|
|addon_climate_min_idle_time|Optional|Positive integer representing the number of seconds|`30`|Minimum duration (in seconds) the idle action must be active before calling another climate action.|
|
||||||
|
|addon_climate_visual_min_temperature|Optional|Number representing a temperature in the selected unit|`5`|The minimum temperature the climate device can reach. Used to set the range of the frontend gauge.|
|
||||||
|
|addon_climate_visual_max_temperature|Optional|Number representing a temperature in the selected unit|`25`|The maximum temperature the climate device can reach. Used to set the range of the frontend gauge.|
|
||||||
|
|addon_climate_visual_temperature_step|Optional|Number representing a temperature in the selected unit|`0.5`|The granularity with which the target temperature can be controlled.|
|
||||||
|
|
||||||
|
- All values must be delimited with `""`
|
||||||
|
- For more details on the keys, please take a look at [ESPHome Base Climate Configurations](https://esphome.io/components/climate/index.html#base-climate-configuration) and [ESPHome Climate Thermostat - Additional actions behavior](https://esphome.io/components/climate/thermostat.html#additional-actions-behavior).
|
||||||
|
|
||||||
|
### Example:
|
||||||
|
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
substitutions:
|
||||||
|
###### CHANGE ME START ######
|
||||||
|
device_name: "YOUR_NSPANEL_NAME"
|
||||||
|
wifi_ssid: !secret wifi_ssid
|
||||||
|
wifi_password: !secret wifi_password
|
||||||
|
|
||||||
|
nextion_update_url: "http://homeassistant.local:8123/local/nspanel_us.tft"
|
||||||
|
|
||||||
|
addon_climate_heater_relay: "1" #Use relay 1
|
||||||
|
addon_climate_temp_units: "°F" #Temperatures in Fahrenheit
|
||||||
|
addon_climate_visual_min_temperature: "40" #Min supported temperature is 40F
|
||||||
|
addon_climate_visual_max_temperature: "80" #Max supported temperature is 80F
|
||||||
|
addon_climate_visual_temperature_step: "1" #Temperature granularity is 1F
|
||||||
|
|
||||||
|
##### CHANGE ME END #####
|
||||||
|
|
||||||
|
|
||||||
|
packages:
|
||||||
|
remote_package:
|
||||||
|
url: https://github.com/Blackymas/NSPanel_HA_Blueprint
|
||||||
|
ref: main
|
||||||
|
files: [nspanel_esphome.yaml]
|
||||||
|
refresh: 300s
|
||||||
|
|
||||||
|
addon_climate:
|
||||||
|
url: https://github.com/Blackymas/NSPanel_HA_Blueprint
|
||||||
|
ref: main
|
||||||
|
files: [nspanel_esphome_addon_climate.yaml]
|
||||||
|
refresh: 300s
|
||||||
|
```
|
||||||
|
|
||||||
@@ -28,20 +28,6 @@ substitutions:
|
|||||||
|
|
||||||
time_source: "homeassistant" # Either "homeassistant" or "sntp" are supported
|
time_source: "homeassistant" # Either "homeassistant" or "sntp" are supported
|
||||||
|
|
||||||
### Local thermostat defaults ###
|
|
||||||
# https://esphome.io/components/climate/thermostat.html
|
|
||||||
embedded_thermostat_disabled: "true"
|
|
||||||
embedded_thermostat_temp_units: "°C"
|
|
||||||
embedded_thermostat_heater_relay: "0" # Select 1 for "Relay 1", 2 for "Relay 2" or "0" to a dummy switch/disabled
|
|
||||||
embedded_thermostat_min_heating_off_time: "300"
|
|
||||||
embedded_thermostat_min_heating_run_time: "300"
|
|
||||||
embedded_thermostat_min_idle_time: "30"
|
|
||||||
# https://esphome.io/components/climate/index.html#base-climate-configuration
|
|
||||||
embedded_thermostat_visual_min_temperature: "5"
|
|
||||||
embedded_thermostat_visual_max_temperature: "25"
|
|
||||||
embedded_thermostat_visual_temperature_step: "0.5"
|
|
||||||
|
|
||||||
|
|
||||||
###### USE THIS ONLY FOR YOUR FIRST TFT UPLOAD
|
###### USE THIS ONLY FOR YOUR FIRST TFT UPLOAD
|
||||||
###### AND IF EXIT-REPARSE BUTTON FAILS
|
###### AND IF EXIT-REPARSE BUTTON FAILS
|
||||||
###### ONCE IT WORKED, REMOVE THESE LINES
|
###### ONCE IT WORKED, REMOVE THESE LINES
|
||||||
@@ -62,7 +48,8 @@ substitutions:
|
|||||||
##### WIFI SETUP #####
|
##### WIFI SETUP #####
|
||||||
wifi:
|
wifi:
|
||||||
networks:
|
networks:
|
||||||
- ssid: ${wifi_ssid}
|
- id: wifi_default
|
||||||
|
ssid: ${wifi_ssid}
|
||||||
password: ${wifi_password}
|
password: ${wifi_password}
|
||||||
hidden: ${wifi_hidden}
|
hidden: ${wifi_hidden}
|
||||||
power_save_mode: none
|
power_save_mode: none
|
||||||
@@ -523,7 +510,7 @@ api:
|
|||||||
ESP_LOGD("global_settings", "date_color: %i", date_color);
|
ESP_LOGD("global_settings", "date_color: %i", date_color);
|
||||||
ESP_LOGD("global_settings", "time_format: %s", time_format.c_str());
|
ESP_LOGD("global_settings", "time_format: %s", time_format.c_str());
|
||||||
ESP_LOGD("global_settings", "time_color: %i", time_color);
|
ESP_LOGD("global_settings", "time_color: %i", time_color);
|
||||||
ESP_LOGD("global_settings", "embedded_climate: %i", (embedded_climate and not (${embedded_thermostat_disabled})) ? 1 : 0);
|
ESP_LOGD("global_settings", "embedded_climate: %i", (embedded_climate) ? 1 : 0);
|
||||||
ESP_LOGD("global_settings", "wakeup_page: %i", wakeup_page);
|
ESP_LOGD("global_settings", "wakeup_page: %i", wakeup_page);
|
||||||
ESP_LOGD("global_settings", "alarm_state: %s", alarm_state.c_str());
|
ESP_LOGD("global_settings", "alarm_state: %s", alarm_state.c_str());
|
||||||
}
|
}
|
||||||
@@ -546,7 +533,10 @@ api:
|
|||||||
id(home_time_color) = time_color;
|
id(home_time_color) = time_color;
|
||||||
|
|
||||||
## Embedded thermostat
|
## Embedded thermostat
|
||||||
- lambda: id(is_embedded_thermostat) = (embedded_climate and not (${embedded_thermostat_disabled}));
|
- script.execute:
|
||||||
|
id: addon_climate_global_settings
|
||||||
|
embedded_climate: !lambda return embedded_climate;
|
||||||
|
#- lambda: id(is_embedded_thermostat) = embedded_climate;
|
||||||
|
|
||||||
## Alarm button
|
## Alarm button
|
||||||
- lambda: id(home_alarm) = (alarm_state != "" and not alarm_state.empty());
|
- lambda: id(home_alarm) = (alarm_state != "" and not alarm_state.empty());
|
||||||
@@ -632,17 +622,6 @@ globals:
|
|||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: '65535'
|
initial_value: '65535'
|
||||||
|
|
||||||
##### Is embedded thermostat set as main climate entity? #####
|
|
||||||
- id: is_embedded_thermostat
|
|
||||||
type: bool
|
|
||||||
restore_value: true
|
|
||||||
initial_value: 'false'
|
|
||||||
##### Is embedded thermostat visible on climate page? #####
|
|
||||||
- id: is_embedded_thermostat_visible
|
|
||||||
type: bool
|
|
||||||
restore_value: false
|
|
||||||
initial_value: 'false'
|
|
||||||
|
|
||||||
##### Relay icons #####
|
##### Relay icons #####
|
||||||
- id: home_relay1_icon
|
- id: home_relay1_icon
|
||||||
type: std::string
|
type: std::string
|
||||||
@@ -861,8 +840,8 @@ text_sensor:
|
|||||||
disabled_by_default: true
|
disabled_by_default: true
|
||||||
|
|
||||||
##### ESPhome version used to compile the app #####
|
##### ESPhome version used to compile the app #####
|
||||||
- platform: version
|
- name: ${device_name} ESPhome Version
|
||||||
name: ${device_name} ESPhome Version
|
platform: version
|
||||||
disabled_by_default: true
|
disabled_by_default: true
|
||||||
|
|
||||||
- platform: wifi_info
|
- platform: wifi_info
|
||||||
@@ -928,7 +907,7 @@ text_sensor:
|
|||||||
id(disp1).set_component_text_printf("climate.button05_icon", "%s", "\uE58D"); //mdi:water-percent
|
id(disp1).set_component_text_printf("climate.button05_icon", "%s", "\uE58D"); //mdi:water-percent
|
||||||
id(disp1).set_component_text_printf("climate.button06_icon", "%s", "\uE20F"); //mdi:fan
|
id(disp1).set_component_text_printf("climate.button06_icon", "%s", "\uE20F"); //mdi:fan
|
||||||
id(disp1).set_component_text_printf("climate.button07_icon", "%s", "\uE424"); //mdi:power
|
id(disp1).set_component_text_printf("climate.button07_icon", "%s", "\uE424"); //mdi:power
|
||||||
if (id(is_embedded_thermostat_visible)) id(update_page_climate);
|
id(addon_climate_update_page_climate);
|
||||||
}
|
}
|
||||||
else if (page=="fan")
|
else if (page=="fan")
|
||||||
{
|
{
|
||||||
@@ -972,40 +951,10 @@ text_sensor:
|
|||||||
ESP_LOGD("text_sensor.localevent", "entity=%s", entity.c_str());
|
ESP_LOGD("text_sensor.localevent", "entity=%s", entity.c_str());
|
||||||
ESP_LOGD("text_sensor.localevent", "embedded=%i", embedded);
|
ESP_LOGD("text_sensor.localevent", "embedded=%i", embedded);
|
||||||
}
|
}
|
||||||
id(is_embedded_thermostat_visible) = (domain == "climate" and embedded == 1);
|
if (domain == "climate") id(service_call_climate)->execute(entity.c_str(), key.c_str(), value.c_str(), (embedded==1));
|
||||||
if (id(is_embedded_thermostat_visible))
|
else if (domain == "alarm_control_panel") id(service_call_alarm_control_panel)->execute(entity.c_str(), value.c_str());
|
||||||
{
|
|
||||||
if (${verbose_log}) ESP_LOGD("text_sensor.localevent", "Embedded thermostat is visible");
|
|
||||||
auto call = id(thermostat_embedded).make_call();
|
|
||||||
if (key == "set_temperature")
|
|
||||||
{
|
|
||||||
if (${verbose_log}) ESP_LOGD("text_sensor.localevent", "set_temperature=%f", stof(value) / 10);
|
|
||||||
call.set_target_temperature(stof(value) / 10);
|
|
||||||
}
|
|
||||||
else if (key == "hvac_mode")
|
|
||||||
{
|
|
||||||
if (${verbose_log}) ESP_LOGD("text_sensor.localevent", "set_mode=%s", value);
|
|
||||||
call.set_mode(value);
|
|
||||||
}
|
|
||||||
call.perform();
|
|
||||||
}
|
|
||||||
else if (entity != "" and not entity.empty() and entity != "embedded_climate")
|
else if (entity != "" and not entity.empty() and entity != "embedded_climate")
|
||||||
{
|
{
|
||||||
if (domain == "alarm_control_panel")
|
|
||||||
{
|
|
||||||
if (${verbose_log}) ESP_LOGD("text_sensor.localevent", "ESPHome remote service call - Alarm control panel");
|
|
||||||
HomeassistantServiceResponse resp;
|
|
||||||
HomeassistantServiceMap resp_kv;
|
|
||||||
resp.service = "alarm_control_panel.XXXX"; // DEBUG
|
|
||||||
resp_kv.key = "entity_id";
|
|
||||||
resp_kv.value = entity;
|
|
||||||
resp.data.push_back(resp_kv);
|
|
||||||
resp_kv.key = "pin"; // DEBUG
|
|
||||||
resp_kv.value = value;
|
|
||||||
resp.data.push_back(resp_kv);
|
|
||||||
id(api_server).send_homeassistant_service_call(resp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (${verbose_log}) ESP_LOGD("text_sensor.localevent", "Blueprint controlled service");
|
if (${verbose_log}) ESP_LOGD("text_sensor.localevent", "Blueprint controlled service");
|
||||||
auto ha_event = new esphome::api::CustomAPIDevice();
|
auto ha_event = new esphome::api::CustomAPIDevice();
|
||||||
@@ -1138,13 +1087,6 @@ switch:
|
|||||||
then:
|
then:
|
||||||
- script.execute:
|
- script.execute:
|
||||||
id: refresh_relays
|
id: refresh_relays
|
||||||
##### PHYSICAL SWITCH 0 (Dummy) - Usend when embedded climate is disabled #####
|
|
||||||
- name: ${device_name} Relay 0 (dummy)
|
|
||||||
platform: template
|
|
||||||
id: relay_0
|
|
||||||
lambda: !lambda return false;
|
|
||||||
internal: true
|
|
||||||
optimistic: true
|
|
||||||
|
|
||||||
##### DISPLAY ALWAYS ON #####
|
##### DISPLAY ALWAYS ON #####
|
||||||
- name: ${device_name} Screen Power
|
- name: ${device_name} Screen Power
|
||||||
@@ -1380,7 +1322,7 @@ script:
|
|||||||
ESP_LOGD("script.set_climate", "target_icon=%s", climate_icon.c_str());
|
ESP_LOGD("script.set_climate", "target_icon=%s", climate_icon.c_str());
|
||||||
ESP_LOGD("script.set_climate", "embedded=%i", (embedded_climate) ? 1 : 0);
|
ESP_LOGD("script.set_climate", "embedded=%i", (embedded_climate) ? 1 : 0);
|
||||||
}
|
}
|
||||||
id(is_embedded_thermostat_visible) = embedded_climate;
|
id(addon_climate_set_climate).execute(embedded_climate);
|
||||||
id(disp1).send_command_printf("climateslider.maxval=%i", total_steps);
|
id(disp1).send_command_printf("climateslider.maxval=%i", total_steps);
|
||||||
id(disp1).set_component_value("temp_offset", temp_offset);
|
id(disp1).set_component_value("temp_offset", temp_offset);
|
||||||
id(disp1).set_component_value("temp_step", temp_step);
|
id(disp1).set_component_value("temp_step", temp_step);
|
||||||
@@ -1483,74 +1425,6 @@ script:
|
|||||||
if (id(relay_1).state and (id(relay1_local).state or (id(relay1_fallback).state and not id(api_status).state))) id(disp1).send_command_printf("home.left_bt_pic.pic=%i", (id(relay_1).state) ? 78 : 77);
|
if (id(relay_1).state and (id(relay1_local).state or (id(relay1_fallback).state and not id(api_status).state))) id(disp1).send_command_printf("home.left_bt_pic.pic=%i", (id(relay_1).state) ? 78 : 77);
|
||||||
if (id(relay_2).state and (id(relay2_local).state or (id(relay2_fallback).state and not id(api_status).state))) id(disp1).send_command_printf("home.right_bt_pic.pic=%i", (id(relay_2).state) ? 78 : 77);
|
if (id(relay_2).state and (id(relay2_local).state or (id(relay2_fallback).state and not id(api_status).state))) id(disp1).send_command_printf("home.right_bt_pic.pic=%i", (id(relay_2).state) ? 78 : 77);
|
||||||
|
|
||||||
- id: refresh_chips_climate
|
|
||||||
mode: restart
|
|
||||||
then:
|
|
||||||
- if:
|
|
||||||
condition:
|
|
||||||
- binary_sensor.is_on: nextion_init
|
|
||||||
- lambda: !lambda 'return (not ${embedded_thermostat_disabled});'
|
|
||||||
- lambda: !lambda 'return id(is_embedded_thermostat);'
|
|
||||||
then:
|
|
||||||
- lambda: |-
|
|
||||||
if (${verbose_log}) ESP_LOGD("script.refresh_chips_climate", "thermostat_embedded.action=%i", int(id(thermostat_embedded).action));
|
|
||||||
switch (int(id(thermostat_embedded).action)) // CLIMATE_ACTION_OFF = 0, CLIMATE_ACTION_COOLING = 2, CLIMATE_ACTION_HEATING = 3, CLIMATE_ACTION_IDLE = 4, CLIMATE_ACTION_DRYING = 5, CLIMATE_ACTION_FAN = 6
|
|
||||||
{
|
|
||||||
case 0: //CLIMATE_ACTION_OFF
|
|
||||||
if (${verbose_log}) ESP_LOGD("script.refresh_chips_climate", "thermostat_embedded.mode=%i", int(id(thermostat_embedded).mode));
|
|
||||||
switch (int(id(thermostat_embedded).mode)) // CLIMATE_MODE_OFF = 0, CLIMATE_MODE_HEAT_COOL = 1, CLIMATE_MODE_COOL = 2, CLIMATE_MODE_HEAT = 3, CLIMATE_MODE_FAN_ONLY = 4, CLIMATE_MODE_DRY = 5, CLIMATE_MODE_AUTO = 6
|
|
||||||
{
|
|
||||||
case 0: //CLIMATE_MODE_OFF
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uFFFF"); // (E424) Don't show icon when off
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
|
||||||
break;
|
|
||||||
case 1: //CLIMATE_MODE_HEAT_COOL
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE069");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
|
||||||
break;
|
|
||||||
case 2: //CLIMATE_MODE_COOL
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE716");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
|
||||||
break;
|
|
||||||
case 3: //CLIMATE_MODE_HEAT
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE237");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 64164);
|
|
||||||
break;
|
|
||||||
case 4: //CLIMATE_MODE_FAN_ONLY
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE20F");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
|
||||||
break;
|
|
||||||
case 5: //CLIMATE_MODE_DRY
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE58D");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
|
||||||
break;
|
|
||||||
case 6: //CLIMATE_MODE_AUTO
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uEE8D");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: //CLIMATE_ACTION_COOLING
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE716");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 1055);
|
|
||||||
break;
|
|
||||||
case 3: //CLIMATE_ACTION_HEATING
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE237");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 64164);
|
|
||||||
break;
|
|
||||||
case 4: //CLIMATE_ACTION_IDLE
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE50E"); // mdi:thermometer
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
|
||||||
break;
|
|
||||||
case 5: //CLIMATE_ACTION_DRYING
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE58D");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 64704);
|
|
||||||
break;
|
|
||||||
case 6: //CLIMATE_ACTION_FAN
|
|
||||||
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE20F");
|
|
||||||
id(disp1).set_component_font_color("home.icon_top_03", 1530);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- id: refresh_wifi_icon
|
- id: refresh_wifi_icon
|
||||||
mode: restart
|
mode: restart
|
||||||
then:
|
then:
|
||||||
@@ -1591,8 +1465,6 @@ script:
|
|||||||
id: refresh_relays
|
id: refresh_relays
|
||||||
- script.execute:
|
- script.execute:
|
||||||
id: refresh_wifi_icon
|
id: refresh_wifi_icon
|
||||||
- script.execute:
|
|
||||||
id: refresh_chips_climate
|
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
- binary_sensor.is_on: nextion_init
|
- binary_sensor.is_on: nextion_init
|
||||||
@@ -1600,10 +1472,9 @@ script:
|
|||||||
id: current_page
|
id: current_page
|
||||||
state: 'home'
|
state: 'home'
|
||||||
then:
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: addon_climate_update_page_home
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
// Update home.entity variable
|
|
||||||
if (id(is_embedded_thermostat) and not (${embedded_thermostat_disabled})) id(disp1).set_component_text_printf("home.entity", "embedded_climate");
|
|
||||||
else id(disp1).set_component_text_printf("home.entity", "");
|
|
||||||
// Show alarm button
|
// Show alarm button
|
||||||
if (id(home_alarm))
|
if (id(home_alarm))
|
||||||
{
|
{
|
||||||
@@ -1617,147 +1488,88 @@ script:
|
|||||||
id(disp1).hide_component("button07_icon");
|
id(disp1).hide_component("button07_icon");
|
||||||
}
|
}
|
||||||
|
|
||||||
- id: update_page_climate
|
- id: service_call_alarm_control_panel
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
entity: string
|
||||||
|
pin: string
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
if (${verbose_log}) ESP_LOGD("service_call_alarm_control_panel", "ESPHome remote service call");
|
||||||
|
HomeassistantServiceResponse resp;
|
||||||
|
HomeassistantServiceMap resp_kv;
|
||||||
|
resp.service = "alarm_control_panel.XXXX"; // DEBUG
|
||||||
|
resp_kv.key = "entity_id";
|
||||||
|
resp_kv.value = entity.c_str();
|
||||||
|
resp.data.push_back(resp_kv);
|
||||||
|
resp_kv.key = "pin"; // DEBUG
|
||||||
|
resp_kv.value = pin.c_str();
|
||||||
|
resp.data.push_back(resp_kv);
|
||||||
|
id(api_server).send_homeassistant_service_call(resp);
|
||||||
|
|
||||||
|
- id: service_call_climate
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
entity: string
|
||||||
|
key: string
|
||||||
|
value: string
|
||||||
|
embedded: bool
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
if (embedded)
|
||||||
|
id(addon_climate_service_call)->execute(key.c_str(), value.c_str());
|
||||||
|
else if (key == "set_temperature")
|
||||||
|
id(ha_call_service)->execute("climate.set_temperature", "temperature", to_string(stof(value) / 10), entity.c_str());
|
||||||
|
else if (key == "hvac_mode")
|
||||||
|
id(ha_call_service)->execute("climate.set_hvac_mode", key.c_str(), value.c_str(), entity.c_str());
|
||||||
|
|
||||||
|
- id: ha_call_service
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
service: string
|
||||||
|
key: string
|
||||||
|
value: string
|
||||||
|
entity: string
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
if (service != "" and not service.empty())
|
||||||
|
{
|
||||||
|
auto ha_event = new esphome::api::CustomAPIDevice();
|
||||||
|
ha_event->fire_homeassistant_event("esphome.nspanel_service_call",
|
||||||
|
{
|
||||||
|
{"service", service},
|
||||||
|
{"entity", entity},
|
||||||
|
{"key", key},
|
||||||
|
{"value", value}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
##### ADD-ONS ############################################################
|
||||||
|
##### Add-on - Climate #####
|
||||||
|
- id: addon_climate_service_call
|
||||||
|
mode: restart
|
||||||
|
parameters:
|
||||||
|
key: string
|
||||||
|
value: string
|
||||||
|
then:
|
||||||
|
# Reserved for Add-on Climate
|
||||||
|
- id: addon_climate_update_page_home
|
||||||
mode: restart
|
mode: restart
|
||||||
then:
|
then:
|
||||||
- if:
|
# Reserved for Add-on Climate
|
||||||
condition:
|
- id: addon_climate_set_climate
|
||||||
- binary_sensor.is_on: nextion_init
|
mode: restart
|
||||||
- text_sensor.state: # Is climate page visible?
|
parameters:
|
||||||
id: current_page
|
embedded_climate: bool
|
||||||
state: 'climate'
|
then:
|
||||||
- lambda: !lambda return id(is_embedded_thermostat_visible);
|
# Reserved for Add-on Climate
|
||||||
- lambda: !lambda 'return (not ${embedded_thermostat_disabled});'
|
- id: addon_climate_global_settings
|
||||||
then: # Embedded thermostat is visible
|
mode: restart
|
||||||
# Update slider, current temperature & target temperature
|
parameters:
|
||||||
- script.execute:
|
embedded_climate: bool
|
||||||
id: set_climate
|
then:
|
||||||
current_temp: !lambda "return id(thermostat_embedded).current_temperature;"
|
# Reserved for Add-on Climate
|
||||||
target_temp: !lambda "return id(thermostat_embedded).target_temperature;"
|
- id: addon_climate_update_page_climate
|
||||||
temp_step: !lambda "return int(round(${embedded_thermostat_visual_temperature_step}*10));"
|
mode: restart
|
||||||
total_steps: !lambda |-
|
then:
|
||||||
float temp_step = ${embedded_thermostat_visual_temperature_step};
|
# Reserved for Add-on Climate
|
||||||
float temp_offset = ${embedded_thermostat_visual_min_temperature};
|
|
||||||
float temp_max = ${embedded_thermostat_visual_max_temperature};
|
|
||||||
float total_steps = (temp_max-temp_offset)/temp_step;
|
|
||||||
return int(round(total_steps));
|
|
||||||
slider_val: !lambda |-
|
|
||||||
float temp_step = ${embedded_thermostat_visual_temperature_step};
|
|
||||||
float temp_offset = ${embedded_thermostat_visual_min_temperature};
|
|
||||||
return int(round((10*id(thermostat_embedded).target_temperature-temp_offset)/temp_step));
|
|
||||||
temp_offset: !lambda "return int(round(${embedded_thermostat_visual_min_temperature}*10));"
|
|
||||||
climate_icon: ""
|
|
||||||
embedded_climate: True
|
|
||||||
|
|
||||||
# Update target temp icon
|
|
||||||
- lambda: |-
|
|
||||||
if (${verbose_log}) ESP_LOGD("script.update_page_climate", "thermostat_embedded.action=%i", int(id(thermostat_embedded).action));
|
|
||||||
switch (int(id(thermostat_embedded).action)) // CLIMATE_ACTION_OFF = 0, CLIMATE_ACTION_COOLING = 2, CLIMATE_ACTION_HEATING = 3, CLIMATE_ACTION_IDLE = 4, CLIMATE_ACTION_DRYING = 5, CLIMATE_ACTION_FAN = 6
|
|
||||||
{
|
|
||||||
case 0: //CLIMATE_ACTION_OFF
|
|
||||||
if (${verbose_log}) ESP_LOGD("script.update_page_climate", "thermostat_embedded.mode=%i", int(id(thermostat_embedded).mode));
|
|
||||||
switch (int(id(thermostat_embedded).mode)) // CLIMATE_MODE_OFF = 0, CLIMATE_MODE_HEAT_COOL = 1, CLIMATE_MODE_COOL = 2, CLIMATE_MODE_HEAT = 3, CLIMATE_MODE_FAN_ONLY = 4, CLIMATE_MODE_DRY = 5, CLIMATE_MODE_AUTO = 6
|
|
||||||
{
|
|
||||||
case 0: //CLIMATE_MODE_OFF
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uFFFF"); // (E424) Don't show icon when off
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
|
||||||
break;
|
|
||||||
case 1: //CLIMATE_MODE_HEAT_COOL
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE069");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
|
||||||
break;
|
|
||||||
case 2: //CLIMATE_MODE_COOL
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE716");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 1055);
|
|
||||||
break;
|
|
||||||
case 3: //CLIMATE_MODE_HEAT
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE237");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 64164);
|
|
||||||
break;
|
|
||||||
case 4: //CLIMATE_MODE_FAN_ONLY
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE20F");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
|
||||||
break;
|
|
||||||
case 5: //CLIMATE_MODE_DRY
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE58D");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 64704);
|
|
||||||
break;
|
|
||||||
case 6: //CLIMATE_MODE_AUTO
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uEE8D");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: //CLIMATE_ACTION_COOLING
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE716");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 1055);
|
|
||||||
break;
|
|
||||||
case 3: //CLIMATE_ACTION_HEATING
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE237");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 64164);
|
|
||||||
break;
|
|
||||||
case 4: //CLIMATE_ACTION_IDLE
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE50E"); // mdi:thermometer
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
|
||||||
break;
|
|
||||||
case 5: //CLIMATE_ACTION_DRYING
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE58D");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 64704);
|
|
||||||
break;
|
|
||||||
case 6: //CLIMATE_ACTION_FAN
|
|
||||||
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE20F");
|
|
||||||
id(disp1).set_component_font_color("climate.target_icon", 1530);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update buttons bar
|
|
||||||
- lambda: |-
|
|
||||||
if (${verbose_log}) ESP_LOGD("script.update_page_climate", "Updating buttons bar");
|
|
||||||
// Hide not supported hotspots
|
|
||||||
id(disp1).hide_component("climate.button01");
|
|
||||||
id(disp1).hide_component("climate.button02");
|
|
||||||
id(disp1).show_component("climate.button03"); //Heat
|
|
||||||
id(disp1).hide_component("climate.button04");
|
|
||||||
id(disp1).hide_component("climate.button05");
|
|
||||||
id(disp1).hide_component("climate.button06");
|
|
||||||
id(disp1).show_component("climate.button07"); //Off
|
|
||||||
// Set buttons colors
|
|
||||||
id(disp1).set_component_font_color("climate.button01_icon", 10597);
|
|
||||||
id(disp1).set_component_font_color("climate.button02_icon", 10597);
|
|
||||||
id(disp1).set_component_font_color("climate.button03_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_HEAT) ? 64164 : 48631);
|
|
||||||
id(disp1).set_component_font_color("climate.button04_icon", 10597);
|
|
||||||
id(disp1).set_component_font_color("climate.button05_icon", 10597);
|
|
||||||
id(disp1).set_component_font_color("climate.button06_icon", 10597);
|
|
||||||
id(disp1).set_component_font_color("climate.button07_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_OFF) ? 35921 : 48631);
|
|
||||||
|
|
||||||
climate:
|
|
||||||
- platform: thermostat
|
|
||||||
name: ${device_name} Thermostat
|
|
||||||
id: thermostat_embedded
|
|
||||||
sensor: temp_nspanel
|
|
||||||
min_heating_off_time: ${embedded_thermostat_min_heating_off_time}s
|
|
||||||
min_heating_run_time: ${embedded_thermostat_min_heating_run_time}s
|
|
||||||
min_idle_time: ${embedded_thermostat_min_idle_time}s
|
|
||||||
visual:
|
|
||||||
min_temperature: ${embedded_thermostat_visual_min_temperature} ${embedded_thermostat_temp_units}
|
|
||||||
max_temperature: ${embedded_thermostat_visual_max_temperature} ${embedded_thermostat_temp_units}
|
|
||||||
temperature_step: ${embedded_thermostat_visual_temperature_step} ${embedded_thermostat_temp_units}
|
|
||||||
# target_temperature: 0.5 #!lambda "return ${embedded_thermostat_visual_target_temperature_step};"
|
|
||||||
# current_temperature: 0.1 #!lambda "return ${embedded_thermostat_visual_current_temperature_step};"
|
|
||||||
heat_action:
|
|
||||||
- switch.turn_on: relay_${embedded_thermostat_heater_relay}
|
|
||||||
idle_action:
|
|
||||||
- switch.turn_off: relay_${embedded_thermostat_heater_relay}
|
|
||||||
default_preset: "Off"
|
|
||||||
on_boot_restore_from: memory
|
|
||||||
preset:
|
|
||||||
- name: "Off"
|
|
||||||
default_target_temperature_low: ${embedded_thermostat_visual_min_temperature} ${embedded_thermostat_temp_units}
|
|
||||||
mode: "off"
|
|
||||||
- name: Home
|
|
||||||
default_target_temperature_low: 21 ${embedded_thermostat_temp_units}
|
|
||||||
internal: ${embedded_thermostat_disabled}
|
|
||||||
on_state:
|
|
||||||
- logger.log: Climate state changed - Start
|
|
||||||
- script.execute:
|
|
||||||
id: update_page_climate
|
|
||||||
- logger.log: Climate state changed - End
|
|
||||||
|
|||||||
286
nspanel_esphome_addon_climate.yaml
Normal file
286
nspanel_esphome_addon_climate.yaml
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
####################################################################################################
|
||||||
|
##### NSPanel ESPHome Add-on for Climate control #####
|
||||||
|
##### Add-on for https://github.com/Blackymas/NSPanel_HA_Blueprint #####
|
||||||
|
####################################################################################################
|
||||||
|
|
||||||
|
substitutions:
|
||||||
|
### Local thermostat defaults ###
|
||||||
|
# https://esphome.io/components/climate/thermostat.html
|
||||||
|
addon_climate_temp_units: "°C"
|
||||||
|
addon_climate_heater_relay: "0" # Select 1 for "Relay 1", 2 for "Relay 2" or "0" to a dummy switch/disabled
|
||||||
|
addon_climate_min_heating_off_time: "300"
|
||||||
|
addon_climate_min_heating_run_time: "300"
|
||||||
|
addon_climate_min_idle_time: "30"
|
||||||
|
# https://esphome.io/components/climate/index.html#base-climate-configuration
|
||||||
|
addon_climate_visual_min_temperature: "5"
|
||||||
|
addon_climate_visual_max_temperature: "25"
|
||||||
|
addon_climate_visual_temperature_step: "0.5"
|
||||||
|
|
||||||
|
climate:
|
||||||
|
- platform: thermostat
|
||||||
|
name: ${device_name} Thermostat
|
||||||
|
id: thermostat_embedded
|
||||||
|
sensor: temp_nspanel
|
||||||
|
min_heating_off_time: ${addon_climate_min_heating_off_time}s
|
||||||
|
min_heating_run_time: ${addon_climate_min_heating_run_time}s
|
||||||
|
min_idle_time: ${addon_climate_min_idle_time}s
|
||||||
|
visual:
|
||||||
|
min_temperature: ${addon_climate_visual_min_temperature} ${addon_climate_temp_units}
|
||||||
|
max_temperature: ${addon_climate_visual_max_temperature} ${addon_climate_temp_units}
|
||||||
|
temperature_step: ${addon_climate_visual_temperature_step} ${addon_climate_temp_units}
|
||||||
|
# target_temperature: 0.5 #!lambda "return ${addon_climate_visual_target_temperature_step};"
|
||||||
|
# current_temperature: 0.1 #!lambda "return ${addon_climate_visual_current_temperature_step};"
|
||||||
|
heat_action:
|
||||||
|
- switch.turn_on: relay_${addon_climate_heater_relay}
|
||||||
|
idle_action:
|
||||||
|
- switch.turn_off: relay_${addon_climate_heater_relay}
|
||||||
|
default_preset: "Off"
|
||||||
|
on_boot_restore_from: memory
|
||||||
|
preset:
|
||||||
|
- name: "Off"
|
||||||
|
default_target_temperature_low: ${addon_climate_visual_min_temperature} ${addon_climate_temp_units}
|
||||||
|
mode: "off"
|
||||||
|
- name: Home
|
||||||
|
default_target_temperature_low: 21 ${addon_climate_temp_units}
|
||||||
|
internal: false
|
||||||
|
on_state:
|
||||||
|
- logger.log: Climate state changed - Start
|
||||||
|
- script.execute:
|
||||||
|
id: addon_climate_update_page_climate
|
||||||
|
- logger.log: Climate state changed - End
|
||||||
|
|
||||||
|
globals:
|
||||||
|
##### Is embedded thermostat set as main climate entity? #####
|
||||||
|
- id: is_embedded_thermostat
|
||||||
|
type: bool
|
||||||
|
restore_value: true
|
||||||
|
initial_value: 'false'
|
||||||
|
##### Is embedded thermostat visible on climate page? #####
|
||||||
|
- id: is_addon_climate_visible
|
||||||
|
type: bool
|
||||||
|
restore_value: false
|
||||||
|
initial_value: 'false'
|
||||||
|
|
||||||
|
script:
|
||||||
|
- id: !extend addon_climate_update_page_home
|
||||||
|
mode: restart
|
||||||
|
then:
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
- binary_sensor.is_on: nextion_init
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
// Update home.entity variable
|
||||||
|
id(disp1).set_component_text_printf("home.entity", (id(is_embedded_thermostat)) ? "embedded_climate" : "");
|
||||||
|
//if (id(is_embedded_thermostat)) id(disp1).set_component_text_printf("home.entity", "embedded_climate");
|
||||||
|
//else id(disp1).set_component_text_printf("home.entity", "");
|
||||||
|
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
- lambda: !lambda 'return id(is_embedded_thermostat);'
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
// Update chips
|
||||||
|
if (${verbose_log}) ESP_LOGD("script.refresh_chips_climate", "thermostat_embedded.action=%i", int(id(thermostat_embedded).action));
|
||||||
|
switch (int(id(thermostat_embedded).action)) // CLIMATE_ACTION_OFF = 0, CLIMATE_ACTION_COOLING = 2, CLIMATE_ACTION_HEATING = 3, CLIMATE_ACTION_IDLE = 4, CLIMATE_ACTION_DRYING = 5, CLIMATE_ACTION_FAN = 6
|
||||||
|
{
|
||||||
|
case 0: //CLIMATE_ACTION_OFF
|
||||||
|
if (${verbose_log}) ESP_LOGD("script.refresh_chips_climate", "thermostat_embedded.mode=%i", int(id(thermostat_embedded).mode));
|
||||||
|
switch (int(id(thermostat_embedded).mode)) // CLIMATE_MODE_OFF = 0, CLIMATE_MODE_HEAT_COOL = 1, CLIMATE_MODE_COOL = 2, CLIMATE_MODE_HEAT = 3, CLIMATE_MODE_FAN_ONLY = 4, CLIMATE_MODE_DRY = 5, CLIMATE_MODE_AUTO = 6
|
||||||
|
{
|
||||||
|
case 0: //CLIMATE_MODE_OFF
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uFFFF"); // (E424) Don't show icon when off
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
||||||
|
break;
|
||||||
|
case 1: //CLIMATE_MODE_HEAT_COOL
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE069");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
||||||
|
break;
|
||||||
|
case 2: //CLIMATE_MODE_COOL
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE716");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
||||||
|
break;
|
||||||
|
case 3: //CLIMATE_MODE_HEAT
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE237");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 64164);
|
||||||
|
break;
|
||||||
|
case 4: //CLIMATE_MODE_FAN_ONLY
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE20F");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
||||||
|
break;
|
||||||
|
case 5: //CLIMATE_MODE_DRY
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE58D");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
||||||
|
break;
|
||||||
|
case 6: //CLIMATE_MODE_AUTO
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uEE8D");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: //CLIMATE_ACTION_COOLING
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE716");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 1055);
|
||||||
|
break;
|
||||||
|
case 3: //CLIMATE_ACTION_HEATING
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE237");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 64164);
|
||||||
|
break;
|
||||||
|
case 4: //CLIMATE_ACTION_IDLE
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE50E"); // mdi:thermometer
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 35921);
|
||||||
|
break;
|
||||||
|
case 5: //CLIMATE_ACTION_DRYING
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE58D");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 64704);
|
||||||
|
break;
|
||||||
|
case 6: //CLIMATE_ACTION_FAN
|
||||||
|
id(disp1).set_component_text_printf("home.icon_top_03", "%s", "\uE20F");
|
||||||
|
id(disp1).set_component_font_color("home.icon_top_03", 1530);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- id: !extend addon_climate_service_call
|
||||||
|
#mode: restart
|
||||||
|
#parameters:
|
||||||
|
# key: string
|
||||||
|
# value: string
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
id(is_addon_climate_visible) = true;
|
||||||
|
auto call = id(thermostat_embedded).make_call();
|
||||||
|
if (key == "set_temperature")
|
||||||
|
{
|
||||||
|
call.set_target_temperature(stof(value) / 10);
|
||||||
|
}
|
||||||
|
else if (key == "hvac_mode")
|
||||||
|
{
|
||||||
|
call.set_mode(value);
|
||||||
|
}
|
||||||
|
call.perform();
|
||||||
|
|
||||||
|
- id: !extend addon_climate_set_climate
|
||||||
|
then:
|
||||||
|
- lambda: id(is_addon_climate_visible) = embedded_climate;
|
||||||
|
|
||||||
|
- id: !extend addon_climate_global_settings
|
||||||
|
then:
|
||||||
|
- lambda: id(is_embedded_thermostat) = embedded_climate;
|
||||||
|
|
||||||
|
- id: !extend addon_climate_update_page_climate
|
||||||
|
then:
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
- binary_sensor.is_on: nextion_init
|
||||||
|
- text_sensor.state: # Is climate page visible?
|
||||||
|
id: current_page
|
||||||
|
state: 'climate'
|
||||||
|
- lambda: !lambda return id(is_addon_climate_visible);
|
||||||
|
then: # Embedded thermostat is visible
|
||||||
|
# Update slider, current temperature & target temperature
|
||||||
|
- script.execute:
|
||||||
|
id: set_climate
|
||||||
|
current_temp: !lambda "return id(thermostat_embedded).current_temperature;"
|
||||||
|
target_temp: !lambda "return id(thermostat_embedded).target_temperature;"
|
||||||
|
temp_step: !lambda "return int(round(${addon_climate_visual_temperature_step}*10));"
|
||||||
|
total_steps: !lambda |-
|
||||||
|
float temp_step = ${addon_climate_visual_temperature_step};
|
||||||
|
float temp_offset = ${addon_climate_visual_min_temperature};
|
||||||
|
float temp_max = ${addon_climate_visual_max_temperature};
|
||||||
|
float total_steps = (temp_max-temp_offset)/temp_step;
|
||||||
|
return int(round(total_steps));
|
||||||
|
slider_val: !lambda |-
|
||||||
|
float temp_step = ${addon_climate_visual_temperature_step};
|
||||||
|
float temp_offset = ${addon_climate_visual_min_temperature};
|
||||||
|
return int(round((10*id(thermostat_embedded).target_temperature-temp_offset)/temp_step));
|
||||||
|
temp_offset: !lambda "return int(round(${addon_climate_visual_min_temperature}*10));"
|
||||||
|
climate_icon: ""
|
||||||
|
embedded_climate: True
|
||||||
|
|
||||||
|
# Update target temp icon
|
||||||
|
- lambda: |-
|
||||||
|
if (${verbose_log}) ESP_LOGD("script.addon_climate_update_page_climate", "thermostat_embedded.action=%i", int(id(thermostat_embedded).action));
|
||||||
|
switch (int(id(thermostat_embedded).action)) // CLIMATE_ACTION_OFF = 0, CLIMATE_ACTION_COOLING = 2, CLIMATE_ACTION_HEATING = 3, CLIMATE_ACTION_IDLE = 4, CLIMATE_ACTION_DRYING = 5, CLIMATE_ACTION_FAN = 6
|
||||||
|
{
|
||||||
|
case 0: //CLIMATE_ACTION_OFF
|
||||||
|
if (${verbose_log}) ESP_LOGD("script.addon_climate_update_page_climate", "thermostat_embedded.mode=%i", int(id(thermostat_embedded).mode));
|
||||||
|
switch (int(id(thermostat_embedded).mode)) // CLIMATE_MODE_OFF = 0, CLIMATE_MODE_HEAT_COOL = 1, CLIMATE_MODE_COOL = 2, CLIMATE_MODE_HEAT = 3, CLIMATE_MODE_FAN_ONLY = 4, CLIMATE_MODE_DRY = 5, CLIMATE_MODE_AUTO = 6
|
||||||
|
{
|
||||||
|
case 0: //CLIMATE_MODE_OFF
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uFFFF"); // (E424) Don't show icon when off
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
||||||
|
break;
|
||||||
|
case 1: //CLIMATE_MODE_HEAT_COOL
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE069");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
||||||
|
break;
|
||||||
|
case 2: //CLIMATE_MODE_COOL
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE716");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 1055);
|
||||||
|
break;
|
||||||
|
case 3: //CLIMATE_MODE_HEAT
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE237");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 64164);
|
||||||
|
break;
|
||||||
|
case 4: //CLIMATE_MODE_FAN_ONLY
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE20F");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
||||||
|
break;
|
||||||
|
case 5: //CLIMATE_MODE_DRY
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE58D");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 64704);
|
||||||
|
break;
|
||||||
|
case 6: //CLIMATE_MODE_AUTO
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uEE8D");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: //CLIMATE_ACTION_COOLING
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE716");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 1055);
|
||||||
|
break;
|
||||||
|
case 3: //CLIMATE_ACTION_HEATING
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE237");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 64164);
|
||||||
|
break;
|
||||||
|
case 4: //CLIMATE_ACTION_IDLE
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE50E"); // mdi:thermometer
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 35921);
|
||||||
|
break;
|
||||||
|
case 5: //CLIMATE_ACTION_DRYING
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE58D");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 64704);
|
||||||
|
break;
|
||||||
|
case 6: //CLIMATE_ACTION_FAN
|
||||||
|
id(disp1).set_component_text_printf("climate.target_icon", "%s", "\uE20F");
|
||||||
|
id(disp1).set_component_font_color("climate.target_icon", 1530);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update buttons bar
|
||||||
|
- lambda: |-
|
||||||
|
if (${verbose_log}) ESP_LOGD("script.addon_climate_update_page_climate", "Updating buttons bar");
|
||||||
|
// Hide not supported hotspots
|
||||||
|
id(disp1).hide_component("climate.button01");
|
||||||
|
id(disp1).hide_component("climate.button02");
|
||||||
|
id(disp1).show_component("climate.button03"); //Heat
|
||||||
|
id(disp1).hide_component("climate.button04");
|
||||||
|
id(disp1).hide_component("climate.button05");
|
||||||
|
id(disp1).hide_component("climate.button06");
|
||||||
|
id(disp1).show_component("climate.button07"); //Off
|
||||||
|
// Set buttons colors
|
||||||
|
id(disp1).set_component_font_color("climate.button01_icon", 10597);
|
||||||
|
id(disp1).set_component_font_color("climate.button02_icon", 10597);
|
||||||
|
id(disp1).set_component_font_color("climate.button03_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_HEAT) ? 64164 : 48631);
|
||||||
|
id(disp1).set_component_font_color("climate.button04_icon", 10597);
|
||||||
|
id(disp1).set_component_font_color("climate.button05_icon", 10597);
|
||||||
|
id(disp1).set_component_font_color("climate.button06_icon", 10597);
|
||||||
|
id(disp1).set_component_font_color("climate.button07_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_OFF) ? 35921 : 48631);
|
||||||
|
|
||||||
|
switch:
|
||||||
|
##### PHYSICAL SWITCH 0 (Dummy) - Usend when embedded climate is disabled #####
|
||||||
|
- name: ${device_name} Relay 0 (dummy)
|
||||||
|
platform: template
|
||||||
|
id: relay_0
|
||||||
|
lambda: !lambda return false;
|
||||||
|
internal: true
|
||||||
|
optimistic: true
|
||||||
Reference in New Issue
Block a user