Знайомимось з вимикачем NSPanel і прошиваємо ESPHome
Минулого року китайська компанія Sonoff розпочала краудфандингову кампанію, де представила цікавий розумний девайс. Вже наприкінці 2021 року Sonoff представила світу NSPanel. Цей девайс являє собою прямокутний пристрій з кольоровим сенсорним дисплеєм розміром 3,5 дюйма та двома фізичними клавішами.

Сенсорний дисплей теж було виготовлено компанією Sonoff, це модель Nextion.
Існує дві версії NSPanel, вони відрізняються лише розмірами. Одна призначена для американського ринку, інша, для європейських країн. Силова і логічна частини девайсів однакові. В якості “мозку” компанія обрала Espressif ESP32-DOWD V3, що дозволило працювати в мережах 802.11n/g/n WiFi 4. Bluetooth 4.2/5.x використовується тут лише для першого налаштування девайсу.
Підключаємо NSPanel до електромережі.
Для налаштування та керування пристроєм необхідно завантажити додаток eWeLink, він має бути вже знайомим для власників продукції Sonoff. Якщо у вас ще немає облікового запису, створіть його, або увійдіть до власного аккаунту. eWeLink дозволяє керувати приєднаними пристроями з будь-якої точки світу де є з’єднання з мережею інтернет.
Отже, для додавання NSPanel на телефоні необхідно увімкнути bluetooth, після цього необхідно підключити девайс до електромережі.
При роботі з високою напругою дотримуйтесь правил безпеки!
В програмі eWeLink натисніть в додатку “додати новий девайс”. Пізніше, на екрані ви побачите новий пристрій, виберіть його для додавання. Далі, можливо, необхідно буде ввести облікові дані вашої Wi-Fi мережі. Після під’єднання до мережі NSPanel скоріш за все “попросить” оновити власну мікропрограму. Зробіть це, адже оновлення може містити покращення роботи чи виправлення помилок. Оновлення може зайняти чимало часу.
Силова частина вимикача містить два реле, які здатні витримати струм до 16А. А це значить, що до нього можна підключити два електричних пристрої. Це можуть бути не лише освітлювальні прилади, а й, наприклад, контролер теплої підлоги. Нижче, на зображенні схема підключення вимикача.

Налаштовуємо NSPanel в eWeLink
В додатку eWeLink можна перемкнути одне з реле вимикача в режим термостату, тоді вбудований термодатчик зможе контролювати температуру в приміщенні. Для термостату оберіть режим нагріву або охолодження в залежності від того, який прилад плануєте підключити (нагрівальний чи охолоджувальний). Задайте цільову температуру в приміщенні і девайс вимкне прилад при досягненні заданої температури.

Щоб перейти до екрану термостата на вимикачі свайпніть по його екрану праворуч. Ще один свайп переведе вас до екрану віджетів. Це піктограми, за допомогою яких можна керувати іншими розумними девайсами. Так ви можете керувати розетками чи лампами, а також їхніми групами. Крім того, ви можете створити віджети для завантаження сцени.

Віджети необхідно створювати в додатку eWeLink. Максимальна кількість віджетів – вісім.

Щоб керувати девайсом за допомогою голосових асистентів Google чи Alexa створіть відповідну інтеграцію в додатку eWeLink. Крім того, Sonoff дозволяє керувати вимикачем в локальній мережі, що дає можливість інтеграцій до альтернативних систем управління розумним домом. Увімкніть відповідний пункт в налаштуваннях девайсу.

Підготовка до завантаження ESPHome
На мою думку, розумний девайс є дійсно розумним лише тоді, коли він може працювати незалежно від хмарних сервісів. NSPanel вміє працювати локально, але, на жаль, його віджети не працюють без підключення до мережі. По суті, через локальну мережу ви зможете керувати лише двома реле пристрою.
Як я вже казав вище, логічна частина вимикача – це дисплей Nextion, який підключений до контролера ESP32. Такий тандем дає нам надію на можливість легкого завантаження альтернативної прошивки Esphome. І дійсно, вже існує прошивка tasmota для NSPanel, також кипить робота по створенню компоненти “NSPanel” для Esphome
Давайте подивимось на друковану плату логічного блоку. Щоб зняти його, легко натисніть викруткою на паз в центрі. Не забудьте перед цим вимкнути живлення.

Далі необхідно викрутити два гвинти які тримають захисну пластину. Акуратно зніміть пластину, після цього ви побачите друковану плату з мікросхемою контролера esp32.

Ви можете побачити п’ять контактів в нижньому куті друкованої плати, вони позначені як 3V3, ESP_TX, ESP_RX, GND та IO0. Останній контакт – це “нульовий” пін контролера. Для того, щоб перевести контроллер в режим прошивки треба приєднати його до нульового дроту.
Для прошивки контроллера вам знадобиться перехідник usb2uart (usb – ttl converter). Перш ніж приєднувати його до комп’ютера, необхідно поставити перемичку на напругу 3,3v, це дуже важливо!

За допомогою дротів Dupont під’єднайте контакти перехідника з друкованою платою NSPanel: vcc – 3V3, GND -GND, RX – ESP_TX,TX – ESP_RX. Контакт IO0 на друкованій платі приєднайте до нульового проводу на контактному майданчику (зелений дріт на фото)

Зверніть увагу: якщо контакти дротів Dupont вийдуть за межі контактних отворів на платі, вони будуть торкатись металевої пластини дисплея. А це може призвести до короткого замикання і виходу зі строю як usb-перехідника так і мікросхем NSPanel. Щоб цього уникнути, відєднайте шлейф дисплея та вийміть друковану плату з корпусу.
Завантажуємо ESPHome на NSPanel
Тепер можна сміливо завантажувати прошивку esphome. Приєднайте usb-перехідник до комп’ютера, а в диспетчері пристроїв подивіться який com-порт він отримав. Тепер, в інтерфейсі Esphome можна створити новий вузол. Насправді достатньо буде завантажити порожній код на esp32, а далі працювати зі створеним вузлом через WiFi. Для цього виберіть варіант прошивки підключеного до комп’ютера esp-контролера. Далі, у спливаючому вікні, виберіть com-порт. Завантаження прошивки відбуватиметься декілька хвилин. Важливо щоб контакти в процесі прошивки не відєдналися.

Від’єднайте дроти та зберіть вимикач після закінчення завантаження . Після того, як підключите NSPanel до мережі з вимикачем можна працювати як зі звичайним контролером esp32. Тепер давайте завантажимо підготовлений код.
esphome:
name: esp-nsp01
comment: Sonoff NSPanel
esp32:
board: esp32dev
wifi:
networks:
- ssid: !secret ssid
password: !secret password
manual_ip:
# Вкажіть свої
static_ip: 192.168.10.200
gateway: 192.168.10.1
subnet: 255.255.255.0
ap:
ssid: "Fallback Hotspot"
password: !secret ap_password
time:
- platform: homeassistant
id: homeassistant_time
logger:
on_message:
level: DEBUG
then:
ota:
web_server:
http_request:
useragent: esphome/device
timeout: 5s
substitutions:
switch_id: "nsp01"
friendly_name: "NSPanel"
uart:
tx_pin: 16
rx_pin: 17
baud_rate: 115200
external_components:
- source: github://pr#2702
components: ["nspanel"]
refresh: 0s
interval:
- interval: 1min
then:
- script.execute: nspanel_weather
nspanel:
id: nspanel1
time_id: homeassistant_time
temperature: ${switch_id}_temperature
eco_mode_switch: ${switch_id}_eco_mode
screen_power_switch: ${switch_id}_screen_power
relays:
- ${switch_id}_relay_1
- ${switch_id}_relay_2
widgets:
- type: scene
name: Mario
on_click:
- logger.log: Mario Scene tapped
- rtttl.play: "Super Mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6"
- type: scene
name: Friends
on_click:
- logger.log: Friends Scene tapped
- rtttl.play: "Friends:d=8,o=5,b=100:16d,g,a,c6,b,a,g.,16g,d,g,a,2a,p,16p,16d,g,a,c.6,16b,16a,g.,16c6,b,a,g,2d6,p,16p,16c6,c6,c6,c6,c6,c6,c.6,16c6,b,2b,p,16a,16a,16b,16c6,c6,c6,c6,c.6,16b,a.,16g,g.,16d,16g,16a,b,4a,4g,p"
- type: empty
- type: empty
- type: empty
- type: empty
- type: empty
- type: empty
output:
- platform: ledc
id: ${switch_id}_buzzer_out
pin:
number: 21
rtttl:
id: ${switch_id}_buzzer
output: ${switch_id}_buzzer_out
api:
id: api_id
services:
- service: send_json
variables:
my_type: int
my_json: string
then:
- lambda: 'id(nspanel1).send_json_command(my_type,my_json);'
switch:
# Restart Switch
- platform: restart
name: "${switch_id} Restart"
- platform: gpio
# Ліве реле
name: ${switch_id} Relay 1
id: ${switch_id}_relay_1
pin:
number: 22
- platform: gpio
# Праве реле
name: ${switch_id} Relay 2
id: ${switch_id}_relay_2
pin:
number: 19
- platform: gpio
id: ${switch_id}_screen_power
entity_category: config
pin:
number: 4
inverted: true
restore_mode: ALWAYS_OFF
on_turn_on:
then:
- lambda: |-
uint8_t rssi = 0;
rssi = (wifi::global_wifi_component->wifi_rssi() * -1) / 20.0f;
std::string json_str = json::build_json([rssi](JsonObject root) {
root["wifiState"] = "connected";
root["rssiLevel"] = rssi;
});
id(nspanel1).send_json_command(0x85, json_str);
- delay: 6s
- script.execute: nspanel_weather
- platform: template
# Вимикач затемнення екрану
id: ${switch_id}_eco_mode
entity_category: config
restore_state: true
optimistic: true
binary_sensor:
# Фізичні кнопки NSPanel
- platform: gpio
id: ${switch_id}_button_1
name: ${switch_id} Left Button
pin:
number: 14
inverted: true
on_click:
- switch.toggle: ${switch_id}_relay_1
- platform: gpio
id: ${switch_id}_button_2
name: ${switch_id} Right Button
pin:
number: 27
inverted: true
on_click:
- switch.toggle: ${switch_id}_relay_2
sensor:
# Wifi
- platform: wifi_signal
name: "${switch_id} WiFi Signal Sensor"
update_interval: 60s
# датчик температури nspanel
- platform: adc
id: ${switch_id}_ntc_source
pin: 38
update_interval: 10s
attenuation: 11db
- platform: resistance
id: ${switch_id}_resistance_sensor
sensor: ${switch_id}_ntc_source
configuration: DOWNSTREAM
resistor: 11.2kOhm
- platform: ntc
id: ${switch_id}_temperature
sensor: ${switch_id}_resistance_sensor
calibration:
b_constant: 3950
reference_temperature: 25°C
reference_resistance: 10kOhm
name: "${switch_id} Temperature"
- platform: homeassistant
id: temperature_sensor
entity_id: sensor.openweathermap_temperature
accuracy_decimals: 1
- platform: homeassistant
id: wfth
entity_id: sensor.openweathermap_forecast_temperature
accuracy_decimals: 1
internal: true
- platform: homeassistant
id: wftl
name: wftl
accuracy_decimals: 1
entity_id: sensor.openweathermap_forecast_temperature_low
internal: true
- platform: template
name: "icon_code"
id: icon_code
lambda: |-
if (id(wcond).state=="sunny") {return 1;}
else if (id(wcond).state=="partlycloudy") {return 2;}
else if (id(wcond).state=="cloudy") {return 7;}
else if (id(wcond).state=="foggy") {return 11;}
else if (id(wcond).state=="snowy") {return 20;}
else if (id(wcond).state=="windy") {return 32;}
else if (id(wcond).state=="rainy") {return 40;}
else {return 30;};
//Якщо ваш погодний провайдер надає інші значення стану погоди ("sunny", "partlycloudy", "rainy" та інші )
//підставте їх вище, замінивши або додавши їх відповідні значення, розмір літер має значення
//нижче можливі варіанти номерів піктограм погоди для дисплея NSPanel
//1 = sunny
//2 = sun+cloud
//7 = cloud+blue cloud
//11 = cloud+fog
//15 = cloud rain lightning
//20 = cloud+snowflake
//22 = cloud + 3 snowflakes
//22 = cloud + 5 ice crystals
//22 = cloud + rain + snow
//30 = red thermostat
//31 = blue thermostat
//32 = wind
//40 = rainy cloud
update_interval: 60s
text_sensor:
- platform: homeassistant
id: wcond
name: wcond
entity_id: sensor.openweathermap_condition
script:
- id: nspanel_weather
then:
- lambda: |-
int wftl_int=30,wfth_int=0,icon_code_int=0;
wftl_int = int(id(wftl).state);
wfth_int = int(id(wfth).state);
icon_code_int = int(id(icon_code).state);
id(nspanel1).send_json_command(0x81, "{\"HMI_weather\":" + to_string(icon_code_int) + ",\"HMI_outdoorTemp\":{\"current\":"+ to_string(id(temperature_sensor).state) +",\"range\":\"" + to_string(wftl_int) + "," + to_string(wfth_int) + "\"}}");
Після перезавантаження вимикач матиме знайомий інтерфейс. Єдине, хочу попередити, тут ще немає офіційної підтримки термостатів, тому я не додавав його в код. Термостат, як і деякі віджети, можна додати за допомогою json запитів. Який формат повинен мати json можна прочитати тут. А тут ви знайдете ще один варіант коду, вже з деякими віджетами і термостатом. Єдине, вам необхідно буде замінити ID пристроїв на ваші.
Для прикладу роботи віджетів-сцен я додав код, який вимикатиме мелодії на вбудованому в NSPanel бузері (п’єзодинамік). Ви можете додавати і завантажувати будь які власні сцени з HomeAssistant.
Відразу після офіційного виходу компоненти NSPanel для esphome я планую актуалізувати статтю, слідкуйте за оновленнями. Крім того, існує спосіб повністю поміняти інтерфейс на дисплеї і повністю відмовитись від NSPanel Protocol, адже на борту вимикача Nextion Display і ESP32, але то вже тема для іншої статті.
