Thank you! I think your reply crossed with my edit. I’ll give that a try for Q2 now.
This feels like a hacking session or design sprint at work
Thank you! I think your reply crossed with my edit. I’ll give that a try for Q2 now.
This feels like a hacking session or design sprint at work
I did see you did find the answer for the first question
I have been working on this all day good thing it was raining all day
Yaml, HMI, tft and images available here
edit: update yaml to include @crlogic work on syncing states on display with home assistant
I think you could save a lot of time and effort. Might be too late. I’m using just 2 images of 480px x 320px for my panel. One has everything off, one has everything on.
Set the STA to “crop image”. When you set picc and picc2 on a button that is, say 100px x 100px then it will only visually change the 100 x 100 section like using the crop image. It would save you having to slice all your screens into little buttons and your code will always be the same. I’m just testing the theory so I could be wrong. That’s how it seems to be working for me though.
Off
On
To read the input_booleans I use for the"house mode" in HA. I have 3 for day, evening and night which just change the behaviour of a load of Node-RED flows. Returns “on” of “off”:
#This is the first icon for sunrise
- platform: homeassistant
id: day_mode
entity_id: input_boolean.day_mode
Then, under the display section:
# This section looks at the text sensor above (day_mode) and sets the images used for a button with the STA set to "crop image"
lambda: |-
int status_day=0;
if (id(day_mode).state == "off") {
status_day=0;
} else if (id(day_mode).state == "on") {
status_day=1;
}
id(disp1).send_command_printf("page0.b0.picc=%i", status_day);
id(disp1).send_command_printf("page0.b0.picc2=%i", status_day);
So, b0 is the button with the STA set to “crop image”. It’s 100px x 100px. I’m just using the 2 images above. off is image id 0. on is image id 1. When the state of an input_boolean changes to on, for example, the display just shows the 100px x 100px section from the “on” image making it look like only that image has changed.
I might be teaching everyone to suck eggs with this but, if I write it down, It’ll stick in my head. I’ve tested it on my live box and it seems to work. I’m loathe to do too much as it’s the middle of the night, If I mess up and the bedroom lights go on my other half will be in here VERY quickly to let me know
Has anyone gotten pages to work?
I have three pages defined in the Nextion Editor with page pagename
defined in the “Touch Press Event”. This works in the debug simulator of the editor (gif below), but does nothing when uploaded to the NSPanel.
So I went looking through the docs and found it.goto_page("pagename");
Adding this to the yaml kinda works; it just goes to a phantom page, not the pages I defined. And only if I use a number, not a name.
- platform: nextion
name: $device_name page0_goto_alarm
id: page0_goto_alarm
page_id: 0
component_id: 13
internal: true
on_press:
then:
# lambda: id(disp1).goto_page("pagealarm"); # does nothing
lambda: id(disp1).goto_page("1"); # goes to phantom page
Here is the phantom page;
[edit] link https://photos.app.goo.gl/CWyp2HCRReHWZF16A
[edit] if you have read this far, disregard everything. I’m blind. Upload your tft to the correct path people. Or waste hours like me!
Hi Christopher,
I have received 2 weeks back several EU version of the NSPanels, as part of the kickstarter project.
I have followed in detail your [great] video, but I unfortunately cannot upload the TFT file into the NS-Panel…I am turning all possibilities since this morning and getting exhausted. The GPIO 16 and 17 (UART) seem to not connect the panel. Do you see anything wrong I could have done?
on 20:39:34 on this log, I am calling the upload_tft function.
The Nextion screen refuses to upload the new TFT from the internal UART of the Nspanel.
Esphome log extract is hereby:
20:39:27][D][text_sensor:067]: 'weather_symbol': Sending state 'rainy'
[20:39:27][W][nextion:078]: Nextion is not connected!
[20:39:27][W][nextion:078]: Nextion is not connected!
[20:39:28][W][nextion:078]: Nextion is not connected!
[20:39:28][W][nextion:078]: Nextion is not connected!
[20:39:29][W][nextion:078]: Nextion is not connected!
[20:39:29][W][nextion:078]: Nextion is not connected!
[20:39:30][W][nextion:078]: Nextion is not connected!
[20:39:30][W][nextion:078]: Nextion is not connected!
[20:39:31][W][nextion:078]: Nextion is not connected!
[20:39:32][W][nextion:078]: Nextion is not connected!
[20:39:32][W][nextion:078]: Nextion is not connected!
[20:39:33][W][nextion:078]: Nextion is not connected!
[20:39:33][W][nextion:078]: Nextion is not connected!
[20:39:34][D][nextion_upload:169]: Connected
[20:39:34][D][nextion_upload:175]: Requesting URL: http://10.0.0.120:8123/local/hmi.tft
[20:39:34][D][nextion_upload:209]: Updating Nextion ...
[20:39:34][D][nextion_upload:235]: Waiting for upgrade response
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][D][nextion_upload:239]: Upgrade response is 19
[20:39:36][D][nextion_upload:242]: Available 0 : 0x00
[20:39:36][D][nextion_upload:242]: Available 1 : 0x00
[20:39:36][D][nextion_upload:242]: Available 2 : 0x00
[20:39:36][D][nextion_upload:242]: Available 3 : 0x00
[20:39:36][D][nextion_upload:242]: Available 4 : 0x00
[20:39:36][D][nextion_upload:242]: Available 5 : 0x00
[20:39:36][D][nextion_upload:242]: Available 6 : 0x00
[20:39:36][D][nextion_upload:242]: Available 7 : 0x00
[20:39:36][D][nextion_upload:242]: Available 8 : 0x00
[20:39:36][D][nextion_upload:242]: Available 9 : 0x00
[20:39:36][D][nextion_upload:242]: Available 10 : 0x00
[20:39:36][D][nextion_upload:242]: Available 11 : 0x00
[20:39:36][D][nextion_upload:242]: Available 12 : 0x00
[20:39:36][D][nextion_upload:242]: Available 13 : 0x00
[20:39:36][D][nextion_upload:242]: Available 14 : 0x00
[20:39:36][D][nextion_upload:242]: Available 15 : 0x00
[20:39:36][D][nextion_upload:242]: Available 16 : 0x00
[20:39:36][D][nextion_upload:242]: Available 17 : 0x00
[20:39:36][D][nextion_upload:242]: Available 18 : 0x00
[20:39:36][D][nextion_upload:248]: preparation for tft update failed 0 ""
[20:39:36][D][nextion_upload:324]: Restarting Nextion
[20:39:38][D][nextion_upload:327]: Restarting esphome
INFO nspanel.local: Error while reading incoming messages: Error while reading data: [Errno 104] Connection reset by peer
INFO Disconnected from ESPHome API for nspanel.local
WARNING Disconnected from API
INFO nspanel.local: Ping Failed: Error while reading data: [Errno 104] Connection reset by peer
INFO Successfully connected to nspanel.local
[20:39:44][W][nextion:078]: Nextion is not connected!
[20:39:44][W][nextion:078]: Nextion is not connected!
Any idea of what I could have done wrong is welcome.
Best, Felix
Any chance you can post your YAML config somewhere? My guess is that you’re not importing the external component (e.g. here) needed to get the display out of Sonoff’s proprietary mode.
Thank you for your time, Christopher.
I am not sure I understang what you mean by the external components. Do you mean the tag external_components refering to pr#2956? I am not sure how this works, but I guess it has to do with the Protocol Reparse Mode change of the Nextion TFT? The tag is in the code.
Here is the code below (I started copying your code, then I tried out this one which is added lately in your git page).
substitutions:
device_name: nspanel-dev
# Example config.yaml
esphome:
name: nspanel
comment: $device_name
esp32:
board: esp32dev
wifi:
ssid: fha2
password: '32323245'
time:
- platform: homeassistant
id: homeassistant_time
on_time:
- seconds: 0
minutes: /1
then:
- lambda: id(disp1).set_component_text_printf("Home.time", "%02i:%02i", id(homeassistant_time).now().hour, id(homeassistant_time).now().minute);
- lambda: id(disp1).set_component_text_printf("Home.date", "%i-%02i-%02i", id(homeassistant_time).now().year, id(homeassistant_time).now().month, id(homeassistant_time).now().day_of_month);
- lambda: id(disp1).set_component_text_printf("Home.temp", "%.1f", id(current_temperature).state);
- lambda: id(disp1).set_component_text_printf("Home.tempfl", "%.1f", id(temp_feelslike).state);
api:
services:
# Service to play a song
- service: play_rtttl
variables:
song_str: string
then:
- rtttl.play:
rtttl: !lambda 'return song_str;'
- service: upload_tft
then:
- lambda: 'id(disp1)->upload_tft();'
logger:
baud_rate: 0
level: DEBUG
ota:
uart:
tx_pin: 16
rx_pin: 17
baud_rate: 115200
id: tf_uart
# debug:
# direction: BOTH
# dummy_receiver: false
# after:
# delimiter: "\n"
# sequence:
# - lambda: UARTDebug::log_string(direction, bytes);
external_components:
- source: github://pr#2956
components: [nextion]
refresh: 1h
# A reboot button is always useful
button:
- platform: restart
name: $device_name Restart
binary_sensor:
- platform: gpio
name: $device_name Left Button
pin:
number: 14
inverted: true
on_click:
- switch.toggle: relay_1
- platform: gpio
name: $device_name Right Button
pin:
number: 27
inverted: true
on_click:
- switch.toggle: relay_2
- platform: nextion
name: $device_name Music previous
page_id: 1
component_id: 1
- platform: nextion
name: $device_name Music play pause
page_id: 1
component_id: 2
- platform: nextion
name: $device_name Music next
page_id: 1
component_id: 3
- platform: nextion
name: $device_name Music cast
page_id: 1
component_id: 4
- platform: nextion
name: $device_name Music voldown
page_id: 1
component_id: 9
- platform: nextion
name: $device_name Music volup
page_id: 1
component_id: 10
- platform: nextion
name: $device_name Playlist cocktail
page_id: 1
component_id: 11
- platform: nextion
name: $device_name Playlist food
page_id: 1
component_id: 12
- platform: nextion
name: $device_name Playlist dance
page_id: 1
component_id: 13
- platform: nextion
name: $device_name Playlist note
page_id: 1
component_id: 14
output:
- platform: ledc
id: buzzer_out
pin:
number: 21
switch:
- platform: gpio
name: $device_name Relay 1
id: relay_1
pin:
number: 22
- platform: gpio
name: $device_name Relay 2
id: relay_2
pin:
number: 19
- platform: gpio
name: $device_name Screen Power
id: screen_power
entity_category: config
pin:
number: 4
inverted: true
restore_mode: ALWAYS_ON
- platform: template
name: $device_name Energy Saving Mode
id: eco_mode
entity_category: config
restore_state: true
optimistic: true
rtttl:
id: buzzer
output: buzzer_out
sensor:
- platform: adc
id: ntc_source
pin: 38
update_interval: 10s
attenuation: 11db
- platform: resistance
id: resistance_sensor
sensor: ntc_source
configuration: DOWNSTREAM
resistor: 11.2kOhm
- platform: ntc
id: temperature
sensor: resistance_sensor
calibration:
b_constant: 3950
reference_temperature: 25°C
reference_resistance: 10kOhm
name: $device_name Temperature
- platform: uptime
name: $device_name Uptime Sensor
id: uptime_sensor
update_interval: 60s
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
state: !lambda |-
int seconds = round(id(uptime_sensor).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(days ? to_string(days) + "d " : "") +
(hours ? to_string(hours) + "h " : "") +
(minutes ? to_string(minutes) + "m " : "") +
(to_string(seconds) + "s")
).c_str();
- platform: wifi_signal
name: $device_name WiFi Signal Sensor
update_interval: 60s
- platform: nextion
id: screen_current_page
variable_name: dp
- platform: homeassistant
id: current_temperature
entity_id: weather.home
attribute: temperature
on_value:
# Push it to the display
then:
- lambda: id(disp1).set_component_text_printf("Home.temp", "%.1f", id(current_temperature).state);
- platform: homeassistant
id: temp_feelslike
entity_id: sensor.home_temperature_feels_like
on_value:
# Push it to the display
then:
- lambda: id(disp1).set_component_text_printf("Home.tempfl", "%.1f", id(temp_feelslike).state);
text_sensor:
- platform: template
name: $device_name Uptime Human Readable
id: uptime_human
icon: mdi:clock-start
- platform: version
name: $device_name ESPHome Version
- platform: homeassistant
id: music_artist
entity_id: media_player.sonos_vardagsrum
attribute: media_artist
on_value:
then:
- lambda: id(disp1).set_component_text_printf("Music.music_sn", "%s", id(music_artist).state.c_str());
- platform: homeassistant
id: music_title
entity_id: media_player.sonos_vardagsrum
attribute: media_title
on_value:
then:
- lambda: id(disp1).set_component_text_printf("Music.music_an", "%s", id(music_title).state.c_str());
- platform: homeassistant
id: sun_sun
entity_id: sun.sun
- platform: homeassistant
id: weather_symbol
entity_id: weather.home
on_value:
then:
- lambda: |-
int symbol=5; // 5 is a empty box.
if (id(weather_symbol).state == "clear-night") {
symbol=6;
} else if (id(weather_symbol).state == "cloudy") {
symbol=7;
if (id(sun_sun).state == "below_horizon") {
symbol=8;
}
} else if (id(weather_symbol).state == "fog") {
symbol=9;
} else if (id(weather_symbol).state == "hail" || id(weather_symbol).state == "snowy-rainy") {
symbol=10;
} else if (id(weather_symbol).state == "lightning") {
symbol=11;
} else if (id(weather_symbol).state == "lightning-rainy" || id(weather_symbol).state == "exceptional") {
symbol=12;
if (id(sun_sun).state == "below_horizon") {
symbol=13;
}
} else if (id(weather_symbol).state == "partlycloudy") {
symbol=14;
if (id(sun_sun).state == "below_horizon") {
symbol=8;
}
} else if (id(weather_symbol).state == "pouring") {
symbol=15;
} else if (id(weather_symbol).state == "rainy") {
symbol=16;
} else if (id(weather_symbol).state == "snowy") {
symbol=17;
} else if (id(weather_symbol).state == "sunny") {
symbol=18;
} else if (id(weather_symbol).state == "windy" || id(weather_symbol).state == "windy-variant") {
symbol=19;
}
id(disp1).send_command_printf("Home.weather_symbol.pic=%i", symbol);
number:
platform: template
name: $device_name Brightness
id: brightness
entity_category: config
unit_of_measurement: '%'
min_value: 0
max_value: 100
step: 1
initial_value: 30
set_action:
then:
- lambda: 'id(disp1).set_backlight_brightness(x/100);'
# Configure the screen itself
display:
- platform: nextion
id: disp1
uart_id: tf_uart
tft_url: 'http://10.0.0.120:8123/local/hmi.tft'
# A little fun...
on_setup:
then:
- number.set:
id: brightness
value: 30
# - rtttl.play: "twobits:d=4,o=5,b=220:c6,8g,8g,a,g,p,b,c6"
Do you spot any obvious error?
Best regards,
Felix
Hi Christopher,
You were right, I wasnt importing the http file. The mistake is that I omitted the quotes around the http link. In my last email I had added them, but hadnt pressed “OTA import” yet.
Now it works like a charm, I imported your video yaml (with the “GO red!” button), and it worked at first try…
I am very thankful that you spent some time on that issue…believe me I spent most of my day figuring out what I had done wrong. Now it is solved, I can focus on making my scheme.
All the best, and please continue doing videos!!
Felix
More progress
Working on a thermostat
Don’t have the coding done just the start of the TFT
Anyone have any idea how to best implement the esp side of it?
You are right, there are also 68 mm electrical boxes around in the EU. But 60 mm are also pretty popular
A friend of mine also measured his box and it’s also 60 mm in diameter.
Maybe 60 mm is only popular in Germany?
I’m sure I will not be the only person with this problem and I just try to warn people with 60 mm boxes
@botts Cool! I have not tried this myself yet but have some thoughts. I assume the command set provided in ESPHome is not sufficient to read the component type you are using for this? If so, would it be possible to
Not the shortest path, but I would try something like that if it cannot be done directly.
On a general note I think it’s very nice to see that there is alot of progress with multiple components. I have refined my own template with further functions (light control, alarm mode and bootup screen) and will publish it on Github within shortly. As we are many persons working with basically the same, but with different specific functionality, I think it would be great to try to collect the different functions into one project (HMI project and ESPHome config). That way it is rather simple for everybody to pick the components they want to create their own system.
My contribution today is investigating Nextion display objects pic/crop changes;
After adding pages to my HMI it looks like all HA icon states are lost on page change. So you end up needing to refresh these after numerous scenarios;
Code here
Have you set the HMI components to global? I think that is required to persist data on page changes.
@marcfager on the Up and down arrows i have added the below code to the Touch Press Events
if(j0.val<89)
{
j0.val++
j0.val++
j0.val++
}
if(n0.val<30)
{
n0.val++
}
which updates the value of the set temp displayed number
Just cant find away to push this the home assistant.
So…
I changed it to a text box and can update my home assistant climate by adding
binary_sensor:
- platform: nextion
name: $device_name Temp Up
id: temp_up_button
page_id: 8
component_id: 3
on_press:
then:
if:
condition:
lambda: 'return id(temp_up_binary).state;'
then:
- lambda: id(disp1).set_component_text_printf("ThermSlide.t2", "%.1f", id(set_temp).state);
- component.update: disp1
- platform: nextion
name: $device_name Temp Down
id: temp_down_button
page_id: 8
component_id: 4
on_press:
then:
if:
condition:
lambda: 'return id(temp_down_binary).state;'
then:
- lambda: id(disp1).set_component_text_printf("ThermSlide.t2", "%.1f", id(set_temp).state);
- component.update: disp1
sensor:
- platform: homeassistant
id: set_temp
entity_id: climate.climate
attribute: temperature
on_value:
# Push it to the display
then:
- lambda: id(disp1).set_component_text_printf("ThermSlide.t2", "%.1f", id(set_temp).state);
This has the up and down arrows controlling the temp on the climate and displaying the set temp on the NSPanel.
Just dont know how to sync the slider with the up and down arrow or sync the slider with the value of the set temp in home assistant
Any ideas on using the number box instead?
to make the climate increase on each button press i had to create 2 scripts and automation to trigger them
alias: NSpanel - Increase Temp by 1
description: ''
trigger:
- platform: state
entity_id: binary_sensor.nspanel_1_temp_up
to: 'on'
condition: []
action:
- service: script.turn_on
target:
entity_id: script.climate_heat_up_by1
mode: single
alias: NSpanel - Decrease Temp by 1
description: ''
trigger:
- platform: state
entity_id: binary_sensor.nspanel_1_temp_down
to: 'on'
condition: []
action:
- service: script.turn_on
target:
entity_id: script.climate_down_by_1
mode: single
alias: Climate Heat Down by 1
sequence:
- service: climate.set_temperature
data_template:
entity_id: climate.climate
temperature: '{{(state_attr(''climate.climate'' , ''temperature'')|round(0)) - 1 }}'
mode: single
icon: mdi:download
alias: 'Climate Heat Up by 1 '
sequence:
- service: climate.set_temperature
data_template:
entity_id: climate.climate
temperature: '{{(state_attr(''climate.climate'' , ''temperature'')|round(0)) + 1 }}'
mode: single
icon: mdi:upload
Not sure how to do this is esphome ???
As we are many persons working with basically the same, but with different specific functionality, I think it would be great to try to collect the different functions into one project (HMI project and ESPHome config). That way it is rather simple for everybody to pick the components they want to create their own system.
Any ideas how we can do this?
I think I played with global but forget the outcome. Will test more.
[edit] lol, that was easy. global solves it. Thanks!
I have been trying to minimize HA scripts/automations needed. What about the nextion up/down button change the HA climate temperature directly (not the Nextion object). Then also have the HA climate temp as a sensor in ESPHome and that ESPHome sensor perform the set_component_text_printf("ThermSlide.t2"...
on_state: … ?
Not sure if I made sense or not…
The most confusing part for is understanding what yaml is ESPHome and what yaml is Home Assistant script/automation. And what object is ESPHome vs HA vs Nextion. I am sure others are less cross-eyed than me.