Sonoff's NSPanel reflashed with Tasmota
The "committee" has taken the brave step of purchasing a series of Kickstarter project units designed and built by Sonoff. Known as the NSPanel the unit comes in two sizes, one for EU and one for US. One of each was purchased here. As it turns out the unit cannot function in the ElectricBrain environment at all because it assumes one of three things: Windows, IOS or Android. Unfortunately all of these operating systems have been removed here at ElectricBrain.
Enter Tasmota! With considerable help from Dennis (the committee's resident Tasmota expert) the NSPanel has been transformed in to a privacy respecting delight integrating well into the Linux phone and computer environment.
Tasmotized NSPanel showing North Pole info - It was actually 38 degree in Melbourne
Flashing and commissioning notes - By Dennis
This was the procedure followed here to get the second EU panel operational. Pay particular attention to the software downloaded and used as the original instructions from the various websites didn't work for me. The release tags were a bit later that noted here but everything pretty much unfolded as documented, with the exception that the flashing program hung at the end. However everything was good and a reboot proceeded as expected.
Reflash NS Panel
================
Main Reference:
https://templates.blakadder.com/sonoff_NSPanel.html
Example (You Tuber)
https://www.youtube.com/watch?v=sCrdiCzxMOQ&t=224s
Preliminary Steps
=================
Software
https://github.com/tasmota/install/raw/main/firmware/unofficial/tasmota32-nspanel.bin
https://raw.githubusercontent.com/blakadder/nspanel/main/nspanel.be
https://github.com/espressif/esptool
https://github.com/Jason2866/ESP_Flasher/releases/tag/v.1.3
Verify connectivity
1. Get Flash Size and info:
esptool.py flash_id
Backup flash from esp32 with 4MB of flash size to "nspanel.bin":
2. Backup existing Firmware
esptool.py read_flash 0x0 0x400000 nspanel.bin
Verify Connectivity
===================
Download esptool.py
https://github.com/espressif/esptool
esptool.py flash_id
/home/dennis/Software/Source/Python/tasmotizer/venv/bin/python /home/dennis/Software/Source/Python/tasmotizer/tasmotizer_esptool.py
(venv) (base) [dennis@swim tasmotizer]$ /home/dennis/Software/Source/Python/tasmotizer/venv/bin/python /home/dennis/Software/Source/Python/tasmotizer/tasmotizer_esptool.py flash_id
esptool.py v2.8
Found 1 serial ports
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ5 (revision 3)
Features: WiFi,
BT,
Dual Core,
240MHz,
VRef calibration in efuse,
Coding Scheme None
Crystal is 40MHz
Uploading stub...
Running stub...
Stub running...
Manufacturer: 5e
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...
Backup Existing Firmware
========================
esptool.py read_flash 0x0 0x400000 nspanel.bin
/home/dennis/Software/Source/Python/tasmotizer/venv/bin/python /home/dennis/Software/Source/Python/tasmotizer/tasmotizer_esptool.py read_flash 0x0 0x400000 nspanel.bin
esptool.py v2.8
Found 1 serial ports
Serial port /dev/ttyUSB0
Connecting.......
Detecting chip type... ESP32
Chip is ESP32D0WDQ5 (revision 3)
Features: WiFi,
BT,
Dual Core,
240MHz,
VRef calibration in efuse,
Coding Scheme None
Crystal is 40MHz
Uploading stub...
Running stub...
Stub running...
/home/dennis/Software/Source/Python/tasmotizer/tasmotizer_esptool.py:2573: DeprecationWarning: an integer is required (got type float). Implicit conversion to integers using __int__ is deprecated,
and may be removed in a future version of Python.
sw.progress.emit('backup',
progress * 100.0 // length)
Read 4194304 bytes at 0x0 in 394.4 seconds (85.1 kbit/s)...
Hard resetting via RTS pin...
(venv) (base) [dennis@swim tasmotizer]$
Reflash
=======
Download Tasmota NS Panel image
https://github.com/tasmota/install/raw/main/firmware/unofficial/tasmota32-nspanel.bin
Download NS Panel screen driver
https://raw.githubusercontent.com/blakadder/nspanel/main/nspanel.be
Download ESP_Flasher
https://github.com/Jason2866/ESP_Flasher/releases/tag/v.1.3
Configure Tasmota and re-load NS Panel Nextion GUI
ESP-flasher
https://github.com/Jason2866/ESP_Flasher/releases/tag/v.1.3
ESP-Flasher tasmota32-nspanel.bin
(base) [dennis@swim tasmota]$ ./ESP-Flasher --help
usage: esp_flasher 1.3.0 [-h] [-p PORT] [--esp8266 | --esp32 | --upload-baud-rate UPLOAD_BAUD_RATE]
[--bootloader BOOTLOADER] [--partitions PARTITIONS] [--otadata OTADATA] [--no-erase]
[--show-logs]
binary
positional arguments:
binary The binary image to flash.
optional arguments:
-h,
--help show this help message and exit
-p PORT,
--port PORT Select the USB/COM port for uploading.
--esp8266
--esp32
--upload-baud-rate UPLOAD_BAUD_RATE
Baud rate to upload with (not for logging)
--bootloader BOOTLOADER
(ESP32-only) The bootloader to flash.
--partitions PARTITIONS
(ESP32-only) The partitions to flash.
--otadata OTADATA (ESP32-only) The otadata file to flash.
--no-erase Do not erase flash before flashing
--show-logs Only show logs
(base) [dennis@swim tasmota]$
(base) [dennis@swim tasmota]$
(base) [dennis@swim tasmota]$
(base) [dennis@swim tasmota]$ ./ESP-Flasher /home/dennis//Software/Source/tasmota/Firmware/NS\ Panel/tasmota32-nspanel.bin
Found more than one serial port:
* /dev/ttyUSB0 (ANT USB-m Stick)
* /dev/ttyUSB1 (FT232R USB UART)
Please choose one with the --port argument.
(base) [dennis@swim tasmota]$ ./ESP-Flasher -p /dev/ttyUSB1 /home/dennis//Software/Source/tasmota/Firmware/NS\ Panel/tasmota32-nspanel.bin
Using '/dev/ttyUSB1' as serial port.
Traceback (most recent call last):
File "serial/serialposix.py",
line 322,
in open
PermissionError: [Errno 13] Permission denied: '/dev/ttyUSB1'
During handling of the above exception,
another exception occurred:
Traceback (most recent call last):
File "esp_flasher/__main__.py",
line 193,
in module
File "esp_flasher/__main__.py",
line 182,
in main
File "esp_flasher/__main__.py",
line 95,
in run_esp_flasher
File "esp_flasher/common.py",
line 195,
in detect_chip
File "esp_flasher/own_esptool.py",
line 364,
in detect_chip
File "esp_flasher/own_esptool.py",
line 323,
in __init__
File "serial/__init__.py",
line 90,
in serial_for_url
File "serial/serialposix.py",
line 325,
in open
serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyUSB1: [Errno 13] Permission denied: '/dev/ttyUSB1'
[82008] Failed to execute script '__main__' due to unhandled exception!
1 of 2
(base) [dennis@swim tasmota]$ sudo ./ESP-Flasher -p /dev/ttyUSB1 /home/dennis//Software/Source/tasmota/Firmware/NS\ Panel/tasmota32-nspanel.bin
[sudo] password for dennis:
Using '/dev/ttyUSB1' as serial port.
Connecting....
Detecting chip type... ESP32
Connecting...
Chip Info:
- Chip Family: ESP32
- Chip Model: ESP32-D0WDQ5-V3 (revision 3)
- Number of Cores: 2
- Max CPU Frequency: 240MHz
- Has Bluetooth: YES
- Has Embedded Flash: NO
- Has Factory-Calibrated ADC: YES
- MAC Address: C4:DD:57:D9:6C:C8
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
- Flash Size: 4MB
- Flash Mode: dout
- Flash Frequency: 40MHz
Erasing flash (this may take a while)...
Chip erase completed successfully in 14.9s
Flash will be erased from 0x00001000 to 0x00005fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x00150fff...
Compressed 17104 bytes to 11191...
Writing at 0x00001000... (100 %)
Wrote 17104 bytes (11191 compressed) at 0x00001000 in 0.5 seconds (effective 295.0 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 129...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (129 compressed) at 0x00008000 in 0.0 seconds (effective 514.1 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.1 seconds (effective 685.1 kbit/s)...
Hash of data verified.
Compressed 1311232 bytes to 890250...
Writing at 0x00010000... (1 %)
Writing at 0x00018e01... (3 %)
Writing at 0x00020343... (5 %)
Writing at 0x00027dea... (7 %)
Writing at 0x00032a34... (9 %)
Writing at 0x0003a318... (10 %)
Writing at 0x00042d24... (12 %)
Writing at 0x00048403... (14 %)
Writing at 0x0004d49a... (16 %)
Writing at 0x00052384... (18 %)
Writing at 0x000573ce... (20 %)
Writing at 0x0005cd74... (21 %)
Writing at 0x00061f6c... (23 %)
Writing at 0x00067175... (25 %)
Writing at 0x0006c2c9... (27 %)
Writing at 0x000710ac... (29 %)
Writing at 0x00075c81... (30 %)
Writing at 0x0007ab61... (32 %)
Writing at 0x000801fd... (34 %)
Writing at 0x00085be8... (36 %)
Writing at 0x0008b7c1... (38 %)
Writing at 0x00090e15... (40 %)
Writing at 0x00096e15... (41 %)
Writing at 0x0009c32e... (43 %)
Writing at 0x000a1df9... (45 %)
Writing at 0x000a79dc... (47 %)
Writing at 0x000ad70a... (49 %)
Writing at 0x000b2e26... (50 %)
Writing at 0x000b8151... (52 %)
Writing at 0x000bd629... (54 %)
Writing at 0x000c2869... (56 %)
Writing at 0x000c7cd2... (58 %)
Writing at 0x000cd069... (60 %)
Writing at 0x000d20ed... (61 %)
Writing at 0x000d7067... (63 %)
Writing at 0x000dccd1... (65 %)
Writing at 0x000e263a... (67 %)
Writing at 0x000e7a93... (69 %)
Writing at 0x000ecd0a... (70 %)
Writing at 0x000f2199... (72 %)
Writing at 0x000f7813... (74 %)
Writing at 0x000fcdd7... (76 %)
Writing at 0x00102666... (78 %)
Writing at 0x001082b3... (80 %)
Writing at 0x0010dbae... (81 %)
Writing at 0x00112c85... (83 %)
Writing at 0x001181cb... (85 %)
Writing at 0x0012086b... (87 %)
Writing at 0x00129524... (89 %)
Writing at 0x0012f03b... (90 %)
Writing at 0x00134695... (92 %)
Writing at 0x0013d749... (94 %)
Writing at 0x00143227... (96 %)
Writing at 0x0014854c... (98 %)
Writing at 0x0014e287... (100 %)
Wrote 1311232 bytes (890250 compressed) at 0x00010000 in 21.4 seconds (effective 491.3 kbit/s)...
Hash of data verified.
Leaving...
Hard Resetting...
Hard resetting via RTS pin...
Done! Flashing is complete!
Showing logs:
Serial port closed!
(base) [dennis@swim tasmota]$
2of2
(base) [dennis@swim ESP32 Flasher]$ sudo ./ESP-Flasher /home/dennis//Software/Source/tasmota/Firmware/NS\ Panel/tasmota32-nspanel.bin
Auto-detected serial port: /dev/ttyUSB0
Connecting....
Detecting chip type... ESP32
Connecting...
Chip Info:
- Chip Family: ESP32
- Chip Model: ESP32-D0WDQ5-V3 (revision 3)
- Number of Cores: 2
- Max CPU Frequency: 240MHz
- Has Bluetooth: YES
- Has Embedded Flash: NO
- Has Factory-Calibrated ADC: YES
- MAC Address: C4:DD:57:D9:41:54
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
- Flash Size: 4MB
- Flash Mode: dout
- Flash Frequency: 40MHz
Erasing flash (this may take a while)...
Chip erase completed successfully in 16.1s
Flash will be erased from 0x00001000 to 0x00005fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x00150fff...
Compressed 17104 bytes to 11191...
Writing at 0x00001000... (100 %)
Wrote 17104 bytes (11191 compressed) at 0x00001000 in 0.5 seconds (effective 285.2 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 129...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (129 compressed) at 0x00008000 in 0.0 seconds (effective 512.6 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.1 seconds (effective 684.7 kbit/s)...
Hash of data verified.
Compressed 1311232 bytes to 890250...
Writing at 0x00010000... (1 %)
Writing at 0x00018e01... (3 %)
Writing at 0x00020343... (5 %)
Writing at 0x00027dea... (7 %)
Writing at 0x00032a34... (9 %)
Writing at 0x0003a318... (10 %)
Writing at 0x00042d24... (12 %)
Writing at 0x00048403... (14 %)
Writing at 0x0004d49a... (16 %)
Writing at 0x00052384... (18 %)
Writing at 0x000573ce... (20 %)
Writing at 0x0005cd74... (21 %)
Writing at 0x00061f6c... (23 %)
Writing at 0x00067175... (25 %)
Writing at 0x0006c2c9... (27 %)
Writing at 0x000710ac... (29 %)
Writing at 0x00075c81... (30 %)
Writing at 0x0007ab61... (32 %)
Writing at 0x000801fd... (34 %)
Writing at 0x00085be8... (36 %)
Writing at 0x0008b7c1... (38 %)
Writing at 0x00090e15... (40 %)
Writing at 0x00096e15... (41 %)
Writing at 0x0009c32e... (43 %)
Writing at 0x000a1df9... (45 %)
Writing at 0x000a79dc... (47 %)
Writing at 0x000ad70a... (49 %)
Writing at 0x000b2e26... (50 %)
Writing at 0x000b8151... (52 %)
Writing at 0x000bd629... (54 %)
Writing at 0x000c2869... (56 %)
Writing at 0x000c7cd2... (58 %)
Writing at 0x000cd069... (60 %)
Writing at 0x000d20ed... (61 %)
Writing at 0x000d7067... (63 %)
Writing at 0x000dccd1... (65 %)
Writing at 0x000e263a... (67 %)
Writing at 0x000e7a93... (69 %)
Writing at 0x000ecd0a... (70 %)
Writing at 0x000f2199... (72 %)
Writing at 0x000f7813... (74 %)
Writing at 0x000fcdd7... (76 %)
Writing at 0x00102666... (78 %)
Writing at 0x001082b3... (80 %)
Writing at 0x0010dbae... (81 %)
Writing at 0x00112c85... (83 %)
Writing at 0x001181cb... (85 %)
Writing at 0x0012086b... (87 %)
Writing at 0x00129524... (89 %)
Writing at 0x0012f03b... (90 %)
Writing at 0x00134695... (92 %)
Writing at 0x0013d749... (94 %)
Writing at 0x00143227... (96 %)
Writing at 0x0014854c... (98 %)
Writing at 0x0014e287... (100 %)
Wrote 1311232 bytes (890250 compressed) at 0x00010000 in 21.4 seconds (effective 489.8 kbit/s)...
Hash of data verified.
Leaving...
Hard Resetting...
Hard resetting via RTS pin...
Done! Flashing is complete!
Showing logs:
Serial port closed!
(base) [dennis@swim ESP32 Flasher]$
Configuration:
==============
Add 5v,
GND to NSPanel Board and power up NS Panel board
Enable WiFi on PC
Select tasmota_XXXXXX AP
On PC Browse to 192.168.4.1
Set AP SSID and Password
After NS Panel has rebooted,
browse to IP address as given (#1: 192.168.2.182):
Goto:
Configuration
Configure Other
Update Template:
{"NAME":"NSPanel","GPIO":[0,0,0,0,3872,0,0,0,0,0,32,0,0,0,0,225,0,480,224,1,0,0,0,33,0,0,0,0,0,0,0,0,0,0,4736,0],"FLAG":0,"BASE":1,"CMND":"ADCParam 2,64000,10000,3950 | Sleep 0 | BuzzerPWM 1"}
Check Activate
Check Web Admin Password
Add Password
Check Enable MQTT
Update Device Name
Update Friendly Name
Save
Configure Module
Confirm Module: NSPanel(0)
Update File System
Console
Manage File System
Browse
Select nspanel.be
Start Upload
For file nspanel.be select edit (pencil icon)
Rename to:
autoexec.be
Finalise configuration of tasmota
Configuration
Configure MQTT
Host: 192.168.2.252
client: (name e.g.nspanel-01="")
user: (mqtt_user)
password: (mqtt_password)
Console:
SetOption19 on
Backlog NtpServer1 192.168.2.2; NtpServer2 192.168.2.2; NtpServer3 192.168.2.2
Backlog timezone +10; timeDST 1,1,10,1,2,660; timeSTD 1,1,4,1,2,600
AdcParam 2,15000,10700,3950
Save Configuration
Configuration
Backup Configuration
==========================End of Config==========================================
Some other notes:
ADC Calibration
RT1 (23 degrees) = 8.83 k
Default
AdcParam 2,64000,10000,3950 -4.2 degrees
Trial and Error
AdcParam 2,64000,8830,3993 -6.1 degrees
AdcParam 2,32000,8830,3993 6.8 degrees
AdcParam 2,20000,8830,3993 16.3 degrees
AdcParam 2,18000,10000,3350 20.6 degrees
AdcParam 2,15000,10000,3350 25.4 degrees
AdcParam 2,16666,10000,3350 22.5 degrees
By Phill
AdcParam 2,14000,10000,3350 within 0.1 of measured value
Temp measured with ALDI TH meter as at 11/01/2021:
AdcParam 2,14000,10000,3350 25.6 vs 25.9 measured
AdcParam 2,15000,10700,3950 exact to ALDI TH meter (25.1 through to 25.5)
Looks close. The compressor was still on and the temperature dropped to 6.5. I open the door and checked the meter - 6.5,
NS Panel 6.6.
In my case with the later version flashing utility the process hung after reading the logs.
Writing at 0x0014e287... (100 %)
Wrote 1311232 bytes (890250 compressed) at 0x00010000 in 20.6 seconds (effective 508.4 kbit/s)...
Hash of data verified.
Leaving...
Hard Resetting...
Hard resetting via RTS pin...
Done! Flashing is complete!
Showing logs:
.... hangs here
However, everything was OK.
In a further gottcha, the Tasmota firmware for the NSPanels now seems to be available in two versions. In fact the NSPanel itself seems to have changed, so that the later release of Tasmota (the V2) won't run on the original units. The newer V2 units are available in white! I think these have Zigbee stuff in them too, whereas the orignal units were WiFi only. Anyway both flavours of the software are available for download.
Replace wttr.in with OpenWeatherMap
The code needed to change http://wttr.in over to OpenWeatherMap is included below. This is early stage (read hacked in) code. Currently the day-night icons are all daytime icons from the original code. Also everything is in metric and degrees C. The comments haven't been updated either.
You'll need an account over at OpenWeatherMap too. Find the line with the URL:
"https://api.openweathermap.org/data/2.5/weather?lat=MY-LAT&lon=MY-LON&appid=MY-APP-ID-KEY&units=metric"
and setup your position and your key from OpenWeatherMap's accounts.
Apple iPhone can tell you your LAT and LON - I just Googled it and followed the instructions. No doubt Android phones can do the same.
# update weather forecast,
since the provider doesn't support range I winged it with FeelsLike temperature
def set_weather()
import json
var weather_icon = {
"": 30,
# Unknown
"01d": 1,
# Sunny
"01n": 1,
# Sunny
"02d": 2,
# PartlyCloudy
"02n": 2,
# PartlyCloudy
"03d": 2,
# Cloudy
"03n": 2,
# Cloudy
"04d": 7,
# VeryCloudy
"04n": 7,
# VeryCloudy
"143": 11,
# Fog
"176": 40,
# LightShowers
"179": 24,
# LightSleetShowers
"182": 24,
# LightSleet
"185": 24,
# LightSleet
"11d": 42,
# ThunderyShowers
"11n": 42,
# ThunderyShowers
"13d": 20,
# LightSnow
"13n": 20,
# LightSnow
"230": 22,
# HeavySnow
"50d": 11,
# Fog
"263": 40,
# LightShowers
"266": 40,
# LightRain
"281": 24,
# LightSleet
"284": 24,
# LightSleet
"09d": 40,
# LightRain
"09n": 40,
# LightRain
"296": 40,
# LightRain
"299": 18,
# HeavyShowers
"10d": 18,
# HeavyRain
"10n": 18,
# HeavyRain
"305": 18,
# HeavyShowers
"308": 18,
# HeavyRain
"311": 24,
# LightSleet
"314": 24,
# LightSleet
"317": 24,
# LightSleet
"320": 20,
# LightSnow
"323": 22,
# LightSnowShowers
"326": 22,
# LightSnowShowers
"329": 22,
# HeavySnow
"332": 22,
# HeavySnow
"335": 29,
# HeavySnowShowers
"338": 22,
# HeavySnow
"350": 24,
# LightSleet
"353": 24,
# LightSleet
"356": 18,
# HeavyShowers
"359": 18,
# HeavyRain
"362": 24,
# LightSleetShowers
"365": 24,
# LightSleetShowers
"368": 22,
# LightSnowShowers
"371": 29,
# HeavySnowShowers
"374": 24,
# LightSleetShowers
"377": 24,
# LightSleet
"386": 42,
# ThunderyShowers
"389": 42,
# ThunderyHeavyRain
"392": 42,
# ThunderySnowShowers
"395": 29,
# HeavySnowShowers
}
var temp
var tmin
var tmax
var icon
var cl = webclient()
var url = "https://api.openweathermap.org/data/2.5/weather?lat=MY-LAT&lon=MY-LON&appid=MY-APP-ID-KEY&units=metric"
cl.set_useragent("curl/7.72.0")
cl.begin(url)
if cl.GET() == "200" || cl.GET() == 200
var b = json.load(cl.get_string())
if persist.tempunit == "F"
temp = b['current_condition'][0]['temp_F']
tmin = b['weather'][0]['mintempF']
tmax = b['weather'][0]['maxtempF']
else
temp = b['main']['temp']
tmin = b['main']['temp_min']
tmax = b['main']['temp_max']
end
# var wttr = '{"HMI_weather":' + str(weather_icon[b['weather'][0]['icon']]) + ',"HMI_outdoorTemp":{"current":' + temp + ',"range":" ' + tmin + ',
' + tmax + '"}}'
icon = b['weather'][0]['icon']
var wttr = '{"HMI_weather":' + str(weather_icon[icon]) + ',"HMI_outdoorTemp":{"current":' + str(temp) + ',"range":" ' + str(tmin) + ',
' + str(tmax) + '"}}'
self.send(wttr)
log('NSP: Weather update for location: ' + b['name']+ ",
"+ b['sys']['country'])
else
log('NSP: Weather update failed!',
3)
end
cl.close()
end