From d57fddbbf57caf359801ffcebde2fd16ec98834a Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 28 Dec 2022 20:00:44 +0100 Subject: [PATCH] start reworking navigation paramters (#644) * modify cardGrid/cardEntities nav * rework backend nav for new style * fix some bugs * update other pages with new nav paramters * readd readme part --- HMI/README.md | 2059 ++++++++++++++++- HMI/code_gen/pages/cardEntitiesSerial.py | 4 +- HMI/code_gen/pages/cardGridSerial.py | 2 +- HMI/code_gen/pages/cardMedia.py | 20 +- HMI/code_gen/pages/cardPower.py | 10 +- HMI/code_gen/pages/cardThermo.py | 28 +- HMI/code_gen/pages/out.txt | 360 +++ HMI/code_gen/pages/shared.py | 55 +- HMI/nspanel.HMI | Bin 9115979 -> 9115979 bytes apps/nspanel-lovelace-ui/luibackend/apis.py | 3 +- apps/nspanel-lovelace-ui/luibackend/config.py | 69 +- .../luibackend/controller.py | 53 +- apps/nspanel-lovelace-ui/luibackend/mqtt.py | 22 +- apps/nspanel-lovelace-ui/luibackend/pages.py | 117 +- .../nspanel-lovelace-ui.py | 37 +- docs/subpages.md | 6 +- 16 files changed, 2567 insertions(+), 278 deletions(-) create mode 100644 HMI/code_gen/pages/out.txt diff --git a/HMI/README.md b/HMI/README.md index 4801898a..60a9a987 100644 --- a/HMI/README.md +++ b/HMI/README.md @@ -9,6 +9,7 @@ Messages from the Panel are send to the `tele/XXX/RESULT` Topic, encoded in json ## Startup On startup the panel will send `{"CustomRecv":"event,startup,39,eu"}` every few seconds. + ``` event, #Every message from the screen will start with `event` startup, #Startup Event @@ -20,15 +21,13 @@ You can answer this message in many different ways, but in general the goal is t Send the following messages to the CustomSend Topic. (You can also send them on tasmota console for testing) - - ### Some preperation before we are acually navigating away: Send this every minute: `time~18:17` Send this at least once at midnight: `date~Donnerstag, 25. August 2022` -Send theese message once after receiving the startup event (parameters will be explained later): +Send theese message once after receiving the startup event (parameters will be explained later): `timeout~20` @@ -36,7 +35,7 @@ Send theese message once after receiving the startup event (parameters will be e ### Navigate from the startup page to the screensaver, by sending this command to the CustomSend Topic. -`pageType~screensaver` +`pageType~screensaver` After sending this command you should already see the time and date. To also show weather data you have to send them with weatherUpdate, but we will skip this for now. @@ -53,7 +52,6 @@ You can answer this by sending theese commands to the CustomSend Topic. `entityUpd~test~1|1~light~light.schreibtischlampe~X~17299~Schreibtischlampe~0~text~sensor.server_energy_power~Y~17299~Server ENERGY Power~155 W~shutter~cover.rolladenfenster_cover_1~Z~17299~Fenster Eingang~A|B|C|disable|enable|enable~switch~switch.bad~D~63142~Bad~1` - ## Messages to Nextion Display ### General Commands, implemented on all pages @@ -104,93 +102,1993 @@ change the page type: ### cardEntities Page -The following message can be used to update the content on the cardEntities Page +Structure (Category): `entityUpd~title~[navigation]~[entity_information]` +Example with 4 Entities: +``` +entityUpd~LightTest~button~navigate.prev~<~65535~~~button~navigate.next~>~65535~~light~light.bed_light~A~17299~Bed Light~0~light~light.ceiling_lights~B~52231~Ceiling Lights~1~switch~switch.ac~C~17299~AC~0~switch~switch.decorative_lights~D~65222~Decorative Lights~1 +``` -`entityUpd~heading~navigation~[~*type*~*internalNameEntity*~*iconId*~*iconColor*~*displayNameEntity*~*optionalValue*]x4` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NumberCategoryLocationTypeFieldAddional Information
0instructioninstructionentityUpd
1titletitletitletitle
2NavigationUpper Left IconEntity Definitiontype(ignored)¹
3intNameEntity
4icon
5iconColor
6displayNameignored
7optionalValueignored
8Upper Right IconEntity Definitiontype(ignored)¹
9intNameEntity
10icon
11iconColor
12displayNameignored
13optionalValueignored
14EntitiesFirst EntityEntity Definitiontype
15intNameEntity
16icon
17iconColor
18displayName
19optionalValue
20Second EntityEntity Definitiontype
21intNameEntity
22icon
23iconColor
24displayName
25optionalValue
26Thrid EntityEntity Definitiontype
27intNameEntity
28icon
29iconColor
30displayName
31optionalValue
32Forth EntiryEntity Definitiontype
33intNameEntity
34icon
35iconColor
36displayName
37optionalValue
38Fifth Entiy (US Portrait   Version)Entity Definitiontype
39intNameEntity
40icon
41iconColor
42displayName
43optionalValue
44Sixth Entiy (US Portrait   Version)Entity Definitiontype
45intNameEntity
46icon
47iconColor
48displayName
49optionalValue
-`~light~light.entityName~1~17299~Light1~0` +### cardGird Page -`~shutter~cover.entityName~0~17299~Shutter2~iconUp|iconStop|iconDown` +cardGrid is using the exact same message cardEntities is using; it ignores the information supplied in optionalValue, because it isn't needed for cardGrid -`~delete~~~~~` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter   NumberCategoryLocationTypeFieldAddional Information
0instructioninstructionentityUpd
1titletitletitletitle
2NavigationUpper Left IconEntity Definitiontype(ignored)¹
3intNameEntity
4icon
5iconColor
6displayNameignored
7optionalValueignored
8Upper Right IconEntity Definitiontype(ignored)¹
9intNameEntity
10icon
11iconColor
12displayNameignored
13optionalValueignored
14EntitiesFirst EntityEntity Definitiontype
15intNameEntity
16icon
17iconColor
18displayName
19optionalValueignored
20Second EntityEntity Definitiontype
21intNameEntity
22icon
23iconColor
24displayName
25optionalValueignored
26Thrid EntityEntity Definitiontype
27intNameEntity
28icon
29iconColor
30displayName
31optionalValueignored
32Forth EntiryEntity Definitiontype
33intNameEntity
34icon
35iconColor
36displayName
37optionalValueignored
38Fifth Entiy (US Portrait   Version)Entity Definitiontype
39intNameEntity
40icon
41iconColor
42displayName
43optionalValueignored
44Sixth Entiy (US Portrait   Version)Entity Definitiontype
45intNameEntity
46icon
47iconColor
48displayName
49optionalValueignored
-`~text~sensor.entityName~3~17299~Temperature~content` +### cardMedia -`~button~button.entityName~3~17299~bt-name~bt-text` +Example without icons in bottom row: `entityUpd~Kitchen~button~navigation.up~U~65535~~~delete~~~~~~media_player.kitchen~I'm a Hurricane~~Wellmess~~100~A~64704~B~media_pl~media_player.kitchen~C~17299~Kitchen~` -`~switch~switch.entityName~4~17299~Switch1~0` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter   NumberCategoryLocationTypeFieldAddional Information
0instructioninstructionentityUpd
1titletitletitletitle
2NavigationUpper Left IconEntity Definitiontype(ignored)¹
3intNameEntity
4icon
5iconColor
6displayNameignored
7optionalValueignored
8Upper Right IconEntity Definitiontype(ignored)¹
9intNameEntity
10icon
11iconColor
12displayNameignored
13optionalValueignored
14cardMedia specificcardMedia specificintNameEntity
151st text rowtitle
16titleColor
172nd text rowauthor
18authorColor
19slidervolume0-100
20icon middleplayPauseIcon
21icon right sideonOffBtn"disable" or color
22icon left sideiconShuffle"disable" or icon
23Entitiesupper left corner media   iconEntity Definitiontype
24intNameEntity
25icon
26iconColor
27displayNameonly used for popups
28optionalValueignored
29First EntityEntity Definitiontype
30intNameEntity
31icon
32iconColor
33displayNameonly used for popups
34optionalValueignored
35Second EntityEntity Definitiontype
36intNameEntity
37icon
38iconColor
39displayNameonly used for popups
40optionalValueignored
41Thrid EntityEntity Definitiontype
42intNameEntity
43icon
44iconColor
45displayNameonly used for popups
46optionalValueignored
47Forth EntiryEntity Definitiontype
48intNameEntity
49icon
50iconColor
51displayNameonly used for popups
52optionalValueignored
53Fifth EntiyEntity Definitiontype
54intNameEntity
55icon
56iconColor
57displayNameonly used for popups
58optionalValueignored
-`~number~input_number.entityName~4~17299~Number123~value|min|max` +### cardThermo -`~input_sel~input_select.entityName~3~17299~sel-name~sel-text` +Serial Protocol of cardThermo is about to change; table will be completed later -### popupLight Page + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter   NumberCategoryLocationTypeFieldAddional Information
0instructioninstructionentityUpd
1titletitletitletitle
2NavigationUpper Left IconEntity Definitiontype(ignored)¹
3intNameEntity
4icon
5iconColor
6displayNameignored
7optionalValueignored
8Upper Right IconEntity Definitiontype(ignored)¹
9intNameEntity
10icon
11iconColor
12displayNameignored
13optionalValueignored
14cardThermo specificcardThermo specificintNameEntity
15currentTemp
16dstTempcurrent temp; multiplied by 10
174th Text Box Left Sidestatus
18minTempmin temp; multiplied by 10
19maxTempmax temp; multiplied by 10
20tempSteptemp adj per step; multiplied by 10
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
-`entityUpdateDetail~entityName~*ignored*~*iconColor*~*buttonState*~*sliderBrightnessPos*~*sliderColorTempPos*~*colorMode*~*color_translation*~*color_temp_translation*~*brightness_translation*` +### cardAlarm -`entityUpdateDetail~1~17299~1~100~78~enable` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter   NumberCategoryLocationTypeFieldAddional Information
0instructioninstructionentityUpd
1titletitletitleintNameEntity
2NavigationUpper Left IconEntity Definitiontype(ignored)¹
3intNameEntity
4icon
5iconColor
6displayNameignored
7optionalValueignored
8Upper Right IconEntity Definitiontype(ignored)¹
9intNameEntity
10icon
11iconColor
12displayNameignored
13optionalValueignored
14cardAlarm specific1st button   right sidedisplayName
15intId
162nd button   right sidedisplayName
17intId
183rd button   right sidedisplayName
19intId
204th button   right sidedisplayName
21intId
22icon next to code displayicon
23iconColor
24numpadnumpadStatus"disable" or "enable"
25flashing of icon next to codeflashing status"enable" or "disable"
26button bottom left cornericon
27iconColor
28intNameEntity
-`entityUpdateDetail~1~17299~1~100~disable` +### cardQR -### popupShutter Page +Example: `entityUpd~Guest Wifi~button~navigate.prev~<~65535~~~button~navigate.next~>~65535~~~WIFI:S:test_ssid;T:WPA;P:test_pw;;~text~iText.test_ssid~���~17299~Name~test_ssid~text~iText.test_pw~���~17299~Password~test_pw` -`entityUpdateDetail~entityName~*sliderPos*~2ndrow~textPosition~icon1~iconUp~iconStop~iconDown~iconUpStatus~iconStopStatus~iconDownStatus~textTilt~iconTiltLeft~iconTiltStop~iconTiltRight~iconTiltLeftStatus~iconTiltStopStatus~iconTiltLeftStatus~tiltPos` - -`entityUpdateDetail~1~77` - -### popupNotify Page - -`entityUpdateDetail~*internalName*~*tHeading*~*tHeadingColor*~*b1*~*tB1Color*~*b2*~*tB2Color*~*tText*~*tTextColor*~*sleepTimeout*~*font*~*alt_icon*~*altIconColor*` - -`exitPopup` - -### popupThermo Page - -`entityUpdateDetail~{entity_id}~{icon_id}~{icon_color}~{heading}~{mode}~mode1~mode1?mode2?mode3~{heading}~{mode}~mode1~mode1?mode2?mode3~{heading}~{mode}~mode1~mode1?mode2?mode3~` - -### popupInSel Page (input_select detail page) - -`entityUpdateDetail2~*entity_id*~~*icon_color*~*input_sel*~*state*~*options*` - -options are ? seperated - -### popupTimer - -editable is 0 or 1 - -action fields are in the answer on the button press - -in case action is empty the button will be hidden - -`entityUpdateDetail~{entity_id}~~{icon_color}~{entity_id}~{min_remaining}~{sec_remaining}~{editable}~{action1}~{action2}~{action3}~{label1}~{label2}~{label3}` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter   NumberCategoryLocationTypeFieldAddional Information
0instructioninstructionentityUpd
1titletitletitleintNameEntity
2NavigationUpper Left IconEntity Definitiontype(ignored)¹
3intNameEntity
4icon
5iconColor
6displayNameignored
7optionalValueignored
8Upper Right IconEntity Definitiontype(ignored)¹
9intNameEntity
10icon
11iconColor
12displayNameignored
13optionalValueignored
14cardQR specificqrcode text
15Entities1st EntityEntity Definitiontype
16intNameEntity
17icon
18iconColor
19displayName
20optionalValue
212nd EntityEntity Definitiontype
22intNameEntity
23icon
24iconColor
25displayName
26optionalValue
-### cardThermo Page +### cardPower (in development) -`entityUpd~*heading*~*navigation*~*internalNameEntiy*~*currentTemp*~*destTemp*~*status*~*minTemp*~*maxTemp*~*stepTemp*[[~*iconId*~*activeColor*~*state*~*hvac_action*]]~tCurTempLbl~tStateLbl~tALbl~iconTemperature~dstTempTwoTempMode~btDetail` - -`[[]]` are not part of the command~ this part repeats 8 times for the buttons - -### cardMedia Page - -onoffbtn has to be`disable` to disable the on off btn -tIconBtnEntityName is the entiy name used in the button event for pressing the upper left icon - -`entityUpd~*heading*~*navigation*~*internalNameEntiy*~*title*~titlecolor~*author*~authorcolor~*volume*~*playpauseicon*~onoffbtn~iconShuffle~*type*~*internalNameEntity*~*iconId*~*iconColor*~~[~*type*~*internalNameEntity*~*iconId*~*iconColor*~*displayNameEntity*~*optionalValue*]x4` - -### cardAlarm Page - -`entityUpd~*internalNameEntity*~*navigation*~*arm1*~*arm1ActionName*~*arm2*~*arm2ActionName*~*arm3*~*arm3ActionName*~*arm4*~*arm4ActionName*~*icon*~*iconcolor*~*numpadStatus*~*flashing*` - -### cardQR Page - -`entityUpd~heading~navigation~textQR[~type~internalName~iconId~displayName~optionalValue]x2` - -### cardPower Page - -`entityUpd~heading~navigation~colorHome~iconHome~textHome[~iconColor~icon~speed~valueDown]x6` - -`entityUpd~test~1|1~6666~A~hu~8888~B~1~t0u~9999~C~2~t1u~1111~D~3~t2u~33333~E~-1~t3u~3333~F~-2~t4u~4444~G~-3~t5u` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter   NumberCategoryLocationTypeFieldAddional Information
0instructioninstructionentityUpd
1titletitletitleintNameEntity
2NavigationUpper Left IconEntity Definitiontype(ignored)¹
3intNameEntity
4icon
5iconColor
6displayNameignored
7optionalValueignored
8Upper Right IconEntity Definitiontype(ignored)¹
9intNameEntity
10icon
11iconColor
12displayNameignored
13optionalValueignored
14cardPower specificHome Icon MiddleiconColor
15icon
16text
171st Item Upper LeftPower Entity DefinitioniconColor
18icon
19speednumbers (-2,-1,0,1,2)
20text
212nd Item Middle LeftPower Entity DefinitioniconColor
22icon
23speednumbers (-2,-1,0,1,2)
24text
253rd Item Bottom LeftPower Entity DefinitioniconColor
26icon
27speednumbers (-2,-1,0,1,2)
28text
294th Item Upper RightPower Entity DefinitioniconColor
30icon
31speednumbers (-2,-1,0,1,2)
32text
335thItem Middle RightPower Entity DefinitioniconColor
34icon
35speednumbers (-2,-1,0,1,2)
36text
376th Item Bottom RightPower Entity DefinitioniconColor
38icon
39speednumbers (-2,-1,0,1,2)
40text
### cardChart Page `entityUpd~heading~navigation~color~yAxisLabel~yAxisTick:[yAxisTick]*[~value[:xAxisLabel]?]*` @@ -279,16 +2177,8 @@ tIconBtnEntityName is the entiy name used in the button event for pressing the u `event,buttonPress2,internalNameEntity,actionName,code` -# Design Guidelines for Nextion HMI Project - -Background Color is -- RGB565: 6371 [18e3] (HEX: #1C1C1C, RGB: 28,28,28) - -Source for Icons is the Material Design Font, used by HASPone -https://github.com/HASwitchPlate/HASPone - - # Custom Protocol + ``` 55 BB [payload length] [payload length] [payload] [crc] [crc] ``` @@ -301,8 +2191,9 @@ This protocol does not try to implement broken JSON Commands with a specified ty Instead the commands are plain text commands with parameters. ## Example for valid Message + This message has to be generated for the Message "1337" (1337 is not a valid command~ this is just an example) + ``` 55 BB 04 00 31 33 33 37 5F 5B ``` - diff --git a/HMI/code_gen/pages/cardEntitiesSerial.py b/HMI/code_gen/pages/cardEntitiesSerial.py index ac19e8d7..05ca2253 100644 --- a/HMI/code_gen/pages/cardEntitiesSerial.py +++ b/HMI/code_gen/pages/cardEntitiesSerial.py @@ -6,8 +6,8 @@ head = sharedhead + """ spstr strCommand.txt,tHeading.txt,"~",1 """ + navigation print(head) -start = 3 -for i in range(1,7): +start = 14 +for i in range(1,5): idxstart = start + (i-1)*6 item = f""" // get Type diff --git a/HMI/code_gen/pages/cardGridSerial.py b/HMI/code_gen/pages/cardGridSerial.py index ab3c6778..2ba08725 100644 --- a/HMI/code_gen/pages/cardGridSerial.py +++ b/HMI/code_gen/pages/cardGridSerial.py @@ -6,7 +6,7 @@ head = sharedhead + """ spstr strCommand.txt,tHeading.txt,"~",1 """ + navigation print(head) -start = 3 +start = 14 for i in range(1,7): idxstart = start + (i-1)*6 item = f""" diff --git a/HMI/code_gen/pages/cardMedia.py b/HMI/code_gen/pages/cardMedia.py index 6e6b5905..4367508d 100644 --- a/HMI/code_gen/pages/cardMedia.py +++ b/HMI/code_gen/pages/cardMedia.py @@ -8,31 +8,31 @@ head = sharedhead + """ print(head) print(""" //entity name - spstr strCommand.txt,entn.txt,"~",3 + spstr strCommand.txt,entn.txt,"~",14 //title - spstr strCommand.txt,tTitle.txt,"~",4 + spstr strCommand.txt,tTitle.txt,"~",15 //title farbe - spstr strCommand.txt,tTmp.txt,"~",5 + spstr strCommand.txt,tTmp.txt,"~",16 if(tTmp.txt!="") { covx tTmp.txt,tTitle.pco,0,0 } //author - spstr strCommand.txt,tAuthor.txt,"~",6 + spstr strCommand.txt,tAuthor.txt,"~",17 //author farbe - spstr strCommand.txt,tTmp.txt,"~",7 + spstr strCommand.txt,tTmp.txt,"~",18 if(tTmp.txt!="") { covx tTmp.txt,tAuthor.pco,0,0 } //volume - spstr strCommand.txt,tTmp.txt,"~",8 + spstr strCommand.txt,tTmp.txt,"~",19 covx tTmp.txt,sys0,0,0 hVolume.val=sys0 //icon - spstr strCommand.txt,tPlayPause.txt,"~",9 + spstr strCommand.txt,tPlayPause.txt,"~",20 // on off button - spstr strCommand.txt,tTmp.txt,"~",10 + spstr strCommand.txt,tTmp.txt,"~",21 if(tTmp.txt=="disable") { vis t5,0 @@ -42,7 +42,7 @@ print(""" covx tTmp.txt,t5.pco,0,0 } // shuffel btn - spstr strCommand.txt,tTmp.txt,"~",11 + spstr strCommand.txt,tTmp.txt,"~",22 if(tTmp.txt=="disable") { vis tShuffle,0 @@ -54,7 +54,7 @@ print(""" """) -start = 12 +start = 23 for i in range(1,7): idxstart = start + (i-1)*6 item = f""" diff --git a/HMI/code_gen/pages/cardPower.py b/HMI/code_gen/pages/cardPower.py index 3dfad24a..d917e174 100644 --- a/HMI/code_gen/pages/cardPower.py +++ b/HMI/code_gen/pages/cardPower.py @@ -5,16 +5,16 @@ head = sharedhead + """ // command format: entityUpd,heading,navigation,colorHome,iconHome[,iconColor,icon,speed,valueUp,valueDown]x6 spstr strCommand.txt,tHeading.txt,"~",1 """ + navigation + """ - // icon color home - spstr strCommand.txt,tTmp.txt,"~",3 + // icon color home + spstr strCommand.txt,tTmp.txt,"~",14 covx tTmp.txt,t1.pco,0,0 // icon home - spstr strCommand.txt,t1.txt,"~",4 + spstr strCommand.txt,t1.txt,"~",15 // text home - spstr strCommand.txt,tHome.txt,"~",5 + spstr strCommand.txt,tHome.txt,"~",16 """ print(head) -start = 6 +start = 17 for i in range(0,6): idxstart = start + (i)*4 item = f""" diff --git a/HMI/code_gen/pages/cardThermo.py b/HMI/code_gen/pages/cardThermo.py index 968b44aa..8cff1568 100644 --- a/HMI/code_gen/pages/cardThermo.py +++ b/HMI/code_gen/pages/cardThermo.py @@ -8,23 +8,23 @@ text = sharedhead + """ text += """ //entity name - spstr strCommand.txt,entn.txt,"~",3 + spstr strCommand.txt,entn.txt,"~",14 //currentTemp - spstr strCommand.txt,tCurTemp.txt,"~",4 + spstr strCommand.txt,tCurTemp.txt,"~",15 //dstTemp - spstr strCommand.txt,tTmp.txt,"~",5 + spstr strCommand.txt,tTmp.txt,"~",16 covx tTmp.txt,xTempDest1.val,0,0 xTempDest.val=xTempDest1.val //status - spstr strCommand.txt,tStatus.txt,"~",6 + spstr strCommand.txt,tStatus.txt,"~",17 //minTemp - spstr strCommand.txt,tTmp.txt,"~",7 + spstr strCommand.txt,tTmp.txt,"~",18 covx tTmp.txt,xTempMin1.val,0,0 //maxTemp - spstr strCommand.txt,tTmp.txt,"~",8 + spstr strCommand.txt,tTmp.txt,"~",19 covx tTmp.txt,xTempMax1.val,0,0 //tempStep - spstr strCommand.txt,tTmp.txt,"~",9 + spstr strCommand.txt,tTmp.txt,"~",20 covx tTmp.txt,xTempStep1.val,0,0 // disable all buttons vis bt0,0 @@ -37,7 +37,7 @@ text += """ vis bt7,0 """ -start = 10 +start = 21 for i in range(0,8): idxstart = start + i*4 text += f""" @@ -59,17 +59,17 @@ for i in range(0,8): text += """ //Text tCurTempLbl - spstr strCommand.txt,tCurTempLbl.txt,"~",42 + spstr strCommand.txt,tCurTempLbl.txt,"~",53 //Text tStateLbl - spstr strCommand.txt,tStateLbl.txt,"~",43 + spstr strCommand.txt,tStateLbl.txt,"~",54 //Text tALbl - spstr strCommand.txt,tALbl.txt,"~",44 + spstr strCommand.txt,tALbl.txt,"~",55 //Text tCF - spstr strCommand.txt,tCF.txt,"~",45 + spstr strCommand.txt,tCF.txt,"~",56 tCF1.txt=tCF.txt tCF2.txt=tCF.txt //Second Temperature - spstr strCommand.txt,tTmp.txt,"~",46 + spstr strCommand.txt,tTmp.txt,"~",57 if(tTmp.txt!="") { covx tTmp.txt,xTempDest2.val,0,0 @@ -87,7 +87,7 @@ text += """ vis tCF2,1 } //Show btDetail - spstr strCommand.txt,tTmp.txt,"~",47 + spstr strCommand.txt,tTmp.txt,"~",58 if(tTmp.txt!="1") { vis btDetail,1 diff --git a/HMI/code_gen/pages/out.txt b/HMI/code_gen/pages/out.txt new file mode 100644 index 00000000..97b638ce --- /dev/null +++ b/HMI/code_gen/pages/out.txt @@ -0,0 +1,360 @@ + +// data available +if(usize>1) +{ + bufferPos=0 + while(bufferPos?5zVU3WL1{r$uHd=8)UZol`v`JVbX zxpS-QNhEGYEf?wLa?sPgyuDlf$e6?~1(}3h6T;Nw?Rj`#@5>Qvw6wC1i+GPkZm+A! z18+jOV_0|CmpdcXSM!8CTBjy$!my5zcl7Sl6iIPS$0cvqXbEjd2bBjF@3E+VqK+t) zj)BWJdM0tC{4>wMUh1t_ROidZ7@CfCf0UlkI)Zi1>!4+RTqJo@C9b1i%DuSVfjff z@8X!p&f>n!ObWK(8l28pyvL%c@ry}ZcO2`nGk)_cLMjUvldu+!c@mmTLx?bcF`1i< zr;lUCG~IMD>3oAHs?AL&6z{R9kIh186`e5lu|dDby8E}V^05PY@}qg)bW6UBS<|D8rHkJq8E zZRC|`j&O$z+_jeb3{Tvzzf;FygI4_Ui90&=EAv^CX6n?+(y0}Pq(E{(az%1Oau+(a z^7!b-=ATycPmAJZ^H1yF`7J-uPs{9Q_BRKZ1I}^geasotB2zf6r@M^E1!qPV^OI^eoH(C<| zH+7K@VR@M*7XCa=y;BhvFK9i@SKNj9nd%}A%C>8Q;RiR~*G-d~Gr0)-FNd^;>QJ+{ ztEOw$A~>?#6bzcTHNLHKa&wAubPE;~jha~ish4%(kmkjQK#e=^4nJPkb%ex4>L4g+ z&3l06y3QN!eqin(tswKZDjXVAHb3~NLLUG(y|rrBv{^ZGfveJlS9Gx{;Z<)wfs2Ps ze{D}lsWrR9-H&mC>JN1-;m4zvK&YuP1yp3I1Kc&UrcIeDuX2?A$yV70?q1hL{pJE= zpQXeXsFQAyu2T$@rr3fZW3Ocp7X#-f@=>tFUmFCyPU)nz zmh`tvYt;<52S7uu(bF}nNRtH-tMpGp;kPP{5It3WhvRxd={Ai4PRvkyD`FC1U7mUY z+?cN3&7}etVG9AxY;|~JZE6G`1ZU=|Jz&vnbxYyV47El9rS&20AperqR}qsSjLuWP z;|i%~L*f5@GIc-pdH}5K(oueMw9|~?M4O|4I ze;p9yg6|4shDL@#^jOtdsM}=^cDz`H{j7V+HQpZZ{Uc?nP*bg*%?Zoxi#u?T_PQzx z(%kU}Dz$61!WSaOhb%4}U2vUex;?*BP zN(QXS2vTyn1%XKhEbCZoD&d9|K}rU!vhjqhkZ|KE1g2#Yzbg|#NXX&w{qEnTA00YEu^|_(n zFqSo3)J4O&vp7n}OFAw5P;NR2X*%0N7*eJ2f|M1e51ZZw!nv=t%8K2VmJmJK9^#m> zPR*x6PcXd%npu1oIPd_M_e~^1^|=VO5*i*@10ZUp>AS~k{m$uH!?|lH6pCN4d%?!R z{7AS;xsRi4VHFeXu|mchCQl9?4CQg5IzAJIbg}h?stkJ;-0Nb~!gnqxwO*;#1VBj? z9}M4Dn(84m$<`n8rrU93I(f=^Q%gv!!d=M~V}$Cpra%s$yR8e{tTcJTwp_c1&`@n^ zD;5R|9oL%z1E5!hDqUE%%k(~;)Ip6qXpXAFqj!&axSVtm`RjBi)X_zvp` zN#p2}33+Kf6G?Bp$wbxOw^;d=jjZprO@#Q!$MxxETH!$VK3jAb0u`|dRI8LR`p@&# z0ic;1?g~BK`2O(T`?`tEX#G2*^>Yp^4mlj6gz5{r9wH#S#Kgxz>Nl$3w{}}N=p$0e5wL2A2qTUN`lESC3oV;e$PvY%U4TAGJhKT|cs$^{W4Ji>c&5uw zX8L?y2{ntt{e_$F8hf`8{07;o+=bIW=&pId+1VN;q@}5qXpoe7s-lE5qt%59C&N!b z!!Mc>BL1P1bSx)Jv8H`w2$VdF@~?WOS|#k*#t%~nhh6kDhC9T@^m?A@|BssL?cNVZ zC&V@j1_q7Ig5kFW!vJ5!0R?3KQ8S!#gP0uc5n=6q-8`3OX(2jK{+DivW@*tZE&gAm z1)3J_79|&n)E4O}q;^Q{kvbrCM2bS{gwz?S3sP64XrvgVSR?~d98x?|0#YJU5>hhK z(@5Qrx+C>K>WS0~DFrDNsW;LyNPUp{BK1S+k2C;jAkrYD!AL`ph9V6^8jh5Pl#Vn4 zX(ZApq|r#vB8@>Bi!=^tJkoPW&m+BnGy!QMQU+2c(j=rTq->-dq{&EAkftI{Lz<2> z11T42CQ=?!K2iZvA<`_Q*+@l5bCBjDy@)gq=_RE3NG~HTKw5~j2&ovU1gTU|a>g%8 zyubbG+7~oPObxki5W2(?Ra~z?ZC*0u{^(@LHJ~9U8(o*2yk!T_Tedq1i}u=5iQk6y+9OxVrN3n&I+CPCyn}`oR)|;aG(z&E z@(6Th$=)(e0dv7!M?34bqd7S~n~;YRe-ypxgQULR^BF$|Z711_pIL%87!wz-f>J_$ zmL|^UneDUO%50(?c2<6FDT^6gKqE~yi7qa~5P&rC6*Smnx89Z4*#@qzkWLQgC!bf~ zs-+G$Dlx($S(EAwj88|SOD?zXVEobD%#aHd*dl`8WxQ%H<3si_K5RcB#qz3KA7B*` z2N|zD#CZK-#<#6we7hqo=+Wst#>X6Gd_q0ryB%xfpCKv7@qLtbJns}6bpC0^FF4cK zfs~$Q<)(9#cUYfomsy1WEDn+w-E6UX@&8L5BoNTQ7y&t_(d_8C!RV!k3#I{!K-Z#a zMY(Y212mxO!qqB2yvt#cm-sNTkr!>0qnVsJYZ7%!#-r7PrW;0v0=0T5xvL6-471t? zR`0N&e{2uNupaHO_)_O%5NK*FJ}}~xIZhFS=H0H4cvx9unIM+9#3V<;k+u4WiWkE@ zX-Fpka%wH@;n;3V09}j{cGn`;ey=46uGCukC}J@ZQkE7f2XX-f=4L;ExpGe(;sg2fnmLfLspPA#O8vc3C zu%gyBq|x-=0=u($$$~`FI}@(XL}#dI-ixNU0a8tB(J1wH_$!%>PmOSeA>LuAq7{zD zb3#)y{2mOPFAq-5aL6~wgG)wuW{Az%uCE%*;}eZx_Baxv5C|01UTc|7*VtIR2;zH%TFFRRdd zD#z5H9m?cmFZ86!fS)>C6lGKZ5i$wGRdR@`6eYGCqFO(i4Z6W8roI6sxg4U}I+jWM zWc0ksG4(#^d6i@8{n7I($JC>oV(M|uG4-C)S?7UHG4&DXRh47vV`j36GxAtW{hLD8 z_b1c{Yr(X;3qFkB8%W5$Xz`UGv->dZZhl|(LM7r$Co5bUeCgyDN{26<{N6l+ z+91A9(#wT!om^o;)lk;r%=psD%8?oU`tl3)3ci4{`WT8YnjG`oh$^GZC*TVu^YxjG zACW`I8cD_cVJglqH(H1Z6>D@#btoR!Ul5cl>3_Z9c)csN8o7jw6@5ni#(h zwM4nRCu)Xrz~VS+gCbA&Kdg*ZTtXF4ZZu&f<8Q5IeBN62md>kYym1}lm!ivF)?q6) zFuwXt#&7-uA))dv<2JG9l(6}+w|!NizE8_vjmrM33=)IES#!d8?7Pj*{omQS9|%(^TWLqG4bFZpbhpA z1GrQ3p>~(0gJ02r{FzSLR05n|tshB!%~g6W{Ha|36jZO$xA%`8n3bQ$l&&PDm`VcQ zVe$%Ql9au!9|k_v`u44&=QK7#&wgomAfz>@T!juR^piNM9Ernjuh2j55*y3LNLIue z=pb5H2>J|EkkbEdm3saJVo&tU(*@06MSCVR>6z&0Iq(gAhD&UcMpUPSBX5Y^k{#Xp zRbn?ov~xEDdd2C4!E3OaAy(@4${O0uV4&R=x)|b`^oV!#_-rlhks$RLS1tCC4(!u) zbRwtINmdxdrxrit!(J5P6D<7`W|B$e$$O9UM!@XA<8jk(K**XZ&AM7=IPTk=*_OiXC~Jb*R(G zJU@!HnSvQLa`})6IKO-olf@bZpk5;92gRV8A@gadPRM*dY6>#HYyp#xD;Bblb{q5~ z_@k;pudaV#UXi*763Em24|vEz*V})_M06C?^vXkN`VBrFdX05wd~bw%xxAAPbXlY<`W3Rp``=j|^e_Q=wd=wD%3;8hu5rHH?pH%lPDujPKu- zYZT-k#WwQABr~D$hJ2sQ_?LTdjhaGbFRoD~-Ji3)_AVb+ckC~{{u@bLI*(MO%*x-E{AwPhBx1p<`*TRWWyxVj?m!E_huPJ z)bOXFZeim0)?5yjO|mC&$pY74?c_moj1m+v$wHZm@2FsTLRbW;1$-w#6Ux8CH7zgn zw{;Ry#@X{Y$e18y9ntoMPoZSqK7sEcM7QC?6)eFBCEjm`)Awlk^C&xGA+;6XT1+;= z=5iEW4QVd61z13%=t6WPzXY4cLwYxUlaQBX-|LQdg0?e1Nr7!@TVP6R-FVE(rO8DC zCKr9d$;B)sX}~yp0^FQ#H$zFj{YyGp5=rXn`E@fn0bo4Iy5VlUJr^J_Vbxo5tPNuv{n+E)nQ&%-TX3C*Y# zZuI7p6nJx|+$3!y`WfC+(6qJTHl$*@4Voz+B)79w(bCWSF#U?2In;EtNo%he$lpgP z|7*Dc0_Fx>!#Z>+(9{05vn`YQLF9KP1P%@3e~}iT1Uz`mq!_|`LP2MJ3t0QTwTng|ZpN9e4sb#Pw4i6wj%chVOioxv3E+Tpvm`KZ{f%;yHv;0?;o{_`)fD) z84cCOI)b~=7*%|qBV@IkLnf6w+32+`m`?FDYG!gYMianzcNKo4fLay3mZUI!&E-CJbbt<*nUp3`cP( zHlDD_=q<-5uz9|trC+caTPD($t;Ke}nX_gZ8qH}(Y$6z}n~k}&Lmb-O;-Dz1=n8VT z;0nY*gt&s&wiqj2Vq=2D;0Sd2QiV2lEVciGpnR*bCoZMzQ&k7({yC~hKHH3w6tQtM zPSIL;b(?VoX5gUHd$Xn+{Ll*B40W|eFDR)s*211>TM+c!X`D@?5qCZe34-eVW?#6z z)A$U^c;U#$=0k2Y7cHw0qKAdX!IbwnmlfjgJrXkUdB?}Tgn zWL(4QeNM2p&k5G{A*?lygRs_!gZtJH(ofnAK`a{}@dMss7&i^^OU6DcN;28AyJ;&S ztEA)YT|-E@#9w@ekiOD5q3^QC@z#EJ(n*Ig65U^FRD6`Vg01yzrPgEY*loudh%R}b zkX};X6DQeoeGUV~sZx361(t=-?lOB%afZck~)h4W7^&g2JJDo1D(4zUXkovd~y%^WU)97F1JTOtu|t0 znzk2)3g$7QNp>28-S56@eg%H0(g(rKJw`v6w%3d(jTX&&=191+*PKBi`_B931hDNh zXCR=*_+h;J;XdrNf1TWE`+nLf(a|a40PU3I=yXQBK^cPI7(?HKX1l@=4d)M<%?fml zigUbt2%DpoB+e0dnBJhpLYvzU)8?4td=QuNbRDgUcl4F8p1D|6V_7o4{+2gb)`m$-y7Vp!Z(h@R4{U9YO91^BfESi^1xjPM8PMh#R}~aT=b@s<{rq4xd(qc zXLlSJA&@X&JlE6PZ zNnrQE3{}gWByhwC2Kif@Byf*$45`mJOW=taOfKBXViI_VlLTJrB!O3<1nwp+?jt7& ze9K7!-*=M0UT93nf;Qa9_%0SF37mo!gxqKZS`ady?Id-xouqEIlhn<2lDgSWQa9U4 z>SoJQ7sXpP3f)EtoQ;-+EP*#WN#MIq5;$-ZlfbcCm;@fVjY;4?J4xW;T}%SkJ4xWQ z1MH+fcb32%>X`(NMX4+63b814W$V#^Qdf37$A7>iaM3CDT;0ww3Eb}^CV|g8N#F@r zog}dB29v;pK4%hmvM6X1pfP`b+09;_$L-oKa3UApDTL~7ZsfJ~wLVZLLt*OUD-i2vB@`4D0Tg!7=ORpEaL q`8FUJe81p>1$6MqkupY$RcQz1qLCq36j8M8<0Q*nIwV8LDFb6Ga4`m+faa6 z6Ks=%2<8$jM6&m@G08XsMmXceHY{F;XM6Yk`UdrA*Yq@ zE>M!?-|YU;!i@!B @S%h`Xpe*NI(FakmSH}r*#X^0dMflW*6?{by&aM%Rpq_P` z^rauXu6tpIMVO85i01^sn$o1cAfeeDi}1p36moXWGc){4%B+b^1caX|Y{H;jtT8AU z)U!^hn5FgUSSkFUAQa5naIzKhvh?|zs&vg?7KFg`O5vMeH4kaRc_xGh|3CGu6avAD z&=F4l0KFgeBi8ru3Oq053*P-Ig%&K639A`xRpof(eddL{Ge0y{{Iei>?jYN930THOsE^H4|;Bcj(rOD{8()lp472&$Dq!|7}?i##w|+Tq*Zp| z9k62kBGkDEjaBmhhWzxW?1IHlsZ-O7W`l)i+&a6Eh<~P+)O1Yy3T|X}{tUTw%LJim zrXVe;65f7F6vVo3k$+#mVPgj`_RgM_eokTJ2ozfP?K6FXN{pkI49zG}2Z#MX`-MZ; z#0KaT1_&cs*(u1`DM$qAKwcnkkRIeCbqex*`{BPQyQlsBd$Rw3J=yJH_Gb3x_HcWI zJ@Tlb#b)ot6){dJezT!eN0;}<=h1uH4AUw8l)+ybvBmIn^zY|8U8f9^>r~Xc6KU;A zOAOs#U@DN7caF;UquLd5&7}OaC~r}kaLV|dG1&Op+HP!7$bkLE(~K6;31y|Q=1je8 z(ZYV9b}L{HdoBV?9#PYMLj<9l%4dfQ!pEtKjO9^5@Kw-2=r{pJIg{^?RaLL29!E;8*kcc=1I_GoE#%jh=(beSEfs@-xO@Uut--Qcqhi8J5z3 zc1FYcuVQ*jS0k(RqN6_AQ6J-|k9E|yaMZ^+>RUSMTRH0EkJTG@KJY%6S=u1=|GILP z4?X*-qXqRD5cfD;s*mp=4gaok$2w{JP;=$u!Is7CE0`m|W=%)>dY3t&>_?2pW9p0; z?8|3O5e8ZN7~f+#UZ;-F$}m0-Ps4AhR?}NV3c@t2@?mWK1!1k49*)`MQu*gFgR~j? z_HaSyu2*MGC}zP_b*9XROZ1A$Tk++!X_kyHukoo9IiH@-`OE^&cb~-h9+NqrRml15 zDVVj|obEVP5Yk{b?8(PW(fIY45nAsPU~*b|0ajTp{d<(7rFU}h^t08RAN3TMS@n#{ zGpjkbkqeFf6K~zv=Q;oQ7S4~~%K3@g1R+nI(g(M5d%OA~x5ICD@bs|VT$lBgR*bAn zq%#jJ-ctTv^ObO2a*|}NH~aZZ-}iREs;4lgC7xC;v6P7E)ao*3>lBu zrqc)WHJvL*Y?G;C0d!E~Kw9B)A60a|c@LE(QN`P)NV@N|1XA8HTLInu#H3cXq{=dx zj_$L?QvOhf|9XdIsxB#=)>d1F1*LW=T~yl1yu#cmDT7Q)fXE*?EWhZIGL?@1?6ef< zk`t+**4B?!-ZW1Zla)Rht1WZDXYWPh^H13Vbjc}-`nR{tzvzvu0(Y@~WNZK;B%CLT0Tql~CXfe>u z3Dx(d`~h|>GDCaX?}}9WmNAmbZy5H{v~hL=moCqCD$)e$`xO6jbc8gfkNqo=w&{?IqA=h`w$osUmOy&9J)z7S;BiDnG|2!Y^zodN`EYu|;(INT1y`nXz!%-cXijh_Vs)cBu)bQ)hhMG*d^%C{{- z{aVIRpqQ31teCHHH?Xd4@Rr*t%v;1|!hmR+?(--|)9qf#`S*ctTKar9$M#==ZZgiZ z{#UK#8Nur~zitEPTW;q3OI!HjeQ+!1PXOJtMg2U`P2(@U!1?!pbXxkImw;%dPnzdZ z@m{mHv|*LKZ(!q^n>T0Sl)3-Kx|}_;VD2ntUh29`@#}4eb;+3w6NmUwi=Fo43>YtZ z)AKq2O8FtXHwEsu2a;Evt2tdQt+a@3sp5K!k!J0;x1-(@9nC3kbTn*dNnC)KLd}{( z>(+j|KNDkhT34%zi$A6lCbl_924$pQNS>gVrlPYnm`A-Z$}nR-M= z=;swrnNmom(}ol=gUYYRn5f{Oy)!lYtEqi(;`~Om$~2Prj3rX~;Glhy2)rywb%c}g zT1+TSIAnjq%W74Mqdy(BXHxI0F&654*q%@3KvM+e-H-B?UOEg#oi&BE!$cjAGNn`x zC7m@*ss5*<_IxjEx>{e!%TS}F3n=jWV@xNL>vW^C>oI0}Rf0m2RaNM5oGAqFa78H1 zJ9h$FNy#2s7&5t^Yfm!0R8`Oa6w?c+b*g%+UtxOcD6wvJ)5d3f9n;eWIUi#dIZ!1)Dx5i>IKRM^#=6;^#%0<^#=_A4Fo+38Uz{)8Uh*$$^qqq z@<78t!$FUMMu0|wMuA3y#(>6x#(^FOJpmdIngE&z$_EvICV?h{3PDpqQ$f=}(?La` zCqXknGeNUJvq5t}#h?<u{4Znqr?WexCZo>O6bsRxX21dMA=r#YBI`h?~j(l33xgmBM@dT!q;=fN_lkZ{-WPDK@n08m{yMfWTKWl~wZ?BLM*S|e_wC?xexX(zvV_CbB_0C{=@@|xYO7zZ|3@+PIz#(T4z@_4V$NvZN2K@pEqWvL;3_WDlnrf2TJC{8XLQ$`*+TmeSM9n$()D zCh>IN-??08O{NNOQ%h-8fODM}Iwvl$gwy@>=nz^H>F}d0UsE`J8-xX>F2or?%R`)p z0NZhFEr_6gq0V9k+Yerk0ch4bL+Qg%XCIw4UCO@XJPkj8p($J1+F%y_l`sRjel{JW ztzTBRqT)bvvXph-JltDa*2a0EfXsuUnp4-7t@U*IFEPz%>%!=2c@s;`{8}5N+##_c zB5e$8jYVxt>;tj2R5CVJFN$qw?T)AjT9F(3fNE^cNSZJm-1wofk>nl*u6QiCn&IG% zY{C#PTO9o->NPQTnAnllE_Yz9T@t-V>N_&lrfZvyD27lpwS8&dg3>8n7WL?n*n!Q) zr2+Uc8W$AJGtNrvWTgiOqNBZKt{}r~p#Gsz;k5N#=W(k2DQ4Dhc7U}@${7;7DDZz) zM_A#MdGm`q%g&_I23GU`sH}LZ{Y&$XVpkfrsVdTIMA0l7HXv#*O&I6&q5eIh!o(V~ zzGH~Q-&#KmS8k5oAm-ArSE62{hJ{fhs5}?`Jvv%Rd6sBz(yum$VQ)tzUibzf>GlE| znHd!&y|6xRTzqis-LWMslFiW9NJnc;31#IN(3ezfY2$&ueSp64YWgI625me4TsTMH zccKO1Ej1Ld6ArQ#SUP}Ul7_Me0jyeJX(j?l8pw`>uZ&&3g1)1HvKqE5f`hDK3juMp z^y6@rwL(vfK?hV^Isqisoa=LNqP3m+Xb&g)vjPN@R6qFjsk~!f&OrT|!g2(bG^aQa zj{(U8`DcOLa%ZT`UURy%_poVJ zm@c!e99Pl}8}8w}{&#`#Ij`gtEB9V|)5f<Oj)(vG?fbf=PWiKUS8dOLjSZeY7|@MM-Z96>n_Ief!*r2qx;r{j!>H&WY+td7 z&Y~{2OdtG9s{}trkd6c13k6X z*qn@sj!>$5!|hA=KQ*1#SyPoZo?aN|L$jZBx1=*?u=eCHM@S*#bJN9t5g5(l57Ek? zo%zD_9h!5g(T!w6es7w3*Ho(tNeN$>!kg2oD|Wyy+xM>d#q{R@seD&u zACWdc07xD1Gq39;_5Ql@*k-D_SlvsV#(1u>TY4M@;eod zQQu7DLgkYM;k0VjJ%J}0sI{BMF{(X0KEyrcXYwpTXs+_}5oOePC!j^+Hv&#HelMUx z1U<6*_*NL;cwcyrpMf<->mNHIBX){wxSts;<|Y{JTDTMG&&p^mne~TvTmP{(F3` zeElKfOo~i%A^J8Bf7S2(!5u+>uXQe}yYz$Il?a#CD&5)S+$uYyh!+5CYK5c79d@>+zwCGBGvF+c@N!~@3opr3@`^K!{1396 z6dLxjD~jIO>2fg$lywqoSx%aw^Y>j$CtcCWImB`@6rIpLOed4+*mX$=q_Qf0J`9N@ z1T9zWqJ)SllsiDn_FD_2o{ ziixQ`4}FEb$UR@LOO`vm1+gSW@^T$AQ`AmxK86BQ)K1?!?VL|O)o|M99C!KA@_J{s zE+tvn71T>EANsJ~*_}F`#NrKs9=eoNI&j?eJbA6OL`eB3Tv<9@3WD{el|~xe*KLrO zA?e#wuGM>kYkk5dvQvKsqS_^ufgD6rv9;FDf6f6!HFsz62 zmgR8zv;c(<5c|d!xsSpfqu98F%xx|5Xz72n6C2m7^vm5NP{?wl{q;{3QiobNk8Z1h6=59Iv7N8xB|?&+XGJY&dU&gTr_eBMyb56|KJ zh+MI8t?Pl)s1UUSgGX|HECL2v`m~9Se3>x6P;8uNy6K!>GlTPSb2z_yuGr}OzkxGv zZBuY}0Z$KDEH?V--z?|+TQ<%gb28pv`8JzYiBvMOvIl*23;vNDJf66s%C;gr6#4Lt zr_3uYnl)u^XR9?aQT3*?^p3;Kk&bCjPxZk`R2zP9P4&GV3~B{fWkw|&C_7rJFyr9WM5?dSrXwFPo}4xMwdTCWwz&HAG@Fr6qz zH@0<1!&%?3gIJJ0>h5?N=_QXitoXZ=<8Ft)ig3pO3M+KSfIlja zX=1G{o7jeh3HEWM%C!fTPFd7gIpvIXJo0<>s6&3|557KB#V<{4E;Y<>Tkx0trK!kc zB4GJE%QlDdWM_S+(T_WVX?R*CyqVE%_O*Yri%qLGjghCowI&k}ss&bg8duyknen!5 z47QkAGu@sO5%tSEMtP16Ov3c|;|j%OhsR7mJICD$3Jr7IO9J^}a58PHGlWyG7mVKY z_hbNYDqVimF$RClO5}E$;vJ*$wr!A{xH{i47H?-#<+tntN4#REvu>FKunGOmQ)1OZ zaiq>HG)=M4G?FbeO|j544+~9GEEMNP%tDdVbfA!Jb}S1@Ym98dTanEZMZrAL2pmH9 zg zQ+bZbcKXK^%68h=SJ_U{HP~seXPI3P?nIzjHqtc3NHNKok>b-cBSmAFk*1Msq?l{W zNYf-3>E8|V-7V?NQTNnl)U(oIq?`_wZKav7xhIR1`!$xVpRQQCkg>|qmvX8d2C1gP z@wS(A;iCJ3sK|Gyx3raJI~@(8H2+Ft>a9*lExX1_Su?YGIfc!sj-i^&%DdFF242Ln zuIAI!DFGt2YAXw(&c{Dp2Z6S?u8A}n?;)r_hR3k?4GVV~DmU}w+vJelNUvn7=6gCni^ zq9=X%p67jdgW65W2zY+lP01YWdA>|jJjFBwu{BS>2ZGpIQ0OwY8`^&9am1>%;KApk zcm#vp_W!%L8aOJRh`6unC@(6MGvpc;6bZs?HT~1sJc9Ar93C;>j%~! zc~_|*3{rL9TFm*lGJZ#*Z8=^-MMWbO`;&jDo2?WFkIjs9VQ-^uH%i?+ecdX46?4N= zJfyN|HBR-^inlz2veojpJj*+<6~QQZw= zu9x|pxA%|nMtmr7{w4xP+ScZy6P#~2iNKMT@i8Jw8vp4lod3Lz^Ix9k{8#myzjub; zC4F#~^WUH2{Lkk(FTC2wcNFx9MrEiy?tuuD)`+Z2oX@@t1&@Q$>?+$9e#vy`l)|C{ zkMn@vx@4-zG`-AnMD)1d*EB2@Nn%}0gjZ4NOscqJLX`a_TL?|_GDQZIB5jIsYQfw| z?2I6dUhy)eQu$wTl2n_8)5jq@Y~AU|Cnoi(%fTJCP~}LVY=_NH->8?WoRijun=CYV zr)`3AX9l-p%(@Kam~;KYI6r!RpS?N7?6M&^wKT3BP2Xh;SB_2B?6UQxQ9h=gbpLr{ z40YUXyGfaTc&*uEGtrbiwi_%?#cuA=ub0e$VzPugdj?Sn?iU}n1+%M)%q^EM?BR-H zA;n+uIFK+Xe%ZtWxUq*2m0S=zM_?f;cKdJr1b32hrw|ty_t64BoEgZ);`$;6W|2j` z{D|v|g_OSn*9F-(JP$QCIgt(jiCnYg1JqKgqWl zi{CLTR{^Q+U2~Dg;YLj*Rv#Q~#A55Gwg|Tz_tDu=STP#!II?J!+*90eETm2Eqo?W( z$7xvbUabUB*JX_mMif>@MTyep1a{v)zZT{(!~p-OKi4(#p%Wc9p@K=;Oe>ll~o( z(!x;xPhwJsu~4w*_}};n_UKRQg&2m<*M8w=C?S9+EhaS-2(I1KK7#XAEhaTDh{v18 zhjD&D1m~^MoNp1w!$&P!az4J5M@$O-Y$G&U5IxgivW= 2: self._current_card = self._previous_cards.pop() @@ -227,28 +225,14 @@ class LuiController(object): if button_type == "bExit": self._pages_gen.render_card(self._current_card) - if button_type == "bUp": - if self._previous_cards: - self._current_card = self._previous_cards.pop() - else: - self._current_card = self._config.getCard(0) - self._pages_gen.render_card(self._current_card) - if button_type == "bHome": - if self._previous_cards: - self._current_card = self._previous_cards[0] - self._previous_cards.clear() - else: - self._current_card = self._config.getCard(0) - self._pages_gen.render_card(self._current_card) - - if button_type == "bNext": - card = self._config.getCard(self._current_card.pos+1) - self._current_card = card - self._pages_gen.render_card(card) - if button_type == "bPrev": - card = self._config.getCard(self._current_card.pos-1) - self._current_card = card - self._pages_gen.render_card(card) + #if button_type == "bHome": + # if self._previous_cards: + # self._current_card = self._previous_cards[0] + # self._previous_cards.clear() + # else: + # self._current_card = self._config.getCard(0) + # self._pages_gen.render_card(self._current_card) + elif entity_id == "updateDisplayNoYes" and value == "no": self._pages_gen.render_card(self._current_card) @@ -295,14 +279,25 @@ class LuiController(object): entity_id = le.entityId if entity_id.startswith('navigate'): + # internal navigation for next/prev + if entity_id.startswith('navigate.uuid'): + dstCard = self._config.get_card_by_uuid(entity_id.replace('navigate.','')) # internal for navigation to nested pages - dstCard = self._config.searchCard(entity_id) + else: + dstCard = self._config.searchCard(entity_id) if dstCard is not None: - self._previous_cards.append(self._current_card) + if dstCard.hidden: + self._previous_cards.append(self._current_card) self._current_card = dstCard self._pages_gen.render_card(self._current_card) else: apis.ha_api.log(f"No page with key {entity_id} found") + if entity_id.startswith('navUp'): + if self._previous_cards: + self._current_card = self._previous_cards.pop() + else: + self._current_card = self._config.get_default_card() + self._pages_gen.render_card(self._current_card) elif entity_id.startswith('scene'): apis.ha_api.get_entity(entity_id).call_service("turn_on") elif entity_id.startswith('script'): diff --git a/apps/nspanel-lovelace-ui/luibackend/mqtt.py b/apps/nspanel-lovelace-ui/luibackend/mqtt.py index c1efada6..30eb6656 100644 --- a/apps/nspanel-lovelace-ui/luibackend/mqtt.py +++ b/apps/nspanel-lovelace-ui/luibackend/mqtt.py @@ -1,18 +1,19 @@ import json +import apis class LuiMqttListener(object): - def __init__(self, mqtt_api, topic, controller, updater): + def __init__(self, topic, controller, updater): self._controller = controller self._updater = updater - self._mqtt_api = mqtt_api + # Setup, mqtt subscription and callback - mqtt_api.mqtt_subscribe(topic=topic) - mqtt_api.listen_event(self.mqtt_event_callback, "MQTT_MESSAGE", topic=topic, namespace='mqtt') + apis.mqtt_api.mqtt_subscribe(topic=topic) + apis.mqtt_api.listen_event(self.mqtt_event_callback, "MQTT_MESSAGE", topic=topic, namespace='mqtt') def mqtt_event_callback(self, event_name, data, kwargs): - self._mqtt_api.log(f'MQTT callback for: {data}') + apis.mqtt_api.log(f'MQTT callback for: {data}') # Parse Json Message from Tasmota and strip out message from nextion display data = json.loads(data["payload"]) if("nlui_driver_version" in data): @@ -22,7 +23,7 @@ class LuiMqttListener(object): if("CustomRecv" not in data): return msg = data["CustomRecv"] - self._mqtt_api.log(f"Received Message from Screen: {msg}") + apis.mqtt_api.log(f"Received Message from Screen: {msg}") # Split message into parts seperated by "," msg = msg.split(",") # run action based on received command @@ -30,9 +31,7 @@ class LuiMqttListener(object): if msg[1] == "startup": self._updater.request_berry_driver_version() display_firmware_version = int(msg[2]) - model = None - if display_firmware_version >= 23: - model = msg[3] + model = msg[3] self._updater.set_current_display_firmware_version(display_firmware_version, model) # check for updates msg_send = self._updater.check_updates() @@ -60,9 +59,8 @@ class LuiMqttListener(object): self._controller.detail_open(msg[2], msg[3]) class LuiMqttSender(object): - def __init__(self, api, mqttapi, topic_send): + def __init__(self, api, topic_send): self._ha_api = api - self._mqtt_api = mqttapi self._topic_send = topic_send self._prev_msg = "" @@ -73,4 +71,4 @@ class LuiMqttSender(object): if topic is None: topic = self._topic_send self._ha_api.log(f"Sending MQTT Message: {msg}") - self._mqtt_api.mqtt_publish(topic, msg) \ No newline at end of file + apis.mqtt_api.mqtt_publish(topic, msg) \ No newline at end of file diff --git a/apps/nspanel-lovelace-ui/luibackend/pages.py b/apps/nspanel-lovelace-ui/luibackend/pages.py index b04ffb14..70c06bd4 100644 --- a/apps/nspanel-lovelace-ui/luibackend/pages.py +++ b/apps/nspanel-lovelace-ui/luibackend/pages.py @@ -9,6 +9,7 @@ from icons import get_icon, get_icon_ha from icons import get_action_icon from helper import scale, rgb_dec565, rgb_brightness, get_attr_safe, convert_temperature from localization import get_translation +from config import Entity # check Babel import importlib @@ -32,43 +33,46 @@ class LuiPagesGen(object): for overwrite_state, overwrite_val in overwrite.items(): if overwrite_state == state: return rgb_dec565(overwrite_val) + if isinstance(entity, str): + default_color = rgb_dec565([68, 115, 158]) + return default_color + else: + 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", "home", "active"] else default_color_off - 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", "home", "active"] else default_color_off + if ha_type == "alarm_control_panel": + if entity.state == "disarmed": + icon_color = rgb_dec565([13,160,53]) + if entity.state == "arming": + icon_color = rgb_dec565([244,180,0]) + if entity.state in ["armed_home", "armed_away", "armed_night", "armed_vacation", "pending", "triggered"]: + icon_color = rgb_dec565([223,76,30]) - if ha_type == "alarm_control_panel": - if entity.state == "disarmed": - icon_color = rgb_dec565([13,160,53]) - if entity.state == "arming": - icon_color = rgb_dec565([244,180,0]) - if entity.state in ["armed_home", "armed_away", "armed_night", "armed_vacation", "pending", "triggered"]: - icon_color = rgb_dec565([223,76,30]) + if ha_type == "climate": + if entity.state in ["auto", "heat_cool"]: + icon_color = 1024 + if entity.state == "heat": + icon_color = 64512 + if entity.state == "off": + icon_color = 35921 + if entity.state == "cool": + icon_color = 11487 + if entity.state == "dry": + icon_color = 60897 + if entity.state == "fan_only": + icon_color = 35921 - if ha_type == "climate": - if entity.state in ["auto", "heat_cool"]: - icon_color = 1024 - if entity.state == "heat": - icon_color = 64512 - if entity.state == "off": - icon_color = 35921 - if entity.state == "cool": - icon_color = 11487 - if entity.state == "dry": - icon_color = 60897 - if entity.state == "fan_only": - icon_color = 35921 - - if "rgb_color" in attr: - color = attr.rgb_color - if "brightness" in attr: - color = rgb_brightness(color, attr.brightness) - icon_color = rgb_dec565(color) - elif "brightness" in attr: - color = rgb_brightness([253, 216, 53], attr.brightness) - icon_color = rgb_dec565(color) - return icon_color + if "rgb_color" in attr: + color = attr.rgb_color + if "brightness" in attr: + color = rgb_brightness(color, attr.brightness) + icon_color = rgb_dec565(color) + elif "brightness" in attr: + color = rgb_brightness([253, 216, 53], attr.brightness) + icon_color = rgb_dec565(color) + return icon_color def update_time(self, kwargs): time = datetime.datetime.now().strftime(self._config.get("timeFormat")) @@ -201,7 +205,7 @@ class LuiPagesGen(object): state = None self._send_mqtt_msg(get_screensaver_color_output(theme=theme, state=state)) - def generate_entities_item(self, item, cardType, temp_unit=""): + def generate_entities_item(self, item, cardType="cardGrid", temp_unit=""): entityId = item.entityId icon = item.iconOverride colorOverride = item.colorOverride @@ -230,7 +234,8 @@ class LuiPagesGen(object): if icon_res[-1] == ".": icon_res = icon_res[:-1] else: - icon_color = rgb_dec565(colorOverride) if colorOverride is not None and type(colorOverride) is list else 17299 + #icon_color = rgb_dec565(colorOverride) if colorOverride is not None and type(colorOverride) is list else 17299 + icon_color = self.get_entity_color(entityId, overwrite=colorOverride) return f"~button~{entityId}~{icon_res}~{icon_color}~{name}~{text}" else: return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~page not found~" @@ -631,20 +636,34 @@ class LuiPagesGen(object): command += f"~{icon_color}~{icon}~{speed}~{entity.state}" self._send_mqtt_msg(command) - def render_card(self, card, send_page_type=True): - apis.ha_api.log(f"Started rendering of page {card.pos} with type {card.cardType}") - - l = 1 - r = 1 + def render_card(self, card, send_page_type=True): + + l = self.generate_entities_item(Entity( + { + 'entity': f'navigate.{card.uuid_prev}', + 'icon': 'mdi:arrow-left-bold', + 'color': [255, 255, 255], + } + ))[1:] + r = self.generate_entities_item(Entity( + { + 'entity': f'navigate.{card.uuid_next}', + 'icon': 'mdi:arrow-right-bold', + 'color': [255, 255, 255], + } + ))[1:] + if len(self._config._config_cards) == 1: - l = 0 - r = 0 - if card.pos is None: - l = 2 - r = 0 - if self._config.get("homeButton"): - r = 2 - navigation = f"{l}|{r}" + l = "delete~~~~~" + r = "delete~~~~~" + + if card.hidden: + l = f"x~navUp~{get_icon_id('mdi:arrow-up-bold')}~65535~~" + r = "delete~~~~~" + # r = 0 + # if self._config.get("homeButton"): + # r = 2 + navigation = f"{l}~{r}" # Switch to page if send_page_type: diff --git a/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py b/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py index e64a4865..ec248992 100644 --- a/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py +++ b/apps/nspanel-lovelace-ui/nspanel-lovelace-ui.py @@ -5,43 +5,44 @@ from luibackend.controller import LuiController from luibackend.mqtt import LuiMqttListener, LuiMqttSender from luibackend.updater import Updater +import apis + class NsPanelLovelaceUIManager(hass.Hass): def initialize(self): self.log('Starting') - mqtt_api = self._mqtt_api = self.get_plugin_api("MQTT") + apis.ha_api = self + apis.mqtt_api = self.get_plugin_api("MQTT") + cfg = self._cfg = LuiBackendConfig(self, self.args["config"]) topic_send = cfg.get("panelSendTopic") - mqttsend = LuiMqttSender(self, mqtt_api, topic_send) + topic_recv = cfg.get("panelRecvTopic") + + mqttsend = LuiMqttSender(self, topic_send) # Request Tasmota Driver Version - mqtt_api.mqtt_publish(topic_send.replace("CustomSend", "GetDriverVersion"), "x") + apis.mqtt_api.mqtt_publish(topic_send.replace("CustomSend", "GetDriverVersion"), "x") controller = LuiController(cfg, mqttsend.send_mqtt_msg) + desired_tasmota_driver_version = 8 desired_display_firmware_version = 46 version = "v3.7.0" model = cfg.get("model") - if model == "us-l": - # us landscape version - desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft" - elif model == "us-p": - # us portrait version - desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft" - else: - # eu version - desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft" - - desired_tasmota_driver_version = 8 + match model: + case "us-l": + desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-l-{version}.tft" + case "us-p": + desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-us-p-{version}.tft" + case _: + desired_display_firmware_url = f"http://nspanel.pky.eu/lovelace-ui/github/nspanel-{version}.tft" desired_tasmota_driver_url = "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be" - + mode = cfg.get("updateMode") - topic_send = cfg.get("panelSendTopic") updater = Updater(self.log, mqttsend.send_mqtt_msg, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url) - topic_recv = cfg.get("panelRecvTopic") - LuiMqttListener(mqtt_api, topic_recv, controller, updater) + LuiMqttListener(topic_recv, controller, updater) self.log('Started') diff --git a/docs/subpages.md b/docs/subpages.md index 452099bd..0db867cc 100644 --- a/docs/subpages.md +++ b/docs/subpages.md @@ -1,9 +1,9 @@ # Subpages -You can configure entities with with the prefix `navigate`, that are navigating to cards, in case it's hidden card, the navigation items will change and the arrow is bringing you back to the privious page. +You can configure entities with with the prefix `navigate`, that are navigating to cards, in case it's hidden card, the navigation items will change and the arrow is bringing you back to the previous page. ```yaml - - entity: navigate.cardGrid_testKey + - entity: navigate.testKey ``` will allow you to navigate to a cardGrid page with the configured key testKey @@ -22,6 +22,6 @@ will allow you to navigate to a cardGrid page with the configured key testKey You can override the status of navigation items, to make them look like different entities. ```yaml - - entity: navigate.cardThermo_test + - entity: navigate.test status: climate.test ```