Compare commits

..

1 Commits

Author SHA1 Message Date
Johannes
19814bf987 Update nspanel-lovelace-ui.py 2022-07-29 17:29:14 +02:00
62 changed files with 1695 additions and 9680 deletions

View File

@@ -3,7 +3,3 @@ contact_links:
- name: NsPanel Lovelace UI Docs
url: https://docs.nspanel.pky.eu
about: All the information related to flashing and configuration.
- name: IoBroker Forum
url: https://forum.iobroker.net/topic/50888/sonoff-nspanel
about: for questions related to the ioBroker Script, ask in the ioBroker Forum Thread

View File

@@ -52,7 +52,3 @@ _Make sure your have performed every step and checked the applicable boxes befor
```
### ADDITIONAL INFORMATION
_Add information about your setup here, if any. (For example docker version of AppDaemon instead of the HomeAssistant Add-on)_

View File

@@ -7,7 +7,7 @@ If you are changeing the page the nextion display will send and event to the esp
HomeAssistant / NodeRed -- MQTT -- Tasmota -- Nextion Screen
See the following picture to get an Idea for the messages send and recived from the screen during cycling though pages. Please note that the messages in the picutre are outdated, but it is still useful to understand the concept.
See the following picture to get an Idea for the messages send and recived from the screen during cycling though pages.
![message_flow](../doc-pics/message-flow.png)

View File

@@ -1,6 +1,6 @@
diff -bur HMI/n2t-out/Program.s.txt HMI/US/landscape/n2t-out/Program.s.txt
--- HMI/n2t-out/Program.s.txt 2022-08-29 19:17:29.747914361 +0000
+++ HMI/US/landscape/n2t-out/Program.s.txt 2022-08-29 19:17:30.983925693 +0000
--- HMI/n2t-out/Program.s.txt 2022-07-23 14:02:48.223325770 +0000
+++ HMI/US/landscape/n2t-out/Program.s.txt 2022-07-23 14:02:49.219337687 +0000
@@ -14,6 +14,3 @@
//color vars
int defaultFontColor=65535
@@ -9,8 +9,8 @@ diff -bur HMI/n2t-out/Program.s.txt HMI/US/landscape/n2t-out/Program.s.txt
- lcd_dev fffb 0002 0000 0020
- page pageStartup
diff -bur HMI/n2t-out/pageStartup.txt HMI/US/landscape/n2t-out/pageStartup.txt
--- HMI/n2t-out/pageStartup.txt 2022-08-29 19:17:29.751914398 +0000
+++ HMI/US/landscape/n2t-out/pageStartup.txt 2022-08-29 19:17:30.983925693 +0000
--- HMI/n2t-out/pageStartup.txt 2022-07-23 14:02:48.223325770 +0000
+++ HMI/US/landscape/n2t-out/pageStartup.txt 2022-07-23 14:02:49.219337687 +0000
@@ -177,7 +177,7 @@
recmod=1
bauds=115200
@@ -20,126 +20,3 @@ diff -bur HMI/n2t-out/pageStartup.txt HMI/US/landscape/n2t-out/pageStartup.txt
//send calc crc
btlen tSend.txt,sys0
crcrest 1,0xffff // reset CRC
diff -bur HMI/n2t-out/pageTest.txt HMI/US/landscape/n2t-out/pageTest.txt
--- HMI/n2t-out/pageTest.txt 2022-08-29 19:17:29.747914361 +0000
+++ HMI/US/landscape/n2t-out/pageTest.txt 2022-08-29 19:17:30.983925693 +0000
@@ -13,36 +13,6 @@
Events
Preinitialize Event
vis p0,0
- recmod=1
- bauds=115200
-
-Variable (string) tInstruction
- Attributes
- Scope : local
- Text :
- Max. Text Size: 30
-
-Variable (string) strCommand
- Attributes
- Scope : local
- Text :
- Max. Text Size: 20
-
-Variable (string) tSend
- Attributes
- Scope : local
- Text :
- Max. Text Size: 40
-
-Text tBench
- Attributes
- Scope : local
- Dragging : 0
- Disable release event after dragging: 0
- Send Component ID : disabled
- Associated Keyboard : none
- Text :
- Max. Text Size : 20
Picture p0
Attributes
@@ -220,82 +190,3 @@
Touch Press Event
page cardQR
-Timer tmSerial
- Attributes
- Scope : local
- Period (ms): 50
- Enabled : yes
-
- Events
- Timer Event
- // data available
- if(usize>1)
- {
- bufferPos=0
- while(bufferPos<usize)
- {
- // check for 0x55 0xBB - Command Init Secuence
- if(u[bufferPos]==187&&u[bufferPos-1]==85)
- {
- //remove garbage at the start of the buffer if there's any to free buffer for command
- if(u[bufferPos]!=1)
- {
- udelete bufferPos-1
- }
- //instruction is now aligned with buffer, because we deleted garbage before instrcution
- //get length after init sequence (check if there are more than to bytes in buffer)
- if(3<usize)
- {
- // check if serial buffer has reached the announced length
- ucopy payloadLength,2,2,0
- // we are only checking payload length so we have to skip first 3 bytes (init+payload length) (-1 because of < instead of <=)
- payloadLength+=3
- // payload length does also not contain crc, so we are adding another 2 bytes for crc
- payloadLength+=2
- if(payloadLength<usize)
- {
- // calculate crc
- crcrest 1,0xFFFF
- // u[2] contains payload legth at 3rd pos in buffer, we are calculating crc from 3rd pos with number of bytes from payload length
- //crcputu 3,u[2]
- // u[2] cotnains payload length, we are calculating a crc over the whole message, so we have to add 3 to the length from u[2]
- crcputu 0,payloadLength-1
- // get recived crc to be able to compare it
- ucopy recvCrc,payloadLength-1,2,0
- // compare crc with recived value
- if(crcval==recvCrc)
- {
- // crc is okay
- // here is the location where acual code should be
- // write command to variable strCommand
- ucopy strCommand.txt,4,payloadLength-5,0
- // write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
- spstr strCommand.txt,tInstruction.txt,"~",0
- if(tInstruction.txt=="ping")
- {
- spstr strCommand.txt,tBench.txt,"~",1
- tSend.txt="pong,"+tBench.txt
- //send calc crc
- btlen tSend.txt,sys0
- crcrest 1,0xffff // reset CRC
- crcputh 55 bb
- crcputs sys0,2
- crcputs tSend.txt,0
- //send cmd
- printh 55 bb
- prints sys0,2
- prints tSend.txt,0
- prints crcval,2
- }
- // end of user code
- udelete payloadLength-1
- bufferPos=0
- }
- }
- }
- }
- // next character
- bufferPos++
- }
- }
-

View File

@@ -44,8 +44,8 @@ pageStartup
122 Unique line(s) of event code
screensaver
38 Component(s)
341 Line(s) of event code
263 Unique line(s) of event code
332 Line(s) of event code
257 Unique line(s) of event code
cardThermo
53 Component(s)
580 Line(s) of event code
@@ -62,5 +62,5 @@ cardEntities
Total
14 Page(s)
432 Component(s)
5150 Line(s) of event code
1358 Unique line(s) of event code
5141 Line(s) of event code
1351 Unique line(s) of event code

View File

@@ -402,7 +402,7 @@ Text tVersion
Horizontal Alignment : center
Vertical Alignment : center
Input Type : character
Text : 41
Text : 39
Max. Text Size : 10
Word wrap : disabled
Horizontal Spacing : 0

View File

@@ -47,7 +47,7 @@ Page popupFan
prints crcval,2
vis hSpeed,0
popupFan.bco=defaultBcoColor
for(sys0=0;sys0<20;sys0++)
for(sys0=0;sys0<40;sys0++)
{
if(b[sys0].type==98||b[sys0].type==116)
{
@@ -117,7 +117,7 @@ Text tEntity
Horizontal Alignment : left
Vertical Alignment : center
Input Type : character
Text :
Text : tEntity1
Max. Text Size : 25
Word wrap : disabled
Horizontal Spacing : 0
@@ -147,7 +147,7 @@ Text tIcon1
Horizontal Alignment : center
Vertical Alignment : center
Input Type : character
Text :
Text : 
Max. Text Size : 10
Word wrap : disabled
Horizontal Spacing : 0
@@ -177,7 +177,7 @@ Text t1
Horizontal Alignment : left
Vertical Alignment : center
Input Type : character
Text :
Text : Speed
Max. Text Size : 50
Word wrap : disabled
Horizontal Spacing : 0

View File

@@ -1075,6 +1075,9 @@ Timer tmSerial
tF4Icon.txt=tF3Icon.txt
tF3Icon.txt=tF2Icon.txt
tF2Icon.txt=tF1Icon.txt
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
}
//tMR
spstr strCommand.txt,tMR.txt,"~",16
@@ -1171,18 +1174,6 @@ Timer tmSerial
covx tTmp.txt,tMR.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",22
covx tTmp.txt,tTimeAdd.pco,0,0
if(tMRIcon.txt!=""&&p0.w!=320)
{
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
tForecast4Val.pco=tForecast3Val.pco
tForecast3Val.pco=tForecast2Val.pco
tForecast2Val.pco=tForecast1Val.pco
tForecast4.pco=tForecast3.pco
tForecast3.pco=tForecast2.pco
tForecast2.pco=tForecast1.pco
}
}
if(tInstruction.txt=="notify")
{

View File

@@ -152,7 +152,7 @@ Text tVersion
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text : 41
Text : 39
Max. Text Size : 10
Picture p0

View File

@@ -39,7 +39,7 @@ Page popupFan
prints crcval,2
vis hSpeed,0
popupFan.bco=defaultBcoColor
for(sys0=0;sys0<20;sys0++)
for(sys0=0;sys0<40;sys0++)
{
if(b[sys0].type==98||b[sys0].type==116)
{
@@ -88,7 +88,7 @@ Text tEntity
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : tEntity1
Max. Text Size : 25
Text tIcon1
@@ -98,7 +98,7 @@ Text tIcon1
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : 
Max. Text Size : 10
Text t1
@@ -108,7 +108,7 @@ Text t1
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : Speed
Max. Text Size : 50
Text tSend

View File

@@ -510,6 +510,9 @@ Timer tmSerial
tF4Icon.txt=tF3Icon.txt
tF3Icon.txt=tF2Icon.txt
tF2Icon.txt=tF1Icon.txt
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
}
//tMR
spstr strCommand.txt,tMR.txt,"~",16
@@ -606,18 +609,6 @@ Timer tmSerial
covx tTmp.txt,tMR.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",22
covx tTmp.txt,tTimeAdd.pco,0,0
if(tMRIcon.txt!=""&&p0.w!=320)
{
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
tForecast4Val.pco=tForecast3Val.pco
tForecast3Val.pco=tForecast2Val.pco
tForecast2Val.pco=tForecast1Val.pco
tForecast4.pco=tForecast3.pco
tForecast3.pco=tForecast2.pco
tForecast2.pco=tForecast1.pco
}
}
if(tInstruction.txt=="notify")
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,6 @@
diff -bur HMI/n2t-out/Program.s.txt HMI/US/portrait/n2t-out/Program.s.txt
--- HMI/n2t-out/Program.s.txt 2022-08-29 19:17:29.747914361 +0000
+++ HMI/US/portrait/n2t-out/Program.s.txt 2022-08-29 19:17:30.347919862 +0000
--- HMI/n2t-out/Program.s.txt 2022-07-23 14:02:48.223325770 +0000
+++ HMI/US/portrait/n2t-out/Program.s.txt 2022-07-23 14:02:48.731331848 +0000
@@ -14,6 +14,6 @@
//color vars
int defaultFontColor=65535
@@ -11,8 +11,8 @@ diff -bur HMI/n2t-out/Program.s.txt HMI/US/portrait/n2t-out/Program.s.txt
+ //lcd_dev fffb 0002 0000 0020
page pageStartup
diff -bur HMI/n2t-out/cardEntities.txt HMI/US/portrait/n2t-out/cardEntities.txt
--- HMI/n2t-out/cardEntities.txt 2022-08-29 19:17:29.751914398 +0000
+++ HMI/US/portrait/n2t-out/cardEntities.txt 2022-08-29 19:17:30.347919862 +0000
--- HMI/n2t-out/cardEntities.txt 2022-07-23 14:02:48.227325818 +0000
+++ HMI/US/portrait/n2t-out/cardEntities.txt 2022-07-23 14:02:48.731331848 +0000
@@ -65,6 +65,16 @@
vis nNum4,0
vis bPrev,0
@@ -458,8 +458,8 @@ diff -bur HMI/n2t-out/cardEntities.txt HMI/US/portrait/n2t-out/cardEntities.txt
if(tInstruction.txt=="pageType")
{
diff -bur HMI/n2t-out/pageStartup.txt HMI/US/portrait/n2t-out/pageStartup.txt
--- HMI/n2t-out/pageStartup.txt 2022-08-29 19:17:29.751914398 +0000
+++ HMI/US/portrait/n2t-out/pageStartup.txt 2022-08-29 19:17:30.347919862 +0000
--- HMI/n2t-out/pageStartup.txt 2022-07-23 14:02:48.223325770 +0000
+++ HMI/US/portrait/n2t-out/pageStartup.txt 2022-07-23 14:02:48.731331848 +0000
@@ -142,7 +142,7 @@
Disable release event after dragging: 0
Send Component ID : disabled
@@ -478,126 +478,3 @@ diff -bur HMI/n2t-out/pageStartup.txt HMI/US/portrait/n2t-out/pageStartup.txt
//send calc crc
btlen tSend.txt,sys0
crcrest 1,0xffff // reset CRC
diff -bur HMI/n2t-out/pageTest.txt HMI/US/portrait/n2t-out/pageTest.txt
--- HMI/n2t-out/pageTest.txt 2022-08-29 19:17:29.747914361 +0000
+++ HMI/US/portrait/n2t-out/pageTest.txt 2022-08-29 19:17:30.347919862 +0000
@@ -13,36 +13,6 @@
Events
Preinitialize Event
vis p0,0
- recmod=1
- bauds=115200
-
-Variable (string) tInstruction
- Attributes
- Scope : local
- Text :
- Max. Text Size: 30
-
-Variable (string) strCommand
- Attributes
- Scope : local
- Text :
- Max. Text Size: 20
-
-Variable (string) tSend
- Attributes
- Scope : local
- Text :
- Max. Text Size: 40
-
-Text tBench
- Attributes
- Scope : local
- Dragging : 0
- Disable release event after dragging: 0
- Send Component ID : disabled
- Associated Keyboard : none
- Text :
- Max. Text Size : 20
Picture p0
Attributes
@@ -220,82 +190,3 @@
Touch Press Event
page cardQR
-Timer tmSerial
- Attributes
- Scope : local
- Period (ms): 50
- Enabled : yes
-
- Events
- Timer Event
- // data available
- if(usize>1)
- {
- bufferPos=0
- while(bufferPos<usize)
- {
- // check for 0x55 0xBB - Command Init Secuence
- if(u[bufferPos]==187&&u[bufferPos-1]==85)
- {
- //remove garbage at the start of the buffer if there's any to free buffer for command
- if(u[bufferPos]!=1)
- {
- udelete bufferPos-1
- }
- //instruction is now aligned with buffer, because we deleted garbage before instrcution
- //get length after init sequence (check if there are more than to bytes in buffer)
- if(3<usize)
- {
- // check if serial buffer has reached the announced length
- ucopy payloadLength,2,2,0
- // we are only checking payload length so we have to skip first 3 bytes (init+payload length) (-1 because of < instead of <=)
- payloadLength+=3
- // payload length does also not contain crc, so we are adding another 2 bytes for crc
- payloadLength+=2
- if(payloadLength<usize)
- {
- // calculate crc
- crcrest 1,0xFFFF
- // u[2] contains payload legth at 3rd pos in buffer, we are calculating crc from 3rd pos with number of bytes from payload length
- //crcputu 3,u[2]
- // u[2] cotnains payload length, we are calculating a crc over the whole message, so we have to add 3 to the length from u[2]
- crcputu 0,payloadLength-1
- // get recived crc to be able to compare it
- ucopy recvCrc,payloadLength-1,2,0
- // compare crc with recived value
- if(crcval==recvCrc)
- {
- // crc is okay
- // here is the location where acual code should be
- // write command to variable strCommand
- ucopy strCommand.txt,4,payloadLength-5,0
- // write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
- spstr strCommand.txt,tInstruction.txt,"~",0
- if(tInstruction.txt=="ping")
- {
- spstr strCommand.txt,tBench.txt,"~",1
- tSend.txt="pong,"+tBench.txt
- //send calc crc
- btlen tSend.txt,sys0
- crcrest 1,0xffff // reset CRC
- crcputh 55 bb
- crcputs sys0,2
- crcputs tSend.txt,0
- //send cmd
- printh 55 bb
- prints sys0,2
- prints tSend.txt,0
- prints crcval,2
- }
- // end of user code
- udelete payloadLength-1
- bufferPos=0
- }
- }
- }
- }
- // next character
- bufferPos++
- }
- }
-

View File

@@ -1,12 +1,12 @@
+++ HMI/US/portrait/diff-eu-version.txt 2022-08-29 19:17:30.363920009 +0000
+--- HMI/n2t-out/Program.s.txt 2022-08-29 19:17:29.747914361 +0000
++++ HMI/US/portrait/n2t-out/Program.s.txt 2022-08-29 19:17:30.347919862 +0000
+++ HMI/US/portrait/diff-eu-version.txt 2022-07-23 14:02:48.743331992 +0000
+--- HMI/n2t-out/Program.s.txt 2022-07-23 14:02:48.223325770 +0000
++++ HMI/US/portrait/n2t-out/Program.s.txt 2022-07-23 14:02:48.731331848 +0000
+@@ -14,6 +14,6 @@
+ //color vars
+ int defaultFontColor=65535
+ int defaultBcoColor=6371
+--- HMI/n2t-out/cardEntities.txt 2022-08-29 19:17:29.751914398 +0000
++++ HMI/US/portrait/n2t-out/cardEntities.txt 2022-08-29 19:17:30.347919862 +0000
+--- HMI/n2t-out/cardEntities.txt 2022-07-23 14:02:48.227325818 +0000
++++ HMI/US/portrait/n2t-out/cardEntities.txt 2022-07-23 14:02:48.731331848 +0000
+@@ -65,6 +65,16 @@
+ vis bPrev,0
+ vis bNext,0
@@ -33,128 +33,5 @@
++ spstr strCommand.txt,tTmp.txt,"~",32
++ covx tTmp.txt,sys0,0,0
++ btOnOff5.val=sys0
+--- HMI/n2t-out/pageStartup.txt 2022-08-29 19:17:29.751914398 +0000
++++ HMI/US/portrait/n2t-out/pageStartup.txt 2022-08-29 19:17:30.347919862 +0000
+diff -bur HMI/n2t-out/pageTest.txt HMI/US/portrait/n2t-out/pageTest.txt
+--- HMI/n2t-out/pageTest.txt 2022-08-29 19:17:29.747914361 +0000
++++ HMI/US/portrait/n2t-out/pageTest.txt 2022-08-29 19:17:30.347919862 +0000
+@@ -13,36 +13,6 @@
+ Events
+ Preinitialize Event
+ vis p0,0
+- recmod=1
+- bauds=115200
+-
+-Variable (string) tInstruction
+- Attributes
+- Scope : local
+- Text :
+- Max. Text Size: 30
+-
+-Variable (string) strCommand
+- Attributes
+- Scope : local
+- Text :
+- Max. Text Size: 20
+-
+-Variable (string) tSend
+- Attributes
+- Scope : local
+- Text :
+- Max. Text Size: 40
+-
+-Text tBench
+- Attributes
+- Scope : local
+- Dragging : 0
+- Disable release event after dragging: 0
+- Send Component ID : disabled
+- Associated Keyboard : none
+- Text :
+- Max. Text Size : 20
+
+ Picture p0
+ Attributes
+@@ -220,82 +190,3 @@
+ Touch Press Event
+ page cardQR
+
+-Timer tmSerial
+- Attributes
+- Scope : local
+- Period (ms): 50
+- Enabled : yes
+-
+- Events
+- Timer Event
+- // data available
+- if(usize>1)
+- {
+- bufferPos=0
+- while(bufferPos<usize)
+- {
+- // check for 0x55 0xBB - Command Init Secuence
+- if(u[bufferPos]==187&&u[bufferPos-1]==85)
+- {
+- //remove garbage at the start of the buffer if there's any to free buffer for command
+- if(u[bufferPos]!=1)
+- {
+- udelete bufferPos-1
+- }
+- //instruction is now aligned with buffer, because we deleted garbage before instrcution
+- //get length after init sequence (check if there are more than to bytes in buffer)
+- if(3<usize)
+- {
+- // check if serial buffer has reached the announced length
+- ucopy payloadLength,2,2,0
+- // we are only checking payload length so we have to skip first 3 bytes (init+payload length) (-1 because of < instead of <=)
+- payloadLength+=3
+- // payload length does also not contain crc, so we are adding another 2 bytes for crc
+- payloadLength+=2
+- if(payloadLength<usize)
+- {
+- // calculate crc
+- crcrest 1,0xFFFF
+- // u[2] contains payload legth at 3rd pos in buffer, we are calculating crc from 3rd pos with number of bytes from payload length
+- //crcputu 3,u[2]
+- // u[2] cotnains payload length, we are calculating a crc over the whole message, so we have to add 3 to the length from u[2]
+- crcputu 0,payloadLength-1
+- // get recived crc to be able to compare it
+- ucopy recvCrc,payloadLength-1,2,0
+- // compare crc with recived value
+- if(crcval==recvCrc)
+- {
+- // crc is okay
+- // here is the location where acual code should be
+- // write command to variable strCommand
+- ucopy strCommand.txt,4,payloadLength-5,0
+- // write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
+- spstr strCommand.txt,tInstruction.txt,"~",0
+- if(tInstruction.txt=="ping")
+- {
+- spstr strCommand.txt,tBench.txt,"~",1
+- tSend.txt="pong,"+tBench.txt
+- //send calc crc
+- btlen tSend.txt,sys0
+- crcrest 1,0xffff // reset CRC
+- crcputh 55 bb
+- crcputs sys0,2
+- crcputs tSend.txt,0
+- //send cmd
+- printh 55 bb
+- prints sys0,2
+- prints tSend.txt,0
+- prints crcval,2
+- }
+- // end of user code
+- udelete payloadLength-1
+- bufferPos=0
+- }
+- }
+- }
+- }
+- // next character
+- bufferPos++
+- }
+- }
+-
+--- HMI/n2t-out/pageStartup.txt 2022-07-23 14:02:48.223325770 +0000
++++ HMI/US/portrait/n2t-out/pageStartup.txt 2022-07-23 14:02:48.731331848 +0000

View File

@@ -18,14 +18,18 @@ popupLight
27 Component(s)
386 Line(s) of event code
211 Unique line(s) of event code
cardMedia
34 Component(s)
388 Line(s) of event code
209 Unique line(s) of event code
popupFan
20 Component(s)
236 Line(s) of event code
150 Unique line(s) of event code
cardMedia
34 Component(s)
388 Line(s) of event code
209 Unique line(s) of event code
pageStartup
19 Component(s)
167 Line(s) of event code
122 Unique line(s) of event code
cardEntities
77 Component(s)
1348 Line(s) of event code
@@ -38,10 +42,10 @@ cardQR
32 Component(s)
403 Line(s) of event code
234 Unique line(s) of event code
pageStartup
19 Component(s)
167 Line(s) of event code
122 Unique line(s) of event code
screensaver
38 Component(s)
332 Line(s) of event code
257 Unique line(s) of event code
cardGrid
42 Component(s)
462 Line(s) of event code
@@ -50,10 +54,6 @@ cardAlarm
40 Component(s)
421 Line(s) of event code
254 Unique line(s) of event code
screensaver
38 Component(s)
341 Line(s) of event code
263 Unique line(s) of event code
cardThermo
53 Component(s)
580 Line(s) of event code
@@ -62,5 +62,5 @@ cardThermo
Total
14 Page(s)
444 Component(s)
5372 Line(s) of event code
1431 Unique line(s) of event code
5363 Line(s) of event code
1424 Unique line(s) of event code

View File

@@ -402,7 +402,7 @@ Text tVersion
Horizontal Alignment : center
Vertical Alignment : center
Input Type : character
Text : 41
Text : 39
Max. Text Size : 10
Word wrap : disabled
Horizontal Spacing : 0

View File

@@ -47,7 +47,7 @@ Page popupFan
prints crcval,2
vis hSpeed,0
popupFan.bco=defaultBcoColor
for(sys0=0;sys0<20;sys0++)
for(sys0=0;sys0<40;sys0++)
{
if(b[sys0].type==98||b[sys0].type==116)
{
@@ -117,7 +117,7 @@ Text tEntity
Horizontal Alignment : left
Vertical Alignment : center
Input Type : character
Text :
Text : tEntity1
Max. Text Size : 25
Word wrap : disabled
Horizontal Spacing : 0
@@ -147,7 +147,7 @@ Text tIcon1
Horizontal Alignment : center
Vertical Alignment : center
Input Type : character
Text :
Text : 
Max. Text Size : 10
Word wrap : disabled
Horizontal Spacing : 0
@@ -177,7 +177,7 @@ Text t1
Horizontal Alignment : left
Vertical Alignment : center
Input Type : character
Text :
Text : Speed
Max. Text Size : 50
Word wrap : disabled
Horizontal Spacing : 0

View File

@@ -1075,6 +1075,9 @@ Timer tmSerial
tF4Icon.txt=tF3Icon.txt
tF3Icon.txt=tF2Icon.txt
tF2Icon.txt=tF1Icon.txt
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
}
//tMR
spstr strCommand.txt,tMR.txt,"~",16
@@ -1171,18 +1174,6 @@ Timer tmSerial
covx tTmp.txt,tMR.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",22
covx tTmp.txt,tTimeAdd.pco,0,0
if(tMRIcon.txt!=""&&p0.w!=320)
{
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
tForecast4Val.pco=tForecast3Val.pco
tForecast3Val.pco=tForecast2Val.pco
tForecast2Val.pco=tForecast1Val.pco
tForecast4.pco=tForecast3.pco
tForecast3.pco=tForecast2.pco
tForecast2.pco=tForecast1.pco
}
}
if(tInstruction.txt=="notify")
{

View File

@@ -152,7 +152,7 @@ Text tVersion
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text : 41
Text : 39
Max. Text Size : 10
Picture p0

View File

@@ -39,7 +39,7 @@ Page popupFan
prints crcval,2
vis hSpeed,0
popupFan.bco=defaultBcoColor
for(sys0=0;sys0<20;sys0++)
for(sys0=0;sys0<40;sys0++)
{
if(b[sys0].type==98||b[sys0].type==116)
{
@@ -88,7 +88,7 @@ Text tEntity
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : tEntity1
Max. Text Size : 25
Text tIcon1
@@ -98,7 +98,7 @@ Text tIcon1
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : 
Max. Text Size : 10
Text t1
@@ -108,7 +108,7 @@ Text t1
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : Speed
Max. Text Size : 50
Text tSend

View File

@@ -510,6 +510,9 @@ Timer tmSerial
tF4Icon.txt=tF3Icon.txt
tF3Icon.txt=tF2Icon.txt
tF2Icon.txt=tF1Icon.txt
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
}
//tMR
spstr strCommand.txt,tMR.txt,"~",16
@@ -606,18 +609,6 @@ Timer tmSerial
covx tTmp.txt,tMR.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",22
covx tTmp.txt,tTimeAdd.pco,0,0
if(tMRIcon.txt!=""&&p0.w!=320)
{
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
tForecast4Val.pco=tForecast3Val.pco
tForecast3Val.pco=tForecast2Val.pco
tForecast2Val.pco=tForecast1Val.pco
tForecast4.pco=tForecast3.pco
tForecast3.pco=tForecast2.pco
tForecast2.pco=tForecast1.pco
}
}
if(tInstruction.txt=="notify")
{

Binary file not shown.

Binary file not shown.

View File

@@ -48,27 +48,15 @@ export class IconsSelector {
""");
# write mapping lib for python
with open(os.path.join(__location__, "../../../ip-symcon", "icon_mapping.php"), 'w') as f:
f.write("$icons = [\n")
for icon in icon_metadata:
iconchar = chr(int(icon['hex'], 16))
name = icon["name"]
f.write(f" \"{name}\" => \"{iconchar}\",\n")
f.write("];\n")
f.write("""
function get_icon($name) {
global $icons;
if (str_contains('text:', $name)) {
return str_replace('text:', "", $name);
}
$ma_name = str_replace('mdi:', "", $name);
if (array_key_exists($ma_name, $icons)) {
return $icons[$ma_name];
}else{
return $icons["alert-circle-outline"];
}
}
""")
# write documentation file
#with open(os.path.join(__location__, "../..","icons.md"), 'w') as f:
# f.write("""
## Icons IDs
#This file contains the Icons IDs included in the display firmware, addressable via serial.
#
#MD Icon Name | Icon
#------------ | ----
#""")
# for icon in icon_metadata:
# val = icon["name"]
# f.write(f"mdi:{val} | ![{val}](https://raw.githubusercontent.com/Templarian/MaterialDesign-SVG/0aeb4d612644d80d9d1fe242f705f362985de5dc/svg/{val}.svg)\n")

View File

@@ -173,6 +173,8 @@ char_res_string += "鎖離狀出目外斷態輔用運判閉碼助啟執轉閒"
print("Out: ")
#print(char_res_string)
import json
# check if translations.py is covered
with open("test", 'r') as f: # open in readonly mode
unique_chars = set(f.read())

View File

@@ -226,28 +226,28 @@ used_items = [
"frontend.ui.card.light.color_temperature",
"frontend.ui.card.light.position",
"frontend.state_attributes.climate.hvac_action.cooling",
"frontend.state_attributes.climate.hvac_action.drying",
"frontend.state_attributes.climate.hvac_action.fan",
"frontend.state_attributes.climate.hvac_action.heating",
"frontend.state_attributes.climate.hvac_action.idle",
"frontend.state_attributes.climate.hvac_action.off",
"frontend.state_attributes.climate.hvac_action.cooling"
"frontend.state_attributes.climate.hvac_action.drying"
"frontend.state_attributes.climate.hvac_action.fan"
"frontend.state_attributes.climate.hvac_action.heating"
"frontend.state_attributes.climate.hvac_action.idle"
"frontend.state_attributes.climate.hvac_action.off"
"backend.component.climate.state._.off",
"backend.component.climate.state._.heat",
"backend.component.climate.state._.cool",
"backend.component.climate.state._.heat_cool",
"backend.component.climate.state._.auto",
"backend.component.climate.state._.dry",
"backend.component.climate.state._.fan_only",
"backend.component.climate.state._.off"
"backend.component.climate.state._.heat"
"backend.component.climate.state._.cool"
"backend.component.climate.state._.heat_cool"
"backend.component.climate.state._.auto"
"backend.component.climate.state._.dry"
"backend.component.climate.state._.fan_only"
"backend.component.climate.state._.heat",
"backend.component.climate.state._.heat"
"frontend.ui.card.alarm_control_panel.arm_home",
"frontend.ui.card.alarm_control_panel.arm_away",
"frontend.ui.card.alarm_control_panel.arm_night",
"frontend.ui.card.alarm_control_panel.arm_vacation",
"frontend.ui.card.alarm_control_panel.disarm",
"frontend.ui.card.alarm_control_panel.arm_home"
"frontend.ui.card.alarm_control_panel.arm_away"
"frontend.ui.card.alarm_control_panel.arm_night"
"frontend.ui.card.alarm_control_panel.arm_vacation"
"frontend.ui.card.alarm_control_panel.disarm"
"backend.component.binary_sensor.state._.off",
"backend.component.binary_sensor.state.battery.off",

View File

@@ -6,22 +6,18 @@ pageIcons
6 Component(s)
0 Line(s) of event code
0 Unique line(s) of event code
pageTest
19 Component(s)
64 Line(s) of event code
61 Unique line(s) of event code
popupShutter
25 Component(s)
388 Line(s) of event code
211 Unique line(s) of event code
screensaver
38 Component(s)
341 Line(s) of event code
263 Unique line(s) of event code
pageStartup
19 Component(s)
167 Line(s) of event code
122 Unique line(s) of event code
screensaver
38 Component(s)
332 Line(s) of event code
257 Unique line(s) of event code
popupNotify
17 Component(s)
226 Line(s) of event code
@@ -38,6 +34,10 @@ cardGrid
42 Component(s)
462 Line(s) of event code
271 Unique line(s) of event code
pageTest
14 Component(s)
14 Line(s) of event code
14 Unique line(s) of event code
popupFan
20 Component(s)
236 Line(s) of event code
@@ -61,6 +61,6 @@ cardEntities
Total
14 Page(s)
437 Component(s)
5202 Line(s) of event code
1372 Unique line(s) of event code
432 Component(s)
5143 Line(s) of event code
1353 Unique line(s) of event code

View File

@@ -402,7 +402,7 @@ Text tVersion
Horizontal Alignment : center
Vertical Alignment : center
Input Type : character
Text : 41
Text : 39
Max. Text Size : 10
Word wrap : disabled
Horizontal Spacing : 0

View File

@@ -21,59 +21,6 @@ Page pageTest
Events
Preinitialize Event
vis p0,0
recmod=1
bauds=115200
Variable (string) tInstruction
Attributes
ID : 16
Scope : local
Text :
Max. Text Size: 30
Variable (string) strCommand
Attributes
ID : 17
Scope : local
Text :
Max. Text Size: 20
Variable (string) tSend
Attributes
ID : 18
Scope : local
Text :
Max. Text Size: 40
Text tBench
Attributes
ID : 15
Scope : local
Dragging : 0
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 288
y coordinate : 90
Width : 152
Height : 30
Effect : load
Effect Priority : 0
Effect Time : 300
Fill : solid color
Style : flat
Associated Keyboard : none
Font ID : 0
Back. Color : 65535
Font Color : 0
Horizontal Alignment : center
Vertical Alignment : center
Input Type : character
Text :
Max. Text Size : 20
Word wrap : disabled
Horizontal Spacing : 0
Vertical Spacing : 0
Picture p0
Attributes
@@ -100,8 +47,8 @@ Button b0
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 0
y coordinate : 0
x coordinate : 5
y coordinate : 12
Width : 100
Height : 50
Effect : load
@@ -172,8 +119,8 @@ Button b6
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 0
y coordinate : 49
x coordinate : 5
y coordinate : 64
Width : 100
Height : 50
Effect : load
@@ -208,8 +155,8 @@ Button b4
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 0
y coordinate : 96
x coordinate : 7
y coordinate : 120
Width : 100
Height : 50
Effect : load
@@ -244,8 +191,8 @@ Button b5
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 100
y coordinate : 0
x coordinate : 111
y coordinate : 12
Width : 100
Height : 50
Effect : load
@@ -280,8 +227,8 @@ Button b7
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 100
y coordinate : 49
x coordinate : 113
y coordinate : 72
Width : 100
Height : 50
Effect : load
@@ -353,8 +300,8 @@ Button b9
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 0
y coordinate : 146
x coordinate : 6
y coordinate : 175
Width : 100
Height : 50
Effect : load
@@ -389,8 +336,8 @@ Button b10
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 100
y coordinate : 98
x coordinate : 115
y coordinate : 128
Width : 100
Height : 50
Effect : load
@@ -425,8 +372,8 @@ Button b11
Disable release event after dragging: 0
Send Component ID : disabled
Opacity : 127
x coordinate : 100
y coordinate : 145
x coordinate : 117
y coordinate : 184
Width : 100
Height : 50
Effect : load
@@ -498,7 +445,7 @@ Button b2
Send Component ID : disabled
Opacity : 127
x coordinate : 0
y coordinate : 195
y coordinate : 244
Width : 100
Height : 50
Effect : load
@@ -525,83 +472,3 @@ Button b2
Touch Press Event
page cardQR
Timer tmSerial
Attributes
ID : 14
Scope : local
Period (ms): 50
Enabled : yes
Events
Timer Event
// data available
if(usize>1)
{
bufferPos=0
while(bufferPos<usize)
{
// check for 0x55 0xBB - Command Init Secuence
if(u[bufferPos]==187&&u[bufferPos-1]==85)
{
//remove garbage at the start of the buffer if there's any to free buffer for command
if(u[bufferPos]!=1)
{
udelete bufferPos-1
}
//instruction is now aligned with buffer, because we deleted garbage before instrcution
//get length after init sequence (check if there are more than to bytes in buffer)
if(3<usize)
{
// check if serial buffer has reached the announced length
ucopy payloadLength,2,2,0
// we are only checking payload length so we have to skip first 3 bytes (init+payload length) (-1 because of < instead of <=)
payloadLength+=3
// payload length does also not contain crc, so we are adding another 2 bytes for crc
payloadLength+=2
if(payloadLength<usize)
{
// calculate crc
crcrest 1,0xFFFF
// u[2] contains payload legth at 3rd pos in buffer, we are calculating crc from 3rd pos with number of bytes from payload length
//crcputu 3,u[2]
// u[2] cotnains payload length, we are calculating a crc over the whole message, so we have to add 3 to the length from u[2]
crcputu 0,payloadLength-1
// get recived crc to be able to compare it
ucopy recvCrc,payloadLength-1,2,0
// compare crc with recived value
if(crcval==recvCrc)
{
// crc is okay
// here is the location where acual code should be
// write command to variable strCommand
ucopy strCommand.txt,4,payloadLength-5,0
// write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
spstr strCommand.txt,tInstruction.txt,"~",0
if(tInstruction.txt=="ping")
{
spstr strCommand.txt,tBench.txt,"~",1
tSend.txt="pong,"+tBench.txt
//send calc crc
btlen tSend.txt,sys0
crcrest 1,0xffff // reset CRC
crcputh 55 bb
crcputs sys0,2
crcputs tSend.txt,0
//send cmd
printh 55 bb
prints sys0,2
prints tSend.txt,0
prints crcval,2
}
// end of user code
udelete payloadLength-1
bufferPos=0
}
}
}
}
// next character
bufferPos++
}
}

View File

@@ -47,7 +47,7 @@ Page popupFan
prints crcval,2
vis hSpeed,0
popupFan.bco=defaultBcoColor
for(sys0=0;sys0<20;sys0++)
for(sys0=0;sys0<40;sys0++)
{
if(b[sys0].type==98||b[sys0].type==116)
{
@@ -117,7 +117,7 @@ Text tEntity
Horizontal Alignment : left
Vertical Alignment : center
Input Type : character
Text :
Text : tEntity1
Max. Text Size : 25
Word wrap : disabled
Horizontal Spacing : 0
@@ -147,7 +147,7 @@ Text tIcon1
Horizontal Alignment : center
Vertical Alignment : center
Input Type : character
Text :
Text : 
Max. Text Size : 10
Word wrap : disabled
Horizontal Spacing : 0
@@ -177,7 +177,7 @@ Text t1
Horizontal Alignment : left
Vertical Alignment : center
Input Type : character
Text :
Text : Speed
Max. Text Size : 50
Word wrap : disabled
Horizontal Spacing : 0

View File

@@ -1075,6 +1075,9 @@ Timer tmSerial
tF4Icon.txt=tF3Icon.txt
tF3Icon.txt=tF2Icon.txt
tF2Icon.txt=tF1Icon.txt
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
}
//tMR
spstr strCommand.txt,tMR.txt,"~",16
@@ -1171,18 +1174,6 @@ Timer tmSerial
covx tTmp.txt,tMR.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",22
covx tTmp.txt,tTimeAdd.pco,0,0
if(tMRIcon.txt!=""&&p0.w!=320)
{
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
tForecast4Val.pco=tForecast3Val.pco
tForecast3Val.pco=tForecast2Val.pco
tForecast2Val.pco=tForecast1Val.pco
tForecast4.pco=tForecast3.pco
tForecast3.pco=tForecast2.pco
tForecast2.pco=tForecast1.pco
}
}
if(tInstruction.txt=="notify")
{

View File

@@ -152,7 +152,7 @@ Text tVersion
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text : 41
Text : 39
Max. Text Size : 10
Picture p0

View File

@@ -13,36 +13,6 @@ Page pageTest
Events
Preinitialize Event
vis p0,0
recmod=1
bauds=115200
Variable (string) tInstruction
Attributes
Scope : local
Text :
Max. Text Size: 30
Variable (string) strCommand
Attributes
Scope : local
Text :
Max. Text Size: 20
Variable (string) tSend
Attributes
Scope : local
Text :
Max. Text Size: 40
Text tBench
Attributes
Scope : local
Dragging : 0
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Max. Text Size : 20
Picture p0
Attributes
@@ -220,82 +190,3 @@ Button b2
Touch Press Event
page cardQR
Timer tmSerial
Attributes
Scope : local
Period (ms): 50
Enabled : yes
Events
Timer Event
// data available
if(usize>1)
{
bufferPos=0
while(bufferPos<usize)
{
// check for 0x55 0xBB - Command Init Secuence
if(u[bufferPos]==187&&u[bufferPos-1]==85)
{
//remove garbage at the start of the buffer if there's any to free buffer for command
if(u[bufferPos]!=1)
{
udelete bufferPos-1
}
//instruction is now aligned with buffer, because we deleted garbage before instrcution
//get length after init sequence (check if there are more than to bytes in buffer)
if(3<usize)
{
// check if serial buffer has reached the announced length
ucopy payloadLength,2,2,0
// we are only checking payload length so we have to skip first 3 bytes (init+payload length) (-1 because of < instead of <=)
payloadLength+=3
// payload length does also not contain crc, so we are adding another 2 bytes for crc
payloadLength+=2
if(payloadLength<usize)
{
// calculate crc
crcrest 1,0xFFFF
// u[2] contains payload legth at 3rd pos in buffer, we are calculating crc from 3rd pos with number of bytes from payload length
//crcputu 3,u[2]
// u[2] cotnains payload length, we are calculating a crc over the whole message, so we have to add 3 to the length from u[2]
crcputu 0,payloadLength-1
// get recived crc to be able to compare it
ucopy recvCrc,payloadLength-1,2,0
// compare crc with recived value
if(crcval==recvCrc)
{
// crc is okay
// here is the location where acual code should be
// write command to variable strCommand
ucopy strCommand.txt,4,payloadLength-5,0
// write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
spstr strCommand.txt,tInstruction.txt,"~",0
if(tInstruction.txt=="ping")
{
spstr strCommand.txt,tBench.txt,"~",1
tSend.txt="pong,"+tBench.txt
//send calc crc
btlen tSend.txt,sys0
crcrest 1,0xffff // reset CRC
crcputh 55 bb
crcputs sys0,2
crcputs tSend.txt,0
//send cmd
printh 55 bb
prints sys0,2
prints tSend.txt,0
prints crcval,2
}
// end of user code
udelete payloadLength-1
bufferPos=0
}
}
}
}
// next character
bufferPos++
}
}

View File

@@ -39,7 +39,7 @@ Page popupFan
prints crcval,2
vis hSpeed,0
popupFan.bco=defaultBcoColor
for(sys0=0;sys0<20;sys0++)
for(sys0=0;sys0<40;sys0++)
{
if(b[sys0].type==98||b[sys0].type==116)
{
@@ -88,7 +88,7 @@ Text tEntity
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : tEntity1
Max. Text Size : 25
Text tIcon1
@@ -98,7 +98,7 @@ Text tIcon1
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : 
Max. Text Size : 10
Text t1
@@ -108,7 +108,7 @@ Text t1
Disable release event after dragging: 0
Send Component ID : disabled
Associated Keyboard : none
Text :
Text : Speed
Max. Text Size : 50
Text tSend

View File

@@ -510,6 +510,9 @@ Timer tmSerial
tF4Icon.txt=tF3Icon.txt
tF3Icon.txt=tF2Icon.txt
tF2Icon.txt=tF1Icon.txt
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
}
//tMR
spstr strCommand.txt,tMR.txt,"~",16
@@ -606,18 +609,6 @@ Timer tmSerial
covx tTmp.txt,tMR.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",22
covx tTmp.txt,tTimeAdd.pco,0,0
if(tMRIcon.txt!=""&&p0.w!=320)
{
tF4Icon.pco=tF3Icon.pco
tF3Icon.pco=tF2Icon.pco
tF2Icon.pco=tF1Icon.pco
tForecast4Val.pco=tForecast3Val.pco
tForecast3Val.pco=tForecast2Val.pco
tForecast2Val.pco=tForecast1Val.pco
tForecast4.pco=tForecast3.pco
tForecast3.pco=tForecast2.pco
tForecast2.pco=tForecast1.pco
}
}
if(tInstruction.txt=="notify")
{

Binary file not shown.

Binary file not shown.

View File

@@ -8,17 +8,14 @@ If you like this project consider buying me a pizza 🍕 <a href="https://paypal
NsPanel Lovelace UI is a Firmware for the nextion screen inside of NSPanel in the Design of [HomeAssistant](https://www.home-assistant.io/)'s Lovelace UI Design.
**Visit https://docs.nspanel.pky.eu/ for installation instructions and documentation of the configuration.**
Supported Home Automation Systems:
- [Home Assistant](https://docs.nspanel.pky.eu/prepare_nspanel/) - AppDaemon Backend
- [ioBroker](https://docs.nspanel.pky.eu/prepare_nspanel_ioBroker/) - 3rd-party Typescript Backend maintained by @britzelpuf and @Armilar
NsPanel needs to be flashed with Tasmota (or through a 3rd-party Component with ESPHome)
**EU Model and US Model supported (in portrait and landscape orientation)**
The content of the screen is controlled by an AppDaemon Python Script installed on your HomeAssistant Instance.
Or a TypeScript on your ioBroker Instance in case you are an ioBroker User.
NsPanel needs to be flashed with Tasmota (or upcoming with ESPHome)
![nspanel-rl](docs/img/nspanel-rl.png)
## Features

View File

@@ -1,8 +1,5 @@
import uuid
class Entity(object):
def __init__(self, entity_input_config):
self.uuid = f"uuid.{uuid.uuid4().hex}"
if type(entity_input_config) is not dict:
#self._ha_api.log("Config error, not a dict check your entity configs")
self.entityId = "error"
@@ -14,7 +11,6 @@ class Entity(object):
self.status = entity_input_config.get("status")
self.condState = entity_input_config.get("state")
self.condStateNot = entity_input_config.get("state_not")
self.assumedState = entity_input_config.get("assumed_state", False)
class Card(object):
def __init__(self, card_input_config, pos=None):
@@ -34,7 +30,7 @@ class Card(object):
self.id = f"{self.cardType}_{self.key}".replace(".","_").replace("~","_").replace(" ","_")
#self._ha_api.log(f"Created Card {self.cardType} with pos {pos} and id {self.id}")
def get_entity_names(self):
def get_entity_list(self):
entityIds = []
if self.entity is not None:
entityIds.append(self.entity.entityId)
@@ -54,16 +50,6 @@ class Card(object):
entityIds.append(val.get("entity"))
return entityIds
def get_entity_list(self):
entitys = []
if self.entity is not None:
entitys.append(self.entity)
else:
for e in self.entities:
entitys.append(e)
return entitys
class LuiBackendConfig(object):
def dict_recursive_update(self, source: dict, target: dict) -> dict:
@@ -89,9 +75,7 @@ class LuiBackendConfig(object):
'sleepTimeout': 20,
'sleepBrightness': 20,
'screenBrightness': 100,
'defaultBackgroundColor': "ha-dark",
'sleepTracking': None,
'sleepTrackingZones': ["not_home", "off"],
'sleepOverride': None,
'locale': "en_US",
'timeFormat': "%H:%M",
@@ -153,13 +137,10 @@ class LuiBackendConfig(object):
# parse screensaver
self._config_screensaver = Card(self.get("screensaver"))
# parse hidden pages that can be accessed through navigate
# parsed hidden pages that can be accessed through navigate
for card in self.get("hiddenCards"):
self._config_hidden_cards.append(Card(card))
# all entites sorted by generated key, to be able to use short identifiers
self._config_entites_table = {x.uuid: x for x in self.get_all_entitys()}
def get(self, name):
path = name.split(".")
value = self._config
@@ -176,20 +157,12 @@ class LuiBackendConfig(object):
return value
def get_all_entity_names(self):
entities = []
for card in self._config_cards:
entities.extend(card.get_entity_names())
for card in self._config_hidden_cards:
entities.extend(card.get_entity_names())
entities.extend(self._config_screensaver.get_entity_names())
return entities
def get_all_entitys(self):
entities = []
for card in self._config_cards:
entities.extend(card.get_entity_list())
for card in self._config_hidden_cards:
entities.extend(card.get_entity_list())
entities.extend(self._config_screensaver.get_entity_list())
return entities
def getCard(self, pos):

View File

@@ -95,7 +95,7 @@ class LuiController(object):
sleepBrightness = 0
brightness = self.calc_current_brightness(self._config.get("screenBrightness"))
if bst is not None and self._ha_api.entity_exists(bst) and self._ha_api.get_entity(bst).state in self._config.get("sleepTrackingZones"):
if bst is not None and self._ha_api.entity_exists(bst) and self._ha_api.get_entity(bst).state in ["not_home", "off"]:
self._ha_api.log(f"sleepTracking setting brightness to 0")
sleepBrightness = 0
@@ -137,14 +137,15 @@ class LuiController(object):
sorted_timesets = sorted(sleep_brightness_config, key=lambda d: self._ha_api.parse_time(d['time']))
# calc current screensaver brightness
found_current_dim_value = False
for i in range(len(sorted_timesets)):
found = self._ha_api.now_is_between(sorted_timesets[i-1]['time'], sorted_timesets[i]['time'])
if found:
for index, timeset in enumerate(sorted_timesets):
self._ha_api.log("Current time %s", self._ha_api.get_now().time())
if self._ha_api.parse_time(timeset["time"]) > self._ha_api.get_now().time() and not found_current_dim_value:
# first time after current time, set dim value
current_screensaver_brightness = sorted_timesets[index-1]["value"]
self._ha_api.log("Setting dim value to %s", sorted_timesets[index-1])
found_current_dim_value = True
current_screensaver_brightness = sorted_timesets[i-1]['value']
# still no dim value
if not found_current_dim_value:
self._ha_api.log("Chooseing %s as fallback", sorted_timesets[0])
current_screensaver_brightness = sorted_timesets[0]["value"]
return current_screensaver_brightness
@@ -157,8 +158,8 @@ class LuiController(object):
def state_change_callback(self, entity, attribute, old, new, kwargs):
self._ha_api.log(f"Got callback for: {entity}", level="DEBUG")
self._ha_api.log(f"Current page has the following items: {self._current_card.get_entity_names()}", level="DEBUG")
if entity in self._current_card.get_entity_names():
self._ha_api.log(f"Current page has the following items: {self._current_card.get_entity_list()}", level="DEBUG")
if entity in self._current_card.get_entity_list():
self._ha_api.log(f"Callback Entity is on current page: {entity}", level="DEBUG")
self._pages_gen.render_card(self._current_card, send_page_type=False)
# send detail page update, just in case
@@ -266,10 +267,6 @@ class LuiController(object):
if button_type == "button":
if entity_id.startswith('uuid'):
le = self._config._config_entites_table.get(entity_id)
entity_id = le.entityId
if entity_id.startswith('navigate'):
# internal for navigation to nested pages
dstCard = self._config.searchCard(entity_id)
@@ -283,7 +280,7 @@ class LuiController(object):
self._ha_api.get_entity(entity_id).call_service("turn_on")
elif entity_id.startswith('script'):
self._ha_api.get_entity(entity_id).call_service("turn_on")
elif entity_id.startswith('light') or entity_id.startswith('switch') or entity_id.startswith('input_boolean') or entity_id.startswith('automation') or entity_id.startswith('fan'):
elif entity_id.startswith('light') or entity_id.startswith('switch') or entity_id.startswith('input_boolean') or entity_id.startswith('automation'):
self._ha_api.get_entity(entity_id).call_service("toggle")
elif entity_id.startswith('lock'):
if self._ha_api.get_entity(entity_id).state == "locked":
@@ -292,13 +289,6 @@ class LuiController(object):
self._ha_api.get_entity(entity_id).call_service("lock")
elif entity_id.startswith('button') or entity_id.startswith('input_button'):
self._ha_api.get_entity(entity_id).call_service("press")
elif entity_id.startswith('input_select'):
self._ha_api.get_entity(entity_id).call_service("select_next")
elif entity_id.startswith('vacuum'):
if self._ha_api.get_entity(entity_id).state == "docked":
self._ha_api.get_entity(entity_id).call_service("start")
else:
self._ha_api.get_entity(entity_id).call_service("return_to_base")
# for media page
if button_type == "media-next":
@@ -357,6 +347,6 @@ class LuiController(object):
entity = self._ha_api.get_entity(entity_id)
if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None:
for e in entity.attributes.open_sensors:
msg += f"- {self._ha_api.get_entity(e).attributes.friendly_name}\r\n"
msg += f"- {self._ha_api.get_entity(e).attributes.friendly_name}\n"
self._pages_gen.send_message_page("opnSensorNotifyRes", "", msg, "", "")

View File

@@ -93,8 +93,6 @@ def map_to_mdi_name(ha_type, state=None, device_class="_", cardType=None):
return "lightbulb"
elif ha_type == "fan":
return "fan"
elif ha_type == "vacuum":
return "robot-vacuum"
elif ha_type == "input_boolean":
return "check-circle-outline" if state == "on" else "close-circle-outline"
elif ha_type == "cover":
@@ -115,22 +113,6 @@ def map_to_mdi_name(ha_type, state=None, device_class="_", cardType=None):
return sensor_mapping[device_class] if device_class in sensor_mapping else "alert-circle-outline"
elif ha_type == "alarm-arm-fail":
return "progress-alert"
elif ha_type == "alarm_control_panel":
if state == "disarmed":
return "shield-off"
if state == "armed_home":
return "shield-home"
if state == "armed_away":
return "shield-lock"
if state == "armed_night":
return "weather-night"
if state == "armed_vacation":
return "shield-airplane"
elif ha_type == "sun":
if state == "above_horizon":
return "weather-sunset-up"
if state == "below_horizon":
return "weather-sunset-down"
else:
return "alert-circle-outline"

View File

@@ -22,7 +22,7 @@ class LuiPagesGen(object):
self._locale = config.get("locale")
self._send_mqtt_msg = send_mqtt_msg
def get_entity_color(self, entity, ha_type=None, overwrite=None):
def get_entity_color(self, entity, overwrite=None):
if overwrite is not None:
if type(overwrite) is list:
return rgb_dec565(overwrite)
@@ -35,19 +35,7 @@ class LuiPagesGen(object):
attr = entity.attributes
default_color_on = rgb_dec565([253, 216, 53])
default_color_off = rgb_dec565([68, 115, 158])
icon_color = default_color_on if entity.state in ["on", "unlocked", "above_horizon"] else default_color_off
if ha_type == "alarm_control_panel":
if entity.state == "disarmed":
icon_color = rgb_dec565([13,160,53])
if entity.state == "armed_home":
icon_color = rgb_dec565([223,76,30])
if entity.state == "armed_away":
icon_color = rgb_dec565([223,76,30])
if entity.state == "armed_night":
icon_color = rgb_dec565([223,76,30])
if entity.state == "armed_vacation":
icon_color = rgb_dec565([223,76,30])
icon_color = default_color_on if entity.state in ["on", "unlocked"] else default_color_off
if "rgb_color" in attr:
color = attr.rgb_color
@@ -141,23 +129,6 @@ class LuiPagesGen(object):
entity = self._ha_api.get_entity(wOF.get("entity"))
up = name if name is not None else entity.attributes.friendly_name
icon = get_icon_id_ha("sensor", state=entity.state, device_class=entity.attributes.get("device_class", ""), overwrite=icon)
if "color" in wOF:
if theme is None:
theme = {}
color = wOF.get("color")
if type(color) is dict:
for overwrite_state, overwrite_val in color.items():
if overwrite_state == entity.state:
color = overwrite_val
if i == 1:
theme["tF1Icon"] = color
elif i == 2:
theme["tF2Icon"] = color
elif i == 3:
theme["tF3Icon"] = color
elif i == 4:
theme["tF4Icon"] = color
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
down = f"{entity.state} {unit_of_measurement}"
weather_res+=f"~{up}~{icon}~{down}"
@@ -191,7 +162,6 @@ class LuiPagesGen(object):
icon = item.iconOverride
colorOverride = item.colorOverride
name = item.nameOverride
uuid = item.uuid
# type of the item is the string before the "." in the entityId
entityType = entityId.split(".")[0]
@@ -209,7 +179,7 @@ class LuiPagesGen(object):
if item.status is not None and self._ha_api.entity_exists(item.status):
status_entity = self._ha_api.get_entity(item.status)
icon_res = get_icon_id_ha(item.status.split(".")[0], state=status_entity.state, device_class=status_entity.attributes.get("device_class", "_"), overwrite=icon)
icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride)
icon_color = self.get_entity_color(entity, overwrite=colorOverride)
if item.status.startswith("sensor") and cardType == "cardGrid":
icon_res = status_entity.state[:4]
if icon_res[-1] == ".":
@@ -224,10 +194,6 @@ class LuiPagesGen(object):
name = name if name is not None else "conf name missing"
icon_res = get_icon_id(icon) if icon is not None else get_icon_id("alert-circle-outline")
return f"~text~{entityId}~{icon_res}~17299~{name}~{value}"
if entityType == "service":
icon_id = get_icon_id_ha("script", overwrite=icon)
text = get_translation(self._locale, "frontend.ui.card.script.run")
return f"~button~{uuid}~{icon_id}~17299~{name}~{text}"
if not self._ha_api.entity_exists(entityId):
return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~Not found check~ apps.yaml"
@@ -239,7 +205,7 @@ class LuiPagesGen(object):
if item.condStateNot is not None and item.condState != entity.state:
return ""
name = name if name is not None else entity.attributes.get("friendly_name","unknown")
name = name if name is not None else entity.attributes.friendly_name
if entityType == "cover":
device_class = entity.attributes.get("device_class", "window")
@@ -259,11 +225,11 @@ class LuiPagesGen(object):
else:
pos_status = pos
if bits & 0b00000001: # SUPPORT_OPEN
if ( pos != 100 and not (entity.state == "open" and pos == "disable") ) or item.assumedState:
if pos != 100 and not (entity.state == "open" and pos == "disable"):
icon_up_status = "enable"
icon_up = get_action_id_ha(ha_type=entityType, action="open", device_class=device_class)
if bits & 0b00000010: # SUPPORT_CLOSE
if ( pos != 0 and not (entity.state == "closed" and pos == "disable") ) or item.assumedState:
if pos != 0 and not (entity.state == "closed" and pos == "disable"):
icon_down_status = "enable"
icon_down = get_action_id_ha(ha_type=entityType, action="close", device_class=device_class)
if bits & 0b00001000: # SUPPORT_STOP
@@ -316,36 +282,15 @@ class LuiPagesGen(object):
icon_color = self.get_entity_color(entity, overwrite=colorOverride)
text = get_translation(self._locale, "frontend.ui.card.lock.lock") if entity.state == "unlocked" else get_translation(self._locale, "frontend.ui.card.lock.unlock")
return f"~button~{entityId}~{icon_id}~{icon_color}~{name}~{text}"
if entityType in ["number", "input_number"]:
icon_id = get_icon_id_ha("number", state=entity.state, overwrite=icon)
if entityType == "number":
icon_id = get_icon_id_ha("number", overwrite=icon)
min_v = entity.attributes.get("min", 0)
max_v = entity.attributes.get("max", 100)
return f"~number~{entityId}~{icon_id}~17299~{name}~{entity.state}|{min_v}|{max_v}"
if entityType == "input_text":
icon_id = get_icon_id_ha("input_text", state=entity.state, overwrite=icon)
icon_id = get_icon_id_ha("input_text", overwrite=icon)
value = entity.state
return f"~text~{entityId}~{icon_id}~17299~{name}~{value}"
if entityType == "input_select":
icon_id = get_icon_id_ha("button", state=entity.state, overwrite=icon)
text = entity.state
return f"~button~{entityId}~{icon_id}~17299~{name}~{text}"
if entityType == "vacuum":
icon_id = get_icon_id_ha("vacuum", state=entity.state, overwrite=icon)
if entity.state == "docked":
text = "Start"
else:
text = "Return"
return f"~button~{entityId}~{icon_id}~17299~{name}~{text}"
if entityType == "alarm_control_panel":
icon_color = self.get_entity_color(entity, ha_type=entityType, overwrite=colorOverride)
icon_id = get_icon_id_ha(entityType, state=entity.state, overwrite=icon)
text = get_translation(self._locale, f"frontend.state_badge.alarm_control_panel.{entity.state}")
return f"~text~{entityId}~{icon_id}~{icon_color}~{name}~{text}"
if entityType == "sun":
icon_color = self.get_entity_color(entity, overwrite=colorOverride)
icon_id = get_icon_id_ha(entityType, state=entity.state, overwrite=icon)
text = get_translation(self._locale, f"backend.component.sun.state._.{entity.state}")
return f"~text~{entityId}~{icon_id}~{icon_color}~{name}~{text}"
return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~unsupported~"
def generate_entities_page(self, navigation, heading, items, cardType):
@@ -464,7 +409,7 @@ class LuiPagesGen(object):
command = f"entityUpd~{heading}~{navigation}~{item}~{icon}~{title}~{author}~{volume}~{iconplaypause}~{source}~{speakerlist[:200]}~{onoffbutton}~{mediaBtn}"
self._send_mqtt_msg(command)
def generate_alarm_page(self, navigation, entity, overwrite_supported_modes, alarmBtn):
def generate_alarm_page(self, navigation, entity, alarmBtn):
item = entity.entityId
if not self._ha_api.entity_exists(item):
command = f"entityUpd~{item}~{navigation}~Not found~Not found~Check your~Check your~apps.~apps.~yaml~yaml~0~~0"
@@ -479,7 +424,6 @@ class LuiPagesGen(object):
icon = get_icon_id("shield-off")
if not entity.attributes.get("code_arm_required", False):
numpad = "disable"
if overwrite_supported_modes is None:
bits = entity.attributes.supported_features
if bits & 0b000001:
supported_modes.append("arm_home")
@@ -489,8 +433,6 @@ class LuiPagesGen(object):
supported_modes.append("arm_night")
if bits & 0b100000:
supported_modes.append("arm_vacation")
else:
supported_modes = overwrite_supported_modes
else:
supported_modes.append("disarm")
@@ -520,7 +462,7 @@ class LuiPagesGen(object):
#add button to show sensor state
add_btn = ""
if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None:
add_btn=f"{get_icon_id('progress-alert')}~{rgb_dec565([243,179,0])}~"
add_btn=f"{get_icon_id('progress-alert')}~{rgb_dec565([243,179,0])}~opnSensorNotify"
if alarmBtn is not None and type(alarmBtn) is dict:
entity = alarmBtn.get("entity")
iconnav = get_icon_id_ha("alarm-arm-fail", overwrite=alarmBtn.get("icon"))
@@ -576,8 +518,7 @@ class LuiPagesGen(object):
self.generate_media_page(navigation, card.title, card.entity, mediaBtn)
if card.cardType == "cardAlarm":
alarmBtn = card.raw_config.get("alarmControl")
overwrite_supported_modes = card.raw_config.get("supportedModes")
self.generate_alarm_page(navigation, card.entity, overwrite_supported_modes, alarmBtn)
self.generate_alarm_page(navigation, card.entity, alarmBtn)
if card.cardType == "screensaver":
theme = card.raw_config.get("theme")
self.update_screensaver_weather(theme)
@@ -653,11 +594,11 @@ class LuiPagesGen(object):
if bits & 0b00001111:
pos_translation = get_translation(self._locale, "frontend.ui.card.cover.position")
if bits & 0b00000001: # SUPPORT_OPEN
if ( pos != 100 and not (entity.state == "open" and pos == "disable") ):
if pos != 100 and not (entity.state == "open" and pos == "disable"):
icon_up_status = "enable"
icon_up = get_action_id_ha(ha_type=entityType, action="open", device_class=device_class)
if bits & 0b00000010: # SUPPORT_CLOSE
if ( pos != 0 and not (entity.state == "closed" and pos == "disable") ):
if pos != 0 and not (entity.state == "closed" and pos == "disable"):
icon_down_status = "enable"
icon_down = get_action_id_ha(ha_type=entityType, action="close", device_class=device_class)
#if bits & 0b00000100: # SUPPORT_SET_POSITION
@@ -692,14 +633,14 @@ class LuiPagesGen(object):
icon_color = self.get_entity_color(entity)
speed = entity.attributes.get("percentage")
speedMax = 100
if(speed is None):
if(speed == None):
speed = "disable"
else:
speed = round(entity.attributes.get("percentage")/entity.attributes.get("percentage_step"))
speedMax = int(100/entity.attributes.get("percentage_step"))
speed_translation = get_translation(self._locale, "frontend.ui.card.fan.speed")
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~{get_icon_id('fan')}~{icon_color}~{switch_val}~{speed}~{speedMax}~{speed_translation}")
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~{get_icon_id('lightbulb')}~{icon_color}~{switch_val}~{speed}~{speedMax}~{speed_translation}")
def send_message_page(self, ident, heading, msg, b1, b2):
self._send_mqtt_msg(f"pageType~popupNotify")

View File

@@ -24,8 +24,8 @@ class NsPanelLovelaceUIManager(hass.Hass):
controller = LuiController(self, cfg, send_mqtt_msg)
desired_display_firmware_version = 41
version = "v3.3.1"
desired_display_firmware_version = 39
version = "v3.2.0"
model = cfg.get("model")
if model == "us-l":

View File

@@ -18,4 +18,3 @@ key | optional | type | default | description
`entity` | False | string | `None` | contains the entity of the current card
`key` | True | string | `None` | Used by navigate items
`alarmControl` | True | complex | `None` | overwrites the action executed on pressing the left bottom icon, by default this button is used to show a list of open sensors on a failed attempt to arm.
`supportedModes` | True | list | `None` | Supply list of arm modes if you want to limit the modes on the card. Example `['arm_away', 'arm_night']`

View File

@@ -31,16 +31,12 @@ List of supported entitiy types for this page:
- sensor
- button
- number
- input_number
- scenes
- script
- input_button
- light
- input_text (read-only)
- input_select
- lock
- fan
- automation
- alarm
- sun
- iText

View File

@@ -37,16 +37,11 @@ List of supported entitiy types for this page:
- sensor
- button
- number
- input_number
- scenes
- script
- input_button
- light
- input_text (read-only)
- input_select
- lock
- fan
- automation
- alarm
- sun
- iText

View File

@@ -36,7 +36,6 @@ List of supported entitiy types for this page:
- scenes
- script
- input_button
- input_select
- light
- input_text (read-only)
- lock

View File

@@ -58,7 +58,6 @@ key | optional | type | default | description
`sleepBrightness` | True | integer/complex | `20` | Brightness for the screen on the screensaver, see example below for complex/scheduled config.
`screenBrightness` | True | integer/complex | `100` | Brightness for the screen during usage, config format is the same as sleepBrightness.
`sleepTracking` | True | string | None | Forces screensaver brightness to 0 in case entity state is not_home or off, can be a group, person or device_tracker entity.
`sleepTrackingZones` | True | list | `["not_home", "off"]` | Allows you to set your own states for sleepTracking
`sleepOverride` | True | complex | None | Allows overriding of the sleepBrightness if entity state is on, true or home. Overrides sleepBrightness but sleepTracking takes precedence.
`locale` | True | string | `en_US` | Used by babel to determinante Date format on screensaver, also used for localization.
`dateFormatBabel` | True | string | `full` | formatting options on https://babel.pocoo.org/en/latest/dates.html?highlight=name%20of%20day#date-fields

View File

@@ -11,8 +11,9 @@ Change the topic to something unique for your panel, you will need this topic la
# Configure MQTT Connection on AppDaemon
For the app to work you need a working MQTT Configuration in AppDaemon. Please add the configuration of your mqtt server, user and password to your existing `appdaemon.yaml` Restart your AppDaemon Container (not HomeAssistant) after adding the MQTT Configuration.
For the app to work you need a working MQTT Configuration in AppDaemon. Please add the configuration of your mqtt server, user and password to your existing `appdaemon.yaml`
NOTE: This are not the options of the AppDaemon Addon in Home Assistant.
You will find this file in the following location: `config/appdaemon/appdeamon.yaml`
```yaml

View File

@@ -15,7 +15,6 @@ key | optional | type | default | description
`state` | True | string | `None` | Only displayed if Entity state is equal to this value
`state_not` | True | string | `None` | Only displayed if Entity state is unequal to this value
`status` | True | string | `None` | Only valid for navigate items, adds a entity to track state for the icon
`assumed_state` | True | string | `None` | Only for cover items, up, down and stop buttons are always shown
## Override Icons or Names

View File

@@ -13,7 +13,7 @@ Your appdaemon mqtt config is wrong, check your appdaemon.yaml.
The log of your mqtt broker might give you additional information.
2. Check MQTT Configuration of Tasmota.
Your Tasmota device needs to connect sucessfully to your MQTT Broker, if you are in the waiting for content screen, the panel will send periodic messages to it's mqtt topic. Note that there is a minimum password length of 5 chars for the MQTT Connection in Tasmota.
Your Tasmota device needs to connect sucessfully to your MQTT Broker, if you are in the waiting for content screen, the panel will send periodic messages to it's mqtt topic.
3. Make sure that you are using the same topic in apps.yaml and in your tasmota configuration.
The examples in the docs ([MQTT Config](https://docs.nspanel.pky.eu/configure_mqtt/)) are an valid example (tasmota<>apps.yaml).

View File

@@ -14,7 +14,7 @@ Content of the screen is controlled by a AppDaemon Python Script installed on yo
Or an TypeScript on your ioBroker Instance in case you are an ioBroker User.
NsPanel needs to be flashed with Tasmota (or with the 3rd Party ESPHome Component from [@sairon](https://github.com/sairon/esphome-nspanel-lovelace-ui))
NsPanel needs to be flashed with Tasmota (or upcoming with ESPHome)
![nspanel-rl](img/nspanel-rl.png)

View File

@@ -2,8 +2,3 @@
The Backend for ioBroker is maintained by [britzelpuf](https://github.com/britzelpuf) and [armilar](https://github.com/armilar)
https://forum.iobroker.net/topic/50888/sonoff-nspanel/612
See the Readme in the ioBroker Folder for more details.
[iobroker ReadMe](https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker)

View File

@@ -14,7 +14,7 @@ It is possible to exit from the page by sending `exitPopup`
Send Message to the Panel combined with a buzzer sound:
```
```
nspanel_popup_notification:
alias: Popup Notification
sequence:
@@ -25,11 +25,11 @@ nspanel_popup_notification:
title }}~65535~~~~~{{ message }}~65535~{{ timeout }}; Buzzer 2,2,2
mode: single
icon: mdi:message-badge
```
```
Send Message to the Panel:
```
```
nspanel_popup_notification:
alias: Popup Notification
sequence:
@@ -40,7 +40,7 @@ nspanel_popup_notification:
title }}~65535~~~~~{{ message }}~65535~{{ timeout }}
mode: single
icon: mdi:message-badge
```
```
## Notification on screensaver
@@ -50,7 +50,7 @@ The screensaver can display Notifications by sending this command to the CustomS
Send Message to the Screensaver combined with a buzzer sound:
```
```
nspanel_screensaver_notification:
alias: Screensaver Notification
sequence:
@@ -60,11 +60,11 @@ nspanel_screensaver_notification:
payload: CustomSend notify~{{ heading }}~{{ message }}; Buzzer 2,2,2
mode: single
icon: mdi:message-badge
```
```
Send Message to the Screensaver:
```
```
nspanel_screensaver_notification:
alias: Screensaver Notification
sequence:
@@ -74,4 +74,5 @@ nspanel_screensaver_notification:
payload: CustomSend notify~{{ heading }}~{{ message }}
mode: single
icon: mdi:message-badge
```
```

View File

@@ -1,6 +1,6 @@
# Flash Tasmota to your NSPanel
You need to connect to your nspanel via serial and flash tasmota [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin) to your NSPanel.
You need to connect to your nspanel via serial and flash tasmtoa [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin) to your NSPanel.
You can use the Tasmota Web Installer to do so. [Tasmota Web Installer](https://tasmota.github.io/install/)
Checkout Blakadders Template Repo for more information on flashing, do not use the autoexec.be from this page.
@@ -44,7 +44,7 @@ US Version Landscape: `FlashNextion http://nspanel.pky.eu/lui-us-l-release.tft`
Note: For the US Version Users - keep in mind that you need to add the model config option to your apps.yaml later, more details on config overview page
Note: For the US Version Users - keepin mind that you need to add the model config option to your apps.yaml later, more details on config overview page
<details>

View File

@@ -1,15 +1,11 @@
# Flash Tasmota to your NSPanel
You need to connect to your nspanel via serial and flash tasmota [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin) to your NSPanel.
You need to connect to your nspanel via serial and flash tasmtoa [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin) to your NSPanel.
You can use the Tasmota Web Installer to do so. [Tasmota Web Installer](https://tasmota.github.io/install/)
Checkout Blakadders Template Repo for more information on flashing, do not use the autoexec.be from this page.
[NSPanel Page of the Tasmota Template Repository](https://templates.blakadder.com/sonoff_NSPanel.html)
If you prefer EspHome over Tasmota, you can use this thrid party esphome component, which is replacing tasmota and the berry driver of this project.
[ESPHome component](https://github.com/sairon/esphome-nspanel-lovelace-ui)
## Configure Tasmota Template for NSPanel
Configure the NSPanel template for Tasmota. (Go to Configuration and Configure Other and paste the template there, make sure to tick the activate checkbox)
@@ -42,15 +38,14 @@ US Version Portrait: `FlashNextion http://nspanel.pky.eu/lui-us-p-release.tft`
US Version Landscape: `FlashNextion http://nspanel.pky.eu/lui-us-l-release.tft`
<details>
<summary>Alternatively you can use your own webserver:</summary>
<summary>Alternatively you can use your own webserver or the one build into HomeAssistant:</summary>
<br>
Upload the nspanel.tft from the lastest release to a Webserver and execute the following command in Tasmota Console.
Upload the nspanel.tft from the lastest release to a Webserver (for example www folder of Home Assistant) and execute the following command in Tasmota Console. (Development Version: [tft file from HMI folder](HMI/nspanel.tft))
**Webserver must be HTTP, HTTPS is not supported, due to limitations of berry lang on tasmota**
`FlashNextion http://ip-address-of-your-webserver:8123/local/nspanel.tft`
`FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft`
</details>

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,5 @@
# NSPanel ioBroker Integration
## Tutorials
https://forum.iobroker.net/post/807730
## German Video Tutorial by haus-automatisierung.com
https://www.youtube.com/watch?v=ZPLJk2ZLo_8 - NSPanel mit Lovelace UI - so habe ich mir das vorgestellt!
## Features
- Thermostat Card
@@ -16,35 +10,35 @@ https://www.youtube.com/watch?v=ZPLJk2ZLo_8 - NSPanel mit Lovelace UI - so habe
- Screensaver Page with Time, Date and Weather Information.
## Requirements
- [ioBroker](https://github.com/ioBroker/ioBroker)
- [MQTT adapter](https://github.com/ioBroker/ioBroker.mqtt) in server mode or configured as client with Mosquitto (or another MQTT broker)
- [JavaScript adapter](https://github.com/ioBroker/ioBroker.javascript)
- [Devices adapter](https://github.com/ioBroker/ioBroker.devices)
- [Accuweather adapter](https://github.com/iobroker-community-adapters/ioBroker.accuweather) for screensaver information
- all devices needs to be defined in the devices panel
- ioBroker
- MQTT Broker/Client
- Javascript
- devices (default)
- all devices needs to be defined in the devices panel
- supported device roles are light, dimmer, blind, thermostat
## Note
Currently the names are pulled from the objects data field ``common.name.de``.
If you use a different language please search and replace the ``common.name.de`` with your language.
Currently the names are pulled from the objects data field common.name.de.
If you use a different language please search and replace the "common.name.de" with your language.
You can find this in the device raw settings.
## Installation
- Import this script into the ioBroker javascript instance and choose TypeScript. *Make sure the version of the adapter is not to old.*
## Installation
- Import this script into the ioBroker javascript instance and choose Typescript.
- Make sure the version of the adapter is not to old.
- Find the config variable and update to your needs.
- Make sure your device is connected with the mqtt instance.
- Create the ``CustomSend`` state by
- sending a dummy message to ``cmnd/<yourPanel>/CustomSend`` (the mqtt adapter will create the object automatically)
- or create the object manually within ioBroker (expert mode required)
- Place the file ``icon_mapping.ts`` in a new script in the ``global`` folder (expert mode required)
- The format strings are not used right now.
- Make sure your device is connected with the mqtt instance. I didn't get it working with the sonoff adapter, but I didn't tried it too long.
- Create a state with a mqtt client or create one per hand. The mqtt adapter will not create the state CustomSend
- you only need to send a dummy message to cmnd/<yourPanel>/CustomSend
- then the state will be created
- Put the file icon_mapping.ts in the global folder
## Hardware buttons
If you like you can add special pages for the buttons.
Add this rule to Tasmota:
First you need to add this rule to Tasmota:
```
Rule2 on Button1#state do Publish tele/%topic%/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish tele/%topic%/RESULT {"CustomRecv":"event,button2"} endon
@@ -52,47 +46,38 @@ Rule2
```
## Colors
You can define colors this way and use them later in the PageItem element
```js
```
const BatteryFull: RGB = { red: 96, green: 176, blue: 62 }
const BatteryEmpty: RGB = { red: 179, green: 45, blue: 25 }
```
## The config element in the script which needs to be configured
```ts
```
var config: Config = {
panelRecvTopic: 'mqtt.0.tele.WzDisplay.RESULT', // Object to receive data from the panel
panelSendTopic: 'mqtt.0.cmnd.WzDisplay.CustomSend', // Object to send data to the panel
panelRecvTopic: "mqtt.0.tele.WzDisplay.RESULT", // This is the object where the panel send the data to.
panelSendTopic: "mqtt.0.cmnd.WzDisplay.CustomSend", // This is the object where data is send to the panel.
firstScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.HUMIDITY", ScreensaverEntityIcon: "water-percent", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "%" },
// Items which should be presented on the screensaver page
firstScreensaverEntity: { ScreensaverEntity: 'alias.0.Wetter.HUMIDITY', ScreensaverEntityIcon: 'water-percent', ScreensaverEntityText: 'Luft', ScreensaverEntityUnitText: '%' },
secondScreensaverEntity: { ScreensaverEntity: 'alias.0.Wetter.PRECIPITATION_CHANCE', ScreensaverEntityIcon: 'weather-pouring', ScreensaverEntityText: 'Regen', ScreensaverEntityUnitText: '%' },
thirdScreensaverEntity: { ScreensaverEntity: 'alias.0.Batterie.ACTUAL', ScreensaverEntityIcon: 'battery-medium', ScreensaverEntityText: 'Batterie', ScreensaverEntityUnitText: '%' },
fourthScreensaverEntity: { ScreensaverEntity: 'alias.0.Pv.ACTUAL', ScreensaverEntityIcon: 'solar-power', ScreensaverEntityText: 'PV', ScreensaverEntityUnitText: 'W' },
screenSaverDoubleClick: false, // Double touch needed to leave screensaver
secondScreensaverEntity: { ScreensaverEntity: "alias.0.Wetter.PRECIPITATION_CHANCE", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" },
thirdScreensaverEntity: { ScreensaverEntity: "alias.0.Batterie.ACTUAL", ScreensaverEntityIcon: "battery-medium", ScreensaverEntityText: "Batterie", ScreensaverEntityUnitText: "%" },
fourthScreensaverEntity: { ScreensaverEntity: "alias.0.Pv.ACTUAL", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "PV", ScreensaverEntityUnitText: "W" },
screenSaverDoubleClick: false, // Doubletouch needed for leaving screensaver.
timeoutScreensaver: 15, // Timeout for screensaver
dimmode: 8, // Display dim
locale: 'de_DE', // not used right now
timeFormat: '%H:%M', // not used right now
dateFormat: '%A, %d. %B %Y', // not used right now
weatherEntity: 'alias.0.Wetter',
locale: "de_DE", // not used right now
timeFormat: "%H:%M", // not used right now
dateFormat: "%A, %d. %B %Y", // not used right now
weatherEntity: "alias.0.Wetter",
defaultColor: Off, // Default color of all elements
defaultOnColor: RGB, // Default on state color for items
defaultOffColor: RGB, // Default off state color for page
temperatureUnit: '°C', // Unit to append on temperature sensors
pages: [
Wohnen,
Strom,
temperatureUnit: "°C", // Unit to append on temperature sensors
pages: [Wohnen, Strom,
{
type: 'cardThermo',
heading: 'Thermostat',
useColor: true,
items:
[<PageItem>{ id: 'alias.0.WzNsPanel' }
]
"type": "cardThermo",
"heading": "Thermostat",
"useColor": true,
"items": [<PageItem>{ id: "alias.0.WzNsPanel" }]
}
],
button1Page: button1Page, // A cardEntities, cardThermo or nothing. This will be opened when pressing button1
@@ -101,8 +86,7 @@ var config: Config = {
```
The pageItem element:
```ts
```
type PageItem = {
id: string, // the element in ioBroker devices
icon: (string | undefined), // the icon which should be displayed instead of the default detected. (not implemented)
@@ -117,37 +101,37 @@ type PageItem = {
}
```
If you want you can create dedicated objects, so you don't need to declare them again. Then you can use tehm in the pages array and button pages.
```ts
const button1Page: PageGrid =
```
var button1Page: PageGrid =
{
type: 'cardGrid',
heading: 'Radio',
useColor: true, // should colors be enabled on this page, can be overridden in PageItem
items: [
<PageItem>{ id: 'alias.0.Radio.NJoy' },
<PageItem>{ id: 'alias.0.Radio.Delta_Radio' },
<PageItem>{ id: 'alias.0.Radio.NDR2' },
"type": "cardGrid",
"heading": "Radio",
"useColor": true, // should colors be enabled on this page, can be overridden in PageItem
"items": [
<PageItem>{ id: "alias.0.Radio.NJoy" },
<PageItem>{ id: "alias.0.Radio.Delta_Radio" },
<PageItem>{ id: "alias.0.Radio.NDR2" },
]
};
```
Pages array can look like this, so you can add the pages as object or define them in the array itself. This is up to you.
```ts
```
pages: [
button1Page,
{
type: 'cardEntities',
heading: 'Strom',
useColor: true, // should colors be enabled on this page, can be overridden in PageItem
items: [
<PageItem>{ id: 'alias.0.Netz', icon: 'flash', interpolateColor: true, offColor: BatteryFull, onColor: Red, minValue: -1000, maxValue: 1000 },
<PageItem>{ id: 'alias.0.Hausverbrauch', icon: 'flash', interpolateColor: true, offColor: BatteryFull, onColor: Red, maxValue: 1000 },
<PageItem>{ id: 'alias.0.Pv', name: 'Solar', icon: 'solar-power', interpolateColor: true, offColor: Off, onColor: BatteryFull, maxValue: 1000 },
<PageItem>{ id: 'alias.0.Batterie', icon: 'battery-medium', interpolateColor: true, offColor: BatteryEmpty, onColor: BatteryFull }
"type": "cardEntities",
"heading": "Strom",
"useColor": true, // should colors be enabled on this page, can be overridden in PageItem
"items": [
<PageItem>{ id: "alias.0.Netz", icon: "flash", interpolateColor: true, offColor: BatteryFull, onColor: Red, minValue: -1000, maxValue: 1000 },
<PageItem>{ id: "alias.0.Hausverbrauch", icon: "flash", interpolateColor: true, offColor: BatteryFull, onColor: Red, maxValue: 1000 },
<PageItem>{ id: "alias.0.Pv", name: "Solar" ,icon: "solar-power", interpolateColor: true, offColor: Off, onColor: BatteryFull, maxValue: 1000 },
<PageItem>{ id: "alias.0.Batterie", icon: "battery-medium", interpolateColor: true, offColor: BatteryEmpty, onColor: BatteryFull }
]
}
];
}]
```

File diff suppressed because it is too large Load Diff

View File

@@ -65,13 +65,13 @@ plugins:
nav:
- "Overview": index.md
- "Getting started (Home Assistant)":
- "Getting started (HA)":
- "First steps":
- "Prepare NsPanel": prepare_nspanel.md
- "Prepare Home Assistant": prepare_ha.md
- "Configure MQTT": configure_mqtt.md
- "FAQ": faq.md
- "Configuration - apps.yaml (Home Assistant)":
- "Configuration - apps.yaml (HA)":
- "Overview": config-overview.md
- "Screensaver": config-screensaver.md
- "Cards":
@@ -87,5 +87,5 @@ nav:
- "Physical Buttons": phys-btn.md
- "Getting started (ioBroker)":
- "Prepare NsPanel": prepare_nspanel_ioBroker.md
- "Prepare NsPanel": prepare_nspanel2.md
- "Prepare ioBroker": iobroker-install.md