Bonjour,
Est-ce que ce nspanel continu de fonctionner en tant qu’interrupteur « physique » si on se retrouve sans internet ?
Bonjour,
Est-ce que ce nspanel continu de fonctionner en tant qu’interrupteur « physique » si on se retrouve sans internet ?
Oui tant que HA est joignable (avec le réglage par défaut sinon le NSPanel reboot)
Au vu des avis sur ITEAD, qui indique le contraire, vous confirmer que ça rentre dans un boîte d’encastrement ronde ?
Merci
Pas eu de souci chez moi. En France les boîtes font normalement 67mm de diamètre.
Faut avoir le neutre et ne pas avoir trop de câble ou domino dans le fond de la boîte si elle est de profondeur standard
Merci pour le retour, pour la profondeur pas de souci
Bonsoir à tous,
J’ai reçu mon nspanel vendredi. Après quelques heures, je suis arrivé à qqchose de pas mal mais pas aussi beau que le travail de @Childebert
J’ai une question, pour faire basculer le relai depuis HA, je suppose que c’est un appel au service ESPHome: nspanel_send_command mais quelle commande ?
Au passage, d’autres commandes utiles ?
Merci d’avance.
[Edit] : Je viens de voir l’entité switch … Désolé … Je débute sur HA après de nombreuses années sur Jeedom.
Salut
binary_sensor:
- platform: nextion
name: $device_name Prise 1 button
page_id: 2
component_id: 12
on_click:
- homeassistant.service:
service: switch.toggle
data:
entity_id: switch.multiprise_jardin_l1 #piscine
le choix de l’appareil a piloter est fait par entity_id et le service c’est switch.toggle
A+ Fred
Merci bcp ! Je garde de côté.
En gros vous allez mettre tous ces interrupteurs dans chaque pièce ?
dommage qu’il existe pas en blanc …
Je n’en ai mis qu’un seul, au RDC facilement accessible. Il est surtout là pour les invités afin qu’ils puissent allumer/éteindre les lumières et qu’ils puissent contrôler les volets roulants sans toucher aux boutons physiques.
Pour nous tout est automatique et on se soucis de rien mais les invités même si on leur explique, cherchent toujours à éteindre la lumière ou à vouloir gérer les VR alors que tout se fait tout seul…
Je regarde pour le thermostat, qu’ils puissent régler la température à leur convenance (pas de commande de réglages manuelle disponible tout est géré tout seul par HA)
j’en ai acheté 2, un pour une utilisation a peu prêt similaire à @Makai et un deuxième que je voudrais programmer spécialement pour la gestion et surveillance de mes fourmilières.
Et si j’arrive a faire ce que je veux pour mes fourmilières, j’en verrai bien un troisième pour la gestion et surveillance d’un aquaterrarium.
Ok merci pour vos retours effectivement je ne pense pas que ce sois utilise d’en avoir partout pour que cela sois homogène dans la maison au niveau des interrupteurs
tu peux m’en dire plus …?
Je contrôle le chauffage et la clim avec HA. Aucune commande murale et je n’ai jamais sortie les télécommandes de leur emballage donc aucun moyen pour un visiteur de régler quoi que ce soit
je reprend un peu de temps pour me remettre sur le nspanel.
@Makai : est ce que tu utilises toujours le FW standard du nextion?
perso même en pointant vers le git pour le composant Nspanel, cela ne fonctionne plus…
Salut tu pourrais peut être créer ton propre sujet afin d’expliquer par exemple ce que tu veux faire, ce sera plus simple pour t’aider à avancer.
tu peux donner ton code ??? car mes 2 nspanel fonctionnent parfaitement
arf…
autant pour moi, l’erreur est que j’utilisais des widgets qui ne sont pas encore supportés.
d’ailleurs toujours pas de news pour les autres widgets? on est toujours que avec le ‹ scene › ?
Oui et non. On peut tout utiliser avec les dernières fonctionnalités ajoutées au PR
Je me rends compte que j’ai jamais posté mon dernier code qui utilise toutes les fonctionnalités du NSPanel avec l’interface par défaut (sauf le thermostat pas encore eu le temps d’y regarder).
substitutions:
devicename: NSPanel
esphome:
name: nspanel
comment: "NSPanel"
esp32:
board: esp32dev
uart:
tx_pin: 16
rx_pin: 17
baud_rate: 115200
external_components:
- source: github://pr#2702
components: ["nspanel"]
nspanel:
id: nspanel_id
time_id: current_time
temperature: temperature
screen_power_switch: screen_power
eco_mode_switch: eco_mode
relays:
- relay_1
- relay_2
on_json_message:
then:
# Widget 1 (type:0x86 id:l_salon)
- if:
condition:
lambda: 'return (type == 0x86 && root.containsKey("id") && strcasecmp(root["id"], "l_salon") == 0);'
then:
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "on");'
then:
- homeassistant.service:
service: light.turn_on
data:
entity_id: light.salon_bulb
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "off");'
then:
- homeassistant.service:
service: light.turn_off
data:
entity_id: light.salon_bulb
- if:
condition:
lambda: 'return (root["params"].containsKey("white"));'
then:
- homeassistant.service:
service: light.turn_on
data:
entity_id: light.salon_bulb
brightness: !lambda 'return int(root["params"]["white"]["br"].as<float>() / 100 * 254);'
# Widget 2 (type:0x86 id:l_entree)
- if:
condition:
lambda: 'return (type == 0x86 && root.containsKey("id") && strcasecmp(root["id"], "l_entree") == 0);'
then:
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "on");'
then:
- homeassistant.service:
service: light.turn_on
data:
entity_id: light.entree_bulb
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "off");'
then:
- homeassistant.service:
service: light.turn_off
data:
entity_id: light.entree_bulb
- if:
condition:
lambda: 'return (root["params"].containsKey("white"));'
then:
- sensor.template.publish:
id: l_entree_ct
state: !lambda 'return int(root["params"]["white"]["ct"].as<float>());'
- homeassistant.service:
service: light.turn_on
data:
entity_id: light.entree_bulb
brightness: !lambda 'return int(root["params"]["white"]["br"].as<float>() / 100 * 254);'
color_temp: !lambda 'return int(id(l_entree_ct).state);'
# Widget 3 (type:0x86 id:vr_salon)
- if:
condition:
lambda: 'return (type == 0x86 && root.containsKey("id") && strcasecmp(root["id"], "vr_salon") == 0);'
then:
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "on");'
then:
- homeassistant.service:
service: cover.open_cover
data:
entity_id: cover.salon_volet_roulant
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "off");'
then:
- homeassistant.service:
service: cover.close_cover
data:
entity_id: cover.salon_volet_roulant
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "pause");'
then:
- homeassistant.service:
service: cover.stop_cover
data:
entity_id: cover.salon_volet_roulant
- if:
condition:
lambda: 'return (root["params"].containsKey("setclose"));'
then:
- homeassistant.service:
service: cover.set_cover_position
data:
entity_id: cover.salon_volet_roulant
position: !lambda 'return 100 - root["params"]["setclose"].as<int>();'
# Widget 4 (type:0x86 id:vr_cuisine)
- if:
condition:
lambda: 'return (type == 0x86 && root.containsKey("id") && strcasecmp(root["id"], "vr_cuisine") == 0);'
then:
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "on");'
then:
- homeassistant.service:
service: cover.open_cover
data:
entity_id: cover.cuisine_volet_roulant
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "off");'
then:
- homeassistant.service:
service: cover.close_cover
data:
entity_id: cover.cuisine_volet_roulant
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "pause");'
then:
- homeassistant.service:
service: cover.stop_cover
data:
entity_id: cover.cuisine_volet_roulant
- if:
condition:
lambda: 'return (root["params"].containsKey("setclose"));'
then:
- homeassistant.service:
service: cover.set_cover_position
data:
entity_id: cover.cuisine_volet_roulant
position: !lambda 'return 100 - root["params"]["setclose"].as<int>();'
# Widget 5 (type:0x86 id:p_terrasse)
- if:
condition:
lambda: 'return (type == 0x86 && root.containsKey("id") && strcasecmp(root["id"], "p_terrasse") == 0);'
then:
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "on");'
then:
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.terrasse_plug
- if:
condition:
lambda: 'return (root["params"].containsKey("switch") && root["params"]["switch"] == "off");'
then:
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.terrasse_plug
binary_sensor:
- platform: status
name: "$devicename Status"
- platform: gpio
name: "$devicename Left Button"
pin:
number: 14
inverted: true
on_click:
- switch.toggle: relay_1
- platform: gpio
name: "$devicename Right Button"
pin:
number: 27
inverted: true
on_multi_click:
# - timing:
# - ON for at most 1s
# - OFF for at least 0.2s
# then:
# - switch.toggle: relay_2
- timing:
- ON for at least 5s
then:
- button.press: restart_button
- platform: homeassistant
id: salon_light
entity_id: light.salon_bulb
on_press:
then:
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_salon\",\"params\":{\"switch\":\"on\"}}");'
on_release:
then:
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_salon\",\"params\":{\"switch\":\"off\"}}");'
- platform: homeassistant
id: entree_light
entity_id: light.entree_bulb
on_press:
then:
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_entree\",\"params\":{\"switch\":\"on\"}}");'
on_release:
then:
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_entree\",\"params\":{\"switch\":\"off\"}}");'
- platform: homeassistant
id: terrasse_plug
entity_id: switch.terrasse_plug
on_press:
then:
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"id\":\"p_terrasse\",\"params\":{\"switch\":\"on\"}}");'
on_release:
then:
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"id\":\"p_terrasse\",\"params\":{\"switch\":\"off\"}}");'
button:
- platform: restart
name: "$devicename Restart"
id: restart_button
sensor:
- platform: uptime
id: uptime_sec
- platform: wifi_signal
name: "$devicename WiFi Signal"
update_interval: 120s
- platform: template
id: uptime_timestamp
name: "$devicename Uptime"
device_class: timestamp
entity_category: diagnostic
accuracy_decimals: 0
update_interval: never
lambda: |-
static float timestamp = (
id(current_time).utcnow().timestamp - id(uptime_sec).state
);
return timestamp;
- platform: adc
id: ntc_source
pin: 38
attenuation: 11db
- platform: resistance
id: resistance_sensor
sensor: ntc_source
configuration: DOWNSTREAM
resistor: 11.2kOhm
- platform: ntc
name: "$devicename Temperature"
id: temperature
sensor: resistance_sensor
calibration:
b_constant: 3950
reference_temperature: 25°C
reference_resistance: 10kOhm
internal: true
- platform: homeassistant
id: entree_light_brightness
entity_id: light.entree_bulb
attribute: brightness
filters:
- calibrate_linear:
- 1 -> 1
- 254 -> 100
on_value:
then:
- script.execute: ha_light_entree_update
- platform: homeassistant
id: entree_light_color_temp
entity_id: light.entree_bulb
attribute: color_temp
filters:
- calibrate_linear:
- 250 -> 254
- 454 -> 0
on_value:
then:
- script.execute: ha_light_entree_update
- platform: homeassistant
id: salon_light_brightness
entity_id: light.salon_bulb
attribute: brightness
filters:
- calibrate_linear:
- 1 -> 1
- 254 -> 100
on_value:
then:
- script.execute: ha_light_salon_update
- platform: homeassistant
id: salon_cover_position
entity_id: cover.salon_volet_roulant
attribute: current_position
filters:
- calibrate_linear:
- 0 -> 100
- 100 -> 0
on_value:
then:
- script.execute: ha_curtain_salon_update_pos
- platform: homeassistant
id: cuisine_cover_position
entity_id: cover.cuisine_volet_roulant
attribute: current_position
filters:
- calibrate_linear:
- 0 -> 100
- 100 -> 0
on_value:
then:
- script.execute: ha_curtain_cuisine_update_pos
- platform: template
id: l_entree_ct
filters:
- calibrate_linear:
- 0 -> 454
- 254 -> 250
switch:
- platform: gpio
name: "$devicename Relay 1"
id: relay_1
pin: 22
- platform: gpio
name: "$devicename Relay 2"
id: relay_2
pin: 19
- platform: gpio
name: "$devicename Screen Power"
id: screen_power
entity_category: config
pin:
number: 4
inverted: true
restore_mode: ALWAYS_OFF
internal: true
on_turn_on:
then:
- delay: 6s
- script.execute: nspanel_init
- platform: template
name: "$devicename Energy Saving Mode"
id: eco_mode
entity_category: config
restore_state: true
optimistic: true
internal: true
text_sensor:
- platform: version
name: "$devicename Version"
hide_timestamp: true
- platform: wifi_info
ip_address:
name: "$devicename IPv4"
icon: "mdi:server-network"
ssid:
name: "$devicename Connected SSID"
icon: "mdi:wifi"
- platform: homeassistant
id: salon_cover
entity_id: cover.salon_volet_roulant
on_value:
then:
- script.execute: ha_curtain_salon_update_state
- platform: homeassistant
id: cuisine_cover
entity_id: cover.cuisine_volet_roulant
on_value:
then:
- script.execute: ha_curtain_cuisine_update_state
script:
- id: nspanel_init
# Script to initialise panel on full power on (or when screen is powered on from ESP)
then:
# Setup Widgets - must send all 8
# Widget 1
- lambda: |-
id(nspanel_id).send_json_command(0x86,"{\"HMI_resources\":[{\"index\":1,\"ctype\":\"device\",\"id\":\"l_salon\",\"uiid\":52}]}");
id(nspanel_id).send_json_command(0x86,"{\"relation\":[{\"ctype\":\"device\",\"id\":\"l_salon\",\"name\":\"Salon\",\"online\":1,\"params\":{\"switch\":\"off\",\"ltype\":\"white\",\"white\":{\"br\":0,\"ct\":0}}]}");
# Widget 2
- lambda: |-
id(nspanel_id).send_json_command(0x86,"{\"HMI_resources\":[{\"index\":2,\"ctype\":\"device\",\"id\":\"l_entree\",\"uiid\":52}]}");
id(nspanel_id).send_json_command(0x86,"{\"relation\":[{\"ctype\":\"device\",\"id\":\"l_entree\",\"name\":\"Entrée\",\"online\":1,\"params\":{\"switch\":\"off\",\"ltype\":\"white\",\"white\":{\"br\":0,\"ct\":0}}]}");
# Widget 3
- lambda: |-
id(nspanel_id).send_json_command(0x86,"{\"HMI_resources\":[{\"index\":3,\"ctype\":\"device\",\"id\":\"vr_salon\",\"uiid\":11}]}");
id(nspanel_id).send_json_command(0x86,"{\"relation\":[{\"ctype\":\"device\",\"id\":\"vr_salon\",\"name\":\"Salon\",\"online\":1,\"params\":{\"switch\":\"on\"}]}");
# Widget 4
- lambda: |-
id(nspanel_id).send_json_command(0x86,"{\"HMI_resources\":[{\"index\":4,\"ctype\":\"device\",\"id\":\"vr_cuisine\",\"uiid\":11}]}");
id(nspanel_id).send_json_command(0x86,"{\"relation\":[{\"ctype\":\"device\",\"id\":\"vr_cuisine\",\"name\":\"Cuisine\",\"online\":1,\"params\":{\"switch\":\"on\"}]}");
# Widget 5
- lambda: |-
id(nspanel_id).send_json_command(0x86,"{\"HMI_resources\":[{\"index\":5,\"ctype\":\"device\",\"id\":\"p_terrasse\",\"uiid\":1}]}");
id(nspanel_id).send_json_command(0x86,"{\"relation\":[{\"ctype\":\"device\",\"id\":\"p_terrasse\",\"name\":\"Pompe\",\"online\":1,\"params\":{\"switch\":\"off\"}]}");
# Widget 6
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"index\":6,\"type\":\"delete\"}");'
# Widget 7
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"index\":7,\"type\":\"delete\"}");'
# Widget 8
- lambda: 'id(nspanel_id).send_json_command(0x86,"{\"index\":8,\"type\":\"delete\"}");'
# Update existing Entities / Widgets
- script.execute: ha_light_salon_update
- script.execute: ha_light_entree_update
- script.execute: ha_curtain_salon_update_state
- script.execute: ha_curtain_cuisine_update_state
- script.execute: ha_plug_terrasse_update
- id: ha_light_salon_update
then:
- lambda: |-
if (id(salon_light).state) {
int i_brightness = int(id(salon_light_brightness).state);
id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_salon\",\"params\":{\"switch\":\"on\",\"ltype\":\"white\",\"white\":{\"br\":" + to_string(i_brightness) + ",\"ct\":0}}}");
} else {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_salon\",\"params\":{\"switch\":\"off\"}}");
}
- id: ha_light_entree_update
then:
- lambda: |-
if (id(entree_light).state) {
int i_brightness = int(id(entree_light_brightness).state);
int i_color_temp = int(id(entree_light_color_temp).state);
id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_entree\",\"params\":{\"switch\":\"on\",\"ltype\":\"white\",\"white\":{\"br\":" + to_string(i_brightness) + ",\"ct\":" + to_string(i_color_temp) + "}}}");
} else {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"l_entree\",\"params\":{\"switch\":\"off\"}}");
}
- id: ha_curtain_salon_update_state
then:
- lambda: |-
if(id(salon_cover).state == "open") {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"vr_salon\",\"params\":{\"switch\":\"on\"}}");
} else {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"vr_salon\",\"params\":{\"switch\":\"off\"}}");
}
- id: ha_curtain_salon_update_pos
then:
- lambda: |-
int vr_pos = int(id(salon_cover_position).state);
id(nspanel_id).send_json_command(0x86,"{\"id\":\"vr_salon\",\"params\":{\"setclose\":" + to_string(vr_pos) + "}}");
- id: ha_curtain_cuisine_update_state
then:
- lambda: |-
if(id(cuisine_cover).state == "open") {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"vr_cuisine\",\"params\":{\"switch\":\"on\"}}");
} else {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"vr_cuisine\",\"params\":{\"switch\":\"off\"}}");
}
- id: ha_curtain_cuisine_update_pos
then:
- lambda: |-
int vr_pos = int(id(cuisine_cover_position).state);
id(nspanel_id).send_json_command(0x86,"{\"id\":\"vr_cuisine\",\"params\":{\"setclose\":" + to_string(vr_pos) + "}}");
- id: ha_plug_terrasse_update
then:
- lambda: |-
if(id(terrasse_plug).state) {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"p_terrasse\",\"params\":{\"switch\":\"on\"}}");
} else {
id(nspanel_id).send_json_command(0x86,"{\"id\":\"p_terrasse\",\"params\":{\"switch\":\"off\"}}");
}
time:
- platform: homeassistant
timezone: Europe/Paris
id: current_time
on_time_sync:
- component.update: uptime_timestamp
output:
- platform: ledc
id: buzzer_out
pin: 21
rtttl:
output: buzzer_out
id: buzzer
wifi:
networks:
- ssid: !secret ssid
password: !secret password
- ssid: !secret ssid_live
password: !secret password_live
ap:
ssid: "$devicename Fallback Hotspot"
password: !secret api_ota_pwd
captive_portal:
web_server:
port: 80
include_internal: true
auth:
username: admin
password: !secret api_ota_pwd
logger:
api:
password: !secret api_ota_pwd
services:
- service: weather_data
variables:
icon: int
temperature: int
min: int
max: int
then:
- lambda: id(nspanel_id).send_weather_data((nspanel::WeatherIcon)icon, temperature, min, max);
- service: play_rtttl
variables:
song_str: string
then:
- rtttl.play:
rtttl: !lambda 'return song_str;'
ota:
password: !secret api_ota_pwd
Les widgets 1 et 2 sont des ampoules blanches (la seconde avec réglage de la température), 3 et 4 sont des volets roulants, le 5 une prise connectée. 6, 7 et 8 sont vides.
Si vous avez des questions sur le code n’hésitez pas !
Je me suis en grande partie inspiré de ce code : HomeAssistantConfig/nspanel-1.yaml at master · peetereczek/HomeAssistantConfig · GitHub qui pour ceux que ça intéresse utilise aussi le thermostat.
merci @makai pour le partage.
je constate que la gestion des widgets a bien évolué avec le json…
j’ai déployé ton code en changeant les cover. et Light. en mettant mes entités sans rien changer d’autres (pas touché au nom des script)
mais malheureusement pas de widget qui s’affiche sur mon panel.
est ce qu’il faut faire qq chose dans HA pour envoyer un JSON?
merci
Rien à faire dans HA, tout est dans ESPHome.
L’affichage des widgets se fait dans le script :
script:
- id: nspanel_init
# Script to initialise panel on full power on (or when screen is powered on from ESP)
then:
# Setup Widgets - must send all 8
Ensuite, l’envoi initial des statuts des entités se fait dans les autres scripts.