Compare commits

...

509 Commits
dev ... v4.7.4

Author SHA1 Message Date
Johannes
a94cf0cef3 fixes #1373 2025-08-02 21:22:31 +02:00
Johannes
d01ccede57 Update nspanel-lovelace-ui.py 2025-07-31 20:39:04 +02:00
Johannes
65be5ffeb0 implements #1351 2025-07-31 20:37:31 +02:00
Johannes
d53afb0b20 fixes #1369 2025-07-31 20:11:02 +02:00
Armilar
9822870fc9 v4.9.3 - EU, US-L, US-P - Update NsPanelTs.ts 2025-07-31 17:54:36 +02:00
Armilar
8a54d1422c v4.9.3 - EU, US-p, US-l - Update NSPanelTs.ts 2025-07-31 17:52:14 +02:00
Armilar
3f573557f0 Merge pull request #1370 from ticaki/main
ready for 9.0.11
2025-07-30 22:06:08 +02:00
ticaki
c2ca3b26d1 fix 2025-07-30 21:59:16 +02:00
ticaki
476a252a92 ready for 9.0.11 2025-07-30 21:52:36 +02:00
Armilar
0af779973b v4.9.3 - DEV Update NSPanelTs.ts
popupShutter2 Changes (new Parameter shutterZeroIsClosed changing Direction of %-Value in HMI (0 <--> 100))
2025-07-30 14:01:04 +02:00
Armilar
8e0609a781 v4.9.3 - DEV Update NSPanelTs.ts
Some Shutter2 Changes
2025-07-30 13:59:25 +02:00
Armilar
5dab816259 v4.9.2.2 - Update NsPanelTs.ts 2025-07-28 14:11:29 +02:00
Armilar
5f8409f5f1 v4.9.2.3 - DEV Update NSPanelTs.ts
- 28.07.2025 - v4.9.2.3  Quick-Fix Errors with TypeScript in JS > 9.X (by ticaki)
2025-07-28 14:10:24 +02:00
Armilar
3d85e86a95 v4.9.2.3 - Update NsPanelTs.ts
Quick-Fix Errors with TypeScript (Bugs in JavaScript > 9.X) by ticaki
2025-07-28 10:17:57 +02:00
Armilar
85de880cda Merge pull request #1368 from ticaki/main
fix/ignore typescript errors
2025-07-28 00:15:53 +02:00
ticaki
98269b19aa fix/ignore typescript errors 2025-07-28 00:10:22 +02:00
Armilar
d77382ee88 v4.9.2.2 - Update NsPanelTs.ts
* Add Weather-Adapter OpenWeatherMap
* Accuweather deprecated
2025-07-25 21:49:57 +02:00
Armilar
e925d133d2 v4.9.2.2 - DEV Update NSPanelTs.ts
* Fix Examples
* Fix OpenWeatherMap fewclouds night
2025-07-25 21:43:23 +02:00
Armilar
5ef3e8132b v4.9.2.2 - DEV Update NSPanelTs.ts
* AccuWeather deprecated
* Add OpenWeatherMap
2025-07-25 16:03:06 +02:00
Armilar
662b79a389 v4.9.2 - DEV - Update NSPanelTs.ts 2025-07-24 14:11:30 +02:00
Armilar
c984ff53a3 v4.8.0 - Update NsPanelTs.ts
* Add popupShutter2
* Add popupLight2
* Add popupSlider (cardMedia EQ)
* Fix Demomodus cardPower
* Small Fixes
2025-06-30 12:40:43 +02:00
Armilar
f8b748a418 Merge pull request #1360 from ticaki/main
Types and variables for popupShutter2 changed.
2025-06-30 12:13:09 +02:00
Armilar
bc31670760 v4.9.0.1 - DEV Update NSPanelTs.ts
Small Fixes
2025-06-30 12:06:11 +02:00
Armilar
cbf6abf4dd v4.9.0 - DEV Update NSPanelTs.ts
Small Fixes
2025-06-30 12:02:17 +02:00
Armilar
5c85e4a6e1 Update NSPanelTs.ts
Change Release
2025-06-30 11:58:08 +02:00
Armilar
cbede2412e v4.9.0 - DEV Update NSPanelTs.ts
New Beta
2025-06-30 11:57:26 +02:00
ticaki
82d22743cc rename customIcons for shutter 2025-06-29 16:08:32 +02:00
ticaki
640d0dfa14 check customIcons 2025-06-29 15:43:19 +02:00
ticaki
ccc62d1e6a Types and variables for popupShutter2 changed. 2025-06-29 15:35:04 +02:00
Armilar
6cec0245a3 v4.7.5 - DEV Update NSPanelTs.ts
Add TFT US-P v4.7.5
2025-06-26 13:01:27 +02:00
Armilar
f3c98adf06 v4.7.5.1 - DEV Update NSPanelTs.ts 2025-06-25 23:48:29 +02:00
Armilar
f4487e4285 v4.7.5.1 - DEV Update NSPanelTs.ts
TFT EU + US-P
2025-06-25 23:46:34 +02:00
Armilar
8e2780b2cb Update NSPanelTs.ts DEV 4.7.5.1
Add popupLight2
2025-06-25 14:21:25 +02:00
Armilar
0372221973 Update NSPanelTs.ts DEV 4.7.4.1
- Add popupShutter2
2025-06-25 00:20:01 +02:00
Johannes
947ef2d592 Update pages.py 2025-06-24 20:28:23 +02:00
Johannes
a1f39236c4 implements #1350 2025-06-23 22:38:20 +02:00
Thomas
4cdd1ed586 Merge pull request #1357 from tt-tom17/main
v4.7.2.4 - DEV-Update NSPanel.ts
2025-06-21 12:28:25 +02:00
tt-tom17
1836d29931 v4.7.2.4 - DEV-Update NSPanel.ts
- fix DEMO mode check of Powerpage
2025-06-21 12:22:07 +02:00
tt-tom17
fca29cfbd8 v4.7.2.4 - DEV-Update NSPanel.ts
- fix DEMO mode check of Powerpage
2025-06-21 12:18:14 +02:00
Armilar
b27910c1af Merge pull request #1354 from ticaki/main
IconSelect left and indicatorScreensaverEntity added
2025-06-20 10:35:21 +02:00
ticaki
f046ae6031 IconSelect left and indicatorScreensaverEntity added 2025-06-20 10:28:46 +02:00
Thomas
4475ab1277 Merge pull request #1348 from ticaki/main
States only respond to any if ack = false
2025-06-13 00:23:53 +02:00
dependabot[bot]
9afdb71a7c Bump home-assistant/builder from 2024.08.2 to 2025.03.0 (#1317)
Bumps [home-assistant/builder](https://github.com/home-assistant/builder) from 2024.08.2 to 2025.03.0.
- [Release notes](https://github.com/home-assistant/builder/releases)
- [Commits](https://github.com/home-assistant/builder/compare/2024.08.2...2025.03.0)

---
updated-dependencies:
- dependency-name: home-assistant/builder
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 20:08:47 +02:00
dependabot[bot]
c84d78551f Bump docker/login-action from 3.3.0 to 3.4.0 (#1316)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3.3.0...v3.4.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 20:08:35 +02:00
Johannes
5e2a4b17ae Update prepare_ha.md 2025-06-12 20:07:00 +02:00
Paweł Zubrycki
acdba468b3 Add weather service call functionality and fix weather forecast assignment (#1349) 2025-06-12 18:40:55 +02:00
ticaki
5803a489f5 States only respond to any if ack = false 2025-06-12 15:29:17 +02:00
patricknitsch
54c8d302a8 Add Entity Type "Valve" (#1347)
* Update pages.py

* Update controller.py

* Update pages.py

* Update pages.py
2025-06-06 19:24:56 +02:00
mikosoft83
8059905579 Update icons.py (#1343)
Climate icons improvement
2025-06-02 23:15:30 +02:00
Johannes
4dc39c1b79 Should fix #1336 2025-05-30 09:00:29 +02:00
Jan Čermák
16909f7e7f Fix AppDaemon 4.5.x compatibility - use entity attributes as dict (#1333)
With update to AppDaemon to 4.5.x (add-on 0.17.x), access to entity
attributes through properties doesn't work anymore - they are a dict.
Refactor the usage to read dict, leverage walrus operator where
applicable.

Fixes #1331
2025-05-28 22:24:30 +02:00
Johannes
397932a6bc disable forecast for now 2025-05-28 21:56:14 +02:00
Johannes
04ac10b453 fix error 2025-05-28 21:55:04 +02:00
Armilar
ff103927e8 v4.7.2.1 - DEV Update NSPanelTs.ts
add popupSlider to cardMedia (alexa)
2025-04-24 12:52:05 +02:00
Armilar
c6e94f80de Merge pull request #1325 from ticaki/main
Same as last :)
2025-04-14 14:18:19 +02:00
ticaki
5d4ae6247d Merge branch 'joBr99:main' into main 2025-04-14 14:16:37 +02:00
ticaki
8b63322e50 ups 2025-04-14 14:12:09 +02:00
Armilar
7fd5b3967a Merge pull request #1324 from ticaki/main
4.7.1.3 MrIcons also allow other mqtt states
2025-04-14 14:05:22 +02:00
ticaki
1d719446c0 MrIcons also allow other mqtt states 2025-04-14 14:00:40 +02:00
Armilar
3913b86228 v4.7.1.2 - Update NsPanelTs.ts
- Add cardMedia "Music Player Daemon (MPD)" (One-Instance-Player with Playlists, Tracklists, Shuffle, Repeat, Seek/Crossfade); mpd.X - Instance required
- Fix cardMedia "Music Player Daemon (MPD)" shuffle with repeat and repeat with repeat/single
- TFT 56 / 4.7.1 (EU)
- Add Player Icon-Logos logo-alexa, logo-spotify, logo-dlna, logo-sonos, logo-mpd, logo-volumios, logo-bose 
- Add parameter playerMediaIcon to cardMedia
- Fix Play/Pause in MediaPlayers
- TFT 56 / 4.7.1 (US-P and US-L)
2025-04-13 17:26:01 +02:00
Armilar
3fddbfe451 v4.7.1.2 - DEV-Update NSPanelTs.ts
Update Links to TFT US-L/US-P (v4.7.1)
2025-04-13 17:20:35 +02:00
Armilar
c7b492c276 v4.7.1.2 - DEV-Update NSPanelTs.ts
Fix Play/Pause Button in cardMedia (new bug with MPD-Player)
2025-04-12 10:44:31 +02:00
Armilar
2e0cff80c1 v4.7.1.1 - DEV-Update NSPanelTs.ts
- Add cardMedia "Music Player Daemon (MPD)" (One-Instance-Player with Playlists, Tracklists, Shuffle, Repeat, Seek/Crossfade); mpd.X - Instance required
- Fix cardMedia "Music Player Daemon (MPD)" shuffle with repeat and repeat with repeat/single
- TFT 56 / 4.7.1 - Add Player Icon-Logos logo-alexa, logo-spotify, logo-dlna, logo-sonos, logo-mpd, logo-volumios, logo-bose 
- Add parameter playerMediaIcon to cardMedia
2025-04-11 14:55:21 +02:00
Armilar
3943dee733 v4.7.0.3 - DEV-Update NSPanelTs.ts - FR #1321
- Add cardMedia "Music Player Daemon (MPD)" (One-Instance-Player with Playlists, Tracklists, Shuffle, Repeat, Seek/Crossfade); mpd.X - Instance required
- Fix cardMedia "Music Player Daemon (MPD)" shuffle with repeat and repeat with repeat/single
2025-04-10 12:41:48 +02:00
Armilar
41e7f3c3e2 v4.7.0.2 - DEV-Update NSPanelTs.ts
Add - cardMedia "Music Player Daemon (MPD)"
2025-04-10 11:04:17 +02:00
Armilar
5e373ad856 v4.7.0 - Update NSPanelTs.ts
- Fix cardSchedule in HMI
2025-04-02 21:58:35 +02:00
Armilar
0d3d40cca2 v4.6.2.1 - Update NsPanelTs.ts
- cardSchedule
- Add Release-Check with HMI
2025-04-02 21:53:54 +02:00
Armilar
221063a5a6 v4.6.2.1 - Update NSPanelTs.ts
- Add startup TFT-Release directly from NSPanel-TFT
- Comparison between version number and release removed
2025-04-01 14:35:02 +02:00
Armilar
8e9b8ab476 v4.6.2.1 - DEV Update NSPanelTs.ts
Add cardSchedule
2025-04-01 11:59:01 +02:00
Armilar
1c6be4681e v4.6.0.1 - Update NsPanelTs.ts
- v4.5.2    Fix Bugs in HUE-Light, Fix Icon-Colors with interpolateColors (Color, ColorTemp, Brightness), Fix ON instead of ON_ACTUAL for writing DP
- v4.5.2.1  Add Functions to Calculate Colors of Icons (Darken and CT (Kelvin))
- v4.5.2.1  Remove New Sliders (popupLightNew), Fix TFT-Pictures in TFT --> with v4.6.0
- v4.6.0    Fix Bugs in Channels Light and RGBsingle-Light, Fix Icon-Colors with interpolateColors (Color, ColorTemp, Brightness), Fix ON instead of ON_ACTUAL for writing DP
- v4.6.0.1  Add Functions to Calculate Colors of RGBsingle Icons (Darken and CT (Kelvin/Mired))
- v4.6.0.1  Fix Light-Icons if Color-Temperature uses Mired instead of Kelvin (500 Mired - 153 Mired = 2000 K - 6536 K)
- v4.6.0.1  Add icon2 to Lights
- v4.6.0.1  Add Functions to Calculate Colors of RGB and CT Icons (Darken and CT (Kelvin/Mired)) 
- v4.6.0.1  Add function cie_to_rgb, Add CIE Channel to Lights
- v4.6.0.1  Add hidden Entity2 (Password/Switch) to cardQR (PageItem-Parameter "hideEntity2" true/false)
2025-03-18 16:01:37 +01:00
Armilar
7b4f4cd863 v4.6.0.1 - DEV Update NSPanelTs.ts
Hide Entity2 in cardQR
2025-03-18 13:34:39 +01:00
Armilar
9b285efe2d v4.6.0 - DEV Update NSPanelTs.ts
- v4.6.0    Fix Bugs in Channels Light and RGBsingle-Light, Fix Icon-Colors with interpolateColors (Color, ColorTemp, Brightness), Fix ON instead of ON_ACTUAL for writing DP
- v4.6.0.1  Add Functions to Calculate Colors of RGBsingle Icons (Darken and CT (Kelvin/Mired))
- v4.6.0.1  Fix Light-Icons if Color-Temperature uses Mired instead of Kelvin (500 Mired - 153 Mired = 2000 K - 6536 K)
- v4.6.0.1  Add icon2 to Lights
- v4.6.0.1  Add Functions to Calculate Colors of RGB and CT Icons (Darken and CT (Kelvin/Mired))
- v4.6.0.1  Add function cie_to_rgb, Add CIE Channel to Lights
2025-03-17 14:38:31 +01:00
Armilar
22e96f2b3a v4.5.2.1 - DEV Update NSPanelTs.ts
- v4.5.2    Fix Bugs in HUE-Light, Fix Icon-Colors with interpolateColors (Color, ColorTemp, Brightness), Fix ON instead of ON_ACTUAL for writing DP
- v4.5.2.1  Add Functions to Calculate Colors of Icons (Darken and CT (Kelvin))
- v4.5.2.1  Remove New Sliders (popupLightNew), Fix TFT-Pictures in TFT --> with v4.5.3
2025-03-16 00:02:20 +01:00
Armilar
23da51f662 Update ioBroker_NSPanel_locales.json 2025-03-14 13:48:50 +01:00
Thomas
b395a08b6e Update CardChart_History.js
add const 'factor' for big value and negativ value on panel
2025-02-23 03:10:01 +01:00
Armilar
ac07dbb185 v4.5.0.5 - Bugfix InitDimmode by Gargano 2025-02-03 12:00:09 +01:00
Armilar
86ab806b6e v4.5.0.5 - Bugfix InitDimmode by Gargano 2025-02-03 11:32:52 +01:00
Armilar
89d08ea507 DEV v4.5.0.4 - Update NSPanelTs.ts
v4.5.0.4  fix DetermineDimBrightness (function returns undefined, because wrong DP check)
2025-01-30 19:36:33 +01:00
Thomas
deacd17fc9 DEV v4.5.0.3 - Update NSPanelTs.ts
fix version
2025-01-30 00:55:11 +01:00
Armilar
4372e4193e Merge pull request #1305 from ticaki/main
add bottemEntityText from ID
2025-01-29 23:54:21 +01:00
ticaki
d4cb8b548d Merge branch 'joBr99:main' into main 2025-01-29 23:45:22 +01:00
ticaki
faa2880e8d bottemEntityText from ID 2025-01-29 08:27:47 +01:00
Armilar
eeeccc786d Delete ioBroker/HMI/Readme 2025-01-28 14:10:32 +01:00
Armilar
3bcf2372b0 Add files via upload 2025-01-28 14:09:39 +01:00
Armilar
9612f882a5 Add files via upload 2025-01-28 14:07:39 +01:00
Armilar
aa29552a90 Add files via upload 2025-01-28 14:05:55 +01:00
Armilar
a38393338a Create Readme 2025-01-28 14:04:11 +01:00
Armilar
d2e953410c v4.5.0.2 - Update NsPanelTs.ts 2025-01-28 13:48:26 +01:00
Armilar
0ac345328b Update NSPanelTs.ts 2025-01-28 13:46:33 +01:00
Armilar
11bf450e4c Merge pull request #1304 from ticaki/main
Different treatment of icon3 fixed
2025-01-23 23:33:04 +01:00
ticaki
e54faea639 switch example 2025-01-23 20:06:24 +01:00
ticaki
25062483c9 ups? 2025-01-23 20:04:01 +01:00
ticaki
f58be676bf Merge branch 'joBr99:main' into main 2025-01-23 20:00:00 +01:00
ticaki
cc147d29ab Different treatment of icon3 fixed 2025-01-23 19:59:40 +01:00
Armilar
78d20f81d2 Merge pull request #1303 from ticaki/main
icon3 functionality also for thermometers and a function based on this in the screensaver
2025-01-23 18:55:08 +01:00
ticaki
29a3c8123c changelog 2025-01-23 17:05:50 +01:00
ticaki
7807651223 Merge branch 'joBr99:main' into main 2025-01-23 17:03:32 +01:00
ticaki
deb7f6788e Add icon 3 2025-01-23 17:01:57 +01:00
Thomas
9ca7a4e829 DEV v4.5.0.2 - Update NSPanelTs.ts
fix version
2025-01-23 16:28:40 +01:00
Thomas
855ab2b28c Merge pull request #1302 from tt-tom17/main
DEV v4.5.0 - Update NSPanelTs.ts
2025-01-23 16:22:15 +01:00
tt-tom17
b1b042a25f DEV v4.5.0 - Update NSPanelTs.ts
fix handleScreensaverUpdate => leftScreensaverentity
fix type leftScreensaverEntity
2025-01-23 16:19:53 +01:00
Thomas
3a82af67b1 Merge pull request #3 from joBr99/main
DEV v4.5.0.1 - Update NSPanelTs.ts
2025-01-23 16:14:16 +01:00
Armilar
84e2105361 v4.5.0.1 - Update NsPanelTs.ts
Change URL's
2025-01-23 14:09:39 +01:00
Armilar
bae90b2b55 DEV v4.5.0.1 - Update NSPanelTs.ts
Change TFT URLs
2025-01-23 12:21:29 +01:00
tt-tom17
f6b605443d DEV v4.5.0 - Update NSPanelTs.ts
- fix leftScreensaverentity
2025-01-23 10:25:59 +01:00
tt-tom17
14d337891a DEV v4.5.0 - Update NSPanelTs.ts
- fix leftScreensaverentity
2025-01-23 10:24:40 +01:00
Armilar
a3df442a6a Update CODEOWNERS 2025-01-22 23:27:19 +01:00
Armilar
53af81f84d Update CODEOWNERS 2025-01-22 23:26:48 +01:00
Armilar
02332cc094 v4.5.0 - Update NsPanelTs.ts
v4.4.0.12 Add JSDocs and some small fixes
v4.4.0.13 Error due to an empty character string when subscribing to icon IDs
v4.4.0.14 Add Screensaver3 and cardGrid3
v4.4.0.14 Added Easy-View Screensaver states handling
v4.4.0.14 icon3 added for use in blind for the state between 0-100
v4.5.0    TFT 54 / 4.5.0
2025-01-22 22:49:58 +01:00
Armilar
19964f4ea6 Merge pull request #1301 from ticaki/main
Add maxEntities = 4
2025-01-22 21:16:11 +01:00
ticaki
3e777246a0 Merge branch 'joBr99:main' into main 2025-01-22 20:56:22 +01:00
ticaki
737bb80af0 add maxEntities 2025-01-22 20:55:43 +01:00
Armilar
07155018ef Merge pull request #1300 from ticaki/main
activate EasyView
2025-01-22 20:18:17 +01:00
ticaki
b8c0939382 activate EasyView 2025-01-22 20:00:12 +01:00
Armilar
985d395ba3 Merge pull request #1299 from ticaki/main
Fixing report of ilove and deactivate EasyView
2025-01-22 19:48:43 +01:00
ticaki
9f8e899af7 Merge branch 'joBr99:main' into main 2025-01-22 19:07:35 +01:00
ticaki
5359ed5e4b fix report from ilove deactivate EasyView 2025-01-22 19:06:55 +01:00
Armilar
081d176f24 Merge pull request #1298 from ticaki/main
icon3 added for use in blind for the state between 0-100
2025-01-21 22:22:11 +01:00
ticaki
0bfe72eec9 Merge pull request #1 from ticaki/add-icon3
icon3 added for use in blind for the state between 0-100
2025-01-21 22:10:52 +01:00
ticaki
d417aa2fb9 Merge branch 'main' into add-icon3 2025-01-21 22:10:42 +01:00
ticaki
d647fb3b4f icon3 added for use in blind for the state between 0-100 2025-01-21 22:08:45 +01:00
Armilar
ebf6300b06 DEV v4.5.0 - Update NSPanelTs.ts 2025-01-21 15:06:23 +01:00
Armilar
3977f9aa53 Merge pull request #1297 from tt-tom17/main
DEV v4.5.0 - Update NSPanelTs.ts
2025-01-21 15:04:27 +01:00
tt-tom17
8478194bb0 DEV v4.5.0 - Update NSPanelTs.ts
fix try catch
2025-01-21 14:49:17 +01:00
Armilar
417c99cdb9 DEV v4.5.0 - Update NSPanelTs.ts 2025-01-21 13:05:51 +01:00
Armilar
0e8849a382 DEV v4.5.0. - Update NSPanelTs.ts 2025-01-21 12:53:26 +01:00
Thomas
dd9ccaf076 Merge pull request #1296 from tt-tom17/main
Add service menue esayView
2025-01-21 11:44:05 +01:00
tt-tom17
ff461d821c Add service menue esayView 2025-01-21 11:40:46 +01:00
Armilar
6d68165fb6 Merge pull request #1295 from ticaki/main
rename channel to DeviceName
2025-01-21 11:35:12 +01:00
ticaki
489fd23edb Merge branch 'joBr99:main' into main 2025-01-21 11:08:11 +01:00
ticaki
4b39d5b438 rename channel to DeviceName 2025-01-21 11:07:16 +01:00
Armilar
b5a5aa41c6 Merge pull request #1294 from ticaki/main
Added Easy-View Screensaver states handling
2025-01-20 22:25:28 +01:00
ticaki
e878e08675 Added Easy-View Screensaver states handling 2025-01-20 22:19:09 +01:00
Armilar
246a7f1922 v4.4.0.14 - Update NSPanelTs.ts
Add Screensaver3 and cardGrid3
2025-01-20 17:56:15 +01:00
Armilar
c83921ca71 Merge pull request #1292 from ticaki/main
Error due to an empty character string when subscribing to icon IDs
2025-01-12 00:25:10 +01:00
ticaki
c9deae3d5c Error due to an empty character string when subscribing to icon IDs 2025-01-11 23:18:29 +01:00
Armilar
8184c10e93 v4.4.0.12 - Merge pull request #1286 from ticaki/main
Add JSDocs
2024-12-07 18:56:36 +01:00
ticaki
98746cc8d1 Version number added and optimisations by Copilot 2024-12-07 16:03:09 +01:00
ticaki
79fe05eb9c Add JSDocs 2024-12-07 15:44:32 +01:00
ticaki
b2dd46411a some more JSDocs and and some small fixes 2024-12-06 23:03:51 +01:00
ticaki
2c7dd23220 Add some JSDocs 2024-12-06 20:35:25 +01:00
Johannes
a873e3e29e Update README.md 2024-11-23 11:54:41 +01:00
Armilar
6a3b984c6c v4.4.0.11 - Update NsPanelTs.ts
v4.4.0.8  Fix: InitDimmode => timeDimMode Day / timeDimMode Night
v4.4.0.8  Add Always On Display (AOD) to cardTHermo
v4.4.0.8  Add Hide Buttons at Power Off to cardThermo (Climate Alias Channel)
v4.4.0.8  Add Custom Icon Object to cartdThermo (Climate Alias Channel
v4.4.0.9  Fix: del 'HandleMessage()' in Trigger 'activeDimmodeBrightness'
v4.4.0.10 Fix: Bug #1266 trigger timeoutScreensaver
v4.4.0.11 Add new value 'PopupNotify' to ActivePage
2024-11-23 11:07:28 +01:00
Armilar
ebbcf7c21e Merge pull request #1283 from tt-tom17/tt-tom17/issue1281
DEV 4.4.0.11 - Update NSPanel.ts
2024-11-23 10:51:51 +01:00
Armilar
0526b26b4a Merge pull request #1282 from tt-tom17/main
DEV 4.4.0.10 - Update NSPanelTs.ts
2024-11-23 10:51:00 +01:00
tt-tom17
c20dab43a6 DEV 4.4.0.11 - Update NSPanel.ts
- Add new value 'PopupNotify' to ActivePage
- Fixes #1281
2024-11-23 00:47:01 +01:00
tt-tom17
918a859a74 DEV 4.4.0.10 - Update NSPanelTs.ts
- Fix: Bug #1266 trigger timeoutScreensaver
2024-11-23 00:14:16 +01:00
tt-tom17
b3d3902399 DEV 4.4.0.10 - Update NSPanelTs.ts
- Fix: Bug #1266 trigger timeoutScreensaver
2024-11-23 00:13:19 +01:00
joBr99
69e02b0886 . (add nextion2text) 2024-11-22 20:00:19 +00:00
joBr99
74a602c34d . 2024-11-22 20:57:26 +01:00
joBr99
710bb2d884 do not send button in entity is empty (add nextion2text) 2024-11-21 19:35:50 +00:00
joBr99
7396806fab do not send button in entity is empty 2024-11-21 20:32:38 +01:00
Johannes
a87044a2b9 Update panel.py 2024-11-20 20:02:23 +01:00
Johannes
0c54f747b9 Update panel.py 2024-11-20 20:01:49 +01:00
dependabot[bot]
d6955eaad7 Bump home-assistant/builder from 2024.03.5 to 2024.08.2 (#1248)
Bumps [home-assistant/builder](https://github.com/home-assistant/builder) from 2024.03.5 to 2024.08.2.
- [Release notes](https://github.com/home-assistant/builder/releases)
- [Commits](https://github.com/home-assistant/builder/compare/2024.03.5...2024.08.2)

---
updated-dependencies:
- dependency-name: home-assistant/builder
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-20 19:50:19 +01:00
Johannes
5638720336 fix buttons light mode detail page 2024-11-20 19:48:37 +01:00
Armilar
e33875e9f5 Merge pull request #1274 from tt-tom17/main
DEV v4.4.0.9 Update NSPanel.ts
2024-10-31 13:59:45 +01:00
Thomas
9532ca2442 Merge pull request #2 from joBr99/main
Bump frenck/action-addon-linter from 2.15 to 2.18 (#1272)
2024-10-31 13:14:22 +01:00
tt-tom17
47f59e1b63 DEV v4.4.0.9 Update NSPanel.ts
- Fix: del 'HandleMessage()' in Trigger activeDimmodeBrightness'
2024-10-31 13:08:25 +01:00
dependabot[bot]
b9195101da Bump frenck/action-addon-linter from 2.15 to 2.18 (#1272)
Bumps [frenck/action-addon-linter](https://github.com/frenck/action-addon-linter) from 2.15 to 2.18.
- [Release notes](https://github.com/frenck/action-addon-linter/releases)
- [Commits](https://github.com/frenck/action-addon-linter/compare/v2.15...v2.18)

---
updated-dependencies:
- dependency-name: frenck/action-addon-linter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-29 22:02:25 +01:00
Armilar
34a9424c29 DEV v4.4.0.8 - Update NSPanelTs.ts
- Fix OnColors without any parameter
2024-10-26 14:40:58 +02:00
Armilar
54ce2a1c10 DEV 4.4.0.8 - Update NSPanelTs.ts
- Add "Custom Icon" Object to cardThermo (Climate Alias Channel)
2024-10-26 00:45:19 +02:00
Armilar
5166fb1f58 DEV v4.4.0.8 - Update NSPanelTs.ts
- Add Always On Display (AOD) to cardTHermo
- Add Hide Buttons at Power Off to cardThermo (Climate Mode)
2024-10-25 12:48:37 +02:00
Armilar
5e9434b7eb Merge pull request #1270 from tt-tom17/main
v4.4.0.8  DEV - NSPanel.ts
2024-10-25 11:04:24 +02:00
tt-tom17
a7398e54e3 v4.4.0.8 - Fix: InitDimmode => timeDimMode Day / timeDimMode Night 2024-10-25 10:52:15 +02:00
tt-tom17
ac54e042ea Fix: activDimmodeBrightness be DimmodeDay/DimmodeNight
Function InitDimmode
2024-10-24 21:09:39 +02:00
Armilar
4f17085a81 v.4.4.0.7 - Fix: first start and initialisation with new NSPanel device (by wolwin)
https://github.com/joBr99/nspanel-lovelace-ui/pull/1263
2024-10-09 23:12:42 +02:00
Armilar
c864eb6e73 Merge pull request #1263 from wolwin/main
ioBroker - Update DEV NSPanelTs.ts - different fixes
2024-10-09 23:00:24 +02:00
wolwin
828aa8fd21 Update NSPanelTs.ts
Final
2024-10-09 20:52:04 +02:00
wolwin
84615fad05 Update NSPanelTs.ts
correct script version and PageNavi entry
2024-10-09 13:36:46 +02:00
wolwin
b90b50395c Update DEV NSPanelTs.ts
Fix: first start and initialisation with new NSPanel device
2024-10-06 14:16:04 +02:00
Armilar
c27a23e5fe v4.4.0.6 - Fix for MQTT-Client adapter
- Fix: Using MQTT adapter or MQTT-CLIENT adapter / Minor Fix by wolwin
2024-09-27 19:01:04 +02:00
Armilar
1b33ddb207 v4.4.0.6 - Fix for MQTT-Client adapter
- Fix: Using MQTT adapter or MQTT-CLIENT adapter / Minor Fix by wolwin
2024-09-27 18:57:22 +02:00
Armilar
d68de45c3b v4.4.0.6 - Fix for MQTT-Client adapter
v4.4.0.6  Fix: Using MQTT adapter or MQTT-CLIENT adapter / Minor Fix by wolwin
2024-09-27 18:37:06 +02:00
Armilar
5b46b39dac Merge pull request #1260 from tt-tom17/main
update NSPanelts.ts DEV
2024-09-27 18:28:50 +02:00
tt-tom17
2d0201759d sendToPanel - log message
CheckConfigParameters - existsObjekt mqtt
2024-09-27 17:23:10 +02:00
Armilar
104788e2a4 v4.4.0.6 - DEV Update NSPanelTs.ts
- Check Ports with mqtt.X and mqtt-client.X
2024-09-19 22:46:35 +02:00
Armilar
4f1139a531 v4.4.0.5 - Update NsPanelTs.ts
- Remove day.js
- Change identifier from day.js to moment.js
2024-09-19 20:51:32 +02:00
Armilar
f673aad38e v4.4.0.5 - Update NSPanelTs.ts
- Remove day.js
- Change identifier from day.js to moment.js
2024-09-19 20:44:12 +02:00
Armilar
c8a8e1351c v4.4.0.5 - Update NSPanelTs.ts
- Remove day.js
2024-09-18 22:39:36 +02:00
Armilar
5d84b59bbd v4.4.0.4 - Update NsPanelTs.ts
v4.4.0.2  Calculated energy consumption in relation to dimming mode and relay state (not the energy consumption of the outputs)
v4.4.0.3  Check prefix '.tele.' in config.NSPanelReceiveTopic
v4.4.0.4  New Feature: Hidden Carts
2024-09-18 09:44:59 +02:00
Armilar
2a807702f4 Merge pull request #1257 from tt-tom17/main
DEV 4.4.0.4 - Update NSPanelTs.ts
2024-09-15 13:36:26 +02:00
tt-tom17
448b9cb30c DEV 4.4.0.4 - Update NSPanelTs.ts
-fix setObject hiddenCards
2024-09-15 12:31:12 +02:00
Armilar
248dc3a1c9 Merge pull request #1256 from tt-tom17/hiddenCards
DEV 4.4.0.4 - Update NSPanelTs.ts
2024-09-15 11:11:07 +02:00
tt-tom17
cd76c0528e DEV 4.4.0.4 - Update NSPanelTs.ts 2024-09-14 23:22:22 +02:00
tt-tom17
58e2febf64 ioBroker_NSPanel_locales_service.json
- "hiddencards_offon"
2024-09-14 23:06:29 +02:00
tt-tom17
0372b034f6 DEV 4.4.0.4 - Update NSPanelTs.ts 2024-09-14 23:04:02 +02:00
Armilar
1d730a0ce5 DEV 4.4.0.4 - Update NSPanelTs.ts
Developer Version
- New Feature: hiddenCards
2024-09-14 12:01:00 +02:00
Armilar
1a629ee8d5 Merge pull request #1252 from tt-tom17/main
Check prefix '.tele.' in config.NSPanelReceiveTopic
2024-09-04 10:09:28 +02:00
tt-tom17
cd563ad1ce nspanel.ts
v4.4.0.3
Check prefix '.tele.' in config.NSPanelReceiveTopic
2024-09-03 22:02:05 +02:00
dependabot[bot]
ec18b6349b Bump docker/login-action from 3.2.0 to 3.3.0 (#1239)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3.2.0...v3.3.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-27 21:49:57 +02:00
Armilar
4d7d87d62a v4.4.0.2 - Calculated energy consumption
- Calculated energy consumption in relation to dimming mode and relay state (not the energy consumption of the outputs)
-add Try/Catch
2024-06-13 21:17:29 +02:00
Armilar
15a021a58f v4.4.0.2 - Calculated energy consumption
- Calculated energy consumption in relation to dimming mode and relay state (not the energy consumption of the outputs)
2024-06-13 21:04:17 +02:00
Thomas
63c85e6b96 Update NSPanelTs.ts
Fix TFT-Version
2024-06-10 22:31:36 +02:00
dependabot[bot]
6a94795a67 Bump docker/login-action from 3.1.0 to 3.2.0 (#1232)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3.1.0...v3.2.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-04 23:10:00 +02:00
Armilar
d302567369 v4.4.0.1 - Update NsPanelTs.ts
Fix TFT 54 to TFT 53
2024-05-19 20:38:39 +02:00
Armilar
f8d6a1543d v4.4.0 - Update NsPanelTs.ts
TFT Update 54
2024-05-13 23:02:30 +02:00
Armilar
6df5a68682 v4.4.0 - Update NSPanelTs.ts
TFT Update
2024-05-13 22:58:20 +02:00
Armilar
7e1cc36805 Merge pull request #1220 from tt-tom17/patch-tt-tom17
v4.3.3.44 - DEV Update NSPanelTs.ts
2024-05-05 22:08:13 +02:00
Thomas
491ed21f98 v4.3.3.44 - DEV Update NSPanelTs.ts
Fix MQTT-Port-check
2024-05-05 14:21:50 +02:00
Johannes
e53cf5dab0 Update prepare_ha.md 2024-04-13 12:50:02 +02:00
Johannes
e853889247 Update prepare_ha.md 2024-04-04 16:26:24 +02:00
Johannes
19b0fe4052 Update prepare_ha.md 2024-04-02 18:12:48 +02:00
Johannes
d94d937d77 Update pages.py 2024-03-30 12:18:31 +01:00
Johannes
e5c1f0588a Update icons.py 2024-03-30 12:17:41 +01:00
Johannes
dd88ebe5da Update prepare_ha.md 2024-03-30 12:15:23 +01:00
Johannes
5536335ac9 Update prepare_ha.md 2024-03-29 21:47:36 +01:00
Johannes
df4fff6911 add docs for workaround script for appdaemon in ha 2024.04 2024-03-29 15:48:30 +01:00
Johannes
3dd83fde66 Update README.md 2024-03-27 21:27:59 +01:00
dependabot[bot]
f50b1ececa Bump docker/login-action from 3.0.0 to 3.1.0 (#1193)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3.0.0...v3.1.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-27 21:22:58 +01:00
dependabot[bot]
ebee7b379e Bump home-assistant/builder from 2024.01.0 to 2024.03.5 (#1198)
Bumps [home-assistant/builder](https://github.com/home-assistant/builder) from 2024.01.0 to 2024.03.5.
- [Release notes](https://github.com/home-assistant/builder/releases)
- [Commits](https://github.com/home-assistant/builder/compare/2024.01.0...2024.03.5)

---
updated-dependencies:
- dependency-name: home-assistant/builder
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-27 21:22:50 +01:00
Odianosen Ejale
255db25f58 Card show helper (#1187)
* Turn app into AD Base app

* Added the ability to keep the messages being sent quiet

* fix little conflict

* Allow other apps to have access to current app

* Fixed card access typing

* Added show card helper

* Added navigate helper
2024-03-21 21:56:26 +01:00
Thomas
19050079d4 Update NSPanelTs.ts
fix demomodus cardPower
2024-03-18 17:03:24 +01:00
Thomas
8d97f98a29 Update NsPanelTs.ts
fix demomodus cradPower
2024-03-18 17:01:57 +01:00
Armilar
137ca5855e Update NsPanelTs.ts - Fix Screensaver BG-Color 2024-03-06 16:25:03 +01:00
Armilar
7707b48622 Update NSPanelTs.ts - Fix Screensaver BG Color 2024-03-06 16:23:24 +01:00
joBr99
193546d1ed fixes #1179 (add nextion2text) 2024-02-25 11:03:17 +00:00
joBr99
6703bca1d0 fixes #1179 2024-02-25 11:59:50 +01:00
Johannes
5739947586 Update pages.py 2024-02-25 11:53:11 +01:00
Johannes
5e1a7f2102 workaround for #1190 2024-02-25 11:49:25 +01:00
joBr99
a0e574391b implemented #1178 (add nextion2text) 2024-02-25 10:48:07 +00:00
joBr99
bd107d930a implemented #1178 2024-02-25 11:44:46 +01:00
Odianosen Ejale
66f83732bb Fixed typing (#1186)
* Turn app into AD Base app

* Added the ability to keep the messages being sent quiet

* fix little conflict

* Allow other apps to have access to current app

* Fixed card access typing
2024-02-19 21:45:31 +01:00
Odianosen Ejale
e796891d8e Current Card access (#1184)
* Turn app into AD Base app

* Added the ability to keep the messages being sent quiet

* fix little conflict

* Allow other apps to have access to current app

* Access other cards from apps
2024-02-19 18:05:00 +01:00
Odianosen Ejale
ba46bc9189 Added ability to keep logs quiet for messages being sent (#1183)
* Turn app into AD Base app

* Added the ability to keep the messages being sent quiet

* fix little conflict
2024-02-19 12:52:18 +01:00
Odianosen Ejale
64ff369a90 Turn app into AD Base app (#1182) 2024-02-19 00:17:40 +01:00
Thomas
92616429ba Merge pull request #1177 from tt-tom17/patch-tt-tom17
v4.3.3.43 - Update NsPanelTs.ts
2024-02-12 13:26:20 +01:00
Thomas
377383d672 v4.3.3.43 - DEV Update NSPanelTs.ts
minor fixes
2024-02-12 13:18:55 +01:00
Thomas
52d405a6d6 v4.3.3.43 - Update NsPanelTs.ts
- Change pageId with Alias in Communication with HMI
- Media-Player: Dynamic loading of the speaker list, playlist, tracklist, fix repeat, add seek, add elapsed/duration
- Minor Fixes; Add miValue / maxValue to Volume-Slider
- Fix: cardGrid2 => 9 Entities for Layout 'us-p' issue #1167
- Fix VolumeSlider
2024-02-12 13:17:25 +01:00
Thomas
2e1492c4fa v4.3.3.43 - DEV Update NSPanelTs.ts
Description extended
2024-02-12 13:10:26 +01:00
Johannes
16673df8cf Update config.yaml 2024-02-11 21:23:50 +01:00
Johannes
cb4c26acfd Update requirements.txt 2024-02-11 21:23:29 +01:00
Johannes
fda7ca4574 Update config.yaml 2024-02-11 21:16:13 +01:00
Yves Schumann
8e2e8d1e82 Fixed typos on Github issue templates (#1170) 2024-02-11 21:15:31 +01:00
jacekowski
4e36f47774 fix obsolete call to get_forecast (#1173) 2024-02-11 21:15:07 +01:00
Armilar
858dac73d0 v4.3.3.43 - DEV Update NSPanelTs.ts
Fix VolumeSlider
2024-02-11 18:37:20 +01:00
Thomas
3cccefb715 Merge pull request #1169 from starwarsfan/bugfix/fixDuplicatedDefinitions
Fixed duplicated definition of 'ct'
2024-02-11 08:54:18 +01:00
Thomas
44640f33d2 Merge pull request #1171 from tt-tom17/patch-tt-tom17
v4.3.3.43 - DEV Update NSPanelTs.ts
2024-02-10 23:35:19 +01:00
Thomas
2ae3b9bd8e v4.3.3.43 - DEV Update NSPanelTs.ts
- Fix: cardGrid2 => 9 Entities for Layout 'us-p' issue #1167
2024-02-10 23:27:22 +01:00
Armilar
2db991a371 v4.3.3.42 - DEV Update NSPanelTs.ts
Add minValue / maxValue to Volume-Slider
2024-02-10 22:30:27 +01:00
Armilar
2e52abd76c v4.3.342 - DEV Update NSPanelTs.ts
Add minValue/maxValue to Volume-Slider
2024-02-10 22:28:52 +01:00
Yves Schumann
03c3acd214 Fixed duplicated definition of 'ct' 2024-02-10 20:43:47 +01:00
Armilar
c26b277c56 v4.3.3.42 - DEV Update NSPanelTs.ts
Spotify Minor Fixes
2024-02-10 11:09:42 +01:00
Armilar
3f7fd40d17 v4.3.3.42 - DEV Update NSPanelTs.ts
- Minor Fixes
- Change pageId with Alias in Communication with HMI (cardMedia)
- spotiffy Media-Player: Dynamic loading of the speaker list, playlist, tracklist, fix repeat, add seek, add elapsed/duration
2024-02-09 17:03:55 +01:00
Armilar
0b01c0d236 Merge pull request #1166 from Armilar/main
Able to merge. These branches can be automatically merged.
2024-02-07 23:22:35 +01:00
Armilar
3107b73430 Merge branch 'joBr99:main' into main 2024-02-07 23:21:27 +01:00
Armilar
5d421ae525 v4.3.3.42 - DEV Update NSPanelTs.ts
Fix Volumio in cardMedia
2024-02-07 22:53:57 +01:00
Johannes
56a8495787 Update config.yaml 2024-02-07 19:38:47 +01:00
Armilar
a12bc03dd7 v4.3.3.42 - DEVUpdate NSPanelTs.ts
Elapsed Fixes in cardMedia
2024-02-07 13:28:46 +01:00
Armilar
6b1a65f8f4 v4.3.3.42 - Update NSPanelTs.ts
Minor Fixes in cardMedia
2024-02-07 11:25:58 +01:00
Thomas
9d94155480 Update NSPanelTs.ts
Fix: bottomScreensaverEntity[i].ScreensaverEntityIconColor
Zeile 8899
2024-02-07 10:38:59 +01:00
joBr99
3b46759134 . 2024-02-06 22:15:57 +01:00
Thomas
8d21c653ae Merge pull request #1164 from tt-tom17/patch-tt-tom17
update CardLChart_Influx2.ts
2024-02-06 15:06:58 +01:00
Thomas
d983c44db7 update CardLChart_Influx2.ts
- codeanpassungen
2024-02-06 15:04:13 +01:00
Thomas
467a1d92bb Merge pull request #1163 from tt-tom17/patch-tt-tom17
v4.3.3.41 Update NSPanel.ts
2024-02-06 10:35:45 +01:00
Thomas
157d3e3e66 v4.3.3.41 Update NSPanel.ts
- Fix: activeBrightness -> null
- Fix: bHome -> corrected PageId
2024-02-06 10:32:06 +01:00
Armilar
51bb320dce Merge pull request #1162 from ticaki/main
Handle null in active*Brightness
2024-02-05 19:37:18 +01:00
ticaki
12c99c6857 Handle null in active*Brightness 2024-02-05 19:29:15 +01:00
Armilar
62e905f336 v4.3.3.40 - Update NsPanelTs.ts
- Fix maxColorTempValue for RGB
- Fix SqueezeboxRPC-Media-Player and add some Functions
2024-02-05 17:21:13 +01:00
Armilar
9b5964a758 v4.3.3.40 - Update NSPanelTs.ts
- Fix maxColorTempValue for RGB
- Fix SqueezeboxRPC-Media-Player and add some Functions
2024-02-05 17:06:01 +01:00
Armilar
9c49a9c67d v4.3.3.39 - Update NSPanelTs.ts
Fix: if (pageItem.minValueColorTemp !== undefined && pageItem.maxValueColorTemp !== undefined) {
2024-02-03 10:45:45 +01:00
Armilar
0a2461f4a5 v4.3.3.39 - Update NsPanelTs.ts
fix maxValueColorTemp
2024-02-03 10:44:24 +01:00
Thomas
49577ddbb6 Merge pull request #1159 from tt-tom17/main
v4.3.3.39 Update NSPanel.ts
2024-01-30 11:02:24 +01:00
Thomas
6172b0c35f v4.3.3.39 Update NSPanel.ts
- Add: Optional setOn & setOff for HW button with mode 'set'
- Fix: ack for read-only state
2024-01-30 10:55:19 +01:00
Thomas
e7cc10692b Update and Rename CardLChart_Influx2 2024-01-30 10:23:19 +01:00
Thomas
221d2c717d Merge pull request #1157 from tt-tom17/patch-tt-tom17
v4.3.3.39  Update NSPanel.ts
2024-01-30 08:55:30 +01:00
Thomas
2b54f742c5 v4.3.3.39 Update NSPanel.ts
- Add: Optional setOn & setOff for HW button with mode 'set'
- Fix: ack for read-only state
2024-01-30 08:50:21 +01:00
Armilar
f02eddcebe Merge branch 'joBr99:main' into main 2024-01-29 12:16:00 +01:00
Thomas
c25a5cef67 Merge pull request #1156 from tt-tom17/patch-tt-tom17
v4.3.3.39 Update NSPanel.ts
2024-01-29 12:14:25 +01:00
Thomas
0f69ee951c v4.3.3.39 Update NSPanel.ts
- Add: Optional setOn & setOff for HW button with mode 'set'
- Fix: ack for read-only state
2024-01-29 11:58:37 +01:00
Thomas
fd6650db50 v4.3.3.39 Update NSPanel.ts
- Add: Optional setOn & setOff for HW button with mode 'set'
- Fix: ack for read-only state
2024-01-29 10:17:37 +01:00
Thomas
f2ad80665a v4.3.3.39 Update NSPanel.ts
- Add: Optional setOn & setOff for HW button with mode 'set'
- Fix: ack for read-only state
2024-01-29 09:40:01 +01:00
Armilar
cff9c94c27 Merge pull request #1154 from ticaki/main
fix ack for read-only state
2024-01-28 02:49:58 +01:00
ticaki
b6fdc12820 fix ack for read-only state 2024-01-27 18:02:05 +01:00
Armilar
01265faef9 Merge pull request #1153 from tt-tom17/patch-tt-tom17
Script vom Wiki nach Github schieben
2024-01-26 18:56:58 +01:00
Thomas
a2feae891e Script vom Wiki nach Github schieben 2024-01-26 18:50:47 +01:00
Armilar
bd24d4bcd1 Merge pull request #1151 from ticaki/main
2 Points
2024-01-23 22:04:52 +01:00
Armilar
0efbd9e23c Merge branch 'joBr99:main' into main 2024-01-23 21:41:06 +01:00
ticaki
4aab72fb10 build nice objects 2024-01-23 18:36:03 +01:00
ticaki
aa266da5ac fix txt.matchall 2024-01-23 18:17:37 +01:00
ticaki
49987d55ce Merge branch 'joBr99:main' into main 2024-01-23 18:16:59 +01:00
Armilar
c6939efd70 Merge pull request #1149 from theknut/patch-1
feat: write button event to states
2024-01-23 18:16:19 +01:00
ticaki
f7f853f05e Add setOn / setOff 2024-01-23 16:55:07 +01:00
ticaki
1faa540a70 Add some optional types 2024-01-23 07:58:21 +01:00
theknut
1746c876bd feat: write button event to states
Whenever a button is pressed there is no event triggered which lets the user easily implement triggers on this event.
This PR adds the functionality that the current button event is written to NSPanel objects structures as states under `0_userdata.0.NSPanel.1.Event.Button`:
- Action - whatever button was pressed (button, media-OnOff, volumeSlider, ...)
- Value -  auxillary value for this action (e.g. action `volumeSlider` - `Value` holds the value the slider was moved to)
- Id
  - Action == `button` - Id of the alias the button is connected to
  - else - Id of the current page item or the page to navigate to
2024-01-22 00:19:23 +01:00
Armilar
cd0c015fea v4.3.3.38 - Update NsPanelTs.ts (add nextion2text) 2024-01-20 23:31:37 +00:00
Armilar
760b25b7a2 v4.3.3.38 - Update NsPanelTs.ts
* v4.3.3.37 Change: Allow data points to be flushed for popUpNotify. Activate screensaver with one click.
* v4.3.3.38 Fix: joBr99#1098
* v4.3.3.38 Types: Number of PageItems defined & HandleScreensaverStatusIcons rewritten
* v4.3.3.38 Optimate: function SendTime()
* v4.3.3.38 Add: ScreensaverEntityIconSelect for MRIcons is like common.states for states.
* v4.3.3.38 Add: Changing the ScreensaverEntityValue value updates the screensaver.
* v4.3.3.38 Change: yAxisTicks parameter is not required in cardLChart PageItem
* v4.3.3.38 Add: click on indicatorIcon navigate to Page
2024-01-20 23:01:36 +01:00
Armilar
eccfad5615 Merge pull request #1147 from tt-tom17/patch-tt-tom17
v4.3.3.38
2024-01-20 22:49:20 +01:00
Thomas
27034e4bae v4.3.3.38
-Add: click on indicatorIcon navigate to Page
2024-01-20 22:41:00 +01:00
joBr99
99376c8fc2 . (add nextion2text) 2024-01-20 19:56:16 +00:00
joBr99
17e7ba1ef2 . 2024-01-20 20:53:25 +01:00
joBr99
38526890cc . (add nextion2text) 2024-01-19 22:12:34 +00:00
joBr99
ae9b33d5f0 . 2024-01-19 23:09:47 +01:00
joBr99
ff96812d26 Merge branch 'main' of github.com:joBr99/nspanel-lovelace-ui (add nextion2text) 2024-01-19 15:23:21 +00:00
joBr99
0359a4b3dc Merge branch 'main' of github.com:joBr99/nspanel-lovelace-ui 2024-01-19 16:20:41 +01:00
joBr99
f75dd3a800 fixes #1146; implements #1144 2024-01-19 16:20:28 +01:00
Armilar
a992dc56c5 Merge pull request #1140 from ticaki/main
siehe Beschreibung
2024-01-19 12:52:22 +01:00
Armilar
576176e1cc Change in cardLChart
Change: yAxisTicks parameter is not required in cardLChart PageItem
2024-01-19 12:44:46 +01:00
Armilar
1d3914ce86 let out_msgs: NSPanel.Payload[] = []; 2024-01-19 12:37:30 +01:00
Armilar
b2f338cad8 Change cardLChart - no yAxisTicks required 2024-01-19 12:33:35 +01:00
Armilar
74a329ca29 Merge pull request #1142 from theknut/patch-1
feat: calculate yAxisTicks based on given values
2024-01-19 12:25:55 +01:00
theknut
29ae1b4034 fix: wrong yAxisTicks logged in debug log 2024-01-19 10:34:50 +01:00
theknut
ae5cab9830 refactor: ensure yAxisTicks are calculated every time if not provided 2024-01-19 10:27:01 +01:00
theknut
a986e588b5 feat: calculate yAxisTicks based on given values
If no yAxisTicks are provided for the signal, try to calculate it based on the given values.
2024-01-19 00:27:10 +01:00
ticaki
8c84c1050f fix pm/am 2024-01-19 00:03:15 +01:00
ticaki
c3ded4d817 buildNSPanelString 2024-01-18 22:15:04 +01:00
ticaki
db32de68e3 add ScreensaverEntityValue to on() 2024-01-17 23:14:54 +01:00
ticaki
f76f2ca393 tweak HandleScreensaverStatusIcons 2024-01-17 17:25:51 +01:00
ticaki
8449257628 fix number/string 2024-01-16 21:39:43 +01:00
ticaki
2bd3d0d290 reduce HandleScreensaverStatusIcons 2024-01-16 20:51:24 +01:00
ticaki
117798a3f5 icon fix 2024-01-16 17:34:09 +01:00
ticaki
01392bcbf8 fix unsubscribePowerSubscriptions 2024-01-16 16:32:38 +01:00
ticaki
5a3478d916 ups :D 2024-01-16 16:06:47 +01:00
ticaki
f3b545fd90 remove commented out code 2024-01-16 16:04:22 +01:00
ticaki
e7a6a05a1b Update Version and Changelog 2024-01-16 15:59:28 +01:00
ticaki
f65ff57a95 HandleScreensaverStatusIcons rewritten
fixed #1098
types: Number of PageItems defined
2024-01-16 15:55:51 +01:00
ticaki
9a8f53e890 Merge branch 'joBr99:main' into main 2024-01-16 13:13:33 +01:00
Armilar
e94c711f12 v4.3.3.37 - Update NSPanelTs.ts
Change: Allow data points to be flushed for popUpNotify. Activate screensaver with one click.
2024-01-15 11:00:22 +01:00
Armilar
4cc8455fff v4.3.3.36 - Update NsPanelTs.ts
- v4.3.3.34 Fix: Disabled Icon Status for Blinds while bug in updating data points in ioBroker (reason unknown)
- v4.3.3.35 Add: relay.1/relay.2 show the confirmed status
- v4.3.3.36 Fix: change ScreensaverTimeout and activeBrightness
- v4.3.3.36 Fix: schedule SendTime
- v4.3.3.36 Fix: Some Types and Minor Fixes
2024-01-14 20:46:19 +01:00
Armilar
943bb93398 v4.3.3.36 - Update NsPanelTs.ts
- v4.3.3.34 Fix: Disabled Icon Status while bug in updating data points in ioBroker (reason unknown)
- v4.3.3.35 Add: relay.1/relay.2 show the confirmed status
- v4.3.3.36 Fix: change ScreensaverTimeout and activeBrightness
- v4.3.3.36 Fix: schedule SendTime
- v4.3.3.36 Fix: Some Types and Minor Fixes
2024-01-14 20:43:14 +01:00
Armilar
0a1eb8c2e5 v4.3.3.26 - Update NsPanelTs.ts
- v4.3.3.34 Fix: Disabled Icon Status while bug in updating data points in ioBroker (reason unknown)
- v4.3.3.35 Add: relay.1/relay.2 show the confirmed status
- v4.3.3.36 Fix: change ScreensaverTimeout and activeBrightness
- v4.3.3.36 Fix: schedule SendTime
- v4.3.3.36 Fix: Function _schedule SummerTime/WinterTime

- v4.3.3.34 Fix: Disabled Icon Status while bug in updating data points in ioBroker (reason unknown)
- v4.3.3.35 Add: relay.1/relay.2 show the confirmed status
- v4.3.3.36 Fix: change ScreensaverTimeout and activeBrightness
- v4.3.3.36 Fix: schedule SendTime
- v4.3.3.36 Fix: Some Types and Minor Fixes
2024-01-14 20:41:38 +01:00
ticaki
b7fd06413d remove all <type> 2024-01-12 20:42:54 +01:00
ticaki
a2b805f4e1 SendTime - optimated 2024-01-12 20:38:47 +01:00
Armilar
bc69af7b6b v4.3.3.36 - Update NSPanelTs.ts
Add common write false/true
2024-01-11 12:51:34 +01:00
Armilar
c36202878f Update ioBroker_NSPanel_locales_service.json 2024-01-11 12:00:26 +01:00
Armilar
60f31595d4 v4.3.3.36 - Update NSPanelTs.ts 2024-01-10 22:39:48 +01:00
Armilar
7194d7f613 v4.3.3.36 - Update NSPanelTs.ts
Fix Alexa Elapsed
2024-01-10 22:31:29 +01:00
Armilar
af02a70600 Merge pull request #1138 from ticaki/main
Fixed: schedule with objects starts only 1 time
2024-01-10 22:27:01 +01:00
ticaki
77d8e0607d Merge branch 'joBr99:main' into main 2024-01-10 22:21:08 +01:00
ticaki
d6d12bc93c Fixed: schedule with objects starts only 1 time 2024-01-10 22:19:44 +01:00
Armilar
ead1def4bb Merge pull request #1134 from tt-tom17/main
v4.3.3.36 Update NSPanel.ts
2024-01-09 22:57:12 +01:00
Thomas
14e944885f v4.3.3.36 Update NSPanel.ts
- Fix: change ScreensaverTimeout and activeBrightness
- Fix: schedule SendTime
- Fix: Function _schedule SummerTime/WinterTime
2024-01-09 22:37:18 +01:00
Armilar
a075e0cba8 Merge pull request #1133 from ticaki/main
2 Fixes
2024-01-09 21:46:44 +01:00
ticaki
dd14e66f10 update summer/winter fix 2024-01-09 21:24:52 +01:00
ticaki
ce0892b986 Fixed: update every minute
Fixed:  Schedule: {hour: minutes:} works with summer/winter time
2024-01-09 21:09:56 +01:00
Armilar
71b84cc8d3 Merge pull request #1131 from ticaki/main
schedule, 1 extendObject, relay show status of tasmota
2024-01-09 18:03:02 +01:00
ticaki
fd3ce243a6 update on replace 2024-01-08 22:29:08 +01:00
ticaki
aa3e90ef98 Get dp from NSPanelSendTopic 2024-01-08 22:23:06 +01:00
ticaki
2621b22ffd fix schedule 2024-01-08 21:55:53 +01:00
ticaki
6460f5f4ff Merge branch 'joBr99:main' into main 2024-01-08 20:28:46 +01:00
ticaki
e45560c27f add relays show status 2024-01-08 20:22:41 +01:00
ticaki
0c6cd158dd change schedule (testing needed)
add 1 extendObjectfor bgColorIndicator
2024-01-08 18:52:33 +01:00
dependabot[bot]
f11de05eb3 Bump github/codeql-action from 2 to 3 (#1094)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-08 16:38:05 +01:00
Armilar
ef47efb9aa Merge pull request #1130 from joBr99/Armilar-patch-4
v4.3.3.34 - Bose Soundtouch final Proto
2024-01-08 11:33:06 +01:00
Armilar
54422eccaa v4.3.3.34 - Bose Soundtouch final Proto
Fix: Disabled Icon Status while bug by updating data points in ioBroker (reason unknown)
2024-01-08 11:29:19 +01:00
dependabot[bot]
02004f4b6d Bump home-assistant/builder from 2023.12.0 to 2024.01.0 (#1129)
Bumps [home-assistant/builder](https://github.com/home-assistant/builder) from 2023.12.0 to 2024.01.0.
- [Release notes](https://github.com/home-assistant/builder/releases)
- [Commits](https://github.com/home-assistant/builder/compare/2023.12.0...2024.01.0)

---
updated-dependencies:
- dependency-name: home-assistant/builder
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-08 09:15:39 +01:00
Armilar
58278c5388 Merge pull request #1127 from joBr99/Armilar-patch-4
Fix Bose Soundtouch Proto
2024-01-07 23:44:53 +01:00
Armilar
ff7d2020f7 Update NSPanelTs.ts 2024-01-07 23:42:35 +01:00
Armilar
160420fe82 Merge pull request #1126 from kuckuckmann/patch-11
Update Alarm_Page_Erweitertes_Skript_mit_PopupNotifyPage.xml
2024-01-07 23:11:19 +01:00
kuckuckmann
56703ec458 Update Alarm_Page_Erweitertes_Skript_mit_PopupNotifyPage.xml
Add further Text to create String for ID
2024-01-07 18:28:37 +01:00
Armilar
9947664ae8 Merge pull request #1125 from kuckuckmann/patch-10
Update Alarm_Page_Erweitertes_Skript_mit_PopupNotifyPage.xml
2024-01-07 14:42:08 +01:00
kuckuckmann
4d3f54439e Update Alarm_Page_Erweitertes_Skript_mit_PopupNotifyPage.xml
Fix Number Value from decimal to integer value and convert to string for Datapoint PopupNotifyPage [string] at Block Value.
2024-01-07 14:41:07 +01:00
Armilar
6254f369f4 Merge pull request #1124 from ticaki/main
add namespace
2024-01-07 14:31:31 +01:00
ticaki
9b98cac4c8 More types without namespace for compatibility. 2024-01-07 13:49:36 +01:00
ticaki
71f3b75ab2 add namespace 2024-01-07 13:33:30 +01:00
Armilar
1a5cf8a2f7 Merge pull request #1122 from ticaki/main
1 Line warning for EHOSTUNREACH
2024-01-07 10:39:01 +01:00
ticaki
33712b198d Merge branch 'joBr99:main' into main 2024-01-07 00:06:33 +01:00
ticaki
1fd5784a54 1 Line warning for EHOSTUNREACH 2024-01-07 00:05:50 +01:00
Armilar
3904ca2343 Fix BoseSoundtouch Proto 2024-01-06 23:44:10 +01:00
Armilar
8ebd0f5193 Merge pull request #1121 from ticaki/main
some types and scriptname for menu
2024-01-06 20:46:45 +01:00
ticaki
8c9bca3f25 Merge branch 'joBr99:main' into main 2024-01-06 19:34:45 +01:00
ticaki
6908744669 some types and scriptname for menu 2024-01-06 19:32:26 +01:00
Armilar
d0e463de98 v4.3.3.33 - Hotfix
* Hotfix max Number of indicatorScreensaverEntity
* Beta Player Bose Soundtouch
2024-01-05 17:54:07 +01:00
Armilar
f4c7287dfd v4.3.3.33 - Update NSPanelTs.ts
Hotfix max Number of indicatorScreensaverEntity
2024-01-05 17:51:15 +01:00
Armilar
a33df14761 Merge pull request #1119 from ticaki/main
Fixed: HandleScreensaverUpdate: Cannot read properties of undefined
2024-01-05 17:38:08 +01:00
ticaki
3afc41269c Merge branch 'joBr99:main' into main 2024-01-05 17:22:49 +01:00
ticaki
11add2bfcc Fix screensaver bla of undefined 2024-01-05 17:22:21 +01:00
Armilar
dd84fa16e5 v4.3.3.33 - Update NSPanelTs.ts
Add Bose Soundtouch Functions
2024-01-05 14:30:34 +01:00
Armilar
e823c0f1ec Update NSPanelTs.ts
Add Bose Soundtouch Functions
2024-01-05 14:28:12 +01:00
Armilar
56c104a5bc v4.3.3.32 - Update NsPanelTs.ts
* Hotfix Spotify
* Add Types see commits
* v4.3.3.32 Add more details to types for: leftScreensaverEntity, indicatorScreensaverEntity, PageThermo, PageMedia 
* Remove not uses propertys from PageItem
* Add Body for BoseSoundtouch-Player
2024-01-05 12:55:36 +01:00
Armilar
bfb2c2eaab v4.3.3.32 - Update NSPanelTs.ts
* Hotfix Spotify
* Add Types see commits
* v4.3.3.32 Add more details to types for: leftScreensaverEntity, indicatorScreensaverEntity, PageThermo, PageMedia 
* Remove not uses propertys from PageItem
* Add Body for BoseSoundtouch-Player
2024-01-05 12:53:46 +01:00
Armilar
7d57205ac2 Merge pull request #1118 from ticaki/main
Add types, Remove not used Propertys
2024-01-05 12:48:06 +01:00
ticaki
4b81b1794d Reset NsPanelTS.ts from ./iobroker/ 2024-01-05 11:16:52 +01:00
ticaki
f5019b494f Reset NsPanelTS.ts from ./iobroker/ 2024-01-05 11:10:42 +01:00
ticaki
5102b8b955 Add Types for
ButtonActionType
EventMethod
SerialType
2024-01-05 11:06:53 +01:00
ticaki
089e553944 remove unused propertys
add types leftScreensaverEntityType
add types indicatorScreensaverEntityType
add types PageMediaItem
add types PageThermoItem
add types roles (common.role)
add types ButtonActionType
add alot undefined checks
add some type checks
merge 2 on() functions
2024-01-05 03:14:55 +01:00
ticaki
dfc07a6d76 Merge branch 'joBr99:main' into main 2024-01-04 22:36:50 +01:00
Armilar
b7687e006c v4.3.3.32 - Update NsPanelTs.ts
Hotfix Spotify Player
2024-01-04 22:23:56 +01:00
Armilar
10cf15bebd v4.3.3.32 - Update NSPanelTs.ts
Hotfix Spotify Player
2024-01-04 22:22:01 +01:00
Armilar
fc3d4adc72 Update NSPanelTs.ts 2024-01-04 22:15:47 +01:00
Armilar
bc330d5aaf Create NSPanelTs.ts 2024-01-04 22:14:03 +01:00
ticaki
c8a8feace2 some more types 2024-01-04 21:49:08 +01:00
Armilar
9afdaa4cbc v4.3.3.31 - Update NsPanelTs.ts
* Remove: autoCreateAlias from cardMedia
* Remove: adapterPlayerInstance from every card except cardMedia
* [dev]: optional with type - cardMedia has adapterPlayerInstance all other not 
* [dev]: add PlayerType some more work to do
* changed: adapterPlayerInstance instance 0-9 allowed. Always require a '.' at the end.
2024-01-03 21:11:51 +01:00
Armilar
18c7f2eb9c Merge pull request #1116 from ticaki/main
some more types
2024-01-03 21:01:29 +01:00
ticaki
de237171ef add cases 2024-01-03 20:53:15 +01:00
ticaki
a4b90944e8 typo 2024-01-03 20:17:53 +01:00
ticaki
cb44fcc8c9 add bose aliase 2024-01-03 20:16:13 +01:00
ticaki
03bae9e9bd add check for adapterPlayerInstanceType 2024-01-03 19:10:42 +01:00
ticaki
1ec463f6c7 type 2024-01-03 18:45:21 +01:00
ticaki
5420abcfaa adapterPlayerInstance more types 2024-01-03 18:38:45 +01:00
ticaki
e2530cdf62 typo in types 2024-01-03 17:38:53 +01:00
ticaki
b14687cb30 some more types 2024-01-03 17:04:07 +01:00
Armilar
360fb881f1 v4.3.3.30 - Update NsPanelTs.ts by Ticaki
- Überarbeitung der Types 
- Verbesserung der Variablenprüfung
- Bessere Fehleranzeige in der Konfiguration
2024-01-02 22:52:47 +01:00
Armilar
90d35a8574 Merge pull request #1113 from ticaki/main
v4.3.3.30 - Types work
2024-01-02 21:49:30 +01:00
ticaki
73a0ba468e ticaki for ever 2024-01-02 19:58:44 +01:00
ticaki
4e7119768b PageType in config 2024-01-02 18:32:39 +01:00
ticaki
8bfa6deb76 Add version 2024-01-02 17:52:31 +01:00
ticaki
e87febc54a cardUnlock partial usecolor 2024-01-02 17:46:29 +01:00
ticaki
43df10e823 Merge branch 'joBr99:main' into main 2024-01-02 17:37:09 +01:00
ticaki
e2acb70a1c some types 2024-01-02 17:36:30 +01:00
Armilar
f8774af675 Merge pull request #1112 from tt-tom17/Tasmota_Buzzer
v4.3.3.29 Update NSPanel.ts
2024-01-02 16:07:07 +01:00
Thomas
9ddb6c7834 Update NsPanelTs.ts 2024-01-02 15:53:38 +01:00
Thomas
330e5fecdf v4.3.3.29 Update NSPanel.ts
- Add Tasmota Buzzer for NotifyPage
- Fix ThermoPage -> UnSubScribsWatcher
2024-01-02 15:51:48 +01:00
ticaki
6cc41bf510 some types work 2024-01-02 14:05:03 +01:00
ticaki
956bd23a56 add types for ScreensaverEntityIconColor 2024-01-02 11:59:19 +01:00
ticaki
f1ce806ded fix cardMedia 2024-01-02 02:02:28 +01:00
ticaki
7748c22292 fix ActivePage 2024-01-01 23:30:31 +01:00
ticaki
131aa491b9 update config: Config 2024-01-01 22:09:19 +01:00
ticaki
dbc5ff7ccd fix typo 2024-01-01 21:55:22 +01:00
ticaki
5c3f366e53 fix types 2024-01-01 21:53:13 +01:00
Armilar
b1b679701e Merge pull request #1110 from joBr99/Armilar-patch-4
v4.3.3.28 - Update NsPanelTs.ts
2023-12-31 11:43:28 +01:00
Armilar
c489f07c0a v4.3.3.28 - Update NsPanelTs.ts
- Fix short ID's in v4.3.3.27
- Fix window Icons in CreateEntity 
- Add MQTT-Client Check
2023-12-31 11:33:40 +01:00
Armilar
14bc7dedec v4.3.3.28 - Update NsPanelTs.ts
- Fix short ID's in v4.3.3.27
- Fix window Icons in CreateEntity 
- Add MQTT-Client Check
2023-12-30 14:15:54 +01:00
Armilar
d4067c5ddb v4.3.3.28 - Update NsPanelTs.ts
- Fix short ID's in v4.3.3.27
- Fix window Icons in CreateEntity 
- Add MQTT-Client Check
2023-12-30 11:56:31 +01:00
Armilar
50209418d7 v4.3.3.28 - Update NsPanelTs.ts
- short ID's
- Fix windows open/close in createEntity
2023-12-30 11:23:09 +01:00
Armilar
8f3c74165d v4.3.3.26 - Downgrade NsPanelTs.ts
Bug with inSel-Popup in v4.3.3.27
2023-12-29 12:27:21 +01:00
Armilar
b7b8f389eb Merge pull request #1108 from tt-tom17/PageId
v4.3.3.27 Update NSPanel.ts
2023-12-28 14:51:14 +01:00
Thomas
9082ed20f3 v4.3.3.27 Update NSPanel.ts
- Fix Payload (pageItem.id -> placeId) by Function CreateEntity
- Fix Fallback PageItem.name by Function CreateEntity
2023-12-28 14:40:09 +01:00
Thomas
f807406a97 Update NsPanelTs.ts 2023-12-28 10:23:02 +01:00
Thomas
93aafe259b Update NsPanelTs.ts
Ablösung pageItem.id durch placeId
2023-12-28 09:46:05 +01:00
Armilar
b96fc6e6bd Merge pull request #1105 from tt-tom17/main
v4.3.3.26 - Update NSPanel.ts
2023-12-26 20:55:31 +01:00
joBr99
1996b29c60 . 2023-12-26 12:04:00 +01:00
Thomas
c8eb476ca8 Merge pull request #1 from tt-tom17/Log-JSON-Convert
v4.3.3.26 - Update NSPanel.ts
2023-12-26 00:52:26 +01:00
Thomas
aeaa995a0a v4.3.3.26 - Update NSPanel.ts
Fix Log output payload -> Json.stringify
2023-12-26 00:51:23 +01:00
Thomas
b35122868f Update NsPanelTs.ts 2023-12-26 00:45:48 +01:00
Thomas
1cb974494f Update NsPanelTs.ts
Fix Log output payload -> Json.stringify
2023-12-25 14:57:04 +01:00
Armilar
723ecde4cd 4.3.3.25 - Update NsPanelTs.ts
Remove Example
2023-12-22 16:30:02 +01:00
Armilar
f29e5c4978 Merge pull request #1100 from tt-tom17/main
v4.3.3.25 - Update NSPanel.ts
2023-12-22 13:57:08 +01:00
Thomas
46ffff7eea Update ioBroker_NSPanel_locales.json
Tag "qr" supplemented
2023-12-22 13:28:10 +01:00
Thomas
774c920591 v4.3.3.25 - Update NSPanel.ts
Add switch of cardQR by hidePassword: true
2023-12-22 13:25:56 +01:00
Thomas
f27eb07827 v4.3.3.25 - Update NSPanel.ts
Add switch of cardQR by hidePassword: true
2023-12-21 12:25:58 +01:00
Armilar
da8362d81d Merge pull request #1097 from joBr99/Armilar-patch-3
v4.3.3.24 - Update NsPanelTs.ts
2023-12-18 16:45:58 +01:00
Armilar
6e38d4f38d v4.3.3.24 - Update NsPanelTs.ts
* Log info commented out
2023-12-18 16:41:49 +01:00
Armilar
2344c9a9ed v4.3.3.24 - Update NsPanelTs.ts
* Hotfix Update Message
* Add Icon Colors to Entity Button
* Add Color-Const Cyan & Magenta
2023-12-18 16:37:46 +01:00
dependabot[bot]
5180f0f869 Bump home-assistant/builder from 2023.09.0 to 2023.12.0 (#1095)
Bumps [home-assistant/builder](https://github.com/home-assistant/builder) from 2023.09.0 to 2023.12.0.
- [Release notes](https://github.com/home-assistant/builder/releases)
- [Commits](https://github.com/home-assistant/builder/compare/2023.09.0...2023.12.0)

---
updated-dependencies:
- dependency-name: home-assistant/builder
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-18 11:11:52 +01:00
Armilar
b4f2789834 Merge pull request #1093 from joBr99/Armilar-patch-3
v4.3.3.23 - Update NsPanelTs.ts
2023-12-17 17:09:39 +01:00
Armilar
78c6029200 v4.3.3.23 - Update NsPanelTs.ts
Optimization of the blind control (enable or disable Up/Stop/Down)
2023-12-17 17:07:53 +01:00
Armilar
dca112e42b v4.3.3.23 - Update NsPanelTs.ts
Optimization of the blind control (enable or disable Up/Stop/Down)
2023-12-17 17:04:29 +01:00
Armilar
5ad16dd735 Update Countdown_Timer.ts 2023-12-16 10:42:51 +01:00
joBr99
723be0735e . 2023-12-15 14:29:31 +01:00
joBr99
a5bfb9388f . 2023-12-15 14:16:59 +01:00
joBr99
9c6f24f984 Merge branch 'main' of github.com:joBr99/nspanel-lovelace-ui 2023-12-15 14:09:52 +01:00
joBr99
59843ffea5 . 2023-12-15 14:09:25 +01:00
Armilar
4de9c4a12f 4.3.3.22 - Update ioBroker_NSPanel_locales_service.json
Update Notifications
2023-12-14 23:13:44 +01:00
Armilar
3eb05e5a84 4.3.3.22 - Update NsPanelTs.ts 2023-12-14 23:08:14 +01:00
Armilar
5d7a7ed1a4 Merge pull request #1090 from tt-tom17/main
v4.3.3.22 Update NSPanel.ts
2023-12-14 22:44:30 +01:00
Thomas
7124a22c38 v4.3.3.22 Update NSPanel.ts
- Add UpdateMessage => disable the update messages
- Fix name by static Navi Icon
- Fix colorscale by Role Info
2023-12-14 22:36:41 +01:00
Armilar
fa4d65a383 Merge pull request #1089 from tt-tom17/main
Update Alarm_clock.ts
2023-12-13 22:01:03 +01:00
Thomas
d26306f892 Update Alarm_clock.ts
fix dpAction to val: true
2023-12-13 21:55:33 +01:00
joBr99
9c0bb037fb Merge branch 'main' of github.com:joBr99/nspanel-lovelace-ui 2023-12-13 16:50:46 +01:00
joBr99
4b73e20b9b implement templtates for brightness 2023-12-13 16:50:28 +01:00
dependabot[bot]
3940a0c2e9 Bump actions/setup-python from 4 to 5 (#1087)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-13 14:22:56 +01:00
Armilar
8f57d4a642 v4.3.3.21 - Update NsPanelTs.ts
- Add createAutoALias to popupTimer only for Time
2023-12-09 11:19:38 +01:00
Armilar
3979fdf6a0 Create Countdown_Timer.ts 2023-12-08 22:58:24 +01:00
Armilar
4cd47126eb Create Alarm_clock.ts 2023-12-08 22:54:16 +01:00
Armilar
eb0dd79c80 v4.3.3.20 - Update ioBroker_NSPanel_locales.json 2023-12-08 22:41:11 +01:00
Armilar
3a39a8ca0e Merge pull request #1086 from tt-tom17/main
v4.3.3.20 - Update NSPanel.ts
2023-12-08 22:27:04 +01:00
Armilar
b5c4a2128b v4.3.3.20 - Update NsPanelTs.ts
Remove semicolon
2023-12-08 22:25:04 +01:00
Armilar
41f43fe5d0 v4.3.3.20 - Update NsPanelTs.ts
Remove Example
2023-12-08 22:22:44 +01:00
Armilar
f3f93b7136 v4.3.3.12 - Update NsPanelTs.ts 2023-12-08 22:20:08 +01:00
joBr99
2fb1855842 fixed binary sensors 2023-12-08 22:09:35 +01:00
Thomas
9a3627427f v4.3.3.20 - Update NSPanel.ts
add Role AlarmTime for Alarm Clock
2023-12-08 20:24:23 +01:00
Armilar
94fbf0a5f7 Merge pull request #1084 from joBr99/Armilar-patch-2
v4.3.3.19 - Update NsPanelTs.ts
2023-12-07 20:02:54 +01:00
Armilar
caddec1190 v4.3.3.19 - Update NsPanelTs.ts
- Fix Trigger activeDimmodeBrightness if Dimmode = -1
2023-12-07 20:02:12 +01:00
Armilar
03367ea27d v4.3.3.19 - Update NsPanelTs.ts
- Fix Trigger activeDimmodeBrightness if Dimmode = -1
2023-12-07 19:58:21 +01:00
Armilar
8e792ae8fc Merge pull request #1083 from joBr99/Armilar-patch-1
v4.3.3.18 - Update NsPanelTs.ts
2023-12-06 22:00:28 +01:00
Armilar
0a03f736ce v4.3.3.18 - Update NsPanelTs.ts
- Add (ELAPSED/DURATION) to v2Adapter alexa2
- Replace missing Type console.log --> log(message, 'serverity')
2023-12-06 21:49:15 +01:00
Armilar
8d7f6ffea5 v4.3.3.18 - Update NsPanelTs.ts
- Add (ELAPSED/DURATION) to v2Adapter alexa2
- Replace missing Type console.log --> log(message, 'serverity')
2023-12-06 15:20:28 +01:00
Armilar
93a6a7a88a v4.3.3.17 - Update NsPanelTs.ts
Add SEEK and CROSSFADE to Sonos cardMedia
2023-12-04 23:01:01 +01:00
Armilar
3913b17596 Update ioBroker_NSPanel_locales.json 2023-12-04 22:06:42 +01:00
Armilar
d08e8eb40c Update ioBroker_NSPanel_locales.json 2023-12-04 21:57:44 +01:00
Johannes
c2d281658e Update panel_cmd.py 2023-12-03 16:25:17 +01:00
joBr99
108582cbfb fix 2023-12-02 16:27:50 +01:00
joBr99
b17db265f4 implement temp unit 2023-12-02 16:26:28 +01:00
joBr99
206739dcc5 implement popup on card thermo 2023-12-02 16:20:31 +01:00
joBr99
adcb618a11 . 2023-12-02 14:23:43 +01:00
joBr99
dfba3b6e84 Merge branch 'main' of github.com:joBr99/nspanel-lovelace-ui 2023-12-02 14:11:25 +01:00
joBr99
2726859135 implement input_select and select for light effects 2023-12-02 14:10:53 +01:00
Armilar
c0e20e6f25 Merge pull request #1077 from joBr99/Armilar-patch-1
v4.3.3.16 - Update NsPanelTs.ts
2023-12-02 13:02:38 +01:00
Armilar
148c2fc5a2 v4.3.3.16 - Update NsPanelTs.ts
- Beautification of the Sonos player Strings / Add Duration & Elapsed
- Fix Datapoints with Value null with -1
- Request replaced by Axios
2023-12-02 00:50:11 +01:00
Armilar
526f5e8946 v4.3.3.16 - Update NsPanelTs.ts
- Beautification of the Sonos player Strings / Add Duration & Elapsed
- Fix Datapoints with Value null with -1
- Request replaced by Axios
2023-12-02 00:36:00 +01:00
joBr99
8cd17b9d9a . 2023-12-02 00:03:22 +01:00
joBr99
70ff46ab4b . 2023-12-01 23:59:59 +01:00
joBr99
770348b07b . 2023-12-01 23:48:11 +01:00
joBr99
4795cc23ad fix state update bug with iid 2023-12-01 23:39:49 +01:00
joBr99
bae64dcee5 do not init mqtt in case ha api is used 2023-12-01 23:28:58 +01:00
joBr99
953a8d7110 . 2023-12-01 23:26:52 +01:00
joBr99
3b5eaac976 initial implementation of esphome api comm 2023-12-01 23:26:27 +01:00
joBr99
6e28237ec5 Merge branch 'main' of github.com:joBr99/nspanel-lovelace-ui 2023-12-01 19:55:36 +01:00
joBr99
b8c47948c3 add queue for outgoing messages 2023-12-01 19:55:29 +01:00
Armilar
0e8f9ad220 Merge pull request #1075 from tt-tom17/main
v4.3.3.15 - Update NsPanelTs.ts
2023-12-01 13:11:13 +01:00
Thomas
79e43e2740 Update NsPanelTs.ts
fix activeDimmodeBrightness -> value -1
fix bExitPage -> value -1
2023-12-01 11:22:01 +01:00
joBr99
c32d2958a6 . 2023-11-30 17:48:31 +01:00
joBr99
3b7c934972 . 2023-11-30 17:43:53 +01:00
joBr99
40f29d09c1 . 2023-11-30 17:39:04 +01:00
joBr99
b601f2d860 . 2023-11-30 17:32:21 +01:00
joBr99
5953d7c8dd . 2023-11-30 17:25:32 +01:00
joBr99
e9859c0d32 . 2023-11-30 17:20:12 +01:00
joBr99
4ad997515f Merge branch 'main' of github.com:joBr99/nspanel-lovelace-ui 2023-11-30 17:15:03 +01:00
joBr99
ba637cf11e . 2023-11-30 17:14:41 +01:00
Armilar
a4abcd1734 Merge pull request #1074 from joBr99/Armilar-patch-1
v4.3.3.15 - Minor bug fixes
2023-11-30 00:06:06 +01:00
Armilar
86bbd36813 v4.3.3.15 - Regex Tracklist
- Regex Tracklist
2023-11-30 00:04:52 +01:00
Armilar
c9dffc431c v4.3.3.15 - Minor bug fixes
- Fix cardMedia Volume-Slider
- Add Init Release to Startup
2023-11-29 21:24:02 +01:00
joBr99
04ffd6257e . 2023-11-29 17:25:25 +01:00
Johannes
4102f56cee Update docs-release.yml 2023-11-28 23:46:03 +01:00
Johannes
6a62a6206a Update docs-release.yml 2023-11-28 23:44:30 +01:00
Johannes
0bddceccfa Update docs-release.yml 2023-11-28 23:44:16 +01:00
Johannes
09156fbc89 Update docs-release.yml 2023-11-28 23:43:18 +01:00
joBr99
76d0075c7d . 2023-11-28 23:41:28 +01:00
60 changed files with 29930 additions and 6206 deletions

View File

@@ -58,5 +58,5 @@ _If applicable, add screenshots/pictures to help explain your problem._
_Add any other context about the problem here._ _Add any other context about the problem here._
_Please note here in case you are using ioBroker_ _Please note here in case you are using ioBroker_
### PANEL / FIRMWARE VERION ### PANEL / FIRMWARE VERSION
_Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_ _Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_

View File

@@ -24,5 +24,5 @@ _A clear and concise description of what the feature should do._
### ADDITIONAL CONTEXT ### ADDITIONAL CONTEXT
_Add any other context about the problem here._ _Add any other context about the problem here._
### PANEL / FIRMWARE VERION ### PANEL / FIRMWARE VERSION
_Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_ _Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_

View File

@@ -92,7 +92,7 @@ jobs:
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
if: env.BUILD_ARGS != '--test' if: env.BUILD_ARGS != '--test'
uses: docker/login-action@v3.0.0 uses: docker/login-action@v3.4.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
@@ -100,7 +100,7 @@ jobs:
- name: Build ${{ matrix.addon }} add-on - name: Build ${{ matrix.addon }} add-on
if: steps.check.outputs.build_arch == 'true' if: steps.check.outputs.build_arch == 'true'
uses: home-assistant/builder@2023.09.0 uses: home-assistant/builder@2025.03.0
with: with:
args: | args: |
${{ env.BUILD_ARGS }} \ ${{ env.BUILD_ARGS }} \

View File

@@ -47,7 +47,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@@ -58,7 +58,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@@ -72,4 +72,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3

View File

@@ -1,10 +1,10 @@
name: docs-ci name: docs-ci
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: branches:
- main - dev
paths: paths:
- docs/* - docs/*
- .github/workflows/docs.yml - .github/workflows/docs.yml
@@ -18,18 +18,11 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@v4 - uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: 3.x
- run: pip install mkdocs-material mkdocs-video markdown-include mike - run: pip install mkdocs-material mkdocs-video markdown-include mike
- run: cp HMI/README.md docs/hmi-serial-protocol.md - run: cp HMI/README.md docs/hmi-serial-protocol.md
#- run: mkdocs gh-deploy --force
- run: git config --global user.name Docs deploy - run: git config --global user.name Docs deploy
- run: git config --global user.email docs@dummy.bot.com - run: git config --global user.email docs@dummy.bot.com
- run: mike deploy --push --update-aliases dev - run: mike deploy --push --update-aliases dev

29
.github/workflows/docs-release.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: docs-ci
on:
workflow_dispatch:
push:
branches:
- main
paths:
- docs/*
- .github/workflows/docs-release.yml
- mkdocs.yml
- HMI/README.md
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: 3.x
- run: pip install mkdocs-material mkdocs-video markdown-include mike
- run: cp HMI/README.md docs/hmi-serial-protocol.md
- run: git config --global user.name Docs deploy
- run: git config --global user.email docs@dummy.bot.com
- run: mike set-default stable
- run: mike deploy --push --update-aliases stable

View File

@@ -36,6 +36,6 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 🚀 Run Home Assistant Add-on Lint - name: 🚀 Run Home Assistant Add-on Lint
uses: frenck/action-addon-linter@v2.15 uses: frenck/action-addon-linter@v2.18
with: with:
path: "./${{ matrix.path }}" path: "./${{ matrix.path }}"

View File

@@ -1,17 +1,5 @@
--- HMI/n2t-out --- HMI/n2t-out
+++ HMI/US/landscape/n2t-out +++ HMI/US/landscape/n2t-out
├── file list
│ @@ -1,10 +1,9 @@
│ Program.s.txt
│ cardAlarm.txt
│ -cardBurnRec.txt
│ cardChart.txt
│ cardEntities.txt
│ cardGrid.txt
│ cardGrid2.txt
│ cardLChart.txt
│ cardMedia.txt
│ cardPower.txt
│ --- HMI/n2t-out/Program.s.txt │ --- HMI/n2t-out/Program.s.txt
├── +++ HMI/US/landscape/n2t-out/Program.s.txt ├── +++ HMI/US/landscape/n2t-out/Program.s.txt
│ @@ -13,10 +13,10 @@ │ @@ -13,10 +13,10 @@
@@ -114,6 +102,49 @@
│ crcputs sys0,2 │ crcputs sys0,2
│ crcputs tSend.txt,0 │ crcputs tSend.txt,0
│ //send cmd │ //send cmd
│ --- HMI/n2t-out/popupLight.txt
├── +++ HMI/US/landscape/n2t-out/popupLight.txt
│ @@ -453,19 +453,14 @@
│ 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
│ spstr strCommand.txt,tTmp.txt,"~",1
│ if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
│ {
│ // change icon
│ - spstr strCommand.txt,tTmp.txt,"~",2
│ - if(tTmp.txt!="")
│ - {
│ - tIcon1.txt=tTmp.txt
│ - }
│ //spstr strCommand.txt,tIcon1.txt,"~",2
│ vis tIcon1,1
│ // change icon color
│ spstr strCommand.txt,tTmp.txt,"~",3
│ covx tTmp.txt,sys0,0,0
│ tIcon1.pco=sys0
│ // get Button State
│ --- HMI/n2t-out/popupNotify.txt
├── +++ HMI/US/landscape/n2t-out/popupNotify.txt
│ @@ -439,18 +439,14 @@
│ {
│ page cardPower
│ }
│ if(tId.txt=="cardChart")
│ {
│ page cardChart
│ }
│ - if(tId.txt=="cardLChart")
│ - {
│ - page cardLChart
│ - }
│ }
│ // end of user code
│ udelete payloadLength-1
│ bufferPos=0
│ }
│ }
│ }
│ --- HMI/n2t-out/screensaver.txt │ --- HMI/n2t-out/screensaver.txt
├── +++ HMI/US/landscape/n2t-out/screensaver.txt ├── +++ HMI/US/landscape/n2t-out/screensaver.txt
│ @@ -19,15 +19,14 @@ │ @@ -19,15 +19,14 @@
@@ -221,7 +252,7 @@
│ vis p0,0 │ vis p0,0
│ vis tNotifyHead,0 │ vis tNotifyHead,0
│ vis tNotifyText,0 │ vis tNotifyText,0
│ @@ -41,17 +40,14 @@ │ @@ -41,52 +40,19 @@
│ } │ }
│ tDate.txt=pageIcons.vaDate.txt │ tDate.txt=pageIcons.vaDate.txt
│ dim=dimValue │ dim=dimValue
@@ -232,14 +263,80 @@
│ - Postinitialize Event │ - Postinitialize Event
│ - click m0,1 │ - click m0,1
│ - │ -
│ -Variable (string) entn1
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn2
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn3
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn4
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn5
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ Variable (string) strCommand │ Variable (string) strCommand
│ Attributes │ Attributes
│ Scope : local │ Scope : local
│ Text : │ Text :
Max. Text Size: 1979 - Max. Text Size: 1935
│ + Max. Text Size: 1979
│ Variable (string) strTmp │ Variable (string) strTmp
@@ -376,34 +372,14 @@ Attributes
│ Scope : local
│ Text :
│ Max. Text Size: 2
│ @@ -96,27 +62,27 @@
│ Text :
│ Max. Text Size: 25
│ Variable (string) tInstruction
│ Attributes
│ Scope : local
│ Text :
│ - Max. Text Size: 15
│ + Max. Text Size: 50
│ Variable (string) tSend
│ Attributes
│ Scope : local
│ Text :
│ Max. Text Size: 50
│ Variable (string) tTmp
│ Attributes
│ Scope : local
│ Text :
│ - Max. Text Size: 30
│ + Max. Text Size: 50
│ Variable (int32) vaTap
│ Attributes
│ Scope: local
│ Value: 0
│ Variable (int32) xc1
│ @@ -370,165 +336,50 @@
│ Scope : local │ Scope : local
│ Dragging : 0 │ Dragging : 0
│ Send Component ID : disabled │ Send Component ID : disabled
@@ -247,6 +344,137 @@
│ Text : │ Text :
│ Max. Text Size : 4 │ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn1.txt+",button"
│ - if(entn1.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f2Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn2.txt+",button"
│ - if(entn2.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f3Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn3.txt+",button"
│ - if(entn3.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f4Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn4.txt+",button"
│ - if(entn4.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f5Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn5.txt+",button"
│ - if(entn5.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ -Text m0 │ -Text m0
│ - Attributes │ - Attributes
│ - Scope : local │ - Scope : local
@@ -274,7 +502,7 @@
│ Send Component ID : disabled │ Send Component ID : disabled
│ Associated Keyboard: none │ Associated Keyboard: none
│ Text : PM │ Text : PM
│ @@ -585,15 +561,14 @@ │ @@ -710,15 +561,14 @@
│ if(tTmp.txt!="") │ if(tTmp.txt!="")
│ { │ {
│ covx tTmp.txt,defaultFontColor,0,0 │ covx tTmp.txt,defaultFontColor,0,0
@@ -290,3 +518,48 @@
│ if(tAMPM.txt=="") │ if(tAMPM.txt=="")
│ { │ {
│ vis tAMPM,0 │ vis tAMPM,0
│ @@ -839,44 +689,34 @@
│ //e6Val
│ spstr strCommand.txt,e6Val.txt,"~",60
│ //f1Icon
│ spstr strCommand.txt,f1Icon.txt,"~",63
│ //f1Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",64
│ covx tTmp.txt,f1Icon.pco,0,0
│ - //f1Icon intNameEntity
│ - spstr strCommand.txt,entn1.txt,"~",62
│ //f2Icon
│ spstr strCommand.txt,f2Icon.txt,"~",69
│ //f2Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",70
│ covx tTmp.txt,f2Icon.pco,0,0
│ - //f2Icon intNameEntity
│ - spstr strCommand.txt,entn2.txt,"~",68
│ //f3Icon
│ spstr strCommand.txt,f3Icon.txt,"~",75
│ //f3Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",76
│ covx tTmp.txt,f3Icon.pco,0,0
│ - //f3Icon intNameEntity
│ - spstr strCommand.txt,entn3.txt,"~",74
│ //f4Icon
│ spstr strCommand.txt,f4Icon.txt,"~",81
│ //f4Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",82
│ covx tTmp.txt,f4Icon.pco,0,0
│ - //f4Icon intNameEntity
│ - spstr strCommand.txt,entn4.txt,"~",80
│ //f5Icon
│ spstr strCommand.txt,f5Icon.txt,"~",87
│ //f5Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",88
│ covx tTmp.txt,f5Icon.pco,0,0
│ - //f5Icon intNameEntity
│ - spstr strCommand.txt,entn5.txt,"~",86
│ }
│ if(tInstruction.txt=="notify")
│ {
│ spstr strCommand.txt,tNotifyHead.txt,"~",1
│ spstr strCommand.txt,tNotifyText.txt,"~",2
│ if(tNotifyHead.txt!=""||tNotifyText.txt!="")
│ {

View File

@@ -1,17 +1,5 @@
--- HMI/n2t-out --- HMI/n2t-out
+++ HMI/US/portrait/n2t-out +++ HMI/US/portrait/n2t-out
├── file list
│ @@ -1,10 +1,9 @@
│ Program.s.txt
│ cardAlarm.txt
│ -cardBurnRec.txt
│ cardChart.txt
│ cardEntities.txt
│ cardGrid.txt
│ cardGrid2.txt
│ cardLChart.txt
│ cardMedia.txt
│ cardPower.txt
│ --- HMI/n2t-out/Program.s.txt │ --- HMI/n2t-out/Program.s.txt
├── +++ HMI/US/portrait/n2t-out/Program.s.txt ├── +++ HMI/US/portrait/n2t-out/Program.s.txt
│ @@ -12,11 +12,11 @@ │ @@ -12,11 +12,11 @@
@@ -1997,6 +1985,26 @@
│ Variable (string) entn │ Variable (string) entn
│ Attributes │ Attributes
│ Scope : local │ Scope : local
│ @@ -453,19 +453,14 @@
│ 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
│ spstr strCommand.txt,tTmp.txt,"~",1
│ if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
│ {
│ // change icon
│ - spstr strCommand.txt,tTmp.txt,"~",2
│ - if(tTmp.txt!="")
│ - {
│ - tIcon1.txt=tTmp.txt
│ - }
│ //spstr strCommand.txt,tIcon1.txt,"~",2
│ vis tIcon1,1
│ // change icon color
│ spstr strCommand.txt,tTmp.txt,"~",3
│ covx tTmp.txt,sys0,0,0
│ tIcon1.pco=sys0
│ // get Button State
│ --- HMI/n2t-out/popupNotify.txt │ --- HMI/n2t-out/popupNotify.txt
├── +++ HMI/US/portrait/n2t-out/popupNotify.txt ├── +++ HMI/US/portrait/n2t-out/popupNotify.txt
│ @@ -348,15 +348,15 @@ │ @@ -348,15 +348,15 @@
@@ -2016,6 +2024,25 @@
│ } │ }
│ if(tInstruction.txt=="exitPopup") │ if(tInstruction.txt=="exitPopup")
│ { │ {
│ @@ -439,18 +439,14 @@
│ {
│ page cardPower
│ }
│ if(tId.txt=="cardChart")
│ {
│ page cardChart
│ }
│ - if(tId.txt=="cardLChart")
│ - {
│ - page cardLChart
│ - }
│ }
│ // end of user code
│ udelete payloadLength-1
│ bufferPos=0
│ }
│ }
│ }
│ --- HMI/n2t-out/screensaver.txt │ --- HMI/n2t-out/screensaver.txt
├── +++ HMI/US/portrait/n2t-out/screensaver.txt ├── +++ HMI/US/portrait/n2t-out/screensaver.txt
│ @@ -7,27 +7,14 @@ │ @@ -7,27 +7,14 @@
@@ -2168,7 +2195,7 @@
│ vis p0,0 │ vis p0,0
│ vis tNotifyHead,0 │ vis tNotifyHead,0
│ vis tNotifyText,0 │ vis tNotifyText,0
│ @@ -41,17 +28,14 @@ │ @@ -41,52 +28,19 @@
│ } │ }
│ tDate.txt=pageIcons.vaDate.txt │ tDate.txt=pageIcons.vaDate.txt
│ dim=dimValue │ dim=dimValue
@@ -2179,14 +2206,80 @@
│ - Postinitialize Event │ - Postinitialize Event
│ - click m0,1 │ - click m0,1
│ - │ -
│ -Variable (string) entn1
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn2
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn3
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn4
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ -Variable (string) entn5
│ - Attributes
│ - Scope : local
│ - Text :
│ - Max. Text Size: 14
│ -
│ Variable (string) strCommand │ Variable (string) strCommand
│ Attributes │ Attributes
│ Scope : local │ Scope : local
│ Text : │ Text :
Max. Text Size: 1979 - Max. Text Size: 1935
│ + Max. Text Size: 1979
│ Variable (string) strTmp │ Variable (string) strTmp
@@ -376,34 +360,14 @@ Attributes
│ Scope : local
│ Text :
│ Max. Text Size: 2
│ @@ -96,27 +50,27 @@
│ Text :
│ Max. Text Size: 25
│ Variable (string) tInstruction
│ Attributes
│ Scope : local
│ Text :
│ - Max. Text Size: 15
│ + Max. Text Size: 50
│ Variable (string) tSend
│ Attributes
│ Scope : local
│ Text :
│ Max. Text Size: 50
│ Variable (string) tTmp
│ Attributes
│ Scope : local
│ Text :
│ - Max. Text Size: 30
│ + Max. Text Size: 50
│ Variable (int32) vaTap
│ Attributes
│ Scope: local
│ Value: 0
│ Variable (int32) xc1
│ @@ -370,165 +324,50 @@
│ Scope : local │ Scope : local
│ Dragging : 0 │ Dragging : 0
│ Send Component ID : disabled │ Send Component ID : disabled
@@ -2194,6 +2287,137 @@
│ Text : │ Text :
│ Max. Text Size : 4 │ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn1.txt+",button"
│ - if(entn1.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f2Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn2.txt+",button"
│ - if(entn2.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f3Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn3.txt+",button"
│ - if(entn3.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f4Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn4.txt+",button"
│ - if(entn4.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ Text f5Icon
│ Attributes
│ Scope : local
│ Dragging : 0
│ Send Component ID : disabled
│ Associated Keyboard: none
│ Text :
│ Max. Text Size : 4
│ - Events
│ - Touch Press Event
│ - tSend.txt="event,buttonPress2,"+entn5.txt+",button"
│ - if(entn5.txt=="")
│ - {
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
│ -
│ -Text m0 │ -Text m0
│ - Attributes │ - Attributes
│ - Scope : local │ - Scope : local
@@ -2221,7 +2445,7 @@
│ Send Component ID : disabled │ Send Component ID : disabled
│ Associated Keyboard: none │ Associated Keyboard: none
│ Text : PM │ Text : PM
│ @@ -585,15 +549,14 @@ │ @@ -710,15 +549,14 @@
│ if(tTmp.txt!="") │ if(tTmp.txt!="")
│ { │ {
│ covx tTmp.txt,defaultFontColor,0,0 │ covx tTmp.txt,defaultFontColor,0,0
@@ -2237,3 +2461,48 @@
│ if(tAMPM.txt=="") │ if(tAMPM.txt=="")
│ { │ {
│ vis tAMPM,0 │ vis tAMPM,0
│ @@ -839,44 +677,34 @@
│ //e6Val
│ spstr strCommand.txt,e6Val.txt,"~",60
│ //f1Icon
│ spstr strCommand.txt,f1Icon.txt,"~",63
│ //f1Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",64
│ covx tTmp.txt,f1Icon.pco,0,0
│ - //f1Icon intNameEntity
│ - spstr strCommand.txt,entn1.txt,"~",62
│ //f2Icon
│ spstr strCommand.txt,f2Icon.txt,"~",69
│ //f2Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",70
│ covx tTmp.txt,f2Icon.pco,0,0
│ - //f2Icon intNameEntity
│ - spstr strCommand.txt,entn2.txt,"~",68
│ //f3Icon
│ spstr strCommand.txt,f3Icon.txt,"~",75
│ //f3Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",76
│ covx tTmp.txt,f3Icon.pco,0,0
│ - //f3Icon intNameEntity
│ - spstr strCommand.txt,entn3.txt,"~",74
│ //f4Icon
│ spstr strCommand.txt,f4Icon.txt,"~",81
│ //f4Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",82
│ covx tTmp.txt,f4Icon.pco,0,0
│ - //f4Icon intNameEntity
│ - spstr strCommand.txt,entn4.txt,"~",80
│ //f5Icon
│ spstr strCommand.txt,f5Icon.txt,"~",87
│ //f5Icon Color
│ spstr strCommand.txt,tTmp.txt,"~",88
│ covx tTmp.txt,f5Icon.pco,0,0
│ - //f5Icon intNameEntity
│ - spstr strCommand.txt,entn5.txt,"~",86
│ }
│ if(tInstruction.txt=="notify")
│ {
│ spstr strCommand.txt,tNotifyHead.txt,"~",1
│ spstr strCommand.txt,tNotifyText.txt,"~",2
│ if(tNotifyHead.txt!=""||tNotifyText.txt!="")
│ {

View File

@@ -1,16 +1,4 @@
+++ /dev/fd/62 2023-11-27 23:28:52.512823638 +0000 +++ /dev/fd/62 2024-11-22 20:00:11.734673876 +0000
+le list
+ +1,9 @@
+.s.txt
+rm.txt
+nRec.txt
+rt.txt
+ities.txt
+d.txt
+d2.txt
+art.txt
+ia.txt
+er.txt
+I/n2t-out/Program.s.txt +I/n2t-out/Program.s.txt
++ HMI/US/portrait/n2t-out/Program.s.txt ++ HMI/US/portrait/n2t-out/Program.s.txt
+1 +12,11 @@ +1 +12,11 @@
@@ -1539,6 +1527,26 @@
+e (string) entn +e (string) entn
+ributes +ributes
+ Scope : local + Scope : local
+19 +453,14 @@
+ 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
+ spstr strCommand.txt,tTmp.txt,"~",1
+ if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
+ {
+ // change icon
+ spstr strCommand.txt,tTmp.txt,"~",2
+ if(tTmp.txt!="")
+ {
+ tIcon1.txt=tTmp.txt
+ }
+ //spstr strCommand.txt,tIcon1.txt,"~",2
+ vis tIcon1,1
+ // change icon color
+ spstr strCommand.txt,tTmp.txt,"~",3
+ covx tTmp.txt,sys0,0,0
+ tIcon1.pco=sys0
+ // get Button State
+I/n2t-out/popupNotify.txt +I/n2t-out/popupNotify.txt
++ HMI/US/portrait/n2t-out/popupNotify.txt ++ HMI/US/portrait/n2t-out/popupNotify.txt
+15 +348,15 @@ +15 +348,15 @@
@@ -1558,6 +1566,25 @@
+ } + }
+ if(tInstruction.txt=="exitPopup") + if(tInstruction.txt=="exitPopup")
+ { + {
+18 +439,14 @@
+ {
+ page cardPower
+ }
+ if(tId.txt=="cardChart")
+ {
+ page cardChart
+ }
+ if(tId.txt=="cardLChart")
+ {
+ page cardLChart
+ }
+ }
+ // end of user code
+ udelete payloadLength-1
+ bufferPos=0
+ }
+ }
+ }
+I/n2t-out/screensaver.txt +I/n2t-out/screensaver.txt
++ HMI/US/portrait/n2t-out/screensaver.txt ++ HMI/US/portrait/n2t-out/screensaver.txt
+ +7,14 @@ + +7,14 @@
@@ -1710,7 +1737,7 @@
+ vis p0,0 + vis p0,0
+ vis tNotifyHead,0 + vis tNotifyHead,0
+ vis tNotifyText,0 + vis tNotifyText,0
+7 +28,14 @@ +2 +28,19 @@
+ } + }
+ tDate.txt=pageIcons.vaDate.txt + tDate.txt=pageIcons.vaDate.txt
+ dim=dimValue + dim=dimValue
@@ -1721,14 +1748,80 @@
+ Postinitialize Event + Postinitialize Event
+ click m0,1 + click m0,1
+ +
+e (string) entn1
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 14
+
+e (string) entn2
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 14
+
+e (string) entn3
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 14
+
+e (string) entn4
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 14
+
+e (string) entn5
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 14
+
+e (string) strCommand +e (string) strCommand
+ributes +ributes
+ Scope : local + Scope : local
+ Text : + Text :
+ Max. Text Size: 1935
+ Max. Text Size: 1979 + Max. Text Size: 1979
+ +
+e (string) strTmp +e (string) strTmp
+34 +360,14 @@ +ributes
+ Scope : local
+ Text :
+ Max. Text Size: 2
+
+7 +50,27 @@
+ Text :
+ Max. Text Size: 25
+
+e (string) tInstruction
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 15
+ Max. Text Size: 50
+
+e (string) tSend
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 50
+
+e (string) tTmp
+ributes
+ Scope : local
+ Text :
+ Max. Text Size: 30
+ Max. Text Size: 50
+
+e (int32) vaTap
+ributes
+ Scope: local
+ Value: 0
+
+e (int32) xc1
+165 +324,50 @@
+ Scope : local + Scope : local
+ Dragging : 0 + Dragging : 0
+ Send Component ID : disabled + Send Component ID : disabled
@@ -1736,6 +1829,137 @@
+ Text : + Text :
+ Max. Text Size : 4 + Max. Text Size : 4
+ +
+nts
+ Touch Press Event
+ tSend.txt="event,buttonPress2,"+entn1.txt+",button"
+ if(entn1.txt=="")
+ {
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
+
+Icon
+ributes
+ Scope : local
+ Dragging : 0
+ Send Component ID : disabled
+ Associated Keyboard: none
+ Text :
+ Max. Text Size : 4
+
+nts
+ Touch Press Event
+ tSend.txt="event,buttonPress2,"+entn2.txt+",button"
+ if(entn2.txt=="")
+ {
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
+
+Icon
+ributes
+ Scope : local
+ Dragging : 0
+ Send Component ID : disabled
+ Associated Keyboard: none
+ Text :
+ Max. Text Size : 4
+
+nts
+ Touch Press Event
+ tSend.txt="event,buttonPress2,"+entn3.txt+",button"
+ if(entn3.txt=="")
+ {
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
+
+Icon
+ributes
+ Scope : local
+ Dragging : 0
+ Send Component ID : disabled
+ Associated Keyboard: none
+ Text :
+ Max. Text Size : 4
+
+nts
+ Touch Press Event
+ tSend.txt="event,buttonPress2,"+entn4.txt+",button"
+ if(entn4.txt=="")
+ {
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
+
+Icon
+ributes
+ Scope : local
+ Dragging : 0
+ Send Component ID : disabled
+ Associated Keyboard: none
+ Text :
+ Max. Text Size : 4
+
+nts
+ Touch Press Event
+ tSend.txt="event,buttonPress2,"+entn5.txt+",button"
+ if(entn5.txt=="")
+ {
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
+
+ +
+ributes +ributes
+ Scope : local + Scope : local
@@ -1779,3 +2003,48 @@
+ if(tAMPM.txt=="") + if(tAMPM.txt=="")
+ { + {
+ vis tAMPM,0 + vis tAMPM,0
+44 +677,34 @@
+ //e6Val
+ spstr strCommand.txt,e6Val.txt,"~",60
+ //f1Icon
+ spstr strCommand.txt,f1Icon.txt,"~",63
+ //f1Icon Color
+ spstr strCommand.txt,tTmp.txt,"~",64
+ covx tTmp.txt,f1Icon.pco,0,0
+ //f1Icon intNameEntity
+ spstr strCommand.txt,entn1.txt,"~",62
+ //f2Icon
+ spstr strCommand.txt,f2Icon.txt,"~",69
+ //f2Icon Color
+ spstr strCommand.txt,tTmp.txt,"~",70
+ covx tTmp.txt,f2Icon.pco,0,0
+ //f2Icon intNameEntity
+ spstr strCommand.txt,entn2.txt,"~",68
+ //f3Icon
+ spstr strCommand.txt,f3Icon.txt,"~",75
+ //f3Icon Color
+ spstr strCommand.txt,tTmp.txt,"~",76
+ covx tTmp.txt,f3Icon.pco,0,0
+ //f3Icon intNameEntity
+ spstr strCommand.txt,entn3.txt,"~",74
+ //f4Icon
+ spstr strCommand.txt,f4Icon.txt,"~",81
+ //f4Icon Color
+ spstr strCommand.txt,tTmp.txt,"~",82
+ covx tTmp.txt,f4Icon.pco,0,0
+ //f4Icon intNameEntity
+ spstr strCommand.txt,entn4.txt,"~",80
+ //f5Icon
+ spstr strCommand.txt,f5Icon.txt,"~",87
+ //f5Icon Color
+ spstr strCommand.txt,tTmp.txt,"~",88
+ covx tTmp.txt,f5Icon.pco,0,0
+ //f5Icon intNameEntity
+ spstr strCommand.txt,entn5.txt,"~",86
+ }
+ if(tInstruction.txt=="notify")
+ {
+ spstr strCommand.txt,tNotifyHead.txt,"~",1
+ spstr strCommand.txt,tNotifyText.txt,"~",2
+ if(tNotifyHead.txt!=""||tNotifyText.txt!="")
+ {

View File

@@ -1,272 +1,274 @@
from shared import * from shared import *
head = sharedhead + """ head = sharedhead + """
if(tInstruction.txt=="wake") if(tInstruction.txt=="wake")
{ {
click tc0,1 click tc0,1
} }
if(tInstruction.txt=="dimmode") if(tInstruction.txt=="dimmode")
{ {
// get value // get value
spstr strCommand.txt,tTmp.txt,"~",1 spstr strCommand.txt,tTmp.txt,"~",1
covx tTmp.txt,dimValue,0,0 covx tTmp.txt,dimValue,0,0
dim=dimValue dim=dimValue
// get value normal // get value normal
spstr strCommand.txt,tTmp.txt,"~",2 spstr strCommand.txt,tTmp.txt,"~",2
covx tTmp.txt,dimValueNormal,0,0 covx tTmp.txt,dimValueNormal,0,0
// get background color // get background color
spstr strCommand.txt,tTmp.txt,"~",3 spstr strCommand.txt,tTmp.txt,"~",3
if(tTmp.txt!="") if(tTmp.txt!="")
{ {
covx tTmp.txt,defaultBcoColor,0,0 covx tTmp.txt,defaultBcoColor,0,0
} }
// get font color // get font color
spstr strCommand.txt,tTmp.txt,"~",4 spstr strCommand.txt,tTmp.txt,"~",4
if(tTmp.txt!="") if(tTmp.txt!="")
{ {
covx tTmp.txt,defaultFontColor,0,0 covx tTmp.txt,defaultFontColor,0,0
} }
} }
if(tInstruction.txt=="time") if(tInstruction.txt=="time")
{ {
click m0,1 click m0,1
//get set time to global variable //get set time to global variable
spstr strCommand.txt,pageIcons.vaTime.txt,"~",1 spstr strCommand.txt,pageIcons.vaTime.txt,"~",1
spstr pageIcons.vaTime.txt,tTime.txt,"?",0 spstr pageIcons.vaTime.txt,tTime.txt,"?",0
spstr pageIcons.vaTime.txt,tAMPM.txt,"?",1 spstr pageIcons.vaTime.txt,tAMPM.txt,"?",1
if(tAMPM.txt=="") if(tAMPM.txt=="")
{ {
vis tAMPM,0 vis tAMPM,0
} }
spstr strCommand.txt,tTimeAdd.txt,"~",2 spstr strCommand.txt,tTimeAdd.txt,"~",2
ref tIcon1 ref tIcon1
ref tIcon2 ref tIcon2
} }
if(tInstruction.txt=="date") if(tInstruction.txt=="date")
{ {
//get set date to global variable //get set date to global variable
spstr strCommand.txt,pageIcons.vaDate.txt,"~",1 spstr strCommand.txt,pageIcons.vaDate.txt,"~",1
tDate.txt=pageIcons.vaDate.txt tDate.txt=pageIcons.vaDate.txt
} }
if(tInstruction.txt=="statusUpdate") if(tInstruction.txt=="statusUpdate")
{ {
//statusIcon1 //statusIcon1
spstr strCommand.txt,tIcon1.txt,"~",1 spstr strCommand.txt,tIcon1.txt,"~",1
spstr strCommand.txt,tTmp.txt,"~",2 spstr strCommand.txt,tTmp.txt,"~",2
covx tTmp.txt,tIcon1.pco,0,0 covx tTmp.txt,tIcon1.pco,0,0
//statusIcon2 //statusIcon2
spstr strCommand.txt,tIcon2.txt,"~",3 spstr strCommand.txt,tIcon2.txt,"~",3
spstr strCommand.txt,tTmp.txt,"~",4 spstr strCommand.txt,tTmp.txt,"~",4
covx tTmp.txt,tIcon2.pco,0,0 covx tTmp.txt,tIcon2.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",5 spstr strCommand.txt,tTmp.txt,"~",5
if(tTmp.txt!="") if(tTmp.txt!="")
{ {
tIcon1.font=3 tIcon1.font=3
} }
spstr strCommand.txt,tTmp.txt,"~",6 spstr strCommand.txt,tTmp.txt,"~",6
if(tTmp.txt!="") if(tTmp.txt!="")
{ {
tIcon2.font=3 tIcon2.font=3
} }
} }
if(tInstruction.txt=="weatherUpdate"&&tNotifyHead.txt==""&&tNotifyText.txt=="") if(tInstruction.txt=="weatherUpdate"&&tNotifyHead.txt==""&&tNotifyText.txt=="")
{ {
//tMainIcon //tMainIcon
spstr strCommand.txt,tMainIcon.txt,"~",3 spstr strCommand.txt,tMainIcon.txt,"~",3
//tMainIcon Color //tMainIcon Color
spstr strCommand.txt,tTmp.txt,"~",4 spstr strCommand.txt,tTmp.txt,"~",4
covx tTmp.txt,tMainIcon.pco,0,0 covx tTmp.txt,tMainIcon.pco,0,0
//tMainText //tMainText
spstr strCommand.txt,tMainText.txt,"~",6 spstr strCommand.txt,tMainText.txt,"~",6
""" """
start = 7 start = 7
for i in range(1,4): for i in range(1,4):
idxstart = start + (i-1)*6 idxstart = start + (i-1)*6
item = f""" item = f"""
//d{i}Icon //d{i}Icon
spstr strCommand.txt,d{i}Icon.txt,"~",{idxstart+2} spstr strCommand.txt,d{i}Icon.txt,"~",{idxstart+2}
//d{i}Icon Color //d{i}Icon Color
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3} spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
covx tTmp.txt,d{i}Icon.pco,0,0 covx tTmp.txt,d{i}Icon.pco,0,0
//d{i}Val //d{i}Val
spstr strCommand.txt,d{i}Val.txt,"~",{idxstart+5} spstr strCommand.txt,d{i}Val.txt,"~",{idxstart+5}
""" """
head = head + item head = head + item
start = idxstart+6 start = idxstart+6
for i in range(1,7): for i in range(1,7):
idxstart = start + (i-1)*6 idxstart = start + (i-1)*6
item = f""" item = f"""
//e{i}Name //e{i}Name
spstr strCommand.txt,e{i}Name.txt,"~",{idxstart+4} spstr strCommand.txt,e{i}Name.txt,"~",{idxstart+4}
//e{i}Icon //e{i}Icon
spstr strCommand.txt,e{i}Icon.txt,"~",{idxstart+2} spstr strCommand.txt,e{i}Icon.txt,"~",{idxstart+2}
//e{i}Icon Color //e{i}Icon Color
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3} spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
covx tTmp.txt,e{i}Icon.pco,0,0 covx tTmp.txt,e{i}Icon.pco,0,0
//e{i}Val //e{i}Val
spstr strCommand.txt,e{i}Val.txt,"~",{idxstart+5} spstr strCommand.txt,e{i}Val.txt,"~",{idxstart+5}
""" """
head = head + item head = head + item
start = idxstart+6 start = idxstart+6
for i in range(1,6): for i in range(1,6):
idxstart = start + (i-1)*6 idxstart = start + (i-1)*6
item = f""" item = f"""
//f{i}Icon //f{i}Icon
spstr strCommand.txt,f{i}Icon.txt,"~",{idxstart+2} spstr strCommand.txt,f{i}Icon.txt,"~",{idxstart+2}
//f{i}Icon Color //f{i}Icon Color
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3} spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
covx tTmp.txt,f{i}Icon.pco,0,0 covx tTmp.txt,f{i}Icon.pco,0,0
""" //f{i}Icon intNameEntity
head = head + item spstr strCommand.txt,entn{i}.txt,"~",{idxstart+1}
"""
head = head + """ head = head + item
}
head = head + """
if(tInstruction.txt=="color"&&tNotifyHead.txt==""&&tNotifyText.txt=="") }
{
spstr strCommand.txt,tTmp.txt,"~",1 if(tInstruction.txt=="color"&&tNotifyHead.txt==""&&tNotifyText.txt=="")
covx tTmp.txt,tTime.bco,0,0 {
if(tTime.bco!=screensaver.bco) spstr strCommand.txt,tTmp.txt,"~",1
{ covx tTmp.txt,tTime.bco,0,0
for(sys0=0;sys0<60;sys0++) if(tTime.bco!=screensaver.bco)
{ {
if(b[sys0].type==98||b[sys0].type==116||b[sys0].type==54) for(sys0=0;sys0<60;sys0++)
{ {
b[sys0].bco=tTime.bco if(b[sys0].type==98||b[sys0].type==116||b[sys0].type==54)
} {
} b[sys0].bco=tTime.bco
} }
spstr strCommand.txt,tTmp.txt,"~",2 }
covx tTmp.txt,tTime.pco,0,0 }
spstr strCommand.txt,tTmp.txt,"~",3 spstr strCommand.txt,tTmp.txt,"~",2
covx tTmp.txt,tAMPM.pco,0,0 covx tTmp.txt,tTime.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",4 spstr strCommand.txt,tTmp.txt,"~",3
covx tTmp.txt,tDate.pco,0,0 covx tTmp.txt,tAMPM.pco,0,0
spstr strCommand.txt,tTmp.txt,"~",5 spstr strCommand.txt,tTmp.txt,"~",4
covx tTmp.txt,tMainText.pco,0,0 covx tTmp.txt,tDate.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",6 spstr strCommand.txt,tTmp.txt,"~",5
//covx tTmp.txt,tForecast1.pco,0,0 covx tTmp.txt,tMainText.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",7 //spstr strCommand.txt,tTmp.txt,"~",6
//covx tTmp.txt,tForecast2.pco,0,0 //covx tTmp.txt,tForecast1.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",8 //spstr strCommand.txt,tTmp.txt,"~",7
//covx tTmp.txt,tForecast3.pco,0,0 //covx tTmp.txt,tForecast2.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",9 //spstr strCommand.txt,tTmp.txt,"~",8
//covx tTmp.txt,tForecast4.pco,0,0 //covx tTmp.txt,tForecast3.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",10 //spstr strCommand.txt,tTmp.txt,"~",9
//covx tTmp.txt,tForecast1Val.pco,0,0 //covx tTmp.txt,tForecast4.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",11 //spstr strCommand.txt,tTmp.txt,"~",10
//covx tTmp.txt,tForecast2Val.pco,0,0 //covx tTmp.txt,tForecast1Val.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",12 //spstr strCommand.txt,tTmp.txt,"~",11
//covx tTmp.txt,tForecast3Val.pco,0,0 //covx tTmp.txt,tForecast2Val.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",13 //spstr strCommand.txt,tTmp.txt,"~",12
//covx tTmp.txt,tForecast4Val.pco,0,0 //covx tTmp.txt,tForecast3Val.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",14 //spstr strCommand.txt,tTmp.txt,"~",13
//covx tTmp.txt,t10.bco,0,0 //covx tTmp.txt,tForecast4Val.pco,0,0
//spstr strCommand.txt,tTmp.txt,"~",15 //spstr strCommand.txt,tTmp.txt,"~",14
//covx tTmp.txt,tMainTextAlt2.pco,0,0 //covx tTmp.txt,t10.bco,0,0
//spstr strCommand.txt,tTmp.txt,"~",16 //spstr strCommand.txt,tTmp.txt,"~",15
//covx tTmp.txt,tTimeAdd.pco,0,0 //covx tTmp.txt,tMainTextAlt2.pco,0,0
} //spstr strCommand.txt,tTmp.txt,"~",16
//covx tTmp.txt,tTimeAdd.pco,0,0
}
if(tInstruction.txt=="notify")
{
spstr strCommand.txt,tNotifyHead.txt,"~",1 if(tInstruction.txt=="notify")
spstr strCommand.txt,tNotifyText.txt,"~",2 {
if(tNotifyHead.txt!=""||tNotifyText.txt!="") spstr strCommand.txt,tNotifyHead.txt,"~",1
{ spstr strCommand.txt,tNotifyText.txt,"~",2
vis tNotifyHead,1 if(tNotifyHead.txt!=""||tNotifyText.txt!="")
vis tNotifyText,1 {
}else vis tNotifyHead,1
{ vis tNotifyText,1
vis tNotifyHead,0 }else
vis tNotifyText,0 {
} vis tNotifyHead,0
tNotifyHead.bco=tTime.bco vis tNotifyText,0
tNotifyText.bco=tTime.bco }
spstr strCommand.txt,tTmp.txt,"~",3 tNotifyHead.bco=tTime.bco
if(tTmp.txt!="") tNotifyText.bco=tTime.bco
{ spstr strCommand.txt,tTmp.txt,"~",3
covx tTmp.txt,tNotifyHead.pco,0,0 if(tTmp.txt!="")
} {
spstr strCommand.txt,tTmp.txt,"~",4 covx tTmp.txt,tNotifyHead.pco,0,0
if(tTmp.txt!="") }
{ spstr strCommand.txt,tTmp.txt,"~",4
covx tTmp.txt,tNotifyText.pco,0,0 if(tTmp.txt!="")
} {
""" covx tTmp.txt,tNotifyText.pco,0,0
}
print(head) """
print(head)
#start = 23
#for i in range(1,7):
# idxstart = start + (i-1)*6 #start = 23
# item = f""" #for i in range(1,7):
# // get Type # idxstart = start + (i-1)*6
# spstr strCommand.txt,type{i}.txt,"~",{idxstart} # item = f"""
# // get internal name # // get Type
# spstr strCommand.txt,entn{i}.txt,"~",{idxstart+1} # spstr strCommand.txt,type{i}.txt,"~",{idxstart}
# if(type{i}.txt=="delete"||type{i}.txt=="") # // get internal name
# {{ # spstr strCommand.txt,entn{i}.txt,"~",{idxstart+1}
# vis tEntity{i},0 # if(type{i}.txt=="delete"||type{i}.txt=="")
# vis bEntity{i},0 # {{
# }}else # vis tEntity{i},0
# {{ # vis bEntity{i},0
# // change icon # }}else
# spstr strCommand.txt,bEntity{i}.txt,"~",{idxstart+2} # {{
# vis bEntity{i},1 # // change icon
# // change icon color # spstr strCommand.txt,bEntity{i}.txt,"~",{idxstart+2}
# spstr strCommand.txt,tTmp.txt,"~",{idxstart+3} # vis bEntity{i},1
# covx tTmp.txt,sys0,0,0 # // change icon color
# bEntity{i}.pco=sys0 # spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
# // set name # covx tTmp.txt,sys0,0,0
# spstr strCommand.txt,tEntity{i}.txt,"~",{idxstart+4} # bEntity{i}.pco=sys0
# vis tEntity{i},1 # // set name
# }} # spstr strCommand.txt,tEntity{i}.txt,"~",{idxstart+4}
#""" # vis tEntity{i},1
# print(item) # }}
foot = """ #"""
} # print(item)
""" + sharedfoot.replace("sleepValue=0", "dim=100").replace(""" foot = """
if(tInstruction.txt=="time") }
{ """ + sharedfoot.replace("sleepValue=0", "dim=100").replace("""
// get set time to global variable if(tInstruction.txt=="time")
spstr strCommand.txt,pageIcons.vaTime.txt,"~",1 {
} // get set time to global variable
if(tInstruction.txt=="date") spstr strCommand.txt,pageIcons.vaTime.txt,"~",1
{ }
// get set date to global variable if(tInstruction.txt=="date")
spstr strCommand.txt,pageIcons.vaDate.txt,"~",1 {
} // get set date to global variable
if(tInstruction.txt=="dimmode") spstr strCommand.txt,pageIcons.vaDate.txt,"~",1
{ }
// get value if(tInstruction.txt=="dimmode")
spstr strCommand.txt,tTmp.txt,"~",1 {
covx tTmp.txt,dimValue,0,0 // get value
// get value normal spstr strCommand.txt,tTmp.txt,"~",1
spstr strCommand.txt,tTmp.txt,"~",2 covx tTmp.txt,dimValue,0,0
covx tTmp.txt,dimValueNormal,0,0 // get value normal
dim=dimValueNormal spstr strCommand.txt,tTmp.txt,"~",2
// get background color covx tTmp.txt,dimValueNormal,0,0
spstr strCommand.txt,tTmp.txt,"~",3 dim=dimValueNormal
if(tTmp.txt!="") // get background color
{ spstr strCommand.txt,tTmp.txt,"~",3
covx tTmp.txt,defaultBcoColor,0,0 if(tTmp.txt!="")
} {
// get font color covx tTmp.txt,defaultBcoColor,0,0
spstr strCommand.txt,tTmp.txt,"~",4 }
if(tTmp.txt!="") // get font color
{ spstr strCommand.txt,tTmp.txt,"~",4
covx tTmp.txt,defaultFontColor,0,0 if(tTmp.txt!="")
} {
}""","") covx tTmp.txt,defaultFontColor,0,0
print(foot) }
}""","")
print(foot)

View File

@@ -1,63 +0,0 @@
Page cardBurnRec
Attributes
ID : 0
Scope : local
Dragging : 0
Send Component ID : disabled
Opacity : 127
Width : 480
Effect : load
Effect Priority : 0
Effect Time : 300
Locked : no
Swide up page ID : disabled
Swide down page ID : disabled
Swide left page ID : disabled
Swide right page ID: disabled
Fill : solid color
Back. Color : 65535
Timer tm0
Attributes
ID : 1
Scope : local
Period (ms): 1001
Enabled : yes
Events
Timer Event
dim=100
sys0=0
sys1=0
if(sys2==WHITE)
{
sys2=BLACK
}else
{
sys2=WHITE
}
sya1=sys2
while(sys0<8)
{
sya0=sys0%2
if(sya1==WHITE)
{
sya1=BLACK
}else
{
sya1=WHITE
}
fill 0,40*sys0,480,40,sya1
sys0++
}
TouchCap tc0
Attributes
ID : 2
Scope: local
Value: 0
Events
Touch Press Event
page pageStartup

View File

@@ -6,10 +6,14 @@ pageIcons
7 Component(s) 7 Component(s)
0 Line(s) of event code 0 Line(s) of event code
0 Unique line(s) of event code 0 Unique line(s) of event code
cardBurnRec pageTest
3 Component(s) 25 Component(s)
25 Line(s) of event code 68 Line(s) of event code
21 Unique line(s) of event code 66 Unique line(s) of event code
popupNotify
19 Component(s)
271 Line(s) of event code
174 Unique line(s) of event code
popupFan popupFan
27 Component(s) 27 Component(s)
355 Line(s) of event code 355 Line(s) of event code
@@ -26,14 +30,10 @@ popupLightNew
23 Component(s) 23 Component(s)
412 Line(s) of event code 412 Line(s) of event code
209 Unique line(s) of event code 209 Unique line(s) of event code
popupNotify popupLight
19 Component(s) 28 Component(s)
267 Line(s) of event code 417 Line(s) of event code
172 Unique line(s) of event code 228 Unique line(s) of event code
pageTest
26 Component(s)
69 Line(s) of event code
67 Unique line(s) of event code
cardGrid2 cardGrid2
52 Component(s) 52 Component(s)
703 Line(s) of event code 703 Line(s) of event code
@@ -46,6 +46,10 @@ cardChart
33 Component(s) 33 Component(s)
447 Line(s) of event code 447 Line(s) of event code
297 Unique line(s) of event code 297 Unique line(s) of event code
cardGrid
44 Component(s)
593 Line(s) of event code
333 Unique line(s) of event code
cardQR cardQR
34 Component(s) 34 Component(s)
420 Line(s) of event code 420 Line(s) of event code
@@ -54,10 +58,6 @@ cardLChart
33 Component(s) 33 Component(s)
412 Line(s) of event code 412 Line(s) of event code
267 Unique line(s) of event code 267 Unique line(s) of event code
popupLight
28 Component(s)
412 Line(s) of event code
227 Unique line(s) of event code
cardPower cardPower
54 Component(s) 54 Component(s)
541 Line(s) of event code 541 Line(s) of event code
@@ -66,10 +66,6 @@ cardThermo
57 Component(s) 57 Component(s)
550 Line(s) of event code 550 Line(s) of event code
320 Unique line(s) of event code 320 Unique line(s) of event code
cardGrid
44 Component(s)
593 Line(s) of event code
333 Unique line(s) of event code
popupInSel popupInSel
34 Component(s) 34 Component(s)
621 Line(s) of event code 621 Line(s) of event code
@@ -91,16 +87,16 @@ popupThermo
523 Line(s) of event code 523 Line(s) of event code
276 Unique line(s) of event code 276 Unique line(s) of event code
screensaver2 screensaver2
59 Component(s) 64 Component(s)
373 Line(s) of event code 448 Line(s) of event code
256 Unique line(s) of event code 272 Unique line(s) of event code
cardEntities cardEntities
67 Component(s) 67 Component(s)
1205 Line(s) of event code 1205 Line(s) of event code
536 Unique line(s) of event code 536 Unique line(s) of event code
Total Total
24 Page(s) 23 Page(s)
880 Component(s) 881 Component(s)
10740 Line(s) of event code 10798 Line(s) of event code
2475 Unique line(s) of event code 2472 Unique line(s) of event code

View File

@@ -335,41 +335,6 @@ Button b13
Touch Press Event Touch Press Event
showqq showqq
Button b14
Attributes
ID : 25
Scope : local
Dragging : 0
Send Component ID : disabled
Opacity : 127
x coordinate : 229
y coordinate : 188
Width : 106
Height : 40
Effect : load
Effect Priority : 0
Effect Time : 300
Fill : solid color
Style : 3D auto
Font ID : 1
Back. Color : 50712
Back. Picture ID (Pressed): 65535
Back. Color (Pressed) : 1024
Font Color (Unpressed) : 0
Font Color (Pressed) : 65535
Horizontal Alignment : center
Vertical Alignment : center
State : unpressed
Text : burntest
Max. Text Size : 10
Word wrap : disabled
Horizontal Spacing : 0
Vertical Spacing : 0
Events
Touch Press Event
page cardBurnRec
Button b15 Button b15
Attributes Attributes
ID : 21 ID : 21

View File

@@ -806,6 +806,11 @@ Timer tmSerial
if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt) if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
{ {
// change icon // change icon
spstr strCommand.txt,tTmp.txt,"~",2
if(tTmp.txt!="")
{
tIcon1.txt=tTmp.txt
}
//spstr strCommand.txt,tIcon1.txt,"~",2 //spstr strCommand.txt,tIcon1.txt,"~",2
vis tIcon1,1 vis tIcon1,1
// change icon color // change icon color

View File

@@ -672,6 +672,10 @@ Timer tmSerial
{ {
page cardChart page cardChart
} }
if(tId.txt=="cardLChart")
{
page cardLChart
}
} }
// end of user code // end of user code
udelete payloadLength-1 udelete payloadLength-1

View File

@@ -56,12 +56,47 @@ Page screensaver2
Postinitialize Event Postinitialize Event
click m0,1 click m0,1
Variable (string) entn1
Attributes
ID : 59
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn2
Attributes
ID : 60
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn3
Attributes
ID : 61
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn4
Attributes
ID : 62
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn5
Attributes
ID : 63
Scope : local
Text :
Max. Text Size: 14
Variable (string) strCommand Variable (string) strCommand
Attributes Attributes
ID : 4 ID : 4
Scope : local Scope : local
Text : Text :
Max. Text Size: 1979 Max. Text Size: 1935
Variable (string) strTmp Variable (string) strTmp
Attributes Attributes
@@ -82,7 +117,7 @@ Variable (string) tInstruction
ID : 18 ID : 18
Scope : local Scope : local
Text : Text :
Max. Text Size: 50 Max. Text Size: 15
Variable (string) tSend Variable (string) tSend
Attributes Attributes
@@ -96,7 +131,7 @@ Variable (string) tTmp
ID : 19 ID : 19
Scope : local Scope : local
Text : Text :
Max. Text Size: 50 Max. Text Size: 30
Variable (int32) vaTap Variable (int32) vaTap
Attributes Attributes
@@ -865,6 +900,25 @@ Text f1Icon
Horizontal Spacing : 0 Horizontal Spacing : 0
Vertical Spacing : 0 Vertical Spacing : 0
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn1.txt+",button"
if(entn1.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f2Icon Text f2Icon
Attributes Attributes
ID : 54 ID : 54
@@ -894,6 +948,25 @@ Text f2Icon
Horizontal Spacing : 0 Horizontal Spacing : 0
Vertical Spacing : 0 Vertical Spacing : 0
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn2.txt+",button"
if(entn2.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f3Icon Text f3Icon
Attributes Attributes
ID : 55 ID : 55
@@ -923,6 +996,25 @@ Text f3Icon
Horizontal Spacing : 0 Horizontal Spacing : 0
Vertical Spacing : 0 Vertical Spacing : 0
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn3.txt+",button"
if(entn3.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f4Icon Text f4Icon
Attributes Attributes
ID : 53 ID : 53
@@ -952,6 +1044,25 @@ Text f4Icon
Horizontal Spacing : 0 Horizontal Spacing : 0
Vertical Spacing : 0 Vertical Spacing : 0
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn4.txt+",button"
if(entn4.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f5Icon Text f5Icon
Attributes Attributes
ID : 52 ID : 52
@@ -981,6 +1092,25 @@ Text f5Icon
Horizontal Spacing : 0 Horizontal Spacing : 0
Vertical Spacing : 0 Vertical Spacing : 0
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn5.txt+",button"
if(entn5.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text m0 Text m0
Attributes Attributes
ID : 32 ID : 32
@@ -1551,26 +1681,36 @@ Timer tmSerial
//f1Icon Color //f1Icon Color
spstr strCommand.txt,tTmp.txt,"~",64 spstr strCommand.txt,tTmp.txt,"~",64
covx tTmp.txt,f1Icon.pco,0,0 covx tTmp.txt,f1Icon.pco,0,0
//f1Icon intNameEntity
spstr strCommand.txt,entn1.txt,"~",62
//f2Icon //f2Icon
spstr strCommand.txt,f2Icon.txt,"~",69 spstr strCommand.txt,f2Icon.txt,"~",69
//f2Icon Color //f2Icon Color
spstr strCommand.txt,tTmp.txt,"~",70 spstr strCommand.txt,tTmp.txt,"~",70
covx tTmp.txt,f2Icon.pco,0,0 covx tTmp.txt,f2Icon.pco,0,0
//f2Icon intNameEntity
spstr strCommand.txt,entn2.txt,"~",68
//f3Icon //f3Icon
spstr strCommand.txt,f3Icon.txt,"~",75 spstr strCommand.txt,f3Icon.txt,"~",75
//f3Icon Color //f3Icon Color
spstr strCommand.txt,tTmp.txt,"~",76 spstr strCommand.txt,tTmp.txt,"~",76
covx tTmp.txt,f3Icon.pco,0,0 covx tTmp.txt,f3Icon.pco,0,0
//f3Icon intNameEntity
spstr strCommand.txt,entn3.txt,"~",74
//f4Icon //f4Icon
spstr strCommand.txt,f4Icon.txt,"~",81 spstr strCommand.txt,f4Icon.txt,"~",81
//f4Icon Color //f4Icon Color
spstr strCommand.txt,tTmp.txt,"~",82 spstr strCommand.txt,tTmp.txt,"~",82
covx tTmp.txt,f4Icon.pco,0,0 covx tTmp.txt,f4Icon.pco,0,0
//f4Icon intNameEntity
spstr strCommand.txt,entn4.txt,"~",80
//f5Icon //f5Icon
spstr strCommand.txt,f5Icon.txt,"~",87 spstr strCommand.txt,f5Icon.txt,"~",87
//f5Icon Color //f5Icon Color
spstr strCommand.txt,tTmp.txt,"~",88 spstr strCommand.txt,tTmp.txt,"~",88
covx tTmp.txt,f5Icon.pco,0,0 covx tTmp.txt,f5Icon.pco,0,0
//f5Icon intNameEntity
spstr strCommand.txt,entn5.txt,"~",86
} }
if(tInstruction.txt=="notify") if(tInstruction.txt=="notify")
{ {

View File

@@ -1,53 +0,0 @@
Page cardBurnRec
Attributes
Scope : local
Dragging : 0
Send Component ID : disabled
Locked : no
Swide up page ID : disabled
Swide down page ID : disabled
Swide left page ID : disabled
Swide right page ID: disabled
Timer tm0
Attributes
Scope : local
Period (ms): 1001
Enabled : yes
Events
Timer Event
dim=100
sys0=0
sys1=0
if(sys2==WHITE)
{
sys2=BLACK
}else
{
sys2=WHITE
}
sya1=sys2
while(sys0<8)
{
sya0=sys0%2
if(sya1==WHITE)
{
sya1=BLACK
}else
{
sya1=WHITE
}
fill 0,40*sys0,480,40,sya1
sys0++
}
TouchCap tc0
Attributes
Scope: local
Value: 0
Events
Touch Press Event
page pageStartup

View File

@@ -141,19 +141,6 @@ Button b13
Touch Press Event Touch Press Event
showqq showqq
Button b14
Attributes
Scope : local
Dragging : 0
Send Component ID: disabled
State : unpressed
Text : burntest
Max. Text Size : 10
Events
Touch Press Event
page cardBurnRec
Button b15 Button b15
Attributes Attributes
Scope : local Scope : local

View File

@@ -457,6 +457,11 @@ Timer tmSerial
if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt) if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
{ {
// change icon // change icon
spstr strCommand.txt,tTmp.txt,"~",2
if(tTmp.txt!="")
{
tIcon1.txt=tTmp.txt
}
//spstr strCommand.txt,tIcon1.txt,"~",2 //spstr strCommand.txt,tIcon1.txt,"~",2
vis tIcon1,1 vis tIcon1,1
// change icon color // change icon color

View File

@@ -443,6 +443,10 @@ Timer tmSerial
{ {
page cardChart page cardChart
} }
if(tId.txt=="cardLChart")
{
page cardLChart
}
} }
// end of user code // end of user code
udelete payloadLength-1 udelete payloadLength-1

View File

@@ -48,11 +48,41 @@ Page screensaver2
Postinitialize Event Postinitialize Event
click m0,1 click m0,1
Variable (string) entn1
Attributes
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn2
Attributes
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn3
Attributes
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn4
Attributes
Scope : local
Text :
Max. Text Size: 14
Variable (string) entn5
Attributes
Scope : local
Text :
Max. Text Size: 14
Variable (string) strCommand Variable (string) strCommand
Attributes Attributes
Scope : local Scope : local
Text : Text :
Max. Text Size: 1979 Max. Text Size: 1935
Variable (string) strTmp Variable (string) strTmp
Attributes Attributes
@@ -70,7 +100,7 @@ Variable (string) tInstruction
Attributes Attributes
Scope : local Scope : local
Text : Text :
Max. Text Size: 50 Max. Text Size: 15
Variable (string) tSend Variable (string) tSend
Attributes Attributes
@@ -82,7 +112,7 @@ Variable (string) tTmp
Attributes Attributes
Scope : local Scope : local
Text : Text :
Max. Text Size: 50 Max. Text Size: 30
Variable (int32) vaTap Variable (int32) vaTap
Attributes Attributes
@@ -344,6 +374,25 @@ Text f1Icon
Text : Text :
Max. Text Size : 4 Max. Text Size : 4
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn1.txt+",button"
if(entn1.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f2Icon Text f2Icon
Attributes Attributes
Scope : local Scope : local
@@ -353,6 +402,25 @@ Text f2Icon
Text : Text :
Max. Text Size : 4 Max. Text Size : 4
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn2.txt+",button"
if(entn2.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f3Icon Text f3Icon
Attributes Attributes
Scope : local Scope : local
@@ -362,6 +430,25 @@ Text f3Icon
Text : Text :
Max. Text Size : 4 Max. Text Size : 4
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn3.txt+",button"
if(entn3.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f4Icon Text f4Icon
Attributes Attributes
Scope : local Scope : local
@@ -371,6 +458,25 @@ Text f4Icon
Text : Text :
Max. Text Size : 4 Max. Text Size : 4
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn4.txt+",button"
if(entn4.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text f5Icon Text f5Icon
Attributes Attributes
Scope : local Scope : local
@@ -380,6 +486,25 @@ Text f5Icon
Text : Text :
Max. Text Size : 4 Max. Text Size : 4
Events
Touch Press Event
tSend.txt="event,buttonPress2,"+entn5.txt+",button"
if(entn5.txt=="")
{
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.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
Text m0 Text m0
Attributes Attributes
Scope : local Scope : local
@@ -718,26 +843,36 @@ Timer tmSerial
//f1Icon Color //f1Icon Color
spstr strCommand.txt,tTmp.txt,"~",64 spstr strCommand.txt,tTmp.txt,"~",64
covx tTmp.txt,f1Icon.pco,0,0 covx tTmp.txt,f1Icon.pco,0,0
//f1Icon intNameEntity
spstr strCommand.txt,entn1.txt,"~",62
//f2Icon //f2Icon
spstr strCommand.txt,f2Icon.txt,"~",69 spstr strCommand.txt,f2Icon.txt,"~",69
//f2Icon Color //f2Icon Color
spstr strCommand.txt,tTmp.txt,"~",70 spstr strCommand.txt,tTmp.txt,"~",70
covx tTmp.txt,f2Icon.pco,0,0 covx tTmp.txt,f2Icon.pco,0,0
//f2Icon intNameEntity
spstr strCommand.txt,entn2.txt,"~",68
//f3Icon //f3Icon
spstr strCommand.txt,f3Icon.txt,"~",75 spstr strCommand.txt,f3Icon.txt,"~",75
//f3Icon Color //f3Icon Color
spstr strCommand.txt,tTmp.txt,"~",76 spstr strCommand.txt,tTmp.txt,"~",76
covx tTmp.txt,f3Icon.pco,0,0 covx tTmp.txt,f3Icon.pco,0,0
//f3Icon intNameEntity
spstr strCommand.txt,entn3.txt,"~",74
//f4Icon //f4Icon
spstr strCommand.txt,f4Icon.txt,"~",81 spstr strCommand.txt,f4Icon.txt,"~",81
//f4Icon Color //f4Icon Color
spstr strCommand.txt,tTmp.txt,"~",82 spstr strCommand.txt,tTmp.txt,"~",82
covx tTmp.txt,f4Icon.pco,0,0 covx tTmp.txt,f4Icon.pco,0,0
//f4Icon intNameEntity
spstr strCommand.txt,entn4.txt,"~",80
//f5Icon //f5Icon
spstr strCommand.txt,f5Icon.txt,"~",87 spstr strCommand.txt,f5Icon.txt,"~",87
//f5Icon Color //f5Icon Color
spstr strCommand.txt,tTmp.txt,"~",88 spstr strCommand.txt,tTmp.txt,"~",88
covx tTmp.txt,f5Icon.pco,0,0 covx tTmp.txt,f5Icon.pco,0,0
//f5Icon intNameEntity
spstr strCommand.txt,entn5.txt,"~",86
} }
if(tInstruction.txt=="notify") if(tInstruction.txt=="notify")
{ {

Binary file not shown.

Binary file not shown.

View File

@@ -5,7 +5,7 @@ If you like this project consider buying me a pizza 🍕 <a href="https://paypal
[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg)](https://github.com/hacs/integration) [![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg)](https://github.com/hacs/integration)
![hacs validation](https://github.com/joBr99/nspanel-lovelace-ui/actions/workflows/hacs-validation.yaml/badge.svg) ![hacs validation](https://github.com/joBr99/nspanel-lovelace-ui/actions/workflows/hacs-validation.yaml/badge.svg)
[![GitHub Release](https://img.shields.io/github/release/joBr99/nspanel-lovelace-ui.svg)](https://github.com/joBr99/nspanel-lovelace-ui/releases) [![GitHub Release](https://img.shields.io/github/release/joBr99/nspanel-lovelace-ui.svg)](https://github.com/joBr99/nspanel-lovelace-ui/releases)
![Project Maintenance](https://img.shields.io/maintenance/yes/2023.svg) ![Project Maintenance](https://img.shields.io/maintenance/yes/2024.svg)
[![GitHub Activity](https://img.shields.io/github/commit-activity/y/joBr99/nspanel-lovelace-ui.svg)](https://github.com/joBr99/nspanel-lovelace-ui/commits/main) [![GitHub Activity](https://img.shields.io/github/commit-activity/y/joBr99/nspanel-lovelace-ui.svg)](https://github.com/joBr99/nspanel-lovelace-ui/commits/main)
@@ -65,3 +65,5 @@ SmartHomeNG: https://github.com/sisamiwe/shng-nspanel-plugin
OpenHAB: https://github.com/donoo/o2n2l OpenHAB: https://github.com/donoo/o2n2l
NodeRed: https://github.com/laluz742/node-red-contrib-nspanel-lui NodeRed: https://github.com/laluz742/node-red-contrib-nspanel-lui
ESPHome without any Backend: https://github.com/olicooper/esphome-nspanel-lovelace-native

View File

@@ -1,2 +1,3 @@
ha_api = None ha_api = None
mqtt_api = None mqtt_api = None
ad_api = None

View File

@@ -132,6 +132,7 @@ class LuiBackendConfig(object):
'sleepTrackingZones': ["not_home", "off"], 'sleepTrackingZones': ["not_home", "off"],
'sleepOverride': None, 'sleepOverride': None,
'locale': "en_US", 'locale': "en_US",
'quiet': True,
'timeFormat': "%H:%M", 'timeFormat': "%H:%M",
'dateFormatBabel': "full", 'dateFormatBabel': "full",
'dateAdditionalTemplate': "", 'dateAdditionalTemplate': "",

View File

@@ -3,6 +3,7 @@ import datetime
import apis import apis
from helper import scale, pos_to_color, rgb_dec565 from helper import scale, pos_to_color, rgb_dec565
from pages import LuiPagesGen from pages import LuiPagesGen
from luibackend.config import Card
class LuiController(object): class LuiController(object):
@@ -333,6 +334,11 @@ class LuiController(object):
apis.ha_api.get_entity(entity_id).call_service("return_to_base") apis.ha_api.get_entity(entity_id).call_service("return_to_base")
elif entity_id.startswith('service'): elif entity_id.startswith('service'):
apis.ha_api.call_service(entity_id.replace('service.', '', 1).replace('.','/', 1), **entity_config.data) apis.ha_api.call_service(entity_id.replace('service.', '', 1).replace('.','/', 1), **entity_config.data)
elif entity_id.startswith('valve'):
if apis.ha_api.get_entity(entity_id).state == "open":
apis.ha_api.get_entity(entity_id).call_service("close_valve")
else:
apis.ha_api.get_entity(entity_id).call_service("open_valve")
# for media page # for media page
if button_type == "media-next": if button_type == "media-next":
@@ -347,8 +353,8 @@ class LuiController(object):
else: else:
apis.ha_api.get_entity(entity_id).call_service("turn_off") apis.ha_api.get_entity(entity_id).call_service("turn_off")
if button_type == "media-shuffle": if button_type == "media-shuffle":
suffle = not apis.ha_api.get_entity(entity_id).attributes.shuffle shuffle = not apis.ha_api.get_entity(entity_id).attributes['shuffle']
apis.ha_api.get_entity(entity_id).call_service("shuffle_set", shuffle=suffle) apis.ha_api.get_entity(entity_id).call_service("shuffle_set", shuffle=shuffle)
if button_type == "volumeSlider": if button_type == "volumeSlider":
pos = int(value) pos = int(value)
# HA wants this value between 0 and 1 as float # HA wants this value between 0 and 1 as float
@@ -365,7 +371,7 @@ class LuiController(object):
if button_type == "colorTempSlider": if button_type == "colorTempSlider":
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
#scale 0-100 from slider to color range of lamp #scale 0-100 from slider to color range of lamp
color_val = scale(int(value), (0, 100), (entity.attributes.min_mireds, entity.attributes.max_mireds)) color_val = scale(int(value), (0, 100), (entity.attributes['min_mireds'], entity.attributes['max_mireds']))
apis.ha_api.get_entity(entity_id).call_service("turn_on", color_temp=color_val) apis.ha_api.get_entity(entity_id).call_service("turn_on", color_temp=color_val)
if button_type == "colorWheel": if button_type == "colorWheel":
apis.ha_api.log(value) apis.ha_api.log(value)
@@ -392,9 +398,9 @@ class LuiController(object):
if button_type == "opnSensorNotify": if button_type == "opnSensorNotify":
msg = "" msg = ""
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None: if open_sensors := entity.attributes.get("open_sensors") is not None:
for e in entity.attributes.open_sensors: for e in open_sensors:
msg += f"- {apis.ha_api.get_entity(e).attributes.friendly_name}\r\n" msg += f"- {apis.ha_api.get_entity(e).attributes['friendly_name']}\r\n"
self._pages_gen.send_message_page("opnSensorNotifyRes", "", msg, "", "") self._pages_gen.send_message_page("opnSensorNotifyRes", "", msg, "", "")
# for cardUnlock # for cardUnlock
@@ -411,22 +417,22 @@ class LuiController(object):
if button_type == "mode-preset_modes": if button_type == "mode-preset_modes":
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
preset_mode = entity.attributes.preset_modes[int(value)] preset_mode = entity.attributes['preset_modes'][int(value)]
entity.call_service("set_preset_mode", preset_mode=preset_mode) entity.call_service("set_preset_mode", preset_mode=preset_mode)
if button_type == "mode-swing_modes": if button_type == "mode-swing_modes":
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
swing_mode = entity.attributes.swing_modes[int(value)] swing_mode = entity.attributes['swing_modes'][int(value)]
entity.call_service("set_swing_mode", swing_mode=swing_mode) entity.call_service("set_swing_mode", swing_mode=swing_mode)
if button_type == "mode-fan_modes": if button_type == "mode-fan_modes":
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
fan_mode = entity.attributes.fan_modes[int(value)] fan_mode = entity.attributes['fan_modes'][int(value)]
entity.call_service("set_fan_mode", fan_mode=fan_mode) entity.call_service("set_fan_mode", fan_mode=fan_mode)
if button_type in ["mode-input_select", "mode-select"]: if button_type in ["mode-input_select", "mode-select"]:
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
option = entity.attributes.options[int(value)] option = entity.attributes['options'][int(value)]
entity.call_service("select_option", option=option) entity.call_service("select_option", option=option)
if button_type == "mode-light": if button_type == "mode-light":
@@ -438,12 +444,12 @@ class LuiController(object):
if options_list is not None: if options_list is not None:
option = options_list[int(value)] option = options_list[int(value)]
else: else:
option = entity.attributes.effect_list[int(value)] option = entity.attributes['effect_list'][int(value)]
entity.call_service("turn_on", effect=option) entity.call_service("turn_on", effect=option)
if button_type == "mode-media_player": if button_type == "mode-media_player":
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
option = entity.attributes.source_list[int(value)] option = entity.attributes['source_list'][int(value)]
entity.call_service("select_source", source=option) entity.call_service("select_source", source=option)
# timer detail page # timer detail page
@@ -458,3 +464,9 @@ class LuiController(object):
apis.ha_api.get_entity(entity_id).call_service("pause") apis.ha_api.get_entity(entity_id).call_service("pause")
if button_type == "timer-finish": if button_type == "timer-finish":
apis.ha_api.get_entity(entity_id).call_service("finish") apis.ha_api.get_entity(entity_id).call_service("finish")
@property
def current_card(self) -> Card:
"""Used to get the current card"""
return self._current_card

View File

@@ -159,8 +159,8 @@ alarm_control_panel_mapping = {
} }
climate_mapping = { climate_mapping = {
'auto': 'calendar-sync', 'auto': 'fan-auto',
'heat_cool': 'calendar-sync', 'heat_cool': 'sun-snowflake-variant',
'heat': 'fire', 'heat': 'fire',
'off': 'power', 'off': 'power',
'cool': 'snowflake', 'cool': 'snowflake',
@@ -213,6 +213,9 @@ def get_icon_ha(entity_id, overwrite=None, stateOverwrite=None):
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
state = entity.state if stateOverwrite is None else stateOverwrite state = entity.state if stateOverwrite is None else stateOverwrite
if entity_id in ["sensor.weather_forecast_daily", "sensor.weather_forecast_hourly"]:
ha_type = "weather"
if overwrite is not None: if overwrite is not None:
if type(overwrite) is str: if type(overwrite) is str:
return get_icon_char(overwrite) return get_icon_char(overwrite)
@@ -263,8 +266,8 @@ def get_icon_ha(entity_id, overwrite=None, stateOverwrite=None):
# based on media_content_type # based on media_content_type
elif ha_type == "media_player": elif ha_type == "media_player":
result_icon = "speaker-off" result_icon = "speaker-off"
if "media_content_type" in entity.attributes: if media_content_type := entity.attributes.get("media_content_type"):
if entity.attributes.media_content_type in media_content_type_mapping: if media_content_type in media_content_type_mapping:
result_icon = media_content_type_mapping[entity.attributes.media_content_type] result_icon = media_content_type_mapping[media_content_type]
return get_icon_char(result_icon) return get_icon_char(result_icon)

View File

@@ -77,12 +77,13 @@ class LuiMqttListener(object):
self._controller.detail_open(msg[2], msg[3]) self._controller.detail_open(msg[2], msg[3])
class LuiMqttSender(object): class LuiMqttSender(object):
def __init__(self, api, use_api, topic_send, api_panel_name): def __init__(self, api, use_api, topic_send, api_panel_name, quiet):
self._ha_api = api self._ha_api = api
self._use_api = use_api self._use_api = use_api
self._topic_send = topic_send self._topic_send = topic_send
self._api_panel_name = api_panel_name self._api_panel_name = api_panel_name
self._prev_msg = "" self._prev_msg = ""
self._quiet = quiet
def send_mqtt_msg(self, msg, topic=None, force=False): def send_mqtt_msg(self, msg, topic=None, force=False):
if not force and self._prev_msg == msg: if not force and self._prev_msg == msg:
@@ -90,7 +91,9 @@ class LuiMqttSender(object):
return return
self._prev_msg = msg self._prev_msg = msg
apis.ha_api.log(f"Sending Message: {msg}") if self._quiet is False:
apis.ha_api.log(f"Sending Message: {msg}")
if self._use_api: if self._use_api:
apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=2, data=msg) apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=2, data=msg)
else: else:

View File

@@ -25,7 +25,7 @@ class LuiPagesGen(object):
self._config = config self._config = config
self._locale = config.get("locale") self._locale = config.get("locale")
self._send_mqtt_msg = send_mqtt_msg self._send_mqtt_msg = send_mqtt_msg
def get_entity_color(self, entity, ha_type=None, stateOverwrite=None, overwrite=None): def get_entity_color(self, entity, ha_type=None, stateOverwrite=None, overwrite=None):
if overwrite is not None: if overwrite is not None:
if type(overwrite) in [str, list]: if type(overwrite) in [str, list]:
@@ -82,7 +82,7 @@ class LuiPagesGen(object):
icon_color = 63878 #red icon_color = 63878 #red
if state == "fog": if state == "fog":
icon_color = 38066 #75% grey icon_color = 38066 #75% grey
if state in ["hail", "snowy"]: if state in ["hail", "snowy"]:
icon_color = 65535 #white icon_color = 65535 #white
if state == "lightning": if state == "lightning":
icon_color = 65120 #golden-yellow icon_color = 65120 #golden-yellow
@@ -97,13 +97,12 @@ class LuiPagesGen(object):
if state == "sunny": if state == "sunny":
icon_color = 65504 #bright-yellow icon_color = 65504 #bright-yellow
if "rgb_color" in attr and attr.rgb_color: if color := attr.get("rgb_color"):
color = attr.rgb_color if brightness := attr.get("brightness"):
if "brightness" in attr and attr.brightness: color = rgb_brightness(color, brightness)
color = rgb_brightness(color, attr.brightness)
icon_color = rgb_dec565(color) icon_color = rgb_dec565(color)
elif "brightness" in attr and attr.brightness: elif brightness := attr.get("brightness"):
color = rgb_brightness([253, 216, 53], attr.brightness) color = rgb_brightness([253, 216, 53], brightness)
icon_color = rgb_dec565(color) icon_color = rgb_dec565(color)
return icon_color return icon_color
@@ -129,7 +128,7 @@ class LuiPagesGen(object):
else: else:
dateformat = self._config.get("dateFormat") dateformat = self._config.get("dateFormat")
date = datetime.datetime.now().strftime(dateformat) date = datetime.datetime.now().strftime(dateformat)
addTemplate = self._config.get("dateAdditionalTemplate") addTemplate = self._config.get("dateAdditionalTemplate")
addDateText = apis.ha_api.render_template(addTemplate) addDateText = apis.ha_api.render_template(addTemplate)
self._send_mqtt_msg(f"date~{date}{addDateText}") self._send_mqtt_msg(f"date~{date}{addDateText}")
@@ -138,7 +137,7 @@ class LuiPagesGen(object):
if target_page == "cardUnlock": if target_page == "cardUnlock":
target_page = "cardAlarm" target_page = "cardAlarm"
self._send_mqtt_msg(f"pageType~{target_page}") self._send_mqtt_msg(f"pageType~{target_page}")
def update_screensaver_weather(self, theme): def update_screensaver_weather(self, theme):
entities = self._config._config_screensaver.entities entities = self._config._config_screensaver.entities
@@ -151,7 +150,7 @@ class LuiPagesGen(object):
item_str = "" item_str = ""
for item in entities: for item in entities:
item_str += self.generate_entities_item(item, "cardEntities", mask=["type", "entityId"]) item_str += self.generate_entities_item(item, "cardEntities", mask=["type", "entityId"])
self._send_mqtt_msg(f"weatherUpdate{item_str}") self._send_mqtt_msg(f"weatherUpdate{item_str}")
# send color if configured in screensaver # send color if configured in screensaver
if theme is not None: if theme is not None:
@@ -181,17 +180,20 @@ class LuiPagesGen(object):
colorOverride = item.colorOverride colorOverride = item.colorOverride
name = item.nameOverride name = item.nameOverride
uuid = item.uuid uuid = item.uuid
# check ha template for name # check ha template for name
if item.nameOverride is not None and ("{" in item.nameOverride and "}" in item.nameOverride): if item.nameOverride is not None and ("{" in item.nameOverride and "}" in item.nameOverride):
name = apis.ha_api.render_template(item.nameOverride) name = apis.ha_api.render_template(item.nameOverride)
# type of the item is the string before the "." in the entityId # type of the item is the string before the "." in the entityId
if entityId is not None: if entityId is not None:
entityType = entityId.split(".")[0] entityType = entityId.split(".")[0]
else: else:
entityType = "delete" entityType = "delete"
if entityId in ["sensor.weather_forecast_daily", "sensor.weather_forecast_hourly"]:
entityType = "weather"
apis.ha_api.log(f"Generating item for {entityId} with type {entityType}", level="DEBUG") apis.ha_api.log(f"Generating item for {entityId} with type {entityType}", level="DEBUG")
status_entity = apis.ha_api.get_entity(item.status) if item.status and apis.ha_api.entity_exists(item.status) else None status_entity = apis.ha_api.get_entity(item.status) if item.status and apis.ha_api.entity_exists(item.status) else None
@@ -221,7 +223,7 @@ class LuiPagesGen(object):
if status_entity: if status_entity:
icon_res = get_icon_ha(item.status, overwrite=icon) icon_res = get_icon_ha(item.status, overwrite=icon)
icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride) icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride)
if item.status.startswith("sensor") and (cardType == "cardGrid" or cardType == "cardGrid2") and item.iconOverride is None: if item.status.startswith("sensor") and cardType in ["cardGrid", "cardGrid1", "cardGrid2"] and item.iconOverride is None:
icon_res = status_entity.state[:4] icon_res = status_entity.state[:4]
if icon_res[-1] == ".": if icon_res[-1] == ".":
icon_res = icon_res[:-1] icon_res = icon_res[:-1]
@@ -245,7 +247,7 @@ class LuiPagesGen(object):
if status_entity: if status_entity:
icon_id = get_icon_ha(item.status, overwrite=icon) icon_id = get_icon_ha(item.status, overwrite=icon)
icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride) icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride)
if item.status.startswith("sensor") and (cardType == "cardGrid" or cardType == "cardGrid2") and item.iconOverride is None: if item.status.startswith("sensor") and cardType in ["cardGrid", "cardGrid1", "cardGrid2"] and item.iconOverride is None:
icon_id = status_entity.state[:4] icon_id = status_entity.state[:4]
if icon_id[-1] == ".": if icon_id[-1] == ".":
icon_id = icon_id[:-1] icon_id = icon_id[:-1]
@@ -254,7 +256,7 @@ class LuiPagesGen(object):
if entity is None: if entity is None:
return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~Not found check~ apps.yaml" return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~Not found check~ apps.yaml"
# HA Entities # HA Entities
# common res vars # common res vars
entityTypePanel = "text" entityTypePanel = "text"
@@ -273,7 +275,7 @@ class LuiPagesGen(object):
icon_up_status = "disable" icon_up_status = "disable"
icon_stop_status = "disable" icon_stop_status = "disable"
icon_down_status = "disable" icon_down_status = "disable"
bits = entity.attributes.supported_features bits = entity.attributes.get('supported_features')
pos = entity.attributes.get("current_position") pos = entity.attributes.get("current_position")
if pos is None: if pos is None:
pos_status = entity.state pos_status = entity.state
@@ -306,19 +308,24 @@ class LuiPagesGen(object):
device_class = entity.attributes.get("device_class", "") device_class = entity.attributes.get("device_class", "")
unit_of_measurement = entity.attributes.get("unit_of_measurement", "") unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
value = entity.state value = entity.state
try:
value = str(round(float(value), 1))
except:
print("An exception occurred")
# limit value to 4 chars on us-p # limit value to 4 chars on us-p
if self._config.get("model") == "us-p" and cardType == "cardEntities": if self._config.get("model") == "us-p" and cardType == "cardEntities":
value = entity.state[:4] value = entity.state[:4]
if value[-1] == ".": if value[-1] == ".":
value = value[:-1] value = value[:-1]
if device_class != "temperature": if device_class != "temperature":
value = value + " " value = value + " "
value = value + unit_of_measurement value = value + unit_of_measurement
if entityType == "binary_sensor": if entityType == "binary_sensor":
value = get_translation(self._locale, f"backend.component.binary_sensor.state.{device_class}.{entity.state}") value = get_translation(self._locale, f"backend.component.binary_sensor.state.{device_class}.{entity.state}")
if (cardType == "cardGrid" or cardType == "cardGrid2") and entityType == "sensor" and icon is None: if cardType in ["cardGrid", "cardGrid1", "cardGrid2"] and entityType == "sensor" and icon is None:
icon_id = entity.state[:4] icon_id = entity.state[:4]
if icon_id[-1] == ".": if icon_id[-1] == ".":
icon_id = icon_id[:-1] icon_id = icon_id[:-1]
@@ -380,20 +387,50 @@ class LuiPagesGen(object):
elif entityType == "weather": elif entityType == "weather":
entityTypePanel = "text" entityTypePanel = "text"
unit = get_attr_safe(entity, "temperature_unit", "") unit = get_attr_safe(entity, "temperature_unit", "")
if type(item.stype) == int and len(entity.attributes.forecast) >= item.stype: rt = None
fdate = dp.parse(entity.attributes.forecast[item.stype]['datetime']) if type(item.stype) == str and ":" in item.stype and len(item.stype.split(":")) == 2:
global babel_spec spintstr = item.stype.split(":")
if babel_spec is not None: rt = spintstr[0]
dateformat = "E" if item.nameOverride is None else item.nameOverride item.stype = int(spintstr[1])
name = babel.dates.format_datetime(fdate.astimezone(), dateformat, locale=self._locale) if type(item.stype) == int:
bits = get_attr_safe(entity, "supported_features", 0b0)
if not rt:
rt = "daily"
if bits & 0b001: #FORECAST_DAILY
rt = "daily"
elif bits & 0b010: #FORECAST_HOURLY
rt = "hourly"
elif bits & 0b100: #FORECAST_TWICE_DAILY
rt = "twice_daily"
results = apis.ha_api.call_service(
"weather/get_forecasts", target={"entity_id": entityId}, service_data={"type": rt}
)
forecast = results.get("result", {}).get("response", {}).get(entityId, {}).get('forecast') or entity.attributes.get('forecast', [])
if len(forecast) >= item.stype:
day_forecast = forecast[item.stype]
fdate = dp.parse(day_forecast['datetime'])
global babel_spec
if babel_spec is not None:
dateformat = "E" if item.nameOverride is None else item.nameOverride
name = babel.dates.format_datetime(fdate.astimezone(), dateformat, locale=self._locale)
else:
dateformat = "%a" if item.nameOverride is None else item.nameOverride
name = fdate.astimezone().strftime(dateformat)
icon_id = get_icon_ha(entityId, stateOverwrite=day_forecast['condition'])
value = f'{day_forecast.get("temperature", "")}{unit}'
color = self.get_entity_color(entity, ha_type=entityType, stateOverwrite=day_forecast['condition'], overwrite=colorOverride)
else: else:
dateformat = "%a" if item.nameOverride is None else item.nameOverride value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
name = fdate.astimezone().strftime(dateformat)
icon_id = get_icon_ha(entityId, stateOverwrite=entity.attributes.forecast[item.stype]['condition'])
value = f'{entity.attributes.forecast[item.stype].get("temperature", "")}{unit}'
color = self.get_entity_color(entity, ha_type=entityType, stateOverwrite=entity.attributes.forecast[item.stype]['condition'], overwrite=colorOverride)
else: else:
value = f'{get_attr_safe(entity, "temperature", "")}{unit}' value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
elif entityType == "valve":
entityTypePanel = "valve"
value = get_translation(self._locale, f"backend.component.binary_sensor.state.door.{entity.state}")
if entity.state == "open":
icon_id = get_icon_id("valve-open")
else:
icon_id = get_icon_id("valve-closed")
else: else:
name = "unsupported" name = "unsupported"
# Overwrite for value # Overwrite for value
@@ -452,7 +489,7 @@ class LuiPagesGen(object):
command = f"entityUpd~Not found~{navigation}~{item}~check~220~apps.yaml~150~300~5~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Please~your~~" command = f"entityUpd~Not found~{navigation}~{item}~check~220~apps.yaml~150~300~5~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Please~your~~"
else: else:
entity = apis.ha_api.get_entity(item) entity = apis.ha_api.get_entity(item)
heading = title if title != "unknown" else entity.attributes.friendly_name heading = title if title != "unknown" else entity.attributes['friendly_name']
current_temp = get_attr_safe(entity, "current_temperature", "") current_temp = get_attr_safe(entity, "current_temperature", "")
dest_temp = get_attr_safe(entity, "temperature", None) dest_temp = get_attr_safe(entity, "temperature", None)
dest_temp2 = "" dest_temp2 = ""
@@ -473,10 +510,10 @@ class LuiPagesGen(object):
state_value += get_translation(self._locale, f"backend.component.climate.state._.{entity.state}") state_value += get_translation(self._locale, f"backend.component.climate.state._.{entity.state}")
if hvac_action != "": if hvac_action != "":
state_value += ")" state_value += ")"
min_temp = int(get_attr_safe(entity, "min_temp", 0)*10) min_temp = int(get_attr_safe(entity, "min_temp", 0)*10)
max_temp = int(get_attr_safe(entity, "max_temp", 0)*10) max_temp = int(get_attr_safe(entity, "max_temp", 0)*10)
step_temp = int(get_attr_safe(entity, "target_temp_step", 0.5)*10) step_temp = int(get_attr_safe(entity, "target_temp_step", 0.5)*10)
icon_res_list = [] icon_res_list = []
icon_res = "" icon_res = ""
@@ -501,7 +538,7 @@ class LuiPagesGen(object):
state = 0 state = 0
if(mode == entity.state): if(mode == entity.state):
state = 1 state = 1
icon_res_list.append(f"~{icon_id}~{color_on}~{state}~{mode}") icon_res_list.append(f"~{icon_id}~{color_on}~{state}~{mode}")
icon_res = "".join(icon_res_list) icon_res = "".join(icon_res_list)
@@ -516,11 +553,11 @@ class LuiPagesGen(object):
icon_res = "~"*4 + icon_res_list[0] + "~"*4 + icon_res_list[1] + "~"*4 + icon_res_list[2] + "~"*4 + icon_res_list[3] icon_res = "~"*4 + icon_res_list[0] + "~"*4 + icon_res_list[1] + "~"*4 + icon_res_list[2] + "~"*4 + icon_res_list[3]
elif len(icon_res_list) >= 5 or self._config.get("model") == "us-p": elif len(icon_res_list) >= 5 or self._config.get("model") == "us-p":
icon_res = "".join(icon_res_list) + "~"*4*(8-len(icon_res_list)) icon_res = "".join(icon_res_list) + "~"*4*(8-len(icon_res_list))
currently_translation = get_translation(self._locale, "frontend.ui.card.climate.currently") currently_translation = get_translation(self._locale, "frontend.ui.card.climate.currently")
state_translation = get_translation(self._locale, "frontend.ui.panel.config.devices.entities.state") state_translation = get_translation(self._locale, "frontend.ui.panel.config.devices.entities.state")
action_translation = get_translation(self._locale, "frontend.ui.card.climate.operation").replace(' ','\r\n') action_translation = get_translation(self._locale, "frontend.ui.card.climate.operation").replace(' ','\r\n')
detailPage = "1" detailPage = "1"
if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in entity.attributes): if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in entity.attributes):
detailPage = "0" detailPage = "0"
@@ -534,7 +571,7 @@ class LuiPagesGen(object):
command = f"entityUpd~Not found~{navigation}" command = f"entityUpd~Not found~{navigation}"
else: else:
entity = apis.ha_api.get_entity(item) entity = apis.ha_api.get_entity(item)
heading = title if title != "unknown" else entity.attributes.friendly_name heading = title if title != "unknown" else entity.attributes['friendly_name']
# get data from homeassistant # get data from homeassistant
data_raw = apis.ha_api.get_history(entity_id = item, days = 7) data_raw = apis.ha_api.get_history(entity_id = item, days = 7)
@@ -581,12 +618,12 @@ class LuiPagesGen(object):
else: else:
media_icon = self.generate_entities_item(entity, "cardGrid") media_icon = self.generate_entities_item(entity, "cardGrid")
ha_entity = apis.ha_api.get_entity(entityId) ha_entity = apis.ha_api.get_entity(entityId)
heading = title if title != "unknown" else ha_entity.attributes.friendly_name heading = title if title != "unknown" else ha_entity.attributes['friendly_name']
title = get_attr_safe(ha_entity, "media_title", "") title = get_attr_safe(ha_entity, "media_title", "")
author = get_attr_safe(ha_entity, "media_artist", "") author = get_attr_safe(ha_entity, "media_artist", "")
volume = int(get_attr_safe(ha_entity, "volume_level", 0)*100) volume = int(get_attr_safe(ha_entity, "volume_level", 0)*100)
iconplaypause = get_icon_id("pause") if ha_entity.state == "playing" else get_icon_id("play") iconplaypause = get_icon_id("pause") if ha_entity.state == "playing" else get_icon_id("play")
bits = ha_entity.attributes.supported_features bits = ha_entity.attributes['supported_features']
onoffbutton = "disable" onoffbutton = "disable"
if bits & 0b10000000: if bits & 0b10000000:
if ha_entity.state == "off": if ha_entity.state == "off":
@@ -604,7 +641,7 @@ class LuiPagesGen(object):
item_str = "" item_str = ""
for item in entities: for item in entities:
item_str += self.generate_entities_item(item, "cardGrid") item_str += self.generate_entities_item(item, "cardGrid")
bck_override = entity.iconOverride bck_override = entity.iconOverride
if entity.status is not None: if entity.status is not None:
bck_entity = entity.entityId bck_entity = entity.entityId
@@ -612,14 +649,14 @@ class LuiPagesGen(object):
entity.iconOverride = "mdi:speaker" entity.iconOverride = "mdi:speaker"
item_str += self.generate_entities_item(entity, "cardGrid") item_str += self.generate_entities_item(entity, "cardGrid")
entity.iconOverride = bck_override entity.iconOverride = bck_override
if entity.status is not None: if entity.status is not None:
entity.entityId = bck_entity entity.entityId = bck_entity
command = f"entityUpd~{heading}~{navigation}~{entityId}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{item_str}" command = f"entityUpd~{heading}~{navigation}~{entityId}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{item_str}"
self._send_mqtt_msg(command) self._send_mqtt_msg(command)
def generate_alarm_page(self, navigation, title, entity, overwrite_supported_modes, alarmBtn): def generate_alarm_page(self, navigation, title, entity, overwrite_supported_modes, alarmBtn):
item = entity.entityId item = entity.entityId
if not apis.ha_api.entity_exists(item): if not apis.ha_api.entity_exists(item):
@@ -636,7 +673,7 @@ class LuiPagesGen(object):
if not entity.attributes.get("code_arm_required", False): if not entity.attributes.get("code_arm_required", False):
numpad = "disable" numpad = "disable"
if overwrite_supported_modes is None: if overwrite_supported_modes is None:
bits = entity.attributes.supported_features bits = entity.attributes['supported_features']
if bits & 0b000001: if bits & 0b000001:
supported_modes.append("arm_home") supported_modes.append("arm_home")
if bits & 0b000010: if bits & 0b000010:
@@ -675,7 +712,7 @@ class LuiPagesGen(object):
#add button to show sensor state #add button to show sensor state
add_btn = "" add_btn = ""
if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None: if entity.attributes.get("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])}~"
if alarmBtn is not None and type(alarmBtn) is dict: if alarmBtn is not None and type(alarmBtn) is dict:
entity = alarmBtn.get("entity") entity = alarmBtn.get("entity")
@@ -686,8 +723,8 @@ class LuiPagesGen(object):
else: else:
icon_color = rgb_dec565([243,179,0]) icon_color = rgb_dec565([243,179,0])
add_btn=f"{iconnav}~{icon_color}~{entity}" add_btn=f"{iconnav}~{icon_color}~{entity}"
# add padding to arm buttons # add padding to arm buttons
arm_buttons = "" arm_buttons = ""
for b in supported_modes: for b in supported_modes:
@@ -697,12 +734,12 @@ class LuiPagesGen(object):
arm_buttons += "~"*((4-len(supported_modes))*2) arm_buttons += "~"*((4-len(supported_modes))*2)
command = f"entityUpd~{title}~{navigation}~{item}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}" command = f"entityUpd~{title}~{navigation}~{item}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}"
self._send_mqtt_msg(command) self._send_mqtt_msg(command)
def generate_unlock_page(self, navigation, item, title, destination, pin): def generate_unlock_page(self, navigation, item, title, destination, pin):
color = rgb_dec565([255,0,0]) color = rgb_dec565([255,0,0])
icon = get_icon_id("lock") icon = get_icon_id("lock")
supported_modes = ["cardUnlock-unlock"] supported_modes = ["cardUnlock-unlock"]
# add padding to arm buttons # add padding to arm buttons
arm_buttons = "" arm_buttons = ""
for b in supported_modes: for b in supported_modes:
@@ -741,8 +778,8 @@ class LuiPagesGen(object):
if (time.time()-card.last_update) < card.cooldown: if (time.time()-card.last_update) < card.cooldown:
return return
card.last_update = time.time() card.last_update = time.time()
leftBtn = "delete~~~~~" leftBtn = "delete~~~~~"
if card.uuid_prev is not None: if card.uuid_prev is not None:
leftBtn = self.generate_entities_item(Entity( leftBtn = self.generate_entities_item(Entity(
@@ -779,6 +816,8 @@ class LuiPagesGen(object):
if send_page_type: if send_page_type:
if card.cardType == "cardGrid" and len(card.entities) > 6: if card.cardType == "cardGrid" and len(card.entities) > 6:
card.cardType = "cardGrid2" card.cardType = "cardGrid2"
if card.cardType == "cardGrid1":
card.cardType = "cardGrid"
self.page_type(card.cardType) self.page_type(card.cardType)
# send sleep timeout if there is one configured for the current card # send sleep timeout if there is one configured for the current card
@@ -786,9 +825,9 @@ class LuiPagesGen(object):
self._send_mqtt_msg(f"timeout~{card.sleepTimeout}") self._send_mqtt_msg(f"timeout~{card.sleepTimeout}")
else: else:
self._send_mqtt_msg(f'timeout~{self._config.get("sleepTimeout")}') self._send_mqtt_msg(f'timeout~{self._config.get("sleepTimeout")}')
temp_unit = card.raw_config.get("temperatureUnit", "celsius") temp_unit = card.raw_config.get("temperatureUnit", "celsius")
if card.cardType in ["cardEntities", "cardGrid", "cardGrid2"]: if card.cardType in ["cardEntities", "cardGrid", "cardGrid1","cardGrid2"]:
self.generate_entities_page(navigation, card.title, card.entities, card.cardType, temp_unit) self.generate_entities_page(navigation, card.title, card.entities, card.cardType, temp_unit)
return return
if card.cardType == "cardThermo": if card.cardType == "cardThermo":
@@ -840,25 +879,26 @@ class LuiPagesGen(object):
color_temp = "disable" color_temp = "disable"
color = "disable" color = "disable"
effect_supported = "disable" effect_supported = "disable"
supported_color_modes = entity.attributes['supported_color_modes']
if "onoff" not in entity.attributes.supported_color_modes:
if "onoff" not in supported_color_modes:
brightness = 0 brightness = 0
if entity.state == "on": if entity.state == "on":
if "brightness" in entity.attributes and entity.attributes.brightness: if brightness := entity.attributes.get("brightness"):
# scale 0-255 brightness from ha to 0-100 # scale 0-255 brightness from ha to 0-100
brightness = int(scale(entity.attributes.brightness,(0,255),(0,100))) brightness = int(scale(brightness, (0,255), (0,100)))
else: else:
brightness = "disable" brightness = "disable"
if "color_temp" in entity.attributes.supported_color_modes and entity.attributes.supported_color_modes: if "color_temp" in supported_color_modes:
if "color_temp" in entity.attributes and entity.attributes.color_temp: if color_temp := entity.attributes.get("color_temp"):
# scale ha color temp range to 0-100 # scale ha color temp range to 0-100
color_temp = int(scale(entity.attributes.color_temp,(entity.attributes.min_mireds, entity.attributes.max_mireds),(0,100))) color_temp = int(scale(color_temp, (entity.attributes['min_mireds'], entity.attributes['max_mireds']),(0, 100)))
else: else:
color_temp = "unknown" color_temp = "unknown"
else: else:
color_temp = "disable" color_temp = "disable"
list_color_modes = ["xy", "rgb", "rgbw", "hs"] list_color_modes = ["xy", "rgb", "rgbw", "hs"]
if any(item in list_color_modes for item in entity.attributes.supported_color_modes): if any(item in list_color_modes for item in supported_color_modes):
color = "enable" color = "enable"
else: else:
color = "disable" color = "disable"
@@ -868,20 +908,20 @@ class LuiPagesGen(object):
brightness_translation = get_translation(self._locale, "frontend.ui.card.light.brightness") brightness_translation = get_translation(self._locale, "frontend.ui.card.light.brightness")
color_temp_translation = get_translation(self._locale, "frontend.ui.card.light.color_temperature") color_temp_translation = get_translation(self._locale, "frontend.ui.card.light.color_temperature")
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{switch_val}~{brightness}~{color_temp}~{color}~{color_translation}~{color_temp_translation}~{brightness_translation}~{effect_supported}", force=is_open_detail) self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{switch_val}~{brightness}~{color_temp}~{color}~{color_translation}~{color_temp_translation}~{brightness_translation}~{effect_supported}", force=is_open_detail)
def generate_shutter_detail_page(self, entity_id, is_open_detail=False): def generate_shutter_detail_page(self, entity_id, is_open_detail=False):
entity = apis.ha_api.get_entity(entity_id) entity = apis.ha_api.get_entity(entity_id)
entityType = "cover" entityType = "cover"
device_class = entity.attributes.get("device_class", "window") device_class = entity.attributes.get("device_class", "window")
icon_id = get_icon_ha(entity_id) icon_id = get_icon_ha(entity_id)
pos = entity.attributes.get("current_position") pos = entity.attributes.get("current_position")
if pos is None: if pos is None:
pos_status = entity.state pos_status = entity.state
pos = "disable" pos = "disable"
else: else:
pos_status = pos pos_status = pos
pos_translation = "" pos_translation = ""
icon_up = "" icon_up = ""
icon_stop = "" icon_stop = ""
@@ -898,7 +938,7 @@ class LuiPagesGen(object):
iconTiltRightStatus = "disable" iconTiltRightStatus = "disable"
tilt_pos = "disable" tilt_pos = "disable"
bits = entity.attributes.supported_features bits = entity.attributes['supported_features']
# position supported # position supported
if bits & 0b00001111: if bits & 0b00001111:
@@ -985,7 +1025,7 @@ class LuiPagesGen(object):
if modes: if modes:
modes_out += f"{heading}~{mode}~{cur_mode}~{modes_res}~" modes_out += f"{heading}~{mode}~{cur_mode}~{modes_res}~"
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~{icon_id}~{icon_color}~{modes_out}", force=is_open_detail) self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~{icon_id}~{icon_color}~{modes_out}", force=is_open_detail)
def generate_input_select_detail_page(self, entity_id, is_open_detail=False): def generate_input_select_detail_page(self, entity_id, is_open_detail=False):
options_list = None options_list = None
@@ -1049,8 +1089,9 @@ class LuiPagesGen(object):
label2 = get_translation(self._locale, "frontend.ui.card.timer.actions.cancel") label2 = get_translation(self._locale, "frontend.ui.card.timer.actions.cancel")
label3 = get_translation(self._locale, "frontend.ui.card.timer.actions.finish") label3 = get_translation(self._locale, "frontend.ui.card.timer.actions.finish")
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{entity_id}~{min_remaining}~{sec_remaining}~{editable}~{action1}~{action2}~{action3}~{label1}~{label2}~{label3}", force=is_open_detail) self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{entity_id}~{min_remaining}~{sec_remaining}~{editable}~{action1}~{action2}~{action3}~{label1}~{label2}~{label3}", force=is_open_detail)
def send_message_page(self, ident, heading, msg, b1, b2): def send_message_page(self, ident, heading, msg, b1, b2):
self._send_mqtt_msg(f"pageType~popupNotify") self._send_mqtt_msg(f"pageType~popupNotify")
self._send_mqtt_msg(f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0") self._send_mqtt_msg(f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")

View File

@@ -1,4 +1,4 @@
import hassapi as hass import adbase as ad
from luibackend.config import LuiBackendConfig from luibackend.config import LuiBackendConfig
from luibackend.controller import LuiController from luibackend.controller import LuiController
@@ -6,15 +6,19 @@ from luibackend.mqtt import LuiMqttListener, LuiMqttSender
from luibackend.updater import Updater from luibackend.updater import Updater
import apis import apis
import json
from typing import Literal
class NsPanelLovelaceUIManager(hass.Hass): class NsPanelLovelaceUIManager(ad.ADBase):
def initialize(self): def initialize(self):
self.log('Starting') self.adapi = self.get_ad_api()
apis.ha_api = self self.adapi.log('Starting')
apis.ad_api = self.adapi
apis.ha_api = self.get_plugin_api("HASS")
apis.mqtt_api = self.get_plugin_api("MQTT") apis.mqtt_api = self.get_plugin_api("MQTT")
cfg = self._cfg = LuiBackendConfig(self, self.args["config"]) cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"])
use_api = cfg.get("use_api") == True use_api = cfg.get("use_api") == True
@@ -22,14 +26,15 @@ class NsPanelLovelaceUIManager(hass.Hass):
topic_recv = cfg.get("panelRecvTopic") topic_recv = cfg.get("panelRecvTopic")
api_panel_name = cfg.get("panelName") api_panel_name = cfg.get("panelName")
api_device_id = cfg.get("panelDeviceId") api_device_id = cfg.get("panelDeviceId")
quiet = cfg.get("quiet")
mqttsend = LuiMqttSender(self, use_api, topic_send, api_panel_name) mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet)
controller = LuiController(cfg, mqttsend.send_mqtt_msg) self._controller = LuiController(cfg, mqttsender.send_mqtt_msg)
desired_tasmota_driver_version = 8 desired_tasmota_driver_version = 8
desired_display_firmware_version = 53 desired_display_firmware_version = 53
version = "v4.3.3" version = "v4.7.3"
model = cfg.get("model") model = cfg.get("model")
if model == "us-l": if model == "us-l":
@@ -41,11 +46,35 @@ class NsPanelLovelaceUIManager(hass.Hass):
desired_tasmota_driver_url = cfg._config.get("berryURL", "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be") desired_tasmota_driver_url = cfg._config.get("berryURL", "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
mode = cfg.get("updateMode") mode = cfg.get("updateMode")
updater = Updater(self.log, mqttsend, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url) updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
# Request Tasmota Driver Version # Request Tasmota Driver Version
updater.request_berry_driver_version() updater.request_berry_driver_version()
LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, controller, updater) LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater)
self.log(f'Started ({version})') self.adapi.log(f'Started ({version})')
#
# helpers
#
def show_card(self, card_key: str) -> None:
"""Used to show card on panel"""
msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"})
topic = self._cfg.get("panelRecvTopic")
self._mqttsender.send_mqtt_msg(msg, topic)
def navigate(self, direction: Literal['up', 'prev', 'next']) -> None:
"""Used to navigate different directions on the panel"""
msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"})
topic = self._cfg.get("panelRecvTopic")
self._mqttsender.send_mqtt_msg(msg, topic)
@property
def current_card(self) -> str:
"""Used to get the panel's current card"""
return self._controller.current_card.key

View File

@@ -93,3 +93,4 @@ Now, to install NSPanel Lovelace UI Backend with HACS, follow these steps:
6. A confirmation panel will appear, click on `Download`, and wait for HACS to 6. A confirmation panel will appear, click on `Download`, and wait for HACS to
proceed with the download proceed with the download
7. The Backend Application is now installed, and HACS will inform you when updates are available 7. The Backend Application is now installed, and HACS will inform you when updates are available

1732
ioBroker/.iobroker/types/javascript.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +0,0 @@
const idAbfalliCal = 'ical.1'; // iCal Instanz zum Abfallkalender
const idZeichenLoeschen = 14; // x Zeichen links vom String abziehen, wenn vor dem Eventname noch Text steht z.B. Strassenname; Standard = 0
const idRestmuellName ='Hausmüll'; // Schwarze Tonne
const idWertstoffName = 'Gelber Sack'; // Gelbe Tonne / Sack
const idPappePapierName = 'Papier'; // Blaue Tonne
const idBioabfaelleName = 'Biomüll'; // Braune Tonne
var i, Muell_JSON, Event2, Color = 0;
for (i = 1; i <= 4; i++) {
if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.date')) {
log(i + '.date nicht vorhanden, wurde erstellt');
createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.date', '',
{
name: parseFloat(i) + '.date',
role: 'state',
type: 'string',
read: true,
write: true,
def: ''
});
};
if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.event')) {
log(i + '.event nicht vorhanden, wurde erstellt');
createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.event', '',
{
name: parseFloat(i) + '.event',
role: 'state',
type: 'string',
read: true,
write: true,
def: ''
});
};
if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.color')) {
log(i + '.color nicht vorhanden, wurde erstellt');
createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.color', 0,
{
name: parseFloat(i) + '.color',
role: 'state',
type: 'number',
read: true,
write: true,
def: 0
});
};
}
function subsequenceFromStartLast(sequence, at1) {
var start = at1;
var end = sequence.length;
return sequence.slice(start, end);
}
on({ id: idAbfalliCal + '.data.table', change: "ne" }, async function () {
for (i = 0; i <= 3; i++) {
Muell_JSON = getState(idAbfalliCal + '.data.table').val;
setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.date'].join('')), getAttr(Muell_JSON, (String(i) + '.date')), false, parseInt(((0) || "").toString(), 10), false);
Event2 = subsequenceFromStartLast(getAttr(Muell_JSON, (String(i) + '.event')), idZeichenLoeschen);
setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.event'].join('')), Event2, false, parseInt(((0) || "").toString(), 10), false);
if (Event2 == idRestmuellName) {
Color = 33840;
} else if (Event2 == idBioabfaelleName) {
Color = 2016;
} else if (Event2 == idPappePapierName) {
Color = 31;
} else if (Event2 == idWertstoffName) {
Color = 65504;
}
setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.color'].join('')), Color, false, parseInt(((0) || "").toString(), 10), false);
}
});

View File

@@ -0,0 +1,224 @@
/*
* @author 2023 @tt-tom
*
* Version 5.1.1
*
* Das Script erstellt die Datenpunkte und Alias für den Abfallkalender im Sonoff NSPanel
* Es wird der iCal Adapter benötigt und eine URL mit Terminen vom Entsorger bzw. eine .ics-Datei mit den Terminen.
* Das Script triggert auf dem bereitgestellten JSON im iCal adapter und füllt die 0_userdata.0 Datenpunkte
* Weitere Informationen findest du in der FAQ auf Github https://github.com/joBr99/nspanel-lovelace-ui/wiki
*
* changelog
* - 06.12.2023 - v5.0.2 add custom name for trashtype
* - 06.12.2023 - v5.1.0 Refactoring
* - 22.01.2024 - v5.1.1 Add tow Events more
*
*
*/
const idTrashData: string = 'ical.0.data.table'; // Datenpunkt mit Daten im JSON Format
const idUserdataAbfallVerzeichnis: string = '0_userdata.0.Abfallkalender'; // Name des Datenpunktverzeichnis unter 0_userdata.0 -> Strandard = 0_userdata.0.Abfallkalender
const idAliasPanelVerzeichnis: string = 'alias.0.NSPanel.allgemein'; //Name PanelVerzeichnis unter alias.0. Standard = alias.0.NSPanel.1
const idAliasAbfallVerzeichnis: string = 'Abfall'; //Name Verzeichnis unterhalb der idPanelverzeichnis Standard = Abfall
const anzahlZeichenLoeschen: number = 14; // x Zeichen links vom String abziehen, wenn vor dem Eventname noch Text steht z.B. Strassenname; Standard = 0
const jsonEventName1: string = 'Hausmüll'; // Vergleichstring für Schwarze Tonne
const customEventName1: string = ''; // benutzerdefinierter Text für schwarze Tonne
const jsonEventName2: string = 'Gelber Sack'; // Vergleichstring für Gelbe Tonne / Sack
const customEventName2: string = ''; // benutzerdefinierter Text für gelbe Tonne
const jsonEventName3: string = 'Papier'; // Vergleichstring für Blaue Tonne
const customEventName3: string = ''; // benutzerdefinierter Text für blaue Tonne
const jsonEventName4: string = 'Biomüll'; // Vergleichstring für Braune Tonne
const customEventName4: string = ''; // benutzerdefinierter Text für braune Tonne
const jsonEventName5: string = 'Treppe'; // Vergleichstring für Event 5
const customEventName5: string = 'Besen schwingen'; // benutzerdefinierter Text für Event 5
const jsonEventName6: string = ''; // Vergleichstring für Event 6
const customEventName6: string = ''; // benutzerdefinierter Text für Event 6
const Debug: boolean = false;
// ------------------------- Trigger zum füllen der 0_userdata Datenpunkte aus dem json vom ical Adapter -------------------------------
// Trigger auf JSON Datenpunkt
on({ id: idTrashData, change: 'ne' }, async function () {
JSON_auswerten();
});
// ------------------------------------- Ende Trigger ------------------------------------
// ------------------------------------- Funktion JSON auswerten und DP füllen -------------------------------
async function JSON_auswerten() {
try {
let trashJSON: any;
let instanzName: any;
let eventName: string;
let eventDatum: string;
let eventStartdatum: string;
let farbNummer: number = 0;
let farbString: string;
let abfallNummer: number = 1;
trashJSON = getState(idTrashData).val;
instanzName = idTrashData.split('.');
if (Debug) log('Rohdaten von Instanz ' + instanzName[0] + ': ' + JSON.stringify(trashJSON), 'info')
if (Debug) log('Anzahl Trash - Daten: ' + trashJSON.length, 'info');
for (let i = 0; i < trashJSON.length; i++) {
if (abfallNummer === 7) {
if (Debug) log('Alle Abfall-Datenpunkte gefüllt', 'warn');
break;
}
log('Daten vom ical Adapter werden ausgewertet', 'info');
eventName = getAttr(trashJSON, (String(i) + '.event')).slice(anzahlZeichenLoeschen, getAttr(trashJSON, (String(i) + '.event')).length);
// Leerzeichen vorne und hinten löschen
eventName = eventName.trimEnd();
eventName = eventName.trimStart();
eventDatum = getAttr(trashJSON, (String(i) + '.date'));
eventStartdatum = getAttr(trashJSON, (String(i) + '._date'));
let d: Date = currentDate();
let d1: Date = new Date(eventStartdatum);
if (Debug) log('--------- Nächster Termin wird geprüft ---------', 'info');
//if (Debug) log(d + ' ' + d1, 'info');
if (Debug) log('Startdatum UTC: ' + eventStartdatum, 'info');
if (Debug) log('Datum: ' + eventDatum, 'info');
if (Debug) log('Event: ' + eventName, 'info');
if (Debug) log('Kontrolle Leerzeichen %' + eventName + '%', 'info');
if (d.getTime() <= d1.getTime()) {
if ((eventName == jsonEventName1) || (eventName == jsonEventName2) || (eventName == jsonEventName3) || (eventName == jsonEventName4) || (eventName == jsonEventName5) || (eventName == jsonEventName6)) {
switch (eventName) {
case jsonEventName1:
farbNummer = 33840;
if (customEventName1 != '') {
eventName = customEventName1;
if (Debug) log('Event customName: ' + eventName, 'info');
};
break;
case jsonEventName2:
farbNummer = 65504;
if (customEventName2 != '') {
eventName = customEventName2;
if (Debug) log('Event customName: ' + eventName, 'info');
};
break;
case jsonEventName3:
farbNummer = 31;
if (customEventName3 != '') {
eventName = customEventName3
if (Debug) log('Event customName: ' + eventName, 'info');
};
break;
case jsonEventName4:
farbNummer = 2016;
if (customEventName4 != '') {
eventName = customEventName4;
if (Debug) log('Event customName: ' + eventName, 'info');
};
break;
case jsonEventName5:
farbNummer = 2016;
if (customEventName5 != '') {
eventName = customEventName5;
if (Debug) log('Event customName: ' + eventName, 'info');
};
break;
case jsonEventName6:
farbNummer = 2016;
if (customEventName6 != '') {
eventName = customEventName6
if (Debug) log('Event customName: ' + eventName, 'info');
};
break;
}
//if (farbString != undefined) farbNummer = rgb_dec565(hex_rgb(farbString));
setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.date', eventDatum);
setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.event', eventName);
setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.color', farbNummer);
//if (Debug) log('farbString: ' + farbString + ' farbNummer: ' + farbNummer, 'info');
if (Debug) log('Abfallnummer: ' + abfallNummer, 'info');
abfallNummer += 1
} else {
if (Debug) log('Kein Abfalltermin => Event passt mit keinem Abfallnamen überein.', 'warn');
}
} else {
if (Debug) log('Termin liegt vor dem heutigen Tag', 'warn');
}
}
} catch (err) {
log('error at subscrption: ' + err.message, 'warn');
}
};
// ------------------------------------- Ende Funktion JSON ------------------------------
// ------------------------------------- Funktion zur Prüfung und Erstellung der Datenpunkte in 0_userdata.0 und alias.0 -----------------------
async function Init_Datenpunkte() {
try {
for (let i = 1; i <= 6; i++) {
if (existsObject(idUserdataAbfallVerzeichnis + '.' + String(i)) == false) {
log('Datenpunkt ' + idUserdataAbfallVerzeichnis + '.' + String(i) + ' werden angelegt', 'info')
await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.date', '', { type: 'string' });
await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.event', '', { type: 'string' });
await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.color', 0, { type: 'number' });
setObject(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis, { type: 'device', common: { name: { de: 'Abfall', en: 'Trash' } }, native: {} });
setObject(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i), { type: 'channel', common: { role: 'warning', name: { de: 'Ereignis ' + String(i), en: 'Event' + String(i) } }, native: {} });
await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.TITLE', idUserdataAbfallVerzeichnis + '.' + String(i) + '.event', true, <iobJS.StateCommon>{ type: 'string', role: 'weather.title.short', name: { de: 'TITEL', en: 'TITLE' } });
await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.LEVEL', idUserdataAbfallVerzeichnis + '.' + String(i) + '.color', true, <iobJS.StateCommon>{ type: 'number', role: 'value.warning', name: { de: 'LEVEL', en: 'LEVEL' } });
await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.INFO', idUserdataAbfallVerzeichnis + '.' + String(i) + '.date', true, <iobJS.StateCommon>{ type: 'string', role: 'weather.title', name: { de: 'INFO', en: 'INFO' } });
log('Fertig', 'info')
} else {
log('Datenpunkt ' + idUserdataAbfallVerzeichnis + '.' + String(i) + ' vorhanden', 'info')
}
}
log('Startabfrage der Daten', 'info');
JSON_auswerten();
} catch (err) {
log('error at function Init_Datenpunkte: ' + err.message, 'warn');
}
}
Init_Datenpunkte();
// --------------------------- Ende Funktion Datenpunkte ------------------------------------------------
// --------------------------- Zusatzfuktionen -------------------------------------------------------------
function currentDate() {
let d: Date = new Date();
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}
function rgb_dec565(rgb: RGB): number {
//return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31)));
return ((rgb.red >> 3) << 11) | ((rgb.green >> 2)) << 5 | ((rgb.blue) >> 3);
}
function hex_rgb(colorhex: string): RGB {
let r = parseInt(colorhex.substring(1, 3), 16);
let g = parseInt(colorhex.substring(3, 5), 16);
let b = parseInt(colorhex.substring(5, 7), 16);
return { red: r, green: g, blue: b };
}
type RGB = {
red: number,
green: number,
blue: number
};
// -------------------- Ende Zudatzfunktionen --------------------------------------------------------------------------

View File

@@ -971,12 +971,37 @@
</value> </value>
</block> </block>
</value> </value>
<value name="VALUE"> <value name="VALUE">
<shadow type="logic_boolean" id="I4PsJQb;6k+70^g*Xt/}"> <shadow type="logic_boolean" id="I4PsJQb;6k+70^g*Xt/}">
<field name="BOOL">TRUE</field> <field name="BOOL">TRUE</field>
</shadow> </shadow>
<block type="math_random_float" id="C5/h)jq=yPM?,9J=(w65"></block> <block type="text_join" id="XdhGC7#MxGw|KhC1x#MY">
</value> <mutation items="2"></mutation>
<value name="ADD0">
<block type="text" id="[(_1;{xE-xfzeB4]$uk;">
<field name="TEXT">ID</field>
</block>
</value>
<value name="ADD1">
<block type="convert_tostring" id="g{jZOA*6Clhc5`9::h.S">
<value name="VALUE">
<block type="math_random_int" id="SXG?j1]Jza!2fg[(cl!i">
<value name="FROM">
<shadow type="math_number" id="#/-;$~`{=}8wYY$kbvA9">
<field name="NUM">1</field>
</shadow>
</value>
<value name="TO">
<shadow type="math_number" id="0x8~a;asHsiJ2Its%!VJ">
<field name="NUM">100</field>
</shadow>
</value>
</block>
</value>
</block>
</value>
</block>
</value>
<value name="DELAY_MS"> <value name="DELAY_MS">
<shadow type="math_number" id="+6#n%fO}e4h%;FhKPV0c"> <shadow type="math_number" id="+6#n%fO}e4h%;FhKPV0c">
<field name="NUM">0</field> <field name="NUM">0</field>

View File

@@ -0,0 +1,44 @@
const dp_userdata: string = '0_userdata.0.NSPanel';
const dp_alias: string = 'alias.0.NSPanel';
// dpAction wird wenn der Wecker gestellt wird auf false geschaltet
// dpAction wird wenn die Weckzeit erreicht ist auf true geschaltet
// Der nachfolgende Datenpunkt muss manuell erstellt werden...
const dpAction: string = '0_userdata.0.example_boolean';
const Debug = true;
let time: number;
let scheduleAlarmTime: any = null;
on({ id: dp_userdata + '.AlarmTime.State', change: 'ne' }, async (obj) => {
time = getState(dp_userdata + '.AlarmTime.Time').val;
if (Debug) log('Uhrzeit: ' + time, 'info');
if ('paused' == obj.state.val) {
(function () { if (scheduleAlarmTime) {
clearSchedule(scheduleAlarmTime);
scheduleAlarmTime = null;
}
});
} else if ('active' == obj.state.val) {
let stunde: number = Math.floor(time / 60);
let minute: number = time % 60;
if (Debug) log('Weckzeit: ' + ('0' + stunde).slice(-2) + ':' + ('0' + minute).slice(-2), 'info');
scheduleAlarmTime = schedule(minute + ' ' + stunde + ' * * *', async () => {
await setStateAsync(dpAction, <iobJS.State>{ val: true, ack: true });
await setStateAsync(dp_userdata + '.AlarmTime.State', <iobJS.State>{ val: 'paused', ack: true });
});
}
});
async function Init_Datenpunkte() {
if (existsState(dp_alias + '.AlarmTime.ACTUAL') == false) {
await createStateAsync(dp_userdata + '.AlarmTime.Time', '0', { type: 'number' });
await createStateAsync(dp_userdata + '.AlarmTime.State', 'paused', { type: 'string' });
setObject(dp_alias + '.AlarmTime', { type: 'channel', common: { role: 'value.alarmtime', name: 'Alarmtime' }, native: {} });
await createAliasAsync(dp_alias + '.AlarmTime.ACTUAL', dp_userdata + '.AlarmTime.Time', true, <iobJS.StateCommon>{ type: 'number', role: 'state', name: 'ACTUAL' });
await createAliasAsync(dp_alias + '.AlarmTime.STATE', dp_userdata + '.AlarmTime.State', true, <iobJS.StateCommon>{ type: 'string', role: 'state', name: 'STATE' });
log("<PageItem>{id: '"+ dp_alias + ".AlarmTime', name: 'Wecker', onColor: Red, offColor: Green, useColor: true}", 'info');
}
}
Init_Datenpunkte();

View File

@@ -0,0 +1,51 @@
const sourceDP = 'alias.0.Wohnzimmer.Heizung.ACTUAL';
const targetDP = '0_userdata.0.Test.chartTest';
const rangeHours = 24;
const maxXAchsisTicks = 6;
const historyInstance = 'history.0';
const factor = 1; // Bei zu großen Werten und negativen Anzeigen im Panel um das 10fache erhöhen
on({id: sourceDP, change: "any"}, async function (obj) {
sendTo(historyInstance, 'getHistory', {
id: sourceDP,
options: {
start: Date.now() - (60 * 60 * 1000 * rangeHours),
end: Date.now(),
count: rangeHours,
limit: rangeHours,
aggregate: 'average'
}
}, function (result) {
var cardChartString = "";
var stepXAchsis = rangeHours / maxXAchsisTicks;
for (var i = 0; i < rangeHours; i++){
var deltaHour = rangeHours - i;
var targetDate = new Date(Date.now() - (deltaHour * 60 * 60 * 1000));
//Check history items for requested hours
for (var j = 0, targetValue = 0; j < result.result.length; j++) {
var valueDate = new Date(result.result[j].ts);
var value = Math.round(result.result[j].val / factor * 10);
if (valueDate > targetDate){
if ((targetDate.getHours() % stepXAchsis) == 0){
cardChartString += targetValue + '^' + targetDate.getHours() + ':00' + '~';
} else {
cardChartString += targetValue + '~';
}
break;
} else {
targetValue = value;
}
}
}
cardChartString = cardChartString.substring(0,cardChartString.length-1);
if (existsState(targetDP) == false ) {
createState(targetDP, cardChartString, true, { type: 'string' });
} else {
setState(targetDP, cardChartString, true);
}
});
});

View File

@@ -0,0 +1,78 @@
const sourceDP = 'alias.0.Wohnzimmer.Heizung.ACTUAL';
const targetDP = '0_userdata.0.Test.chartTest';
const numberOfHoursAgo = 24; // Period of time in hours which shall be visualized
const xAxisTicksEveryM = 60; // Time after x axis gets a tick in minutes
const xAxisLabelEveryM = 240; // Time after x axis is labeled in minutes
const historyInstance = 'history.0';
const Debug = false;
const maxX = 1420;
const limitMeasurements = 35;
createState(targetDP, "", {
name: 'SensorGrid',
desc: 'Sensor Values [~<time>:<value>]*',
type: 'string',
role: 'value',
});
on({id: sourceDP, change: "any"}, async function (obj) {
sendTo(historyInstance, 'getHistory', {
id: sourceDP,
options: {
start: Date.now() - (numberOfHoursAgo * 60 * 60 * 1000 ), //Time in ms: hours * 60m * 60s * 1000ms
end: Date.now(),
count: limitMeasurements,
limit: limitMeasurements,
aggregate: 'average'
}
}, function (result) {
var ticksAndLabels = ""
var coordinates = "";
var cardLChartString = "";
let ticksAndLabelsList = []
var date = new Date();
date.setMinutes(0, 0, 0);
var ts = Math.round(date.getTime() / 1000);
var tsYesterday = ts - (numberOfHoursAgo * 3600);
for (var x = tsYesterday, i = 0; x < ts; x += (xAxisTicksEveryM * 60), i += xAxisTicksEveryM)
{
if (i % xAxisLabelEveryM)
{
ticksAndLabelsList.push(i);
} else
{
var currentDate = new Date(x * 1000);
// Hours part from the timestamp
var hours = "0" + currentDate.getHours();
// Minutes part from the timestamp
var minutes = "0" + currentDate.getMinutes();
// Seconds part from the timestamp
var seconds = "0" + currentDate.getSeconds();
var formattedTime = hours.slice(-2) + ':' + minutes.slice(-2);
ticksAndLabelsList.push(String(i) + "^" + formattedTime);
}
}
ticksAndLabels = ticksAndLabelsList.join("+");
let list = [];
let offSetTime = Math.round(result.result[0].ts / 1000);
let counter = Math.round((result.result[result.result.length -1 ].ts / 1000 - offSetTime) / maxX);
for (var i = 0; i < result.result.length; i++)
{
var time = Math.round(((result.result[i].ts / 1000) - offSetTime) / counter);
var value = Math.round(result.result[i].val * 10);
if ((value != null) && (value != 0)){
list.push(time + ":" + value)
}
}
coordinates = list.join("~");
cardLChartString = ticksAndLabels + '~' + coordinates
setState(targetDP, cardLChartString, true);
if (Debug) console.log(cardLChartString);
});
});

View File

@@ -0,0 +1,130 @@
/**
* Dieses Script fragt eine influxDb ab, um Daten für die cardLcart (Liniendiagramm) zuberechnen und im richtigen Format bereitzustellen.
* Es erstellt automatisch einen Datenpunkt.
* Die Abfrage muss ggf. angepasst werden. Aktuell ermittelt sie Werte der letzten 24h, zu Stundenwerten zusammengefasst.
*/
const Debug = false; // true für erweiterte Ausgaben im Log
const NSPanel_Path = '0_userdata.0.NSPanel.';
const Path = NSPanel_Path + 'Influx2NSPanel.cardLChart.';
const InfluxInstance = 'influxdb.0';
const influxDbBucket = 'storage_short';
const numberOfHoursAgo = 24;
const xAxisTicksEveryM = 60;
const xAxisLabelEveryM = 240;
//
const sensors : Record<string, Record <string, string>> = {};
/**
* Hier werden die Sensoren festgelegt nach flogendem Schema
*
* sensors[Datenpunkt(kompletter Pfad) des Messwertes'] = {'taget': 'Name des Datenpunkt für die Chartwerte', 'measurement': 'genutzter Alias in der Influxdb für den Messwert'};
*
* Wenn der Wert in der Datenbank keinen Alias hat bleibt der Wert 'measurement': weg.
* Jeder Messwert bekommt einen eigenen sensors[...] = {'target':....}
*/
sensors['netatmo-crawler.0.stationData.1.temperature'] = {'target':'AussenTemp', 'measurement':'wetter.temperatur'};
// ##### ab hier keine Änderungen mehr nötig #####
// create data source for NsPanel on script startup
Object.keys(sensors).forEach(async id => {
await generateDateAsync(id);
});
// then listen to the sensors and update the data source states accordingly
on({ id: Object.keys(sensors), change: 'any' }, async function (obj) {
if (!obj.id) {
return;
}
await generateDateAsync(obj.id);
});
//__________________________
// Beschreibe diese Funktion: Daten generieren
async function generateDateAsync(sensorId: string) {
let idMeasurement = sensors[sensorId].measurement;
if (idMeasurement =='' ||idMeasurement == undefined) {idMeasurement = sensorId};
const dataPointId:string = Path + sensors[sensorId].target +'.ACTUAL';
if (Debug) log(`(f) generateDateAsync: ${sensorId} ${dataPointId} > ${idMeasurement}`);
const query =[
'from(bucket: "' + influxDbBucket + '")',
'|> range(start: -' + numberOfHoursAgo + 'h)',
'|> filter(fn: (r) => r["_measurement"] == "' + idMeasurement + '")',
'|> filter(fn: (r) => r["_field"] == "value")',
'|> drop(columns: ["from", "ack", "q"])',
'|> aggregateWindow(every: 1h, fn: last, createEmpty: false)',
'|> map(fn: (r) => ({ r with _rtime: int(v: r._time) - int(v: r._start)}))',
'|> yield(name: "_result")'].join('');
if (Debug) console.log('Query: ' + query);
const result : any = await sendToAsync(InfluxInstance, 'query', query);
if (result.error) {
console.error(result.error);
return;
}
if (Debug) console.log(JSON.stringify(result));
const numResults = result.result.length;
let coordinates : string = '';
for (let r = 0; r < numResults; r++)
{
const list : string[] = [];
const numValues = result.result[r].length;
for (let i = 0; i < numValues; i++)
{
const time = Math.round(result.result[r][i]._rtime/1000/1000/1000/60);
const value = Math.round(result.result[r][i]._value * 10);
list.push(time + ":" + value);
}
coordinates = list.join("~");
if (Debug) console.log(coordinates);
}
const ticksAndLabelsList : string[] = []
const date = new Date();
date.setMinutes(0, 0, 0);
const ts = Math.round(date.getTime() / 1000);
const tsYesterday = ts - (numberOfHoursAgo * 3600);
if (Debug) console.log('Iterate from ' + tsYesterday + ' to ' + ts + ' stepsize=' + (xAxisTicksEveryM * 60));
for (let x = tsYesterday, i = 0; x < ts; x += (xAxisTicksEveryM * 60), i += xAxisTicksEveryM)
{
if ((i % xAxisLabelEveryM))
ticksAndLabelsList.push('' + i);
else
{
const currentDate = new Date(x * 1000);
// Hours part from the timestamp
const hours = "0" + String(currentDate.getHours());
// Minutes part from the timestamp
const minutes = "0" + String(currentDate.getMinutes());
const formattedTime = hours.slice(-2) + ':' + minutes.slice(-2);
ticksAndLabelsList.push(String(i) + "^" + formattedTime);
}
}
if (Debug) console.log('Ticks & Label: ' + ticksAndLabelsList);
if (Debug) console.log('Coordinates: ' + coordinates);
await setOrCreate(dataPointId, ticksAndLabelsList.join("+") + '~' + coordinates, true);
}
//__________________________
// Beschreibe diese Funktion: Datenpunkte anlegen bzw. schreiben
async function setOrCreate(id : string, value : any, ack : boolean) {
if (!(await existsStateAsync(id))) {
await createStateAsync(id, value, {
name: id.split('.').reverse()[0],
desc: 'Sensor Values [~<time>:<value>]*',
type: 'string',
role: 'value',
});
} else {
await setStateAsync(id, value, ack);
}
}

View File

@@ -0,0 +1,54 @@
/**
* generate an JSON for display Power-Card on NSPanel
* Source: https://github.com/joBr99/nspanel-lovelace-ui/wiki/ioBroker-Card-Definitionen-(Seiten)#cardpower-ab-ts-script-v341
* Version: 0.1 - L4rs
*/
schedule("* * * * *", function () {
// Definition der Datenpunkte für das JSON der POWER-Card und der anzuzeigenden Leistungswerte
var powerCardJson = "0_userdata.0.NSPanel.Energie.PowerCard",
pwr1 = "", // Batterie
pwr2 = Math.round(getState("mqtt.0.SmartHome.Energie.PV.openDTU.114180710360.0.power").val), // Solar
pwr3 = "", // Wind
pwr4 = "", // Verbraucher
pwr5 = Math.round(getState("hm-rpc.0.MEQ0706303.1.POWER").val), // Stromnetz
pwr6 = 0, // Auto
pwrHome = Math.round(pwr5 - pwr2); // Berechnung des Energiefluss anstelle eines Datenpunktes
// Definition der Keys im JSON
var keys = ["id", "value", "unit", "icon", "iconColor", "speed"];
// Definition der "Kacheln", inkl. StandardIcon. Es können alle Icon aus dem Iconmapping genutzt werden.
// Kacheln die nicht genutzt werden sollen, müssen wie z.b. item1 formatiert sein
var home = [0, pwrHome, "W", "home-lightning-bolt-outline", 0]; // Icon home
var item1 = [1, pwr1, "", "", 0, ""]; // Icon battery-charging-60
var item2 = [2, pwr2, "W", "solar-power-variant-outline", 3, pwr2 > 0 ? -2 : 0]; // Icon solar-power-variant
var item3 = [3, pwr3, "", "", 0, ""]; // Icon wind-turbine
var item4 = [4, pwr4, "", "", 0, ""]; // Icon shape
var item5 = [5, pwr5, "W", "transmission-tower", 10, 10]; // Icon transmission-tower
var item6 = [6, pwr6, "kW", "car-electric-outline", 5, 0]; // Icon car
/**
* JSON generieren und in den Datenpunkt schreiben,
*
* --- ab hier keine Änderungen mehr ---
*/
function func(tags, values) {
return Object.assign(
...tags.map((element, index) => ({ [element]: values[index] }))
);
}
setState(
powerCardJson,
JSON.stringify([
func(keys, home),
func(keys, item1),
func(keys, item2),
func(keys, item3),
func(keys, item4),
func(keys, item5),
func(keys, item6),
])
);
});

View File

@@ -0,0 +1,46 @@
const dp_userdata: string = '0_userdata.0.NSPanel';
const dp_alias: string = 'alias.0.NSPanel';
// Der nachfolgende Datenpunkt muss manuell angelegt werden
const dpAction: string = '0_userdata.0.example_boolean'; // anpassen
const Debug = false;
let intervallCounter: any;
let sec_timer = getState(dp_userdata + '.Countdown.Time').val;
on({ id: dp_userdata + '.Countdown.State', change: 'ne' }, async (obj) => {
switch (obj.state.val) {
case 'active':
if (intervallCounter) { clearInterval(intervallCounter); intervallCounter = null; };
intervallCounter = setInterval(async () => {
if (getState(dp_userdata + '.Countdown.Time').val > 0) {
sec_timer = getState(dp_userdata + '.Countdown.Time').val;
setState(dp_userdata + '.Countdown.Time', (sec_timer - 1), false);
} else {
setState(dp_userdata + '.Countdown.Time', 0, false);
setState(dp_userdata + '.Countdown.State', 'idle', false);
// An dieser Stelle kann auch noch eine Meldung an Alexa oder Telegram, etc. erfolgen
}
}, 1000);
break;
default:
if (intervallCounter) { clearInterval(intervallCounter); intervallCounter = null; };
break;
}
});
async function Init_Datenpunkte() {
if (existsState(dp_alias + '.Countdown.ACTUAL') == false) {
await createStateAsync(dp_userdata + '.Countdown.Time', '0', { type: 'number'});
await createStateAsync(dp_userdata + '.Countdown.State', 'paused', { type: 'string' });
setObject(dp_alias + '.Countdown', { type: 'channel', common: { role: 'level.timer', name: 'Countdown' }, native: {} });
await createAliasAsync(dp_alias + '.Countdown.ACTUAL', dp_userdata + '.Countdown.Time', true, <iobJS.StateCommon>{ type: 'number', role: 'state', name: 'ACTUAL' });
await createAliasAsync(dp_alias + '.Countdown.STATE', dp_userdata + '.Countdown.State', true, <iobJS.StateCommon>{ type: 'string', role: 'state', name: 'STATE' });
log("<PageItem>{id: '"+ dp_alias + ".Countdown', name: 'Timer'}", 'info');
}
}
Init_Datenpunkte();

14457
ioBroker/DEV/NSPanelTs.ts Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1047,6 +1047,14 @@
"zh-CN":"空闲", "zh-CN":"空闲",
"zh-TW":"暫停" "zh-TW":"暫停"
}, },
"on":{
"en-US":"On",
"de-DE":"Ein"
},
"off":{
"en-US":"Off",
"de-DE":"Aus"
},
"paused":{ "paused":{
"en-US":"Paused", "en-US":"Paused",
"de-DE":"pausiert", "de-DE":"pausiert",
@@ -2489,6 +2497,14 @@
"vi-VN":"Mật khẩu", "vi-VN":"Mật khẩu",
"zh-CN":"密码", "zh-CN":"密码",
"zh-TW":"密碼" "zh-TW":"密碼"
},
"Wlan enabled":{
"en-US":"Wlan enabled",
"de-DE":"Wlan aktiviert"
},
"Wlan disabled":{
"en-US":"Wlan disabled",
"de-DE":"Wlan deaktiviert"
} }
}, },
"media":{ "media":{
@@ -2533,6 +2549,26 @@
"zh-CN":"没有音乐可以控制", "zh-CN":"没有音乐可以控制",
"zh-TW":"沒有音樂可以控制" "zh-TW":"沒有音樂可以控制"
}, },
"on":{
"en-US":"On",
"de-DE":"An"
},
"off":{
"en-US":"Off",
"de-DE":"Aus"
},
"seek":{
"en-US":"Seek",
"de-DE":"Suchen"
},
"crossfade":{
"en-US":"Crossfade",
"de-DE":"Überblenden"
},
"tools":{
"en-US":"Tools",
"de-DE":"Tools"
},
"speaker":{ "speaker":{
"en-US":"Speakerlist", "en-US":"Speakerlist",
"de-DE":"Wiedergabegeräte", "de-DE":"Wiedergabegeräte",

View File

@@ -2693,5 +2693,21 @@
"update_nextion_tft":{ "update_nextion_tft":{
"en-US":"Update Nextion TFT", "en-US":"Update Nextion TFT",
"de-DE":"Nextion TFT Update" "de-DE":"Nextion TFT Update"
},
"update_message":{
"en-US":"Update Notifications",
"de-DE":"Update Mitteilungen"
},
"scriptname":{
"en-US":"Script name",
"de-DE":"Skriptname"
},
"hiddencards_offon":{
"en-US":"hidden Cards (on/off)",
"de-DE":"ausgeblendete Seiten (an/aus)"
},
"easyview_layout":{
"en-US":"Easyview Layout",
"de-DE":"Einfaches Layout"
} }
} }

28
ioBroker/tsconfig.json Normal file
View File

@@ -0,0 +1,28 @@
{
"compileOnSave": true,
"compilerOptions": {
"noEmit": true,
"allowJs": true,
"checkJs": true,
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"resolveJsonModule": true,
"strict": true,
"noImplicitReturns": true,
"noImplicitAny": false,
"target": "ES2022",
"typeRoots": [
".iobroker/types",
"node_modules/@types"
]
},
"include": [
"**/*.js",
"**/*.ts",
"./.iobroker/types/javascript.d.ts"
],
"exclude": [
"node_modules/**"
]
}

View File

@@ -1,6 +1,6 @@
# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config # https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config
name: NSPanel Lovelace UI Addon name: NSPanel Lovelace UI Addon
version: "4.7.54" version: "4.7.80"
slug: nspanel-lovelace-ui slug: nspanel-lovelace-ui
description: NSPanel Lovelace UI Addon description: NSPanel Lovelace UI Addon
services: services:

View File

@@ -52,6 +52,8 @@ class HAEntity(panel_cards.Entity):
self.state = data.get("state") self.state = data.get("state")
self.attributes = data.get("attributes", []) self.attributes = data.get("attributes", [])
else: else:
self.state = "not found"
self.attributes = []
return "~text~iid.404~X~6666~not found~" return "~text~iid.404~X~6666~not found~"
# HA Entities # HA Entities
@@ -188,7 +190,7 @@ class HAEntity(panel_cards.Entity):
icon_char = value icon_char = value
case 'binary_sensor': case 'binary_sensor':
device_class = self.attributes.get("device_class", "") device_class = self.attributes.get("device_class", "")
value = get_translation(self.locale, f"backend.component.binary_sensor.state.{device_class}.{entity.state}") value = get_translation(self.locale, f"backend.component.binary_sensor.state.{device_class}.{self.state}")
case 'weather': case 'weather':
attr = self.config.get("attribute", "temperature") attr = self.config.get("attribute", "temperature")
value = str(self.attributes.get(attr, self.state)) value = str(self.attributes.get(attr, self.state))
@@ -207,11 +209,11 @@ class HAEntity(panel_cards.Entity):
forecast = libs.home_assistant.execute_script( forecast = libs.home_assistant.execute_script(
entity_name=self.entity_id, entity_name=self.entity_id,
domain='weather', domain='weather',
service="get_forecast", service="get_forecasts",
service_data={ service_data={
'type': forecast_type 'type': forecast_type
} }
).get("forecast", []) ).get(self.entity_id,{}).get("forecast", [])
if len(forecast) > pos: if len(forecast) > pos:
forcast_pos = forecast[pos] forcast_pos = forecast[pos]
forcast_condition = forcast_pos.get("condition", "") forcast_condition = forcast_pos.get("condition", "")
@@ -297,21 +299,19 @@ class EntitiesCard(HACard):
result = f"{self.title}~{self.gen_nav()}" result = f"{self.title}~{self.gen_nav()}"
for e in self.entities: for e in self.entities:
result += e.render(cardType=self.type) result += e.render(cardType=self.type)
libs.panel_cmd.entityUpd(self.panel.sendTopic, result) libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
class QRCard(HACard): class QRCard(HACard):
def __init__(self, locale, config, panel): def __init__(self, locale, config, panel):
super().__init__(locale, config, panel) super().__init__(locale, config, panel)
self.qrcode = config.get("qrCode", "https://www.youtube.com/watch?v=dQw4w9WgXcQ") self.qrcode = config.get("qrCode", "https://www.youtube.com/watch?v=dQw4w9WgXcQ")
def render(self): def render(self):
# TODO: Render QRCode as HomeAssistant Template
#qrcode = apis.ha_api.render_template(qrcode)
if self.qrcode.startswith("ha:"): if self.qrcode.startswith("ha:"):
self.qrcode = libs.home_assistant.get_template(self.qrcode)[3:] self.qrcode = libs.home_assistant.get_template(self.qrcode)[3:]
result = f"{self.title}~{self.gen_nav()}~{self.qrcode}" result = f"{self.title}~{self.gen_nav()}~{self.qrcode}"
for e in self.entities: for e in self.entities:
result += e.render() result += e.render()
libs.panel_cmd.entityUpd(self.panel.sendTopic, result) libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
class PowerCard(HACard): class PowerCard(HACard):
def __init__(self, locale, config, panel): def __init__(self, locale, config, panel):
@@ -329,7 +329,7 @@ class PowerCard(HACard):
# if isinstance(speed, str): # if isinstance(speed, str):
# speed = apis.ha_api.render_template(speed) # speed = apis.ha_api.render_template(speed)
result += f"~{speed}" result += f"~{speed}"
libs.panel_cmd.entityUpd(self.panel.sendTopic, result) libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
class MediaCard(HACard): class MediaCard(HACard):
def __init__(self, locale, config, panel): def __init__(self, locale, config, panel):
@@ -366,7 +366,7 @@ class MediaCard(HACard):
for e in self.entities[1:]: for e in self.entities[1:]:
button_str += e.render() button_str += e.render()
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{button_str}" result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{button_str}"
libs.panel_cmd.entityUpd(self.panel.sendTopic, result) libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
class ClimateCard(HACard): class ClimateCard(HACard):
def __init__(self, locale, config, panel): def __init__(self, locale, config, panel):
@@ -375,9 +375,8 @@ class ClimateCard(HACard):
def render(self): def render(self):
main_entity = self.entities[0] main_entity = self.entities[0]
#TODO: temp unit temp_unit = self.panel.temp_unit
temp_unit = "celsius" if temp_unit == "celsius":
if(temp_unit == "celsius"):
temperature_unit_icon = get_icon_char("temperature-celsius") temperature_unit_icon = get_icon_char("temperature-celsius")
temperature_unit = "°C" temperature_unit = "°C"
@@ -411,7 +410,12 @@ class ClimateCard(HACard):
min_temp = int(main_entity.attributes.get("min_temp", 0)*10) min_temp = int(main_entity.attributes.get("min_temp", 0)*10)
max_temp = int(main_entity.attributes.get("max_temp", 0)*10) max_temp = int(main_entity.attributes.get("max_temp", 0)*10)
step_temp = int(main_entity.attributes.get("target_temp_step", 0.5)*10)
if temp_unit == "celsius":
step_default = 0.5
else:
step_default = 0.5
step_temp = int(main_entity.attributes.get("target_temp_step", step_default)*10)
icon_res_list = [] icon_res_list = []
icon_res = "" icon_res = ""
@@ -460,8 +464,8 @@ class ClimateCard(HACard):
if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in main_entity.attributes): if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in main_entity.attributes):
detailPage = "0" detailPage = "0"
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{current_temp} {temperature_unit}~{dest_temp}~{state_value}~{min_temp}~{max_temp}~{step_temp}{icon_res}~{currently_translation}~{state_translation}~{action_translation}~{temperature_unit_icon}~{dest_temp2}~{detailPage}" result = f"{self.title}~{self.gen_nav()}~iid.{main_entity.iid}~{current_temp} {temperature_unit}~{dest_temp}~{state_value}~{min_temp}~{max_temp}~{step_temp}{icon_res}~{currently_translation}~{state_translation}~{action_translation}~{temperature_unit_icon}~{dest_temp2}~{detailPage}"
libs.panel_cmd.entityUpd(self.panel.sendTopic, result) libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
class AlarmCard(HACard): class AlarmCard(HACard):
def __init__(self, locale, config, panel): def __init__(self, locale, config, panel):
@@ -471,6 +475,8 @@ class AlarmCard(HACard):
main_entity = self.entities[0] main_entity = self.entities[0]
main_entity.render() main_entity.render()
print(main_entity.state)
icon = get_icon_char("shield-off") icon = get_icon_char("shield-off")
color = rgb_dec565([255,255,255]) color = rgb_dec565([255,255,255])
supported_modes = [] supported_modes = []
@@ -531,7 +537,7 @@ class AlarmCard(HACard):
if len(supported_modes) < 4: if len(supported_modes) < 4:
arm_buttons += "~"*((4-len(supported_modes))*2) arm_buttons += "~"*((4-len(supported_modes))*2)
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}" result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}"
libs.panel_cmd.entityUpd(self.panel.sendTopic, result) libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
class UnlockCard(HACard): class UnlockCard(HACard):
@@ -544,7 +550,7 @@ class UnlockCard(HACard):
icon = get_icon_char("lock") icon = get_icon_char("lock")
supported_modes = ["cardUnlock-unlock"] supported_modes = ["cardUnlock-unlock"]
entity_id = self.config.get("entity") entity_id = self.config.get("destination")
# add padding to arm buttons # add padding to arm buttons
arm_buttons = "" arm_buttons = ""
@@ -555,7 +561,7 @@ class UnlockCard(HACard):
numpad = "enable" numpad = "enable"
result = f"{self.title}~{self.gen_nav()}~{entity_id}{arm_buttons}~{icon}~{color}~{numpad}~disable~" result = f"{self.title}~{self.gen_nav()}~{entity_id}{arm_buttons}~{icon}~{color}~{numpad}~disable~"
libs.panel_cmd.entityUpd(self.panel.sendTopic, result) libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
class Screensaver(HACard): class Screensaver(HACard):
def __init__(self, locale, config, panel): def __init__(self, locale, config, panel):
@@ -583,7 +589,7 @@ class Screensaver(HACard):
result = "" result = ""
for e in self.entities: for e in self.entities:
result += e.render(cardType=self.type) result += e.render(cardType=self.type)
libs.panel_cmd.weatherUpdate(self.panel.sendTopic, result[1:]) libs.panel_cmd.weatherUpdate(self.panel.msg_out_queue, self.panel.sendTopic, result[1:])
statusUpdateResult = "" statusUpdateResult = ""
icon1font = "" icon1font = ""
@@ -601,7 +607,7 @@ class Screensaver(HACard):
else: else:
statusUpdateResult += "~~" statusUpdateResult += "~~"
libs.panel_cmd.statusUpdate(self.panel.sendTopic, f"{statusUpdateResult}~{icon1font}~{icon2font}") libs.panel_cmd.statusUpdate(self.panel.msg_out_queue, self.panel.sendTopic, f"{statusUpdateResult}~{icon1font}~{icon2font}")
def card_factory(locale, settings, panel): def card_factory(locale, settings, panel):
@@ -625,7 +631,7 @@ def card_factory(locale, settings, panel):
return "NotImplemented", None return "NotImplemented", None
return card.iid, card return card.iid, card
def detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=None): def detail_open(locale, detail_type, ha_entity_id, entity_id, msg_out_queue, sendTopic=None, options_list=None):
data = libs.home_assistant.get_entity_data(ha_entity_id) data = libs.home_assistant.get_entity_data(ha_entity_id)
if data: if data:
state = data.get("state") state = data.get("state")
@@ -762,9 +768,51 @@ def detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=None):
return f'{entity_id}~~{icon_color}~{switch_val}~{speed}~{speedMax}~{speed_translation}~{preset_mode}~{preset_modes}' return f'{entity_id}~~{icon_color}~{switch_val}~{speed}~{speedMax}~{speed_translation}~{preset_mode}~{preset_modes}'
case 'popupThermo' | 'climate': case 'popupThermo' | 'climate':
print(f"not implemented {detail_type}") icon_id = ha_icons.get_icon_ha("climate", state)
case 'popupInSel' | 'input_select' | 'select': icon_color = ha_colors.get_entity_color("climate", state, attributes)
print(f"not implemented {detail_type}")
modes_out = ""
for mode in ["preset_modes", "swing_modes", "fan_modes"]:
heading = get_translation(locale, f"frontend.ui.card.climate.{mode[:-1]}")
cur_mode = attributes.get(mode[:-1], "")
modes = attributes.get(mode, [])
if modes is not None:
if mode == "preset_modes":
translated_modes = []
for elem in modes:
translated_modes.append(get_translation(locale, f"frontend.state_attributes.climate.preset_mode.{elem}"))
cur_mode = get_translation(locale, f"frontend.state_attributes.climate.preset_mode.{cur_mode}")
modes_res = "?".join(translated_modes)
else:
modes_res = "?".join(modes)
if modes:
modes_out += f"{heading}~{mode}~{cur_mode}~{modes_res}~"
return f"{entity_id}~{icon_id}~{icon_color}~{modes_out}"
case 'popupInSel' | 'input_select' | 'select' | 'media_player':
hatype = ha_entity_id.split(".")[0]
options = []
icon_color = 0
icon_color = ha_colors.get_entity_color(detail_type, state, attributes)
state = state
if hatype in ["input_select", "select"]:
options = attributes.get("options", [])
elif hatype == "light":
if options_list is not None:
options = options_list
else:
options = attributes.get("effect_list", [])[:15]
state = attributes.get("effect")
elif hatype == "media_player":
state = attributes.get("source", "")
options = attributes.get("source_list", [])
options = "?".join(options)
return f"{entity_id}~~{icon_color}~{hatype}~{state}~{options}~"
case 'popupTimer' | 'timer': case 'popupTimer' | 'timer':
icon_color = ha_colors.get_entity_color("timer", state, attributes) icon_color = ha_colors.get_entity_color("timer", state, attributes)
if state in ["idle", "paused"]: if state in ["idle", "paused"]:
@@ -787,8 +835,8 @@ def detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=None):
#update timer in a second #update timer in a second
def update_time(): def update_time():
time.sleep(1) time.sleep(1)
out = detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=sendTopic) out = detail_open(locale, detail_type, ha_entity_id, entity_id, msg_out_queue, sendTopic=sendTopic)
libs.panel_cmd.entityUpdateDetail(sendTopic, out) libs.panel_cmd.entityUpdateDetail(msg_out_queue, sendTopic, out)
tt = threading.Thread(target=update_time, args=()) tt = threading.Thread(target=update_time, args=())
tt.daemon = True tt.daemon = True
tt.start() tt.start()

View File

@@ -8,6 +8,7 @@ def wait_for_ha_cache():
while time.time() < mustend: while time.time() < mustend:
if len(libs.home_assistant.home_assistant_entity_state_cache) == 0: if len(libs.home_assistant.home_assistant_entity_state_cache) == 0:
time.sleep(0.1) time.sleep(0.1)
time.sleep(1)
def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, screenBrightness, sleepOverride, return_involved_entities=False): def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, screenBrightness, sleepOverride, return_involved_entities=False):
dimmode = 10 dimmode = 10
@@ -17,17 +18,34 @@ def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, scr
if sleepBrightness: if sleepBrightness:
if isinstance(sleepBrightness, int): if isinstance(sleepBrightness, int):
dimmode = sleepBrightness dimmode = sleepBrightness
elif isinstance(sleepBrightness, list):
logging.error("list style config for sleepBrightness no longer supported")
#elif sleepBrightness.startswith("ha:"):
# time.sleep(1)
# dimmode = int(float(libs.home_assistant.get_template(sleepBrightness)[3:]))
# involved_entities.extend(libs.home_assistant.get_template_listener_entities(sleepBrightness))
elif libs.home_assistant.is_existent(sleepBrightness): elif libs.home_assistant.is_existent(sleepBrightness):
involved_entities.append(sleepBrightness) involved_entities.append(sleepBrightness)
dimmode = int(float(libs.home_assistant.get_entity_data(sleepBrightness).get('state', 10))) try:
dimmode = int(float(libs.home_assistant.get_entity_data(sleepBrightness).get('state', 10)))
except ValueError:
print("sleepBrightness entity invalid")
if screenBrightness: if screenBrightness:
if isinstance(screenBrightness, int): if isinstance(screenBrightness, int):
dimValueNormal = screenBrightness dimValueNormal = screenBrightness
elif isinstance(screenBrightness, list):
logging.error("list style config for screenBrightness no longer supported")
#elif screenBrightness.startswith("ha:"):
# time.sleep(1)
# dimValueNormal = int(float(libs.home_assistant.get_template(screenBrightness)[3:]))
# involved_entities.extend(libs.home_assistant.get_template_listener_entities(screenBrightness))
elif libs.home_assistant.is_existent(screenBrightness): elif libs.home_assistant.is_existent(screenBrightness):
involved_entities.append(screenBrightness) involved_entities.append(screenBrightness)
dimValueNormal = int(float(libs.home_assistant.get_entity_data(screenBrightness).get('state', 100))) try:
dimValueNormal = int(float(libs.home_assistant.get_entity_data(screenBrightness).get('state', 100)))
except ValueError:
print("screenBrightness entity invalid")
# force sleep brightness to zero in case sleepTracking is active # force sleep brightness to zero in case sleepTracking is active
if sleepTracking: if sleepTracking:
if libs.home_assistant.is_existent(sleepTracking): if libs.home_assistant.is_existent(sleepTracking):
@@ -51,7 +69,7 @@ def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, scr
else: else:
return dimmode, dimValueNormal return dimmode, dimValueNormal
def handle_buttons(entity_id, btype, value): def handle_buttons(entity_id, btype, value, entity_config=None):
match btype: match btype:
case 'button': case 'button':
button_press(entity_id, value) button_press(entity_id, value)
@@ -60,7 +78,7 @@ def handle_buttons(entity_id, btype, value):
case 'number-set': case 'number-set':
if entity_id.startswith('fan'): if entity_id.startswith('fan'):
attr = libs.home_assistant.get_entity_data(entity_id).get('attributes', []) attr = libs.home_assistant.get_entity_data(entity_id).get('attributes', [])
value = float(value) * float(attr.get(percentage_step, 0)) value = float(value) * float(attr.get('percentage_step', 0))
service_data = { service_data = {
"value": int(value) "value": int(value)
} }
@@ -156,19 +174,20 @@ def handle_buttons(entity_id, btype, value):
} }
call_ha_service(entity_id, f"alarm_{btype}", service_data=service_data) call_ha_service(entity_id, f"alarm_{btype}", service_data=service_data)
case 'mode-preset_modes' | 'mode-swing_modes' | 'mode-fan_modes': case 'mode-preset_modes' | 'mode-swing_modes' | 'mode-fan_modes':
attr = libs.home_assistant.get_entity_data(entity_id).get('attributes', [])
mapping = { mapping = {
'mode-preset_modes': 'preset_modes', 'mode-preset_modes': 'preset_modes',
'mode-swing_modes': 'swing_modes', 'mode-swing_modes': 'swing_modes',
'mode-fan_modes': 'fan_mode' 'mode-fan_modes': 'fan_modes'
} }
if btype in mapping: if btype in mapping:
modes = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get(mapping[btype], []) modes = attr.get(mapping[btype], [])
if modes: if modes:
mode = modes[int(value)] mode = modes[int(value)]
service_data = { service_data = {
mapping[btype]: mode mapping[btype][:-1]: mode
} }
call_ha_service(entity_id, f"set_{mapping[btype]}", service_data=service_data) call_ha_service(entity_id, f"set_{mapping[btype][:-1]}", service_data=service_data)
case 'mode-input_select' | 'mode-select': case 'mode-input_select' | 'mode-select':
options = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("options", []) options = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("options", [])
if options: if options:
@@ -186,7 +205,7 @@ def handle_buttons(entity_id, btype, value):
} }
call_ha_service(entity_id, "select_source", service_data=service_data) call_ha_service(entity_id, "select_source", service_data=service_data)
case 'mode-light': case 'mode-light':
options = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("effect_list", []) options = entity_config.get("effectList", libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("effect_list", []))
if options: if options:
option = options[int(value)] option = options[int(value)]
service_data = { service_data = {
@@ -216,30 +235,6 @@ def handle_buttons(entity_id, btype, value):
case _: case _:
logging.error("Not implemented: %s", btype) logging.error("Not implemented: %s", btype)
# # for cardUnlock
# if button_type == "cardUnlock-unlock":
# curCard = self._config.get_card_by_uuid(
# entity_id.replace('navigate.', ''))
# if curCard is not None:
# if int(curCard.raw_config.get("pin")) == int(value):
# dstCard = self._config.search_card(
# curCard.raw_config.get("destination"))
# if dstCard is not None:
# if dstCard.hidden:
# self._previous_cards.append(self._current_card)
# self._current_card = dstCard
# self._pages_gen.render_card(self._current_card)
# if button_type == "opnSensorNotify":
# msg = ""
# entity = apis.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"- {apis.ha_api.get_entity(e).attributes.friendly_name}\r\n"
# self._pages_gen.send_message_page(
# "opnSensorNotifyRes", "", msg, "", "")
def call_ha_service(entity_id, service, service_data = {}): def call_ha_service(entity_id, service, service_data = {}):
etype = entity_id.split(".")[0] etype = entity_id.split(".")[0]
libs.home_assistant.call_service( libs.home_assistant.call_service(

View File

@@ -70,7 +70,8 @@ def on_message(ws, message):
for template, template_cache_entry in template_cache.items(): for template, template_cache_entry in template_cache.items():
if entity_id in template_cache_entry.get("listener-entities", []): if entity_id in template_cache_entry.get("listener-entities", []):
cache_template(template) cache_template(template)
elif json_msg["type"] == "event" and json_msg["event"]["event_type"] == "esphome.nspanel.data":
nspanel_data_callback(json_msg["event"]["data"]["device_id"], json_msg["event"]["data"]["CustomRecv"])
elif json_msg["type"] == "result" and not json_msg["success"]: elif json_msg["type"] == "result" and not json_msg["success"]:
logging.error("Failed result: ") logging.error("Failed result: ")
logging.error(json_msg) logging.error(json_msg)
@@ -143,6 +144,15 @@ def subscribe_to_events():
} }
send_message(json.dumps(msg)) send_message(json.dumps(msg))
def subscribe_to_nspanel_events(nsp_callback):
global next_id, nspanel_data_callback
nspanel_data_callback = nsp_callback
msg = {
"id": next_id,
"type": "subscribe_events",
"event_type": "esphome.nspanel.data"
}
send_message(json.dumps(msg))
def _get_all_states(): def _get_all_states():
global next_id, request_all_states_id global next_id, request_all_states_id
@@ -158,6 +168,10 @@ def send_entity_update(entity_id):
global on_ha_update global on_ha_update
on_ha_update(entity_id) on_ha_update(entity_id)
def nspanel_data_callback(device_id, msg):
global nspanel_data_callback
nspanel_data_callback(device_id, msg)
def call_service(entity_name: str, domain: str, service: str, service_data: dict) -> bool: def call_service(entity_name: str, domain: str, service: str, service_data: dict) -> bool:
global next_id global next_id
try: try:
@@ -177,6 +191,22 @@ def call_service(entity_name: str, domain: str, service: str, service_data: dict
logging.exception("Failed to call Home Assisatant service.") logging.exception("Failed to call Home Assisatant service.")
return False return False
def send_msg_to_panel(service: str, service_data: dict) -> bool:
global next_id
try:
msg = {
"id": next_id,
"type": "call_service",
"domain": "esphome",
"service": service,
"service_data": service_data,
}
send_message(json.dumps(msg))
return True
except Exception as e:
logging.exception("Failed to call Home Assisatant service.")
return False
def execute_script(entity_name: str, domain: str, service: str, service_data: dict) -> str: def execute_script(entity_name: str, domain: str, service: str, service_data: dict) -> str:
global next_id, response_buffer global next_id, response_buffer
try: try:
@@ -202,7 +232,7 @@ def execute_script(entity_name: str, domain: str, service: str, service_data: di
] ]
} }
send_message(json.dumps(msg)) send_message(json.dumps(msg))
# busy waiting for response with a timeout of 0.2 seconds - maybe there's a better way of doing this # busy waiting for response with a timeout of 0.4 seconds- maybe there's a better way of doing this
mustend = time.time() + 0.4 mustend = time.time() + 0.4
while time.time() < mustend: while time.time() < mustend:
if response_buffer[call_id] == True: if response_buffer[call_id] == True:
@@ -216,6 +246,8 @@ def execute_script(entity_name: str, domain: str, service: str, service_data: di
return {} return {}
def cache_template(template): def cache_template(template):
if not template:
raise Exception("Invalid template")
global next_id, response_buffer global next_id, response_buffer
try: try:
call_id = next_id call_id = next_id
@@ -243,6 +275,18 @@ def get_template(template):
else: else:
return template_cache.get(template, []).get("result", "404") return template_cache.get(template, []).get("result", "404")
def get_template_listener_entities(template):
global template_cache
if template in template_cache:
return template_cache[template].get("listener-entities")
else:
mustend = time.time() + 0.5
while time.time() < mustend:
if template not in template_cache:
time.sleep(0.0001)
else:
return template_cache.get(template, []).get("listener-entities", "404")
def get_entity_data(entity_id: str): def get_entity_data(entity_id: str):
if entity_id in home_assistant_entity_state_cache: if entity_id in home_assistant_entity_state_cache:
return home_assistant_entity_state_cache[entity_id] return home_assistant_entity_state_cache[entity_id]

View File

@@ -1,46 +1,47 @@
import logging import logging
def init(mqtt_client_from_manager): def custom_send(msg_out_queue, topic, msg):
global mqtt_client msg_out_queue.put((topic, msg))
mqtt_client = mqtt_client_from_manager logging.debug("Sent Message to NsPanel (%s): %s", topic, msg)
def custom_send(topic, msg): def page_type(msg_out_queue, topic, target_page):
global mqtt_client if target_page == "cardUnlock":
mqtt_client.publish(topic, msg) target_page = "cardAlarm"
logging.debug("Sent Message to NsPanel (%s): %s", topic, msg) custom_send(msg_out_queue, topic, f"pageType~{target_page}")
def page_type(topic, target_page): def send_time(msg_out_queue, topic, time, addTimeText=""):
if target_page == "cardUnlock": custom_send(msg_out_queue, topic, f"time~{time}~{addTimeText}")
target_page = "cardAlarm"
custom_send(topic, f"pageType~{target_page}")
def send_date(msg_out_queue, topic, date):
custom_send(msg_out_queue, topic, f"date~{date}")
def send_time(topic, time, addTimeText=""):
custom_send(topic, f"time~{time}~{addTimeText}")
def entityUpd(msg_out_queue, topic, data):
custom_send(msg_out_queue, topic, f"entityUpd~{data}")
def send_date(topic, date):
custom_send(topic, f"date~{date}") def weatherUpdate(msg_out_queue, topic, data):
custom_send(msg_out_queue, topic, f"weatherUpdate~{data}")
def entityUpd(topic, data): def timeout(msg_out_queue, topic, timeout):
custom_send(topic, f"entityUpd~{data}") custom_send(msg_out_queue, topic, f"timeout~{timeout}")
def weatherUpdate(topic, data): def dimmode(msg_out_queue, topic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders):
custom_send(topic, f"weatherUpdate~{data}") if dimValue==dimValueNormal:
dimValue=dimValue-1
def timeout(topic, timeout): custom_send(msg_out_queue, topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}")
custom_send(topic, f"timeout~{timeout}")
def entityUpdateDetail(msg_out_queue, topic, data):
def dimmode(topic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders): custom_send(msg_out_queue, topic, f"entityUpdateDetail~{data}")
if dimValue==dimValueNormal:
dimValue=dimValue-1 def entityUpdateDetail2(msg_out_queue, topic, data):
custom_send(topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}") custom_send(msg_out_queue, topic, f"entityUpdateDetail2~{data}")
def entityUpdateDetail(topic, data): def statusUpdate(msg_out_queue, topic, data):
custom_send(topic, f"entityUpdateDetail~{data}") custom_send(msg_out_queue, topic, f"statusUpdate~{data}")
def statusUpdate(topic, data): def send_message_page(msg_out_queue, topic, ident, heading, msg, b1, b2):
custom_send(topic, f"statusUpdate~{data}") page_type(msg_out_queue, topic, "popupNotify")
custom_send(msg_out_queue, topic, f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")

View File

@@ -1,224 +1,197 @@
#!/usr/bin/env python #!/usr/bin/env python
import logging import logging
import paho.mqtt.client as mqtt import time
import time import subprocess
import json import libs.home_assistant
import subprocess import libs.panel_cmd
import libs.home_assistant import yaml
import libs.panel_cmd from panel import LovelaceUIPanel
import yaml import os
from uuid import getnode as get_mac import threading
from panel import LovelaceUIPanel from watchdog.events import FileSystemEventHandler
import os from watchdog.observers import Observer
import threading import signal
from watchdog.events import FileSystemEventHandler import sys
from watchdog.observers import Observer from queue import Queue
import signal from mqtt import MqttManager
import sys
from queue import Queue logging.getLogger("watchdog").propagate = False
logging.getLogger("watchdog").propagate = False settings = {}
panels = {}
settings = {} panel_in_queues = {}
panels = {} panel_out_queue = Queue(maxsize=20)
panel_queues = {} last_settings_file_mtime = 0
last_settings_file_mtime = 0 mqtt_connect_time = 0
mqtt_connect_time = 0 has_sent_reload_command = False
has_sent_reload_command = False
mqtt_client_name = "NSPanelLovelaceManager_" + str(get_mac()) logging.basicConfig(level=logging.DEBUG)
client = mqtt.Client(mqtt_client_name)
logging.basicConfig(level=logging.DEBUG) def on_ha_update(entity_id):
global panel_in_queues
def on_connect(client, userdata, flags, rc): # send HA updates to all panels
global settings for queue in panel_in_queues.values():
logging.info("Connected to MQTT Server") queue.put(("HA:", entity_id))
# subscribe to panelRecvTopic of each panel
for settings_panel in settings["nspanels"].values(): def on_ha_panel_event(device_id, msg):
client.subscribe(settings_panel["panelRecvTopic"]) global panel_in_queues
def on_ha_update(entity_id): if device_id in panel_in_queues.keys():
global panel_queues queue = panel_in_queues[device_id]
for queue in panel_queues.values(): queue.put(("MQTT:", msg))
queue.put(("HA:", entity_id))
def process_output_to_panel():
def on_message(client, userdata, msg): while True:
global panel_queues msg = panel_out_queue.get()
try:
if msg.payload.decode() == "": #client.publish(msg[0], msg[1])
return #apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=2, data=msg)
parts = msg.topic.split('/') service = msg[0] + "_nspanelui_api_call"
if msg.topic in panel_queues.keys(): service_data = {
data = json.loads(msg.payload.decode('utf-8')) "data": msg[1],
if "CustomRecv" in data: "command":2
queue = panel_queues[msg.topic] }
queue.put(("MQTT:", data["CustomRecv"])) libs.home_assistant.send_msg_to_panel(
else: service = service,
logging.debug("Received unhandled message on topic: %s", msg.topic) service_data = service_data
)
except Exception: # pylint: disable=broad-exception-caught
logging.exception("Something went wrong during processing of message:")
try: def connect():
logging.error(msg.payload.decode('utf-8')) global settings, panel_out_queue
except: # pylint: disable=bare-except if "mqtt_server" in settings and not "use_ha_api" in settings:
logging.error( MqttManager(settings, panel_out_queue, panel_in_queues)
"Something went wrong when processing the exception message, couldn't decode payload to utf-8.") else:
logging.info("MQTT values not configured, will not connect.")
def get_config_file():
CONFIG_FILE = os.getenv('CONFIG_FILE') # MQTT Connected, start APIs if configured
if not CONFIG_FILE: if settings["home_assistant_address"] != "" and settings["home_assistant_token"] != "":
CONFIG_FILE = './panels.yaml' libs.home_assistant.init(settings, on_ha_update)
return CONFIG_FILE libs.home_assistant.connect()
else:
def get_config(file): logging.info("Home Assistant values not configured, will not connect.")
global settings
while not libs.home_assistant.ws_connected:
try: time.sleep(1)
with open(file, 'r', encoding="utf8") as file: if settings.get("use_ha_api"):
settings = yaml.safe_load(file) libs.home_assistant.subscribe_to_nspanel_events(on_ha_panel_event)
except yaml.YAMLError as exc: send_to_panel_thread = threading.Thread(target=process_output_to_panel, args=())
print ("Error while parsing YAML file:") send_to_panel_thread.daemon = True
if hasattr(exc, 'problem_mark'): send_to_panel_thread.start()
if exc.context != None:
print (' parser says\n' + str(exc.problem_mark) + '\n ' + def setup_panels():
str(exc.problem) + ' ' + str(exc.context) + global settings, panel_in_queues
'\nPlease correct data and retry.') # Create NsPanel object
else: for name, settings_panel in settings["nspanels"].items():
print (' parser says\n' + str(exc.problem_mark) + '\n ' + if "timeZone" not in settings_panel:
str(exc.problem) + '\nPlease correct data and retry.') settings_panel["timeZone"] = settings.get("timeZone", "Europe/Berlin")
else: if "locale" not in settings_panel:
print ("Something went wrong while parsing yaml file") settings_panel["timezone"] = settings.get("locale", "en_US")
return False if "hiddenCards" not in settings_panel:
settings_panel["hiddenCards"] = settings.get("hiddenCards", [])
if not settings.get("mqtt_username"):
settings["mqtt_username"] = os.getenv('MQTT_USER') msg_in_queue = Queue(maxsize=20)
if not settings.get("mqtt_password"): panel_in_queues[settings_panel["panelRecvTopic"]] = msg_in_queue
settings["mqtt_password"] = os.getenv('MQTT_PASS') panel_thread = threading.Thread(target=panel_thread_target, args=(msg_in_queue, name, settings_panel, panel_out_queue))
if not settings.get("mqtt_port"): panel_thread.daemon = True
settings["mqtt_port"] = os.getenv('MQTT_PORT') panel_thread.start()
if not settings.get("mqtt_server"):
settings["mqtt_server"] = os.getenv('MQTT_SERVER') def panel_thread_target(queue_in, name, settings_panel, queue_out):
panel = LovelaceUIPanel(name, settings_panel, queue_out)
while True:
settings["is_addon"] = False msg = queue_in.get()
if msg[0] == "MQTT:":
if not settings.get("home_assistant_token"): panel.customrecv_event_callback(msg[1])
st = os.getenv('SUPERVISOR_TOKEN') elif msg[0] == "HA:":
if st and "home_assistant_token" not in settings and "home_assistant_address" not in settings: panel.ha_event_callback(msg[1])
settings["home_assistant_token"] = st
settings["home_assistant_address"] = "http://supervisor" def get_config_file():
settings["is_addon"] = True CONFIG_FILE = os.getenv('CONFIG_FILE')
return True if not CONFIG_FILE:
CONFIG_FILE = './panels.yaml'
def connect(): return CONFIG_FILE
global settings, home_assistant, client
client.on_connect = on_connect def get_config(file):
client.on_message = on_message global settings
client.username_pw_set(
settings["mqtt_username"], settings["mqtt_password"]) try:
# Wait for connection with open(file, 'r', encoding="utf8") as file:
connection_return_code = 0 settings = yaml.safe_load(file)
mqtt_server = settings["mqtt_server"] except yaml.YAMLError as exc:
mqtt_port = int(settings["mqtt_port"]) print ("Error while parsing YAML file:")
logging.info("Connecting to %s:%i as %s", if hasattr(exc, 'problem_mark'):
mqtt_server, mqtt_port, mqtt_client_name) if exc.context != None:
while True: print (' parser says\n' + str(exc.problem_mark) + '\n ' +
try: str(exc.problem) + ' ' + str(exc.context) +
client.connect(mqtt_server, mqtt_port, 5) '\nPlease correct data and retry.')
break # Connection call did not raise exception, connection is sucessfull else:
except: # pylint: disable=bare-except print (' parser says\n' + str(exc.problem_mark) + '\n ' +
logging.exception( str(exc.problem) + '\nPlease correct data and retry.')
"Failed to connect to MQTT %s:%i. Will try again in 10 seconds. Code: %s", mqtt_server, mqtt_port, connection_return_code) else:
time.sleep(10.) print ("Something went wrong while parsing yaml file")
return False
# MQTT Connected, start APIs if configured
if settings["home_assistant_address"] != "" and settings["home_assistant_token"] != "": if not settings.get("mqtt_username"):
libs.home_assistant.init(settings, on_ha_update) settings["mqtt_username"] = os.getenv('MQTT_USER')
libs.home_assistant.connect() if not settings.get("mqtt_password"):
else: settings["mqtt_password"] = os.getenv('MQTT_PASS')
logging.info("Home Assistant values not configured, will not connect.") if not settings.get("mqtt_port"):
settings["mqtt_port"] = os.getenv('MQTT_PORT')
libs.panel_cmd.init(client) if not settings.get("mqtt_server"):
settings["mqtt_server"] = os.getenv('MQTT_SERVER')
setup_panels()
def loop(): settings["is_addon"] = False
global client
# Loop MQTT if not settings.get("home_assistant_token"):
client.loop_forever() st = os.getenv('SUPERVISOR_TOKEN')
if st and "home_assistant_token" not in settings and "home_assistant_address" not in settings:
def setup_panels(): settings["home_assistant_token"] = st
global settings, panel_queues settings["home_assistant_address"] = "http://supervisor"
# Create NsPanel object settings["is_addon"] = True
for name, settings_panel in settings["nspanels"].items(): return True
if "timeZone" not in settings_panel:
settings_panel["timeZone"] = settings.get("timeZone", "Europe/Berlin") def config_watch():
if "locale" not in settings_panel: class ConfigChangeEventHandler(FileSystemEventHandler):
settings_panel["timezone"] = settings.get("locale", "en_US") def __init__(self, base_paths):
if "hiddenCards" not in settings_panel: self.base_paths = base_paths
settings_panel["hiddenCards"] = settings.get("hiddenCards", [])
def dispatch(self, event):
#panels[name] = LovelaceUIPanel(name, settings_panel) for base_path in self.base_paths:
if event.src_path.endswith(base_path):
mqtt_queue = Queue(maxsize=20) super(ConfigChangeEventHandler, self).dispatch(event)
panel_queues[settings_panel["panelRecvTopic"]] = mqtt_queue return
panel_thread = threading.Thread(target=panel_thread_target, args=(mqtt_queue, name, settings_panel))
panel_thread.daemon = True def on_modified(self, event):
logging.info('Modification detected. Reloading panels.')
panel_thread.start() pid = os.getpid()
os.kill(pid, signal.SIGTERM)
def panel_thread_target(queue, name, settings_panel):
panel = LovelaceUIPanel(name, settings_panel) logging.info('Watching for changes in config file')
while True: project_files = []
msg = queue.get() project_files.append(get_config_file())
#print(msg) handler = ConfigChangeEventHandler(project_files)
if msg[0] == "MQTT:": observer = Observer()
panel.customrecv_event_callback(msg[1]) observer.schedule(handler, path=os.path.dirname(get_config_file()), recursive=True)
elif msg[0] == "HA:": observer.start()
panel.ha_event_callback(msg[1]) while True:
time.sleep(1)
def signal_handler(signum, frame):
logging.info(f"Received signal {signum}. Initiating restart...")
python = sys.executable
os.execl(python, python, *sys.argv)
def config_watch(): if __name__ == '__main__':
class ConfigChangeEventHandler(FileSystemEventHandler): signal.signal(signal.SIGTERM, signal_handler)
def __init__(self, base_paths): threading.Thread(target=config_watch).start()
self.base_paths = base_paths if (get_config(get_config_file())):
connect()
def dispatch(self, event): setup_panels()
for base_path in self.base_paths:
if event.src_path.endswith(base_path): # main thread sleep forever
super(ConfigChangeEventHandler, self).dispatch(event) while True:
return time.sleep(100)
else:
def on_modified(self, event): while True:
logging.info('Modification detected. Reloading panels.')
pid = os.getpid()
os.kill(pid, signal.SIGTERM)
logging.info('Watching for changes in config file')
project_files = []
project_files.append(get_config_file())
handler = ConfigChangeEventHandler(project_files)
observer = Observer()
observer.schedule(handler, path=os.path.dirname(get_config_file()), recursive=True)
observer.start()
while True:
time.sleep(1)
def signal_handler(signum, frame):
logging.info(f"Received signal {signum}. Initiating restart...")
python = sys.executable
os.execl(python, python, *sys.argv)
if __name__ == '__main__':
signal.signal(signal.SIGTERM, signal_handler)
threading.Thread(target=config_watch).start()
if (get_config(get_config_file())):
connect()
loop()
else:
while True:
time.sleep(100) time.sleep(100)

View File

@@ -0,0 +1,68 @@
from uuid import getnode as get_mac
import paho.mqtt.client as mqtt
import logging
import time
import json
import threading
class MqttManager:
def __init__(self, settings, msg_in_queue, msg_out_queue_list):
mqtt_client_name = "NSPanelLovelaceManager_" + str(get_mac())
self.client = mqtt.Client(mqtt_client_name)
self.msg_in_queue = msg_in_queue
self.msg_out_queue_list = msg_out_queue_list
self.settings = settings
self.client.on_connect = self.on_mqtt_connect
self.client.on_message = self.on_mqtt_message
self.client.username_pw_set(
settings["mqtt_username"], settings["mqtt_password"])
# Wait for connection
connection_return_code = 0
mqtt_server = settings["mqtt_server"]
mqtt_port = int(settings["mqtt_port"])
logging.info("Connecting to %s:%i as %s",
mqtt_server, mqtt_port, mqtt_client_name)
while True:
try:
self.client.connect(mqtt_server, mqtt_port, 5)
break # Connection call did not raise exception, connection is sucessfull
except: # pylint: disable=bare-except
logging.exception(
"Failed to connect to MQTT %s:%i. Will try again in 10 seconds. Code: %s", mqtt_server, mqtt_port, connection_return_code)
time.sleep(10.)
self.client.loop_start()
process_thread = threading.Thread(target=self.process_in_queue, args=(self.client, self.msg_in_queue))
process_thread.daemon = True
process_thread.start()
def on_mqtt_connect(self, client, userdata, flags, rc):
logging.info("Connected to MQTT Server")
# subscribe to panelRecvTopic of each panel
for settings_panel in self.settings["nspanels"].values():
client.subscribe(settings_panel["panelRecvTopic"])
def on_mqtt_message(self, client, userdata, msg):
try:
if msg.payload.decode() == "":
return
if msg.topic in self.msg_out_queue_list.keys():
data = json.loads(msg.payload.decode('utf-8'))
if "CustomRecv" in data:
queue = self.msg_out_queue_list[msg.topic]
queue.put(("MQTT:", data["CustomRecv"]))
else:
logging.debug("Received unhandled message on topic: %s", msg.topic)
except Exception: # pylint: disable=broad-exception-caught
logging.exception("Something went wrong during processing of message:")
try:
logging.error(msg.payload.decode('utf-8'))
except: # pylint: disable=bare-except
logging.error(
"Something went wrong when processing the exception message, couldn't decode payload to utf-8.")
def process_in_queue(self, client, msg_in_queue):
while True:
msg = msg_in_queue.get()
client.publish(msg[0], msg[1])

View File

@@ -7,18 +7,20 @@ from scheduler import Scheduler
import scheduler.trigger as trigger import scheduler.trigger as trigger
import time import time
import babel.dates import babel.dates
from ha_cards import Screensaver, EntitiesCard, card_factory, detail_open from ha_cards import Screensaver, card_factory, detail_open
import ha_control import ha_control
class LovelaceUIPanel: class LovelaceUIPanel:
def __init__(self, name_panel, settings_panel): def __init__(self, name_panel, settings_panel, msg_out_queue):
self.name = name_panel self.name = name_panel
self.settings = settings_panel self.settings = settings_panel
self.msg_out_queue = msg_out_queue
self.sendTopic = self.settings["panelSendTopic"] self.sendTopic = self.settings["panelSendTopic"]
self.recvTopic = self.settings["panelRecvTopic"] self.recvTopic = self.settings["panelRecvTopic"]
self.model = self.settings.get("model", "eu") self.model = self.settings.get("model", "eu")
self.temp_unit = self.settings.get("temp_unit", "celsius")
self.current_card = None self.current_card = None
self.privious_cards = [] self.privious_cards = []
@@ -65,7 +67,7 @@ class LovelaceUIPanel:
self.schedule = Scheduler() self.schedule = Scheduler()
self.schedule.minutely(datetime.time(second=0), self.update_time) self.schedule.minutely(datetime.time(second=0), self.update_time)
self.schedule.hourly(datetime.time( self.schedule.hourly(datetime.time(
minute=0, second=0), self.update_time) minute=0, second=0), self.update_date)
schedule_thread = threading.Thread(target=self.schedule_thread_target) schedule_thread = threading.Thread(target=self.schedule_thread_target)
schedule_thread.daemon = True schedule_thread.daemon = True
schedule_thread.start() schedule_thread.start()
@@ -74,6 +76,10 @@ class LovelaceUIPanel:
ha_control.wait_for_ha_cache() ha_control.wait_for_ha_cache()
#request templates on cards #request templates on cards
if isinstance(self.settings.get("sleepBrightness",""), str) and self.settings.get("sleepBrightness", "").startswith("ha:"):
libs.home_assistant.cache_template(self.settings.get("sleepBrightness"))
if isinstance(self.settings.get("sleepBrightness",""), str) and self.settings.get("screenBrightness", "").startswith("ha:"):
libs.home_assistant.cache_template(self.settings.get("screenBrightness"))
for c in self.cards.values(): for c in self.cards.values():
if hasattr(c, "qrcode"): if hasattr(c, "qrcode"):
if c.qrcode.startswith("ha:"): if c.qrcode.startswith("ha:"):
@@ -94,7 +100,7 @@ class LovelaceUIPanel:
for e in self.screensaver.entities: for e in self.screensaver.entities:
e.prerender() e.prerender()
libs.panel_cmd.page_type(self.sendTopic, "pageStartup") libs.panel_cmd.page_type(self.msg_out_queue, self.sendTopic, "pageStartup")
def schedule_thread_target(self): def schedule_thread_target(self):
@@ -106,13 +112,13 @@ class LovelaceUIPanel:
use_timezone = tz.gettz(self.settings["timeZone"]) use_timezone = tz.gettz(self.settings["timeZone"])
time_string = datetime.datetime.now( time_string = datetime.datetime.now(
use_timezone).strftime(self.settings["timeFormat"]) use_timezone).strftime(self.settings["timeFormat"])
libs.panel_cmd.send_time(self.sendTopic, time_string) libs.panel_cmd.send_time(self.msg_out_queue, self.sendTopic, time_string)
def update_date(self): def update_date(self):
dateformat = self.settings["dateFormat"] dateformat = self.settings["dateFormat"]
date_string = babel.dates.format_date( date_string = babel.dates.format_date(
datetime.datetime.now(), dateformat, locale=self.settings["locale"]) datetime.datetime.now(), dateformat, locale=self.settings["locale"])
libs.panel_cmd.send_date(self.sendTopic, date_string) libs.panel_cmd.send_date(self.msg_out_queue, self.sendTopic, date_string)
def searchCard(self, iid): def searchCard(self, iid):
if iid in self.navigate_keys: if iid in self.navigate_keys:
@@ -129,13 +135,23 @@ class LovelaceUIPanel:
# send update for detail popup in case it's open # send update for detail popup in case it's open
etype = entity_id.split('.')[0] etype = entity_id.split('.')[0]
if etype in ['light', 'timer', 'cover', 'input_select', 'select', 'fan']: if etype in ['light', 'timer', 'cover', 'input_select', 'select', 'fan', 'climate']:
# figure out iid of entity # figure out iid of entity
entity_id_iid = "" entity_id_iid = ""
for e in self.current_card.get_iid_entities(): for e in self.current_card.entities:
if entity_id == e[1]: if entity_id == e.entity_id:
entity_id_iid = f'iid.{e[0]}' entity_id_iid = f'iid.{e.iid}'
libs.panel_cmd.entityUpdateDetail(self.sendTopic, detail_open(self.settings["locale"], etype, entity_id, entity_id_iid, sendTopic=self.sendTopic))
effectList = None
if etype=="light":
effectList = e.config.get("effectList")
if etype == 'light':
libs.panel_cmd.entityUpdateDetail2(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], "popupInSel", entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic, options_list=effectList))
libs.panel_cmd.entityUpdateDetail(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], "popupLight", entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic))
elif etype in ['input_select', 'media_player']:
libs.panel_cmd.entityUpdateDetail2(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], etype, entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic))
else:
libs.panel_cmd.entityUpdateDetail(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], etype, entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic))
involved_entities = ha_control.calculate_dim_values( involved_entities = ha_control.calculate_dim_values(
self.settings.get("sleepTracking"), self.settings.get("sleepTracking"),
@@ -150,16 +166,12 @@ class LovelaceUIPanel:
def render_current_page(self, switchPages=False, requested=False): def render_current_page(self, switchPages=False, requested=False):
if not self.current_card:
return
if switchPages: if switchPages:
libs.panel_cmd.page_type(self.sendTopic, self.current_card.type) libs.panel_cmd.page_type(self.msg_out_queue, self.sendTopic, self.current_card.type)
if requested: if requested:
self.current_card.render() self.current_card.render()
# send sleepTimeout
#sleepTimeout = self.settings.get("sleepTimeout", 20)
#if self.current_card.config.get("sleepTimeout"):
# sleepTimeout = self.current_card.config.get("sleepTimeout")
#libs.panel_cmd.timeout(self.sendTopic, sleepTimeout)
#self.dimmode()
def dimmode(self): def dimmode(self):
# send dimmode # send dimmode
@@ -178,8 +190,15 @@ class LovelaceUIPanel:
backgroundColor = 0 backgroundColor = 0
fontColor = "" fontColor = ""
featExperimentalSliders = self.settings.get("featExperimentalSliders", 0) featExperimentalSliders = self.settings.get("featExperimentalSliders", 0)
libs.panel_cmd.dimmode(self.sendTopic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders) libs.panel_cmd.dimmode(self.msg_out_queue, self.sendTopic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders)
def get_default_card(self):
defaultCard = self.settings.get("defaultCard")
if defaultCard and "." in defaultCard:
card = self.searchCard(defaultCard.split(".")[1])
if card:
return card
return list(self.cards.values())[0]
def customrecv_event_callback(self, msg): def customrecv_event_callback(self, msg):
logging.debug("Recv Message from NsPanel (%s): %s", self.name, msg) logging.debug("Recv Message from NsPanel (%s): %s", self.name, msg)
@@ -198,7 +217,7 @@ class LovelaceUIPanel:
sleepTimeout = self.settings.get("sleepTimeout", 20) sleepTimeout = self.settings.get("sleepTimeout", 20)
if self.current_card.config.get("sleepTimeout"): if self.current_card.config.get("sleepTimeout"):
sleepTimeout = self.current_card.config.get("sleepTimeout") sleepTimeout = self.current_card.config.get("sleepTimeout")
libs.panel_cmd.timeout(self.sendTopic, sleepTimeout) libs.panel_cmd.timeout(self.msg_out_queue, self.sendTopic, sleepTimeout)
self.dimmode() self.dimmode()
if msg[1] == "sleepReached": if msg[1] == "sleepReached":
@@ -209,16 +228,22 @@ class LovelaceUIPanel:
self.render_current_page(requested=True) self.render_current_page(requested=True)
if msg[1] == "buttonPress2": if msg[1] == "buttonPress2":
entity_id = msg[2] entity_id = msg[2]
if entity_id == "":
return
btype = msg[3] btype = msg[3]
value = msg[4] if len(msg) > 4 else None value = msg[4] if len(msg) > 4 else None
if btype == "bExit": if btype == "bExit":
if entity_id=="screensaver" and self.settings.get("screensaver").get("doubleTapToUnlock") and value == "1": if entity_id in ["screensaver", "screensaver2"] and self.settings.get("screensaver").get("doubleTapToUnlock") and value == "1":
return return
# in case privious_cards is empty add a default card # in case privious_cards is empty add a default card
if len(self.privious_cards) == 0: if len(self.privious_cards) == 0:
self.privious_cards.append( self.privious_cards.append(self.get_default_card())
list(self.cards.values())[0]) # TODO: Impelement default card config
if self.settings.get("defaultCard") and entity_id in ["screensaver", "screensaver2"]:
logging.debug("Defaulting to card %s", self.settings.get("defaultCard"))
self.privious_cards = [self.get_default_card()]
self.current_card = self.privious_cards.pop() self.current_card = self.privious_cards.pop()
self.render_current_page(switchPages=True) self.render_current_page(switchPages=True)
return return
@@ -226,8 +251,10 @@ class LovelaceUIPanel:
# replace iid with real entity id # replace iid with real entity id
if entity_id.startswith("iid."): if entity_id.startswith("iid."):
iid = entity_id.split(".")[1] iid = entity_id.split(".")[1]
if iid in self.entity_iids: for e in self.current_card.entities:
entity_id = self.entity_iids[iid] if e.iid == iid:
entity_id = e.entity_id
entity_config = e.config
match btype: match btype:
case 'button': case 'button':
@@ -236,8 +263,9 @@ class LovelaceUIPanel:
case 'navigate': case 'navigate':
card_iid = entity_id.split(".")[1] card_iid = entity_id.split(".")[1]
if card_iid == "UP": if card_iid == "UP":
if len(self.privious_cards) == 0:
self.privious_cards.append(self.get_default_card())
self.current_card = self.privious_cards.pop() self.current_card = self.privious_cards.pop()
# TODO Handle privious_cards empty with default card
self.render_current_page(switchPages=True) self.render_current_page(switchPages=True)
else: else:
self.privious_cards.append(self.current_card) self.privious_cards.append(self.current_card)
@@ -245,13 +273,15 @@ class LovelaceUIPanel:
self.render_current_page(switchPages=True) self.render_current_page(switchPages=True)
# send ha stuff to ha # send ha stuff to ha
case _: case _:
ha_control.handle_buttons(entity_id, btype, value) ha_control.handle_buttons(entity_id, btype, value, entity_config=entity_config)
case 'cardUnlock-unlock': case 'cardUnlock-unlock':
card_iid = entity_id.split(".")[1] card_iid = entity_id.split(".")[1]
if int(self.current_card.config.get("pin")) == int(value): if int(self.current_card.config.get("pin")) == int(value):
self.privious_cards.append(self.current_card) self.privious_cards.append(self.current_card)
self.current_card = self.searchCard(card_iid) self.current_card = self.searchCard(card_iid)
self.render_current_page(switchPages=True) self.render_current_page(switchPages=True)
case 'mode-light':
ha_control.handle_buttons(entity_id, btype, value, entity_config=entity_config)
case _: case _:
ha_control.handle_buttons(entity_id, btype, value) ha_control.handle_buttons(entity_id, btype, value)
@@ -260,6 +290,15 @@ class LovelaceUIPanel:
# replace iid with real entity id # replace iid with real entity id
if entity_id.startswith("iid."): if entity_id.startswith("iid."):
iid = entity_id.split(".")[1] iid = entity_id.split(".")[1]
if iid in self.entity_iids: for e in self.current_card.entities:
entity_id = self.entity_iids[iid] if e.iid == iid:
libs.panel_cmd.entityUpdateDetail(self.sendTopic, detail_open(self.settings["locale"], msg[2], entity_id, msg[3], sendTopic=self.sendTopic)) entity_id = e.entity_id
effectList = None
if entity_id.startswith("light"):
effectList = e.config.get("effectList")
if msg[2] == "popupInSel": #entity_id.split(".")[0] in ['input_select', 'media_player']:
libs.panel_cmd.entityUpdateDetail2(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], msg[2], entity_id, msg[3], self.msg_out_queue, sendTopic=self.sendTopic, options_list=effectList))
else:
libs.panel_cmd.entityUpdateDetail(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], msg[2], entity_id, msg[3], self.msg_out_queue, sendTopic=self.sendTopic))

View File

@@ -1,4 +1,4 @@
paho-mqtt paho-mqtt==1.6.1
pyyaml pyyaml
websockets websockets
websocket-client websocket-client
@@ -7,4 +7,4 @@ python-dateutil
scheduler scheduler
babel babel
watchdog watchdog
jinja2 jinja2