mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2026-02-17 10:27:00 +01:00
Compare commits
32 Commits
603d207e12
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41f4062ab8 | ||
|
|
f3fffe7b70 | ||
|
|
c4b6a8bd8a | ||
|
|
81d876b53b | ||
|
|
d15cb218ce | ||
|
|
114f630b8a | ||
|
|
53b627be88 | ||
|
|
f2e1a7263d | ||
|
|
1e2f89ed1d | ||
|
|
b6f36d4eac | ||
|
|
fa239f8bf0 | ||
|
|
2d1719673c | ||
|
|
e9c275216c | ||
|
|
b226b61281 | ||
|
|
056d8f95c2 | ||
|
|
52c695cf1c | ||
|
|
8805e2189c | ||
|
|
341cdb47ab | ||
|
|
3b25d47bc7 | ||
|
|
a721d4ccd7 | ||
|
|
044abda65b | ||
|
|
155b08d6d5 | ||
|
|
c038745d1b | ||
|
|
154c9aced1 | ||
|
|
f5119f86ac | ||
|
|
77b7400b04 | ||
|
|
995e7eebd2 | ||
|
|
c91ca0912a | ||
|
|
a6742f88c8 | ||
|
|
9f146ec8b3 | ||
|
|
0cccfac4a6 | ||
|
|
fbe5f9658e |
8
.github/workflows/builder.yaml
vendored
8
.github/workflows/builder.yaml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
changed: ${{ steps.changed_addons.outputs.changed }}
|
changed: ${{ steps.changed_addons.outputs.changed }}
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repository
|
- name: Check out the repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed_files
|
id: changed_files
|
||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Get information
|
- name: Get information
|
||||||
id: info
|
id: info
|
||||||
@@ -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.5.0
|
uses: docker/login-action@v3.7.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@2025.03.0
|
uses: home-assistant/builder@2025.09.0
|
||||||
with:
|
with:
|
||||||
args: |
|
args: |
|
||||||
${{ env.BUILD_ARGS }} \
|
${{ env.BUILD_ARGS }} \
|
||||||
|
|||||||
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@@ -43,11 +43,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v4
|
||||||
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@v3
|
uses: github/codeql-action/autobuild@v4
|
||||||
|
|
||||||
# ℹ️ 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@v3
|
uses: github/codeql-action/analyze@v4
|
||||||
|
|||||||
4
.github/workflows/docs-dev.yml
vendored
4
.github/workflows/docs-dev.yml
vendored
@@ -15,10 +15,10 @@ jobs:
|
|||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
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
|
||||||
|
|||||||
4
.github/workflows/docs-release.yml
vendored
4
.github/workflows/docs-release.yml
vendored
@@ -15,10 +15,10 @@ jobs:
|
|||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
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
|
||||||
|
|||||||
2
.github/workflows/hacs-validation.yaml
vendored
2
.github/workflows/hacs-validation.yaml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
name: HACS Action
|
name: HACS Action
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v4"
|
- uses: "actions/checkout@v6"
|
||||||
- name: HACS Action
|
- name: HACS Action
|
||||||
uses: "hacs/action@main"
|
uses: "hacs/action@main"
|
||||||
with:
|
with:
|
||||||
|
|||||||
4
.github/workflows/iobroker-localization.yml
vendored
4
.github/workflows/iobroker-localization.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
gen-ioBroker-localization:
|
gen-ioBroker-localization:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ jobs:
|
|||||||
python HMI/code_gen/localization/iobroker.py
|
python HMI/code_gen/localization/iobroker.py
|
||||||
mv ioBroker_NSPanel_locales.json ioBroker/ioBroker_NSPanel_locales.json
|
mv ioBroker_NSPanel_locales.json ioBroker/ioBroker_NSPanel_locales.json
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
- uses: stefanzweifel/git-auto-commit-action@v7
|
||||||
with:
|
with:
|
||||||
commit_message: Update iobroker localization file
|
commit_message: Update iobroker localization file
|
||||||
#file_pattern: "**.txt"
|
#file_pattern: "**.txt"
|
||||||
|
|||||||
6
.github/workflows/lint.yaml
vendored
6
.github/workflows/lint.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
addons: ${{ steps.addons.outputs.addons_list }}
|
addons: ${{ steps.addons.outputs.addons_list }}
|
||||||
steps:
|
steps:
|
||||||
- name: ⤵️ Check out code from GitHub
|
- name: ⤵️ Check out code from GitHub
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: 🔍 Find add-on directories
|
- name: 🔍 Find add-on directories
|
||||||
id: addons
|
id: addons
|
||||||
@@ -33,9 +33,9 @@ jobs:
|
|||||||
path: ${{ fromJson(needs.find.outputs.addons) }}
|
path: ${{ fromJson(needs.find.outputs.addons) }}
|
||||||
steps:
|
steps:
|
||||||
- name: ⤵️ Check out code from GitHub
|
- name: ⤵️ Check out code from GitHub
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: 🚀 Run Home Assistant Add-on Lint
|
- name: 🚀 Run Home Assistant Add-on Lint
|
||||||
uses: frenck/action-addon-linter@v2.18
|
uses: frenck/action-addon-linter@v2.21
|
||||||
with:
|
with:
|
||||||
path: "./${{ matrix.path }}"
|
path: "./${{ matrix.path }}"
|
||||||
|
|||||||
4
.github/workflows/nextion2text.yml
vendored
4
.github/workflows/nextion2text.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ jobs:
|
|||||||
find -name "**.txt"
|
find -name "**.txt"
|
||||||
rm Nextion2Text.py* ignore-id.py out.txt
|
rm Nextion2Text.py* ignore-id.py out.txt
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
- uses: stefanzweifel/git-auto-commit-action@v7
|
||||||
with:
|
with:
|
||||||
commit_message: ${{ steps.last-commit-message.outputs.msg }} (add nextion2text)
|
commit_message: ${{ steps.last-commit-message.outputs.msg }} (add nextion2text)
|
||||||
#file_pattern: "**.txt"
|
#file_pattern: "**.txt"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
+++ /dev/fd/62 2024-11-22 20:00:11.734673876 +0000
|
+++ /dev/fd/62 2025-12-26 19:43:25.803166597 +0000
|
||||||
+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 @@
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class LuiController(object):
|
|||||||
items = self._config.get_all_entity_names()
|
items = self._config.get_all_entity_names()
|
||||||
apis.ha_api.log(f"gtest123: {items}")
|
apis.ha_api.log(f"gtest123: {items}")
|
||||||
prefixes = ("navigate.", "delete", "iText")
|
prefixes = ("navigate.", "delete", "iText")
|
||||||
items = [x for x in items if not (x is None or x.startswith(prefixes))]
|
items = set([x for x in items if not (x is None or x.startswith(prefixes))])
|
||||||
apis.ha_api.log(f"Registering callbacks for the following items: {items}")
|
apis.ha_api.log(f"Registering callbacks for the following items: {items}")
|
||||||
for item in items:
|
for item in items:
|
||||||
if apis.ha_api.entity_exists(item):
|
if apis.ha_api.entity_exists(item):
|
||||||
|
|||||||
@@ -388,11 +388,12 @@ class LuiPagesGen(object):
|
|||||||
entityTypePanel = "text"
|
entityTypePanel = "text"
|
||||||
unit = get_attr_safe(entity, "temperature_unit", "")
|
unit = get_attr_safe(entity, "temperature_unit", "")
|
||||||
rt = None
|
rt = None
|
||||||
|
index = item.stype
|
||||||
if type(item.stype) == str and ":" in item.stype and len(item.stype.split(":")) == 2:
|
if type(item.stype) == str and ":" in item.stype and len(item.stype.split(":")) == 2:
|
||||||
spintstr = item.stype.split(":")
|
spintstr = item.stype.split(":")
|
||||||
rt = spintstr[0]
|
rt = spintstr[0]
|
||||||
item.stype = int(spintstr[1])
|
index = int(spintstr[1])
|
||||||
if type(item.stype) == int:
|
if type(index) == int:
|
||||||
bits = get_attr_safe(entity, "supported_features", 0b0)
|
bits = get_attr_safe(entity, "supported_features", 0b0)
|
||||||
if not rt:
|
if not rt:
|
||||||
rt = "daily"
|
rt = "daily"
|
||||||
@@ -407,8 +408,8 @@ class LuiPagesGen(object):
|
|||||||
"weather/get_forecasts", target={"entity_id": entityId}, service_data={"type": rt}
|
"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', [])
|
forecast = results.get("result", {}).get("response", {}).get(entityId, {}).get('forecast') or entity.attributes.get('forecast', [])
|
||||||
if len(forecast) >= item.stype:
|
if len(forecast) >= index:
|
||||||
day_forecast = forecast[item.stype]
|
day_forecast = forecast[index]
|
||||||
fdate = dp.parse(day_forecast['datetime'])
|
fdate = dp.parse(day_forecast['datetime'])
|
||||||
global babel_spec
|
global babel_spec
|
||||||
if babel_spec is not None:
|
if babel_spec is not None:
|
||||||
|
|||||||
@@ -1,70 +1,71 @@
|
|||||||
# Flash Tasmota to your NSPanel
|
# Flash Tasmota to Your NSPanel
|
||||||
|
|
||||||
You need to connect to your nspanel via serial and flash tasmota [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin) to your NSPanel.
|
You need to connect to your NSPanel via serial and flash Tasmota using [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin).
|
||||||
You can use the Tasmota Web Installer to do so. [Tasmota Web Installer](https://tasmota.github.io/install/)
|
You can use the [Tasmota Web Installer](https://tasmota.github.io/install/) to do so.
|
||||||
|
|
||||||
Checkout Blakadders Template Repo for more information on flashing, do not use the autoexec.be from this page.
|
Check out Blakadder's Template Repo for more information on flashing. **Do not** use the autoexec.be from that page.
|
||||||
[NSPanel Page of the Tasmota Template Repository](https://templates.blakadder.com/sonoff_NSPanel.html)
|
[NSPanel Page of the Tasmota Template Repository](https://templates.blakadder.com/sonoff_NSPanel.html)
|
||||||
|
|
||||||
If you prefer EspHome over Tasmota, you can use this thrid party esphome component, which is replacing tasmota and the berry driver of this project.
|
If you prefer ESPHome over Tasmota, you can use this third-party ESPHome component, which replaces Tasmota and the Berry driver used in this project.
|
||||||
[ESPHome component](https://github.com/sairon/esphome-nspanel-lovelace-ui)
|
[ESPHome Component](https://github.com/sairon/esphome-nspanel-lovelace-ui)
|
||||||
|
|
||||||
## Downgrade Tasmota
|
|
||||||
|
|
||||||
Downgrade your tasmoto to the 15.0.1 - in newer versions flashing the display is currently not working.
|
---
|
||||||
|
|
||||||
`https://ota.tasmota.com/tasmota32/release-15.0.1/tasmota32-nspanel.bin`
|
|
||||||
|
|
||||||
## Configure Tasmota Template for NSPanel
|
## Configure Tasmota Template for NSPanel
|
||||||
|
|
||||||
Configure the NSPanel template for Tasmota. (Go to Configuration and Configure Other and paste the template there, make sure to tick the activate checkbox)
|
Configure the NSPanel template for Tasmota. (Go to Configuration > Configure Other, paste the template there, and make sure to tick the Activate checkbox.)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
You can use the following template or copy the one on the [Tasmota Template Repo Site](https://templates.blakadder.com/sonoff_NSPanel.html).
|
You can use the following template or copy the one from the [Tasmota Template Repo Site](https://templates.blakadder.com/sonoff_NSPanel.html):
|
||||||
|
|
||||||
`{"NAME":"NSPanel","GPIO":[0,0,0,0,3872,0,0,0,0,0,32,0,0,0,0,225,0,480,224,1,0,0,0,33,0,0,0,0,0,0,0,0,0,0,4736,0],"FLAG":0,"BASE":1,"CMND":"ADCParam 2,11200,10000,3950 | Sleep 0 | BuzzerPWM 1"}`
|
{"NAME":"NSPanel","GPIO":[0,0,0,0,3872,0,0,0,0,0,32,0,0,0,0,225,0,480,224,1,0,0,0,33,0,0,0,0,0,0,0,0,0,0,4736,0],"FLAG":0,"BASE":1,"CMND":"ADCParam 2,11200,10000,3950 | Sleep 0 | BuzzerPWM 1"}
|
||||||
|
|
||||||
After a reboot of tasmota your screen will light up with the stock display firmware.
|
After a reboot of Tasmota, your screen will light up with the stock display firmware.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Upload Berry Driver to Tasmota
|
## Upload Berry Driver to Tasmota
|
||||||
|
|
||||||
Go to `Consoles` > `Console` in Tasmota and execute the following command:
|
Go to Consoles > Console in Tasmota and execute the following command:
|
||||||
|
|
||||||
```
|
Backlog UrlFetch https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; SetOption151 0; Restart 1
|
||||||
Backlog UrlFetch https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; SetOption151 0;Restart 1
|
|
||||||
```
|
|
||||||
|
|
||||||
This will download the autoexec.be file from the repository and restart tasmota.
|
This downloads the autoexec.be file from the repository and restarts Tasmota.
|
||||||
|
|
||||||
Note: The command is also disabling matter to free up memory, as it's most likely not used by any homeassistant users anyway.
|
Note: This command also disables Matter to free up memory, as it's unlikely to be used by most Home Assistant users. (Matter can cause memory issues during flashing of the Nextion screen, but you can re-enable it later if needed.)
|
||||||
(Matter could cause memory issues during flashing of the Nextion Screen, but you can still enable it if you need to.)
|
|
||||||
|
---
|
||||||
|
|
||||||
## Flash Firmware to Nextion Screen
|
## Flash Firmware to Nextion Screen
|
||||||
|
|
||||||
Due the limitations of Berry, it's not possible to download the tft file directly from github, so I'm also renting a small server where you can download the file via HTTP.
|
Due to the limitations of Berry, it's not possible to download the TFT file directly from GitHub. A small server is available to download the file via HTTP.
|
||||||
|
|
||||||
Use the one following commands in the tasmota console (not berry console) to flash the latest release from this repository:
|
Use one of the following commands in the Tasmota console (not the Berry console) to flash the latest release from this repository:
|
||||||
|
|
||||||
EU Version: `FlashNextion http://nspanel.pky.eu/lui-release.tft`
|
EU Version:
|
||||||
|
FlashNextion http://nspanel.pky.eu/lui-release.tft
|
||||||
|
|
||||||
US Version Portrait: `FlashNextion http://nspanel.pky.eu/lui-us-p-release.tft`
|
US Version Portrait:
|
||||||
|
FlashNextion http://nspanel.pky.eu/lui-us-p-release.tft
|
||||||
|
|
||||||
US Version Landscape: `FlashNextion http://nspanel.pky.eu/lui-us-l-release.tft`
|
US Version Landscape:
|
||||||
|
FlashNextion http://nspanel.pky.eu/lui-us-l-release.tft
|
||||||
|
|
||||||
After sending the command, the screen should show a progress bar. The flashing progress takes around 5 minutes.
|
After sending the command, the screen should show a progress bar. The flashing process takes around 5 minutes.
|
||||||
|
|
||||||
Note: For the US Version Users - keep in mind that you need to add the model config option to your apps.yaml later, more details on config overview page
|
Note for US users: You'll need to add the model config option to your apps.yaml later. More details can be found on the config overview page.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Alternatively you can use your own webserver or the one build into HomeAssistant:</summary>
|
<summary>Alternatively, you can use your own web server or the one built into Home Assistant:</summary>
|
||||||
<br>
|
<br>
|
||||||
Upload the nspanel.tft from the lastest release to a Webserver (for example www folder of Home Assistant) and execute the following command in Tasmota Console. (Development Version: [tft file from HMI folder](HMI/nspanel.tft))
|
Upload the nspanel.tft from the latest release to a web server (for example, the www folder of Home Assistant) and execute the following command in the Tasmota Console.
|
||||||
|
(Development version: [TFT file from HMI folder](HMI/nspanel.tft))
|
||||||
|
|
||||||
**Webserver must be HTTP, HTTPS is not supported, due to limitations of berry lang on tasmota**
|
**The web server must be HTTP. HTTPS is not supported due to Berry language limitations in Tasmota.**
|
||||||
|
|
||||||
`FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft`
|
FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
TypeScript v5.1.0.1 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar / @TT-Tom / @ticaki / @Britzelpuf / @Sternmiere / @ravenS0ne
|
TypeScript v5.1.1.3 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar / @TT-Tom / @ticaki / @Britzelpuf / @Sternmiere / @ravenS0ne
|
||||||
- abgestimmt auf TFT 60 / v5.1.0 / BerryDriver 10 / Tasmota 15.0.1
|
- abgestimmt auf TFT 61 / v5.1.1 (v5.1.2 us-p) / BerryDriver 10 / Tasmota 15.2.0
|
||||||
|
|
||||||
Projekt:
|
Projekt:
|
||||||
https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker
|
https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker
|
||||||
@@ -96,12 +96,17 @@ ReleaseNotes:
|
|||||||
- 19.10.2025 - v5.0.2.1 TFT 59 / 5.0.2 - EU/US-L/US-P - Fix cardAlarm Icon; Fix Notification in Advanced Screensaver; Fix Dimensions in cardChart/cardLChart
|
- 19.10.2025 - v5.0.2.1 TFT 59 / 5.0.2 - EU/US-L/US-P - Fix cardAlarm Icon; Fix Notification in Advanced Screensaver; Fix Dimensions in cardChart/cardLChart
|
||||||
- 12.11.2025 - v5.1.0 TFT 61 / 5.1.0 - Breaking Changes in popupNotify TFT - add 3. Button only for Adapter
|
- 12.11.2025 - v5.1.0 TFT 61 / 5.1.0 - Breaking Changes in popupNotify TFT - add 3. Button only for Adapter
|
||||||
- 12.11.2025 - v5.1.0.1 Change Brightsky icon to icon_special
|
- 12.11.2025 - v5.1.0.1 Change Brightsky icon to icon_special
|
||||||
|
- 15.11.2025 - v5.1.0.2 Add Swiss-Weather-API Adapter
|
||||||
|
- 18.11.2025 - v5.1.0.3 Fix QR-Code Generation cardQR
|
||||||
|
- 21.11.2025 - v5.1.1.1 Add some LongPress Actions in TFT/HMI v5.1.1 for NSPanel Adapter
|
||||||
|
- 21.11.2025 - v5.1.1.1 Remove Subscription if .ON and ON_ACTUAL
|
||||||
|
- 21.12.2025 - v5.1.1.2 Left screensaver unit from ioBroker data point to create a dynamic screensaver (by ernstdaheim-hub)
|
||||||
|
- 29.12.2025 - v5.1.1.3 Fix popupSlider (Standard-Slider (not cardMedia) with Functionality on popupSlider) / Wrong Pictures in us-p Slider if BG-Color is black (0)
|
||||||
|
|
||||||
***************************************************************************************************************
|
***************************************************************************************************************
|
||||||
* DE: Für die Erstellung der Aliase durch das Skript, muss in der JavaScript Instanz "setObject" gesetzt sein! *
|
* DE: Für die Erstellung der Aliase durch das Skript, muss in der JavaScript Instanz "setObject" gesetzt sein! *
|
||||||
* EN: In order for the script to create the aliases, “setObject” must be set in the JavaScript instance! *
|
* EN: In order for the script to create the aliases, “setObject” must be set in the JavaScript instance! *
|
||||||
***************************************************************************************************************{
|
***************************************************************************************************************
|
||||||
|
|
||||||
Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden
|
Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden
|
||||||
|
|
||||||
@@ -192,9 +197,13 @@ Tasmota-Status0 - (zyklische Ausführung)
|
|||||||
|
|
||||||
Erforderliche Adapter:
|
Erforderliche Adapter:
|
||||||
|
|
||||||
Pirate-Weather oder BrightSky oder OpenWeatherMap --> Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver
|
Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver einen der folgenden Wetter-Adapter:
|
||||||
!!!DasWetter deprecated - Dienst nur noch für ältere Accounts funktional
|
- Pirate-Weather
|
||||||
!!!AccuWeather deprecated - Dienst schaltet Free-Account ab!!!
|
- BrightSky
|
||||||
|
- OpenWeatherMap
|
||||||
|
- Swiss-Weather-API
|
||||||
|
- !!!DasWetter deprecated - Dienst nur noch für ältere Accounts funktional
|
||||||
|
- !!!AccuWeather deprecated - Dienst schaltet Free-Account ab!!!
|
||||||
Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia
|
Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia
|
||||||
Geräte verwalten - Für Erstellung der Aliase
|
Geräte verwalten - Für Erstellung der Aliase
|
||||||
MQTT-Adapter - Für Kommunikation zwischen Skript und Tasmota
|
MQTT-Adapter - Für Kommunikation zwischen Skript und Tasmota
|
||||||
@@ -205,10 +214,10 @@ Install/Upgrades in Konsole:
|
|||||||
Tasmota BerryDriver Install: Backlog UrlFetch https://raw.githubusercontent.com/ticaki/ioBroker.nspanel-lovelace-ui/refs/heads/main/tasmota/berry/10/autoexec.be; Restart 1
|
Tasmota BerryDriver Install: Backlog UrlFetch https://raw.githubusercontent.com/ticaki/ioBroker.nspanel-lovelace-ui/refs/heads/main/tasmota/berry/10/autoexec.be; Restart 1
|
||||||
Tasmota BerryDriver Update: Backlog UpdateDriverVersion https://raw.githubusercontent.com/ticaki/ioBroker.nspanel-lovelace-ui/refs/heads/main/tasmota/berry/10/autoexec.be; Restart 1
|
Tasmota BerryDriver Update: Backlog UpdateDriverVersion https://raw.githubusercontent.com/ticaki/ioBroker.nspanel-lovelace-ui/refs/heads/main/tasmota/berry/10/autoexec.be; Restart 1
|
||||||
|
|
||||||
TFT EU STABLE Version: FlashNextionAdv0 http://nspanel.de/nspanel-v5.1.0.tft
|
TFT EU STABLE Version: FlashNextionAdv0 http://nspanel.de/nspanel-v5.1.1.tft
|
||||||
|
|
||||||
TFT US-L STABLE Version: FlashNextionAdv0 http://nspanel.de/nspanel-us-l-v5.1.0.tft
|
TFT US-L STABLE Version: FlashNextionAdv0 http://nspanel.de/nspanel-us-l-v5.1.1.tft
|
||||||
TFT US-P STABLE Version: FlashNextionAdv0 http://nspanel.de/nspanel-us-p-v5.1.0.tft
|
TFT US-P STABLE Version: FlashNextionAdv0 http://nspanel.de/nspanel-us-p-v5.1.2.tft
|
||||||
---------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -256,8 +265,8 @@ const NSPanel_Alarm_Path = '0_userdata.0.NSPanel.';
|
|||||||
|
|
||||||
/***** 3. Weather adapter Config *****/
|
/***** 3. Weather adapter Config *****/
|
||||||
|
|
||||||
// DE: Mögliche Wetteradapter 'pirate-weather.0.' oder 'brightsky.0.' oder 'openweathermap.0.' oder 'daswetter.0.' (deprecated) oder 'accuweather.0.' (deprecated)
|
// DE: Mögliche Wetteradapter 'pirate-weather.0.' oder 'brightsky.0.' oder 'openweathermap.0.' oder 'swiss-weather-api.0.' oder 'daswetter.0.' (deprecated) oder 'accuweather.0.' (deprecated)
|
||||||
// EN: Possible weather adapters 'pirate-weather.0.' or 'brightsky.0.' or 'openweathermap.0.' or 'daswetter.0.' (deprecated) or 'accuweather.0.' (deprecated)
|
// EN: Possible weather adapters 'pirate-weather.0.' or 'brightsky.0.' or 'openweathermap.0.' or 'swiss-weather-api.0.' or 'daswetter.0.' (deprecated) or 'accuweather.0.' (deprecated)
|
||||||
const weatherAdapterInstance: string = 'pirate-weather.0.';
|
const weatherAdapterInstance: string = 'pirate-weather.0.';
|
||||||
|
|
||||||
// DE: Mögliche Werte: 'Min', 'Max' oder 'MinMax' im Screensaver
|
// DE: Mögliche Werte: 'Min', 'Max' oder 'MinMax' im Screensaver
|
||||||
@@ -408,10 +417,10 @@ const defaultBackgroundColorParam: any = HMIDark;
|
|||||||
- Servicemenü aus pages "NSPanel_Service" unter pages kommentieren ("//" hinzufügen)
|
- Servicemenü aus pages "NSPanel_Service" unter pages kommentieren ("//" hinzufügen)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*************************************************************************************************
|
/***********************************************************************************************
|
||||||
** Service pages with auto alias (subsequent pages are automatically created with alias) **
|
** Service pages with auto alias (subsequent pages are automatically created with alias) **
|
||||||
** https://github.com/joBr99/nspanel-lovelace-ui/wiki/NSPanel-Service-Men%C3%BC **
|
** https://github.com/joBr99/nspanel-lovelace-ui/wiki/NSPanel-Service-Men%C3%BC **
|
||||||
************************************************************************************************/
|
***********************************************************************************************/
|
||||||
|
|
||||||
/* EN: English
|
/* EN: English
|
||||||
If the service menu needs to be secured, a cardUnlock can be installed upstream.
|
If the service menu needs to be secured, a cardUnlock can be installed upstream.
|
||||||
@@ -824,7 +833,7 @@ export const config: Config = {
|
|||||||
NSPanel_Wifi_Info_2, //Auto-Alias Service Page
|
NSPanel_Wifi_Info_2, //Auto-Alias Service Page
|
||||||
NSPanel_Sensoren, //Auto-Alias Service Page
|
NSPanel_Sensoren, //Auto-Alias Service Page
|
||||||
NSPanel_Hardware, //Auto-Alias Service Page
|
NSPanel_Hardware, //Auto-Alias Service Page
|
||||||
NSPanel_IoBroker, //Auot-Alias Service Page
|
NSPanel_IoBroker, //Auto-Alias Service Page
|
||||||
NSPanel_Einstellungen, //Auto-Alias Service Page
|
NSPanel_Einstellungen, //Auto-Alias Service Page
|
||||||
NSPanel_Screensaver, //Auto-Alias Service Page
|
NSPanel_Screensaver, //Auto-Alias Service Page
|
||||||
NSPanel_ScreensaverDimmode, //Auto-Alias Service Page
|
NSPanel_ScreensaverDimmode, //Auto-Alias Service Page
|
||||||
@@ -994,8 +1003,8 @@ export const config: Config = {
|
|||||||
// _________________________________ DE: Ab hier keine Konfiguration mehr _____________________________________
|
// _________________________________ DE: Ab hier keine Konfiguration mehr _____________________________________
|
||||||
// _________________________________ EN: No more configuration from here _____________________________________
|
// _________________________________ EN: No more configuration from here _____________________________________
|
||||||
|
|
||||||
const scriptVersion: string = 'v5.1.0.1';
|
const scriptVersion: string = 'v5.1.1.3';
|
||||||
const tft_version: string = 'v5.1.0';
|
const tft_version: string = 'v5.1.1';
|
||||||
const desired_display_firmware_version = 61;
|
const desired_display_firmware_version = 61;
|
||||||
const berry_driver_version = 10;
|
const berry_driver_version = 10;
|
||||||
|
|
||||||
@@ -1113,6 +1122,11 @@ async function CheckConfigParameters () {
|
|||||||
log('Weather adapter: << weatherAdapterInstance - ' + weatherAdapterInstance + ' >> is not installed. Please Check Adapter!', 'error');
|
log('Weather adapter: << weatherAdapterInstance - ' + weatherAdapterInstance + ' >> is not installed. Please Check Adapter!', 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (weatherAdapterInstance.substring(0, weatherAdapterInstance.length - 3) == 'swiss-weather-api') {
|
||||||
|
if (existsObject(weatherAdapterInstance + 'forecast.days.day0.0000.symbol_code') == false) {
|
||||||
|
log('Weather adapter: << weatherAdapterInstance - ' + weatherAdapterInstance + ' >> is not installed. Please Check Adapter!', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let weatherAdapterInstanceArray: any = weatherAdapterInstance.split('.');
|
let weatherAdapterInstanceArray: any = weatherAdapterInstance.split('.');
|
||||||
weatherAdapterInstanceNumber = weatherAdapterInstanceArray[1];
|
weatherAdapterInstanceNumber = weatherAdapterInstanceArray[1];
|
||||||
@@ -2605,6 +2619,57 @@ async function CreateWeatherAlias () {
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
log('error at function CreateWeatherAlias brightsky.' + weatherAdapterInstanceNumber + '.: ' + err.message, 'warn');
|
log('error at function CreateWeatherAlias brightsky.' + weatherAdapterInstanceNumber + '.: ' + err.message, 'warn');
|
||||||
}
|
}
|
||||||
|
} else if (weatherAdapterInstance == 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.') {
|
||||||
|
try {
|
||||||
|
if (isSetOptionActive) {
|
||||||
|
if (!existsState(config.weatherEntity + '.ICON') && existsState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.symbol_code')) {
|
||||||
|
log('Weather alias for swiss-weather-api.' + weatherAdapterInstanceNumber + '. does not exist yet, will be created now', 'info');
|
||||||
|
setObject(config.weatherEntity, {
|
||||||
|
_id: config.weatherEntity,
|
||||||
|
type: 'channel',
|
||||||
|
common: {role: 'weatherCurrent', name: 'weatherCurrent'},
|
||||||
|
native: {}
|
||||||
|
});
|
||||||
|
await createAliasAsync(config.weatherEntity + '.ICON', ('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.symbol_code'), true, {
|
||||||
|
type: 'string',
|
||||||
|
role: 'value',
|
||||||
|
name: 'ICON',
|
||||||
|
alias: {id: 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.symbol_code'},
|
||||||
|
});
|
||||||
|
await createAliasAsync(config.weatherEntity + '.TEMP', 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.current_hour.TTT_C', true, {
|
||||||
|
type: 'number',
|
||||||
|
role: 'value.temperature',
|
||||||
|
name: 'TEMP',
|
||||||
|
alias: {
|
||||||
|
id: 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.current_hour.TTT_C',
|
||||||
|
read: 'Math.round(val*10)/10'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await createAliasAsync(config.weatherEntity + '.TEMP_MIN', 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.TN_C', true, {
|
||||||
|
type: 'number',
|
||||||
|
role: 'value.temperature.forecast.0',
|
||||||
|
name: 'TEMP_MIN',
|
||||||
|
alias: {
|
||||||
|
id: 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.TN_C',
|
||||||
|
read: 'Math.round(val)'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await createAliasAsync(config.weatherEntity + '.TEMP_MAX', 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.TX_C', true, {
|
||||||
|
type: 'number',
|
||||||
|
role: 'value.temperature.max.forecast.0',
|
||||||
|
name: 'TEMP_MAX',
|
||||||
|
alias: {
|
||||||
|
id: 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.TX_C',
|
||||||
|
read: 'Math.round(val)'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
log('weather alias for swiss-weather-api.' + weatherAdapterInstanceNumber + '. already exists', 'info');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
log('error at function CreateWeatherAlias swiss-weather-api.' + weatherAdapterInstanceNumber + '.: ' + err.message, 'warn');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
@@ -3899,6 +3964,7 @@ function get_current_tasmota_ip_address () {
|
|||||||
log('error at function get_current_tasmota_ip_address: ' + err.message, 'warn');
|
log('error at function get_current_tasmota_ip_address: ' + err.message, 'warn');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the current IP address of the Tasmota device.
|
* Retrieves the current IP address of the Tasmota device.
|
||||||
*
|
*
|
||||||
@@ -4377,7 +4443,6 @@ on({id: config.panelRecvTopic}, async (obj) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the Berry driver version on the NSPanel.
|
* Updates the Berry driver version on the NSPanel.
|
||||||
*
|
*
|
||||||
@@ -4668,6 +4733,7 @@ function HandleMessage (typ: string, method: NSPanel.EventMethod, page: number |
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'buttonPress3':
|
||||||
case 'buttonPress2':
|
case 'buttonPress2':
|
||||||
screensaverEnabled = false;
|
screensaverEnabled = false;
|
||||||
HandleButtonEvent(words);
|
HandleButtonEvent(words);
|
||||||
@@ -5174,7 +5240,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
val = getState(pageItem.id + '.ACTUAL').val;
|
val = getState(pageItem.id + '.ACTUAL').val;
|
||||||
RegisterEntityWatcher(pageItem.id + '.ACTUAL');
|
RegisterEntityWatcher(pageItem.id + '.ACTUAL');
|
||||||
}
|
}
|
||||||
if (existsState(pageItem.id + '.SET')) {
|
if (existsState(pageItem.id + '.SET') && !existsState(pageItem.id + 'ACTUAL')) {
|
||||||
val = getState(pageItem.id + '.SET').val;
|
val = getState(pageItem.id + '.SET').val;
|
||||||
RegisterEntityWatcher(pageItem.id + '.SET');
|
RegisterEntityWatcher(pageItem.id + '.SET');
|
||||||
}
|
}
|
||||||
@@ -5187,7 +5253,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
val = getState(pageItem.id + '.ON_SET').val;
|
val = getState(pageItem.id + '.ON_SET').val;
|
||||||
RegisterEntityWatcher(pageItem.id + '.ON_SET');
|
RegisterEntityWatcher(pageItem.id + '.ON_SET');
|
||||||
}
|
}
|
||||||
if (existsState(pageItem.id + '.ON')) {
|
if (existsState(pageItem.id + '.ON') && !existsState(pageItem.id + '.ON_ACTUAL')) {
|
||||||
val = getState(pageItem.id + '.ON').val;
|
val = getState(pageItem.id + '.ON').val;
|
||||||
RegisterEntityWatcher(pageItem.id + '.ON');
|
RegisterEntityWatcher(pageItem.id + '.ON');
|
||||||
}
|
}
|
||||||
@@ -5231,7 +5297,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
/**
|
/**
|
||||||
* The same extension can be found below in blind. vval=0 means closed / val=100 means open. If val is in between, icon3 is used.
|
* The same extension can be found below in blind. vval=0 means closed / val=100 means open. If val is in between, icon3 is used.
|
||||||
* Icons in this part can be states and strings. The specifications are based on German shutters.
|
* Icons in this part can be states and strings. The specifications are based on German shutters.
|
||||||
*/
|
*/
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['window-shutter', 'window-shutter-open', 'window-shutter-alert']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['window-shutter', 'window-shutter-open', 'window-shutter-alert']);
|
||||||
iconColor = existsState(pageItem.id + '.COLORDEC')
|
iconColor = existsState(pageItem.id + '.COLORDEC')
|
||||||
? getState(pageItem.id + '.COLORDEC').val
|
? getState(pageItem.id + '.COLORDEC').val
|
||||||
@@ -5341,7 +5407,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
||||||
} else if (role == 'humidity' || role == 'value.humidity') {
|
} else if (role == 'humidity' || role == 'value.humidity') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert' , 'water-percent']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert', 'water-percent']);
|
||||||
}
|
}
|
||||||
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
||||||
|
|
||||||
@@ -5448,7 +5514,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5492,7 +5558,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5532,7 +5598,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5587,7 +5653,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5614,7 +5680,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (Debug) log('CIE wurde zuletzt geändert - Lampe ist Color-Mode');
|
if (Debug) log('CIE wurde zuletzt geändert - Lampe ist Color-Mode');
|
||||||
if (getState(pageItem.id + '.CIE').val != null) {
|
if (getState(pageItem.id + '.CIE').val != null) {
|
||||||
let cie: string = getState(pageItem.id + '.CIE').val;
|
let cie: string = getState(pageItem.id + '.CIE').val;
|
||||||
let cieArray = (cie.substring(1, cie.length -1)).split(',');
|
let cieArray = (cie.substring(1, cie.length - 1)).split(',');
|
||||||
let rgb: RGB = cie_to_rgb(parseFloat(cieArray[0]), parseFloat(cieArray[1]), 254);
|
let rgb: RGB = cie_to_rgb(parseFloat(cieArray[0]), parseFloat(cieArray[1]), 254);
|
||||||
let cRGB: RGB = lightenDarkenColor(ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue), (100 - brightness) * -1);
|
let cRGB: RGB = lightenDarkenColor(ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue), (100 - brightness) * -1);
|
||||||
iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? cRGB : config.defaultOnColor);
|
iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? cRGB : config.defaultOnColor);
|
||||||
@@ -5641,7 +5707,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5697,7 +5763,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5723,7 +5789,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'shutter';
|
type = 'shutter';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'shutter2';
|
type = 'shutter2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5864,7 +5930,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
||||||
} else if (role == 'humidity' || role == 'value.humidity') {
|
} else if (role == 'humidity' || role == 'value.humidity') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert' , 'water-percent']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert', 'water-percent']);
|
||||||
}
|
}
|
||||||
|
|
||||||
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
||||||
@@ -5927,7 +5993,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (!pageItem.useValue) iconId = pageItem.icon != undefined ? Icons.GetIcon(pageItem.icon) : iconId;
|
if (!pageItem.useValue) iconId = pageItem.icon != undefined ? Icons.GetIcon(pageItem.icon) : iconId;
|
||||||
iconColor = pageItem.onColor != undefined ? rgb_dec565(pageItem.onColor) : iconColor;
|
iconColor = pageItem.onColor != undefined ? rgb_dec565(pageItem.onColor) : iconColor;
|
||||||
} else {
|
} else {
|
||||||
if(!pageItem.useValue) iconId = pageItem.icon2 != undefined ? Icons.GetIcon(pageItem.icon2) : iconId;
|
if (!pageItem.useValue) iconId = pageItem.icon2 != undefined ? Icons.GetIcon(pageItem.icon2) : iconId;
|
||||||
iconColor = pageItem.offColor != undefined ? rgb_dec565(pageItem.offColor) : iconColor;
|
iconColor = pageItem.offColor != undefined ? rgb_dec565(pageItem.offColor) : iconColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6354,7 +6420,7 @@ function RegisterEntityWatcher (id: string): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptions[id] = on({id: id, change: 'any'}, (obj) => {
|
subscriptions[id] = on({id: id, change: 'ne'}, (obj) => {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (obj.oldState && obj.oldState.val === obj.state.val && obj.state.ack) {
|
if (obj.oldState && obj.oldState.val === obj.state.val && obj.state.ack) {
|
||||||
return;
|
return;
|
||||||
@@ -7162,6 +7228,7 @@ function subscribeMediaSubscriptionsSonosAdd (id: string): void {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates media aliases for a specific media device and adapter player instance.
|
* Creates media aliases for a specific media device and adapter player instance.
|
||||||
*
|
*
|
||||||
@@ -8018,9 +8085,9 @@ function GenerateMediaPage (page: NSPanel.PageMedia): NSPanel.Payload[] {
|
|||||||
page.items[0].playList = getState(page.items[0].adapterPlayerInstance + 'playlists.playlistListString').val.split(';');
|
page.items[0].playList = getState(page.items[0].adapterPlayerInstance + 'playlists.playlistListString').val.split(';');
|
||||||
} else if (v2Adapter == 'mpd') {
|
} else if (v2Adapter == 'mpd') {
|
||||||
let tempPL = getState(page.items[0].adapterPlayerInstance + 'listplaylists').val;
|
let tempPL = getState(page.items[0].adapterPlayerInstance + 'listplaylists').val;
|
||||||
tempPL = tempPL.replace('[','');
|
tempPL = tempPL.replace('[', '');
|
||||||
tempPL = tempPL.replace(']','');
|
tempPL = tempPL.replace(']', '');
|
||||||
tempPL = tempPL.replaceAll('"','');
|
tempPL = tempPL.replaceAll('"', '');
|
||||||
page.items[0].playList = tempPL.split(',');
|
page.items[0].playList = tempPL.split(',');
|
||||||
}
|
}
|
||||||
playListIconCol = rgb_dec565(HMIOn);
|
playListIconCol = rgb_dec565(HMIOn);
|
||||||
@@ -8600,7 +8667,7 @@ async function createAutoQRAlias (id: string, dpPath: string) {
|
|||||||
if (autoCreateAlias) {
|
if (autoCreateAlias) {
|
||||||
if (isSetOptionActive) {
|
if (isSetOptionActive) {
|
||||||
if (existsState(dpPath + 'Daten') == false) {
|
if (existsState(dpPath + 'Daten') == false) {
|
||||||
await createStateAsync(dpPath + 'Daten', 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;', {type: 'string', write: true});
|
await createStateAsync(dpPath + 'Daten', 'WIFI:T:undefined;S:undefined;P:undefined;H:;', {type: 'string', write: true});
|
||||||
await createStateAsync(dpPath + 'Switch', false, {type: 'boolean', write: true});
|
await createStateAsync(dpPath + 'Switch', false, {type: 'boolean', write: true});
|
||||||
setObject(id, {_id: id, type: 'channel', common: {role: 'switch.mode.wlan', name: 'QR Page'}, native: {}});
|
setObject(id, {_id: id, type: 'channel', common: {role: 'switch.mode.wlan', name: 'QR Page'}, native: {}});
|
||||||
await createAliasAsync(id + '.ACTUAL', dpPath + 'Daten', true, {type: 'string', role: 'state', name: 'ACTUAL'});
|
await createAliasAsync(id + '.ACTUAL', dpPath + 'Daten', true, {type: 'string', role: 'state', name: 'ACTUAL'});
|
||||||
@@ -8645,7 +8712,7 @@ function GenerateQRPage (page: NSPanel.PageQR): NSPanel.Payload[] {
|
|||||||
let o = getObject(id);
|
let o = getObject(id);
|
||||||
|
|
||||||
let heading = page.heading !== undefined ? page.heading : typeof o.common.name === 'object' ? o.common.name.de : o.common.name;
|
let heading = page.heading !== undefined ? page.heading : typeof o.common.name === 'object' ? o.common.name.de : o.common.name;
|
||||||
let textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:undefined;';
|
let textQR = page.items[0].id + '.ACTUAL' !== undefined ? getState(page.items[0].id + '.ACTUAL').val : 'WIFI:T:undefined;S:undefined;P:undefined;H:;';
|
||||||
let hiddenPWD = false;
|
let hiddenPWD = false;
|
||||||
if (page.items[0].hidePassword !== undefined && page.items[0].hidePassword == true) {
|
if (page.items[0].hidePassword !== undefined && page.items[0].hidePassword == true) {
|
||||||
hiddenPWD = true;
|
hiddenPWD = true;
|
||||||
@@ -9103,6 +9170,7 @@ function triggerButton (id: string): boolean {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// End Monobutton
|
// End Monobutton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -10121,6 +10189,10 @@ function HandleButtonEvent (words: any): void {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let pageItemSlider = findPageItem(id);
|
||||||
|
let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItemSlider.maxValueLevel ? pageItemSlider.maxValue : 100, pageItemSlider.minValueLevel ? pageItemSlider.minValue : 0));
|
||||||
|
setIfExists(pageItemSlider.id + '.SET', sliderPos) ? true : setIfExists(id + '.ACTUAL', sliderPos);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'mode-seek':
|
case 'mode-seek':
|
||||||
@@ -10436,7 +10508,11 @@ function HandleButtonEvent (words: any): void {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
log('error at function HandleButtonEvent: ' + err.message, 'warn');
|
if (err.message == "Cannot read properties of undefined (reading 'id')") {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log('error at function HandleButtonEvent: ' + err.message, 'warn');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11377,7 +11453,7 @@ function GenerateDetailPage (type: NSPanel.PopupType, optional: NSPanel.mediaOpt
|
|||||||
let hSlider2MinVal: number = pageItem.minValue ?? 0;
|
let hSlider2MinVal: number = pageItem.minValue ?? 0;
|
||||||
let hSlider2MaxVal: number = pageItem.maxValue ?? 100;
|
let hSlider2MaxVal: number = pageItem.maxValue ?? 100;
|
||||||
let hSlider2ZeroVal: number = 0;
|
let hSlider2ZeroVal: number = 0;
|
||||||
let hSlider2CurVal: number = getState(id + '.ACTUAL').val;
|
let hSlider2CurVal: number = existsState(id + '.ACTUAL') ? getState(id + '.ACTUAL').val : getState(id + '.SET').val;
|
||||||
let hSlider2Step: number = 1;
|
let hSlider2Step: number = 1;
|
||||||
let hSlider2Visibility: string = "enable";
|
let hSlider2Visibility: string = "enable";
|
||||||
|
|
||||||
@@ -12393,7 +12469,10 @@ function HandleScreensaverUpdate (): void {
|
|||||||
} else if (weatherAdapterInstance == 'openweathermap.' + weatherAdapterInstanceNumber + '.') {
|
} else if (weatherAdapterInstance == 'openweathermap.' + weatherAdapterInstanceNumber + '.') {
|
||||||
entityIcon = Icons.GetIcon(GetOpenWeatherMapIcon(icon));
|
entityIcon = Icons.GetIcon(GetOpenWeatherMapIcon(icon));
|
||||||
entityIconCol = GetOpenWeatherMapIconColor(icon);
|
entityIconCol = GetOpenWeatherMapIconColor(icon);
|
||||||
} else if (weatherAdapterInstance == 'pirate-weather.' + weatherAdapterInstanceNumber + '.') {
|
} else if (weatherAdapterInstance == 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.') {
|
||||||
|
entityIcon = Icons.GetIcon(GetSwissWeatherApiIcon(icon));
|
||||||
|
entityIconCol = GetSwissWeatherApiIconColor(icon);
|
||||||
|
} else if (weatherAdapterInstance == 'pirate-weather.' + weatherAdapterInstanceNumber + '.' || weatherAdapterInstance == 'brightsky.' + weatherAdapterInstanceNumber + '.') {
|
||||||
entityIcon = Icons.GetIcon(GetPirateWeatherIcon(icon));
|
entityIcon = Icons.GetIcon(GetPirateWeatherIcon(icon));
|
||||||
entityIconCol = GetPirateWeatherIconColor(icon);
|
entityIconCol = GetPirateWeatherIconColor(icon);
|
||||||
} else if (weatherAdapterInstance == 'brightsky.' + weatherAdapterInstanceNumber + '.') {
|
} else if (weatherAdapterInstance == 'brightsky.' + weatherAdapterInstanceNumber + '.') {
|
||||||
@@ -12405,76 +12484,85 @@ function HandleScreensaverUpdate (): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3 leftScreensaverEntities
|
// 3 leftScreensaverEntities
|
||||||
if (screensaverAdvanced) {
|
if (screensaverAdvanced) {
|
||||||
let checkpoint = true;
|
let checkpoint = true;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
if (config.leftScreensaverEntity && Array.isArray(config.leftScreensaverEntity) && config.leftScreensaverEntity.length > 0) {
|
if (config.leftScreensaverEntity && Array.isArray(config.leftScreensaverEntity) && config.leftScreensaverEntity.length > 0) {
|
||||||
for (i = 0; i < 3 && i < config.leftScreensaverEntity.length; i++) {
|
for (i = 0; i < 3 && i < config.leftScreensaverEntity.length; i++) {
|
||||||
const leftScreensaverEntity = config.leftScreensaverEntity[i];
|
const leftScreensaverEntity = config.leftScreensaverEntity[i];
|
||||||
if (leftScreensaverEntity === null || leftScreensaverEntity === undefined) {
|
if (leftScreensaverEntity === null || leftScreensaverEntity === undefined) {
|
||||||
checkpoint = false;
|
checkpoint = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
RegisterScreensaverEntityWatcher(leftScreensaverEntity.ScreensaverEntity);
|
RegisterScreensaverEntityWatcher(leftScreensaverEntity.ScreensaverEntity);
|
||||||
|
|
||||||
let val = getState(leftScreensaverEntity.ScreensaverEntity).val;
|
let val = getState(leftScreensaverEntity.ScreensaverEntity).val;
|
||||||
let iconColor = rgb_dec565(White);
|
let iconColor = rgb_dec565(White);
|
||||||
let icon;
|
let icon;
|
||||||
if (typeof leftScreensaverEntity.ScreensaverEntityIconOn == 'string' && existsObject(leftScreensaverEntity.ScreensaverEntityIconOn as string)) {
|
if (typeof leftScreensaverEntity.ScreensaverEntityIconOn == 'string' && existsObject(leftScreensaverEntity.ScreensaverEntityIconOn as string)) {
|
||||||
let iconName = getState(leftScreensaverEntity.ScreensaverEntityIconOn!).val;
|
let iconName = getState(leftScreensaverEntity.ScreensaverEntityIconOn!).val;
|
||||||
icon = Icons.GetIcon(iconName);
|
icon = Icons.GetIcon(iconName);
|
||||||
} else {
|
} else {
|
||||||
icon = Icons.GetIcon(leftScreensaverEntity.ScreensaverEntityIconOn);
|
icon = Icons.GetIcon(leftScreensaverEntity.ScreensaverEntityIconOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseFloat(val + '') == val) {
|
if (parseFloat(val + '') == val) {
|
||||||
val = parseFloat(val);
|
val = parseFloat(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof val == 'number') {
|
if (typeof val == 'number') {
|
||||||
val = val * (leftScreensaverEntity.ScreensaverEntityFactor ? leftScreensaverEntity.ScreensaverEntityFactor! : 0)
|
val = val * (leftScreensaverEntity.ScreensaverEntityFactor ? leftScreensaverEntity.ScreensaverEntityFactor! : 0)
|
||||||
icon = determineScreensaverStatusIcon(leftScreensaverEntity,val,icon)
|
icon = determineScreensaverStatusIcon(leftScreensaverEntity, val, icon)
|
||||||
val = val.toFixed(
|
|
||||||
leftScreensaverEntity.ScreensaverEntityDecimalPlaces
|
|
||||||
) + leftScreensaverEntity.ScreensaverEntityUnitText;
|
|
||||||
iconColor = GetScreenSaverEntityColor(leftScreensaverEntity);
|
|
||||||
} else if (typeof val == 'boolean') {
|
|
||||||
iconColor = GetScreenSaverEntityColor(leftScreensaverEntity);
|
|
||||||
if (!val && leftScreensaverEntity.ScreensaverEntityIconOff != null) {
|
|
||||||
icon = Icons.GetIcon(leftScreensaverEntity.ScreensaverEntityIconOff);
|
|
||||||
}
|
|
||||||
} else if (typeof val == 'string') {
|
|
||||||
iconColor = GetScreenSaverEntityColor(leftScreensaverEntity);
|
|
||||||
let pformat = parseFormat(val);
|
|
||||||
if (Debug) log('moments.js --> Datum ' + val + ' valid?: ' + moment(val, pformat, true).isValid(), 'info');
|
|
||||||
if (moment(val, pformat, true).isValid()) {
|
|
||||||
let DatumZeit = moment(val, pformat).unix(); // Umwandlung in Unix Time-Stamp
|
|
||||||
if (leftScreensaverEntity.ScreensaverEntityDateFormat !== undefined) {
|
|
||||||
val = new Date(DatumZeit * 1000).toLocaleString(getState(NSPanel_Path + 'Config.locale').val, leftScreensaverEntity.ScreensaverEntityDateFormat);
|
|
||||||
} else {
|
|
||||||
val = new Date(DatumZeit * 1000).toLocaleString(getState(NSPanel_Path + 'Config.locale').val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const temp = leftScreensaverEntity.ScreensaverEntityIconColor;
|
|
||||||
if (temp && typeof temp == 'string' && existsObject(temp)) {
|
|
||||||
iconColor = getState(temp).val;
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadString += '~' + '~' + icon + '~' + iconColor + '~' + leftScreensaverEntity.ScreensaverEntityText + '~' + val + '~';
|
// Einheit ermitteln: String oder aus DP
|
||||||
}
|
let unitText = '';
|
||||||
}
|
if (typeof leftScreensaverEntity.ScreensaverEntityUnitText === 'string') {
|
||||||
|
if (existsObject(leftScreensaverEntity.ScreensaverEntityUnitText)) {
|
||||||
|
unitText = getState(leftScreensaverEntity.ScreensaverEntityUnitText).val;
|
||||||
|
} else {
|
||||||
|
unitText = leftScreensaverEntity.ScreensaverEntityUnitText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (i < 3) {
|
val = val.toFixed(leftScreensaverEntity.ScreensaverEntityDecimalPlaces) + unitText;
|
||||||
checkpoint = false;
|
iconColor = GetScreenSaverEntityColor(leftScreensaverEntity);
|
||||||
}
|
} else if (typeof val == 'boolean') {
|
||||||
|
iconColor = GetScreenSaverEntityColor(leftScreensaverEntity);
|
||||||
|
if (!val && leftScreensaverEntity.ScreensaverEntityIconOff != null) {
|
||||||
|
icon = Icons.GetIcon(leftScreensaverEntity.ScreensaverEntityIconOff);
|
||||||
|
}
|
||||||
|
} else if (typeof val == 'string') {
|
||||||
|
iconColor = GetScreenSaverEntityColor(leftScreensaverEntity);
|
||||||
|
let pformat = parseFormat(val);
|
||||||
|
if (Debug) log('moments.js --> Datum ' + val + ' valid?: ' + moment(val, pformat, true).isValid(), 'info');
|
||||||
|
if (moment(val, pformat, true).isValid()) {
|
||||||
|
let DatumZeit = moment(val, pformat).unix(); // Umwandlung in Unix Time-Stamp
|
||||||
|
if (leftScreensaverEntity.ScreensaverEntityDateFormat !== undefined) {
|
||||||
|
val = new Date(DatumZeit * 1000).toLocaleString(getState(NSPanel_Path + 'Config.locale').val, leftScreensaverEntity.ScreensaverEntityDateFormat);
|
||||||
|
} else {
|
||||||
|
val = new Date(DatumZeit * 1000).toLocaleString(getState(NSPanel_Path + 'Config.locale').val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const temp = leftScreensaverEntity.ScreensaverEntityIconColor;
|
||||||
|
if (temp && typeof temp == 'string' && existsObject(temp)) {
|
||||||
|
iconColor = getState(temp).val;
|
||||||
|
}
|
||||||
|
|
||||||
if (checkpoint == false) {
|
payloadString += '~' + '~' + icon + '~' + iconColor + '~' + leftScreensaverEntity.ScreensaverEntityText + '~' + val + '~';
|
||||||
for (let j = i; j < 3; j++) {
|
}
|
||||||
payloadString += '~~~~~~';
|
}
|
||||||
}
|
|
||||||
}
|
if (i < 3) {
|
||||||
}
|
checkpoint = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkpoint == false) {
|
||||||
|
for (let j = i; j < 3; j++) {
|
||||||
|
payloadString += '~~~~~~';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 6 bottomScreensaverEntities
|
// 6 bottomScreensaverEntities
|
||||||
let maxEntities: number = 7;
|
let maxEntities: number = 7;
|
||||||
@@ -12611,6 +12699,30 @@ function HandleScreensaverUpdate (): void {
|
|||||||
RegisterScreensaverEntityWatcher('brightsky.' + weatherAdapterInstanceNumber + '.daily.0' + String(i-1) + '.timestamp');
|
RegisterScreensaverEntityWatcher('brightsky.' + weatherAdapterInstanceNumber + '.daily.0' + String(i-1) + '.timestamp');
|
||||||
RegisterScreensaverEntityWatcher('brightsky.' + weatherAdapterInstanceNumber + '.daily.0' + String(i-1) + '.icon_special');
|
RegisterScreensaverEntityWatcher('brightsky.' + weatherAdapterInstanceNumber + '.daily.0' + String(i-1) + '.icon_special');
|
||||||
}
|
}
|
||||||
|
} else if (weatherAdapterInstance == 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.') {
|
||||||
|
if (i < 6) {
|
||||||
|
// swiss-weather-api. 0 .forecast.days.day 0 .0000.TN_C
|
||||||
|
TempMin = existsObject('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.TN_C')
|
||||||
|
? Math.round(getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.TN_C').val * 10) / 10
|
||||||
|
: 0;
|
||||||
|
TempMax = existsObject('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.TX_C')
|
||||||
|
? Math.round(getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.TX_C').val * 10) / 10
|
||||||
|
: 0;
|
||||||
|
DayOfWeek = existsObject('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.day_name')
|
||||||
|
? getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.day_name').val
|
||||||
|
: 0;
|
||||||
|
WeatherIcon = existsObject('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.symbol_code')
|
||||||
|
? GetSwissWeatherApiIcon(String(getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.symbol_code').val))
|
||||||
|
: '';
|
||||||
|
WheatherColor = existsObject('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.symbol_code')
|
||||||
|
? GetSwissWeatherApiIconColor(String(getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.symbol_code').val))
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
RegisterScreensaverEntityWatcher('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.TN_C');
|
||||||
|
RegisterScreensaverEntityWatcher('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.TX_C');
|
||||||
|
RegisterScreensaverEntityWatcher('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.day_name');
|
||||||
|
RegisterScreensaverEntityWatcher('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day' + String(i - 1) + '.0000.symbol_code');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tempMinMaxString: string = '';
|
let tempMinMaxString: string = '';
|
||||||
@@ -12719,6 +12831,30 @@ function HandleScreensaverUpdate (): void {
|
|||||||
sun = 'weather-sunset-up';
|
sun = 'weather-sunset-up';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payloadString += '~' + '~' + Icons.GetIcon(sun) + '~' + rgb_dec565(MSYellow) + '~' + 'Sonne' + '~' + formatDate(getDateObject(arraySunEvent[nextSunEvent]), 'hh:mm') + '~';
|
||||||
|
} else if (weatherAdapterInstance == 'swiss-weather-api.' + weatherAdapterInstanceNumber + '.' && i == 6) {
|
||||||
|
let nextSunEvent = 0;
|
||||||
|
let valDateNow = getDateObject((new Date().getTime())).getTime();
|
||||||
|
let arraySunEvent: number[] = [];
|
||||||
|
|
||||||
|
arraySunEvent[0] = getDateObject(getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.SUNRISE').val).getTime();
|
||||||
|
arraySunEvent[1] = getDateObject(getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day0.0000.SUNSET').val).getTime();
|
||||||
|
arraySunEvent[2] = getDateObject(getState('swiss-weather-api.' + weatherAdapterInstanceNumber + '.forecast.days.day1.0000.SUNRISE').val).getTime();
|
||||||
|
|
||||||
|
let j = 0;
|
||||||
|
for (j = 0; j < 3; j++) {
|
||||||
|
if (arraySunEvent[j] > valDateNow) {
|
||||||
|
nextSunEvent = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let sun = '';
|
||||||
|
if (j == 1) {
|
||||||
|
sun = 'weather-sunset-down';
|
||||||
|
} else {
|
||||||
|
sun = 'weather-sunset-up';
|
||||||
|
}
|
||||||
|
|
||||||
payloadString += '~' + '~' + Icons.GetIcon(sun) + '~' + rgb_dec565(MSYellow) + '~' + 'Sonne' + '~' + formatDate(getDateObject(arraySunEvent[nextSunEvent]), 'hh:mm') + '~';
|
payloadString += '~' + '~' + Icons.GetIcon(sun) + '~' + rgb_dec565(MSYellow) + '~' + 'Sonne' + '~' + formatDate(getDateObject(arraySunEvent[nextSunEvent]), 'hh:mm') + '~';
|
||||||
} else {
|
} else {
|
||||||
payloadString += '~' + '~' + Icons.GetIcon(WeatherIcon) + '~' + WheatherColor + '~' + DayOfWeek + '~' + tempMinMaxString + '~';
|
payloadString += '~' + '~' + Icons.GetIcon(WeatherIcon) + '~' + WheatherColor + '~' + DayOfWeek + '~' + tempMinMaxString + '~';
|
||||||
@@ -13691,6 +13827,193 @@ function GetOpenWeatherMapIconColor (icon: string): number {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the SwissWeatherApi icon string based on the provided icon string.
|
||||||
|
*
|
||||||
|
* This function maps the given SwissWeatherApi icon string to its corresponding icon string representation.
|
||||||
|
* See https://github.com/baerengraben/ioBroker.swiss-weather-api/tree/master/img/Meteo_API_Icons/Color for
|
||||||
|
* list of icons.
|
||||||
|
*
|
||||||
|
* @function GetSwissWeatherApiIcon
|
||||||
|
* @param {string} icon - The icon string.
|
||||||
|
* @returns {string} The corresponding icon string.
|
||||||
|
*/
|
||||||
|
function GetSwissWeatherApiIcon(icon: string): string {
|
||||||
|
try {
|
||||||
|
switch (icon) {
|
||||||
|
case "1":
|
||||||
|
return 'weather-sunny';
|
||||||
|
case "-1":
|
||||||
|
return 'weather-night';
|
||||||
|
case "3": //few clouds day
|
||||||
|
return 'weather-partly-cloudy';
|
||||||
|
case "-3": //few clouds night
|
||||||
|
return 'weather-night-partly-cloudy';
|
||||||
|
case "10": //scattered clouds
|
||||||
|
case "-10":
|
||||||
|
return 'weather-cloudy';
|
||||||
|
case "18": //cloudy
|
||||||
|
case "-18":
|
||||||
|
case "19":
|
||||||
|
case "-19":
|
||||||
|
return 'weather-cloudy';
|
||||||
|
case "23": //shower rain
|
||||||
|
case "-23":
|
||||||
|
return 'weather-rainy';
|
||||||
|
case "4": //rain
|
||||||
|
case "-4":
|
||||||
|
case "8":
|
||||||
|
case "-8":
|
||||||
|
case "11":
|
||||||
|
case "-11":
|
||||||
|
case "15":
|
||||||
|
case "-15":
|
||||||
|
case "20":
|
||||||
|
case "-20":
|
||||||
|
case "22":
|
||||||
|
case "-22":
|
||||||
|
case "25":
|
||||||
|
case "-25":
|
||||||
|
case "29":
|
||||||
|
case "-29":
|
||||||
|
return 'weather-pouring';
|
||||||
|
case "5": //Thunderstorm
|
||||||
|
case "-5":
|
||||||
|
case "7":
|
||||||
|
case "-7":
|
||||||
|
case "9":
|
||||||
|
case "-9":
|
||||||
|
case "12":
|
||||||
|
case "-12":
|
||||||
|
case "14":
|
||||||
|
case "-14":
|
||||||
|
case "16":
|
||||||
|
case "-16":
|
||||||
|
case "26":
|
||||||
|
case "-26":
|
||||||
|
case "28":
|
||||||
|
case "-28":
|
||||||
|
case "30":
|
||||||
|
case "-30":
|
||||||
|
return 'weather-lightning';
|
||||||
|
case "6": //snow
|
||||||
|
case "-6":
|
||||||
|
case "13":
|
||||||
|
case "-13":
|
||||||
|
case "21":
|
||||||
|
case "-21":
|
||||||
|
case "24":
|
||||||
|
case "-24":
|
||||||
|
case "27":
|
||||||
|
case "-27":
|
||||||
|
return 'weather-snowy';
|
||||||
|
case "2": //mist
|
||||||
|
case "-2":
|
||||||
|
case "17":
|
||||||
|
case "-17":
|
||||||
|
return 'weather-fog';
|
||||||
|
default:
|
||||||
|
return 'alert-circle-outline';
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
log('error at function GetSwissWeatherApiIcon: ' + err.message, 'warn');
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the color code for a given SwissWeatherApi icon string.
|
||||||
|
*
|
||||||
|
* This function maps the provided SwissWeatherApi icon string to its corresponding color code.
|
||||||
|
* See https://github.com/baerengraben/ioBroker.swiss-weather-api/tree/master/img/Meteo_API_Icons/Color for
|
||||||
|
* list of icons.
|
||||||
|
*
|
||||||
|
* @function GetSwissWeatherApiIconColor
|
||||||
|
* @param {string} icon - The icon string.
|
||||||
|
* @returns {number} The corresponding color code.
|
||||||
|
*/
|
||||||
|
function GetSwissWeatherApiIconColor(icon: string): number {
|
||||||
|
try {
|
||||||
|
switch (icon) {
|
||||||
|
case "1": //clear sky day
|
||||||
|
return rgb_dec565(swSunny);
|
||||||
|
case "-1": //clear sky night
|
||||||
|
return rgb_dec565(swClearNight);
|
||||||
|
case "3": //few clouds day
|
||||||
|
case "-3": //few clouds night
|
||||||
|
return rgb_dec565(swPartlycloudy);
|
||||||
|
case "10": //scattered clouds
|
||||||
|
case "-10":
|
||||||
|
return rgb_dec565(swCloudy);
|
||||||
|
case "18": //cloudy
|
||||||
|
case "-18":
|
||||||
|
case "19":
|
||||||
|
case "-19":
|
||||||
|
return rgb_dec565(swCloudy);
|
||||||
|
case "23": //shower rain
|
||||||
|
case "-23":
|
||||||
|
return rgb_dec565(swRainy);
|
||||||
|
case "4": //rain
|
||||||
|
case "-4":
|
||||||
|
case "8":
|
||||||
|
case "-8":
|
||||||
|
case "11":
|
||||||
|
case "-11":
|
||||||
|
case "15":
|
||||||
|
case "-15":
|
||||||
|
case "20":
|
||||||
|
case "-20":
|
||||||
|
case "22":
|
||||||
|
case "-22":
|
||||||
|
case "25":
|
||||||
|
case "-25":
|
||||||
|
case "29":
|
||||||
|
case "-29":
|
||||||
|
return rgb_dec565(swPouring);
|
||||||
|
case "5": //Thunderstorm
|
||||||
|
case "-5":
|
||||||
|
case "7":
|
||||||
|
case "-7":
|
||||||
|
case "9":
|
||||||
|
case "-9":
|
||||||
|
case "12":
|
||||||
|
case "-12":
|
||||||
|
case "14":
|
||||||
|
case "-14":
|
||||||
|
case "16":
|
||||||
|
case "-16":
|
||||||
|
case "26":
|
||||||
|
case "-26":
|
||||||
|
case "28":
|
||||||
|
case "-28":
|
||||||
|
case "30":
|
||||||
|
case "-30":
|
||||||
|
return rgb_dec565(swLightningRainy);
|
||||||
|
case "6": //snow
|
||||||
|
case "-6":
|
||||||
|
case "13":
|
||||||
|
case "-13":
|
||||||
|
case "21":
|
||||||
|
case "-21":
|
||||||
|
case "24":
|
||||||
|
case "-24":
|
||||||
|
case "27":
|
||||||
|
case "-27":
|
||||||
|
return rgb_dec565(swSnowy);
|
||||||
|
case "2": //mist
|
||||||
|
case "-2":
|
||||||
|
case "17":
|
||||||
|
case "-17":
|
||||||
|
return rgb_dec565(swFog);
|
||||||
|
default:
|
||||||
|
return rgb_dec565(White);
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
log('error at function GetSwissWeatherApiIconColor: ' + err.message, 'warn');
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the PirateWeather icon string based on the provided icon string.
|
* Retrieves the PirateWeather icon string based on the provided icon string.
|
||||||
*
|
*
|
||||||
@@ -14002,6 +14325,7 @@ on({id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESUL
|
|||||||
log('error Trigger reading senor-data: ' + err.message, 'warn');
|
log('error Trigger reading senor-data: ' + err.message, 'warn');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//------------------End Read Internal Sensor Data
|
//------------------End Read Internal Sensor Data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14449,6 +14773,7 @@ function determineStatusIcon (
|
|||||||
if (min === undefined || max === undefined) {
|
if (min === undefined || max === undefined) {
|
||||||
return iconId;
|
return iconId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickIcon(iconKey?: string, defIndex?: number): string {
|
function pickIcon(iconKey?: string, defIndex?: number): string {
|
||||||
return (
|
return (
|
||||||
(iconKey && existsState(iconKey) && Icons.GetIcon(getState(iconKey).val)) ||
|
(iconKey && existsState(iconKey) && Icons.GetIcon(getState(iconKey).val)) ||
|
||||||
@@ -14489,6 +14814,7 @@ function spotifyGetDeviceID (vDeviceString: string): string {
|
|||||||
let strDevID = arrayDeviceListIds[indexPos];
|
let strDevID = arrayDeviceListIds[indexPos];
|
||||||
return strDevID;
|
return strDevID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Join arguments with ~ and return the string;
|
* Join arguments with ~ and return the string;
|
||||||
* @param tokens unlimited numbers of strings
|
* @param tokens unlimited numbers of strings
|
||||||
@@ -14564,6 +14890,7 @@ function _schedule (time: {hour?: number; minute?: number} | undefined | number,
|
|||||||
const timeout = targetTime - new Date().getTime();
|
const timeout = targetTime - new Date().getTime();
|
||||||
scheduleList[ref] = setTimeout(_schedule, timeout, time, ref, repeatTime, callback);
|
scheduleList[ref] = setTimeout(_schedule, timeout, time, ref, repeatTime, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears a scheduled task based on the reference ID.
|
* Clears a scheduled task based on the reference ID.
|
||||||
*
|
*
|
||||||
@@ -14578,6 +14905,7 @@ function _clearSchedule (ref: number): null {
|
|||||||
delete scheduleList[ref];
|
delete scheduleList[ref];
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ArrayPlayerTypeWithMediaDevice = ['alexa2', 'sonos', 'squeezeboxrpc'] as const;
|
const ArrayPlayerTypeWithMediaDevice = ['alexa2', 'sonos', 'squeezeboxrpc'] as const;
|
||||||
const ArrayPlayerTypeWithOutMediaDevice = ['spotify-premium', 'volumio', 'bosesoundtouch', 'mpd'] as const;
|
const ArrayPlayerTypeWithOutMediaDevice = ['spotify-premium', 'volumio', 'bosesoundtouch', 'mpd'] as const;
|
||||||
|
|
||||||
@@ -14593,6 +14921,7 @@ const ArrayPlayerTypeWithOutMediaDevice = ['spotify-premium', 'volumio', 'boseso
|
|||||||
function isPlayerWithMediaDevice (F: string | NSPanel._PlayerTypeWithMediaDevice): F is NSPanel._PlayerTypeWithMediaDevice {
|
function isPlayerWithMediaDevice (F: string | NSPanel._PlayerTypeWithMediaDevice): F is NSPanel._PlayerTypeWithMediaDevice {
|
||||||
return ArrayPlayerTypeWithMediaDevice.indexOf(F as NSPanel._PlayerTypeWithMediaDevice) != -1;
|
return ArrayPlayerTypeWithMediaDevice.indexOf(F as NSPanel._PlayerTypeWithMediaDevice) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** check if NSPanel.adapterPlayerInstanceType has all Playertypes */
|
/** check if NSPanel.adapterPlayerInstanceType has all Playertypes */
|
||||||
function checkSortedPlayerType (F: NSPanel.notSortedPlayerType) {
|
function checkSortedPlayerType (F: NSPanel.notSortedPlayerType) {
|
||||||
const test: NSPanel.adapterPlayerInstanceType = F;
|
const test: NSPanel.adapterPlayerInstanceType = F;
|
||||||
@@ -14639,6 +14968,7 @@ function isEventMethod (F: string | NSPanel.EventMethod): F is NSPanel.EventMeth
|
|||||||
case 'sleepReached':
|
case 'sleepReached':
|
||||||
case 'pageOpenDetail':
|
case 'pageOpenDetail':
|
||||||
case 'buttonPress2':
|
case 'buttonPress2':
|
||||||
|
case 'buttonPress3':
|
||||||
case 'renderCurrentPage':
|
case 'renderCurrentPage':
|
||||||
case 'button1':
|
case 'button1':
|
||||||
case 'button2':
|
case 'button2':
|
||||||
@@ -14678,10 +15008,12 @@ function isPopupType (F: NSPanel.PopupType | string): F is NSPanel.PopupType {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If u get a error here u forgot something in PagetypeType or PageType
|
// If u get a error here u forgot something in PagetypeType or PageType
|
||||||
function checkPageType (F: NSPanel.PagetypeType, A: NSPanel.PageType) {
|
function checkPageType (F: NSPanel.PagetypeType, A: NSPanel.PageType) {
|
||||||
A.type = F;
|
A.type = F;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPageMediaItem (F: NSPanel.PageItem | NSPanel.PageMediaItem): F is NSPanel.PageMediaItem {
|
function isPageMediaItem (F: NSPanel.PageItem | NSPanel.PageMediaItem): F is NSPanel.PageMediaItem {
|
||||||
return 'adapterPlayerInstance' in F;
|
return 'adapterPlayerInstance' in F;
|
||||||
}
|
}
|
||||||
@@ -14693,6 +15025,7 @@ function isPageThermoItem (F: PageItem | NSPanel.PageThermoItem): F is NSPanel.P
|
|||||||
function isPageMedia (F: NSPanel.PageType | NSPanel.PageMedia): F is NSPanel.PageMedia {
|
function isPageMedia (F: NSPanel.PageType | NSPanel.PageMedia): F is NSPanel.PageMedia {
|
||||||
return F.type == 'cardMedia';
|
return F.type == 'cardMedia';
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPagePower (F: NSPanel.PageType | NSPanel.PagePower): F is NSPanel.PagePower {
|
function isPagePower (F: NSPanel.PageType | NSPanel.PagePower): F is NSPanel.PagePower {
|
||||||
return F.type == 'cardPower';
|
return F.type == 'cardPower';
|
||||||
}
|
}
|
||||||
@@ -14700,7 +15033,7 @@ function isPagePower (F: NSPanel.PageType | NSPanel.PagePower): F is NSPanel.Pag
|
|||||||
namespace NSPanel {
|
namespace NSPanel {
|
||||||
export type PopupType = 'popupFan' | 'popupInSel' | 'popupLight' | 'popupNotify' | 'popupShutter' | 'popupShutter2' | 'popupSlider' | 'popupThermo' | 'popupTimer' | 'popupColor';
|
export type PopupType = 'popupFan' | 'popupInSel' | 'popupLight' | 'popupNotify' | 'popupShutter' | 'popupShutter2' | 'popupSlider' | 'popupThermo' | 'popupTimer' | 'popupColor';
|
||||||
|
|
||||||
export type EventMethod = 'startup' | 'sleepReached' | 'pageOpenDetail' | 'buttonPress2' | 'renderCurrentPage' | 'button1' | 'button2';
|
export type EventMethod = 'startup' | 'sleepReached' | 'pageOpenDetail' | 'buttonPress2' | 'buttonPress3' | 'renderCurrentPage' | 'button1' | 'button2';
|
||||||
export type panelRecvType = {
|
export type panelRecvType = {
|
||||||
event: 'event';
|
event: 'event';
|
||||||
method: EventMethod;
|
method: EventMethod;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ ReleaseNotes:
|
|||||||
***************************************************************************************************************
|
***************************************************************************************************************
|
||||||
* DE: Für die Erstellung der Aliase durch das Skript, muss in der JavaScript Instanz "setObject" gesetzt sein! *
|
* DE: Für die Erstellung der Aliase durch das Skript, muss in der JavaScript Instanz "setObject" gesetzt sein! *
|
||||||
* EN: In order for the script to create the aliases, “setObject” must be set in the JavaScript instance! *
|
* EN: In order for the script to create the aliases, “setObject” must be set in the JavaScript instance! *
|
||||||
***************************************************************************************************************{
|
***************************************************************************************************************
|
||||||
|
|
||||||
Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden
|
Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden
|
||||||
|
|
||||||
@@ -406,10 +406,10 @@ const defaultBackgroundColorParam: any = HMIDark;
|
|||||||
- Servicemenü aus pages "NSPanel_Service" unter pages kommentieren ("//" hinzufügen)
|
- Servicemenü aus pages "NSPanel_Service" unter pages kommentieren ("//" hinzufügen)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*************************************************************************************************
|
/***********************************************************************************************
|
||||||
** Service pages with auto alias (subsequent pages are automatically created with alias) **
|
** Service pages with auto alias (subsequent pages are automatically created with alias) **
|
||||||
** https://github.com/joBr99/nspanel-lovelace-ui/wiki/NSPanel-Service-Men%C3%BC **
|
** https://github.com/joBr99/nspanel-lovelace-ui/wiki/NSPanel-Service-Men%C3%BC **
|
||||||
************************************************************************************************/
|
***********************************************************************************************/
|
||||||
|
|
||||||
/* EN: English
|
/* EN: English
|
||||||
If the service menu needs to be secured, a cardUnlock can be installed upstream.
|
If the service menu needs to be secured, a cardUnlock can be installed upstream.
|
||||||
@@ -822,7 +822,7 @@ export const config: Config = {
|
|||||||
NSPanel_Wifi_Info_2, //Auto-Alias Service Page
|
NSPanel_Wifi_Info_2, //Auto-Alias Service Page
|
||||||
NSPanel_Sensoren, //Auto-Alias Service Page
|
NSPanel_Sensoren, //Auto-Alias Service Page
|
||||||
NSPanel_Hardware, //Auto-Alias Service Page
|
NSPanel_Hardware, //Auto-Alias Service Page
|
||||||
NSPanel_IoBroker, //Auot-Alias Service Page
|
NSPanel_IoBroker, //Auto-Alias Service Page
|
||||||
NSPanel_Einstellungen, //Auto-Alias Service Page
|
NSPanel_Einstellungen, //Auto-Alias Service Page
|
||||||
NSPanel_Screensaver, //Auto-Alias Service Page
|
NSPanel_Screensaver, //Auto-Alias Service Page
|
||||||
NSPanel_ScreensaverDimmode, //Auto-Alias Service Page
|
NSPanel_ScreensaverDimmode, //Auto-Alias Service Page
|
||||||
@@ -3895,6 +3895,7 @@ function get_current_tasmota_ip_address () {
|
|||||||
log('error at function get_current_tasmota_ip_address: ' + err.message, 'warn');
|
log('error at function get_current_tasmota_ip_address: ' + err.message, 'warn');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the current IP address of the Tasmota device.
|
* Retrieves the current IP address of the Tasmota device.
|
||||||
*
|
*
|
||||||
@@ -4373,7 +4374,6 @@ on({id: config.panelRecvTopic}, async (obj) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the Berry driver version on the NSPanel.
|
* Updates the Berry driver version on the NSPanel.
|
||||||
*
|
*
|
||||||
@@ -5227,7 +5227,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
/**
|
/**
|
||||||
* The same extension can be found below in blind. vval=0 means closed / val=100 means open. If val is in between, icon3 is used.
|
* The same extension can be found below in blind. vval=0 means closed / val=100 means open. If val is in between, icon3 is used.
|
||||||
* Icons in this part can be states and strings. The specifications are based on German shutters.
|
* Icons in this part can be states and strings. The specifications are based on German shutters.
|
||||||
*/
|
*/
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['window-shutter', 'window-shutter-open', 'window-shutter-alert']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['window-shutter', 'window-shutter-open', 'window-shutter-alert']);
|
||||||
iconColor = existsState(pageItem.id + '.COLORDEC')
|
iconColor = existsState(pageItem.id + '.COLORDEC')
|
||||||
? getState(pageItem.id + '.COLORDEC').val
|
? getState(pageItem.id + '.COLORDEC').val
|
||||||
@@ -5337,7 +5337,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
||||||
} else if (role == 'humidity' || role == 'value.humidity') {
|
} else if (role == 'humidity' || role == 'value.humidity') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert' , 'water-percent']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert', 'water-percent']);
|
||||||
}
|
}
|
||||||
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
||||||
|
|
||||||
@@ -5444,7 +5444,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5488,7 +5488,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5528,7 +5528,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5583,7 +5583,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5610,7 +5610,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (Debug) log('CIE wurde zuletzt geändert - Lampe ist Color-Mode');
|
if (Debug) log('CIE wurde zuletzt geändert - Lampe ist Color-Mode');
|
||||||
if (getState(pageItem.id + '.CIE').val != null) {
|
if (getState(pageItem.id + '.CIE').val != null) {
|
||||||
let cie: string = getState(pageItem.id + '.CIE').val;
|
let cie: string = getState(pageItem.id + '.CIE').val;
|
||||||
let cieArray = (cie.substring(1, cie.length -1)).split(',');
|
let cieArray = (cie.substring(1, cie.length - 1)).split(',');
|
||||||
let rgb: RGB = cie_to_rgb(parseFloat(cieArray[0]), parseFloat(cieArray[1]), 254);
|
let rgb: RGB = cie_to_rgb(parseFloat(cieArray[0]), parseFloat(cieArray[1]), 254);
|
||||||
let cRGB: RGB = lightenDarkenColor(ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue), (100 - brightness) * -1);
|
let cRGB: RGB = lightenDarkenColor(ConvertRGBtoHex(rgb.red, rgb.green, rgb.blue), (100 - brightness) * -1);
|
||||||
iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? cRGB : config.defaultOnColor);
|
iconColor = rgb_dec565(pageItem.interpolateColor !== undefined ? cRGB : config.defaultOnColor);
|
||||||
@@ -5637,7 +5637,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5693,7 +5693,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'light';
|
type = 'light';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'light2';
|
type = 'light2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5719,7 +5719,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (pageItem.popupVersion !== undefined) {
|
if (pageItem.popupVersion !== undefined) {
|
||||||
if (pageItem.popupVersion == 1) {
|
if (pageItem.popupVersion == 1) {
|
||||||
type = 'shutter';
|
type = 'shutter';
|
||||||
} else if (pageItem.popupVersion == 2){
|
} else if (pageItem.popupVersion == 2) {
|
||||||
type = 'shutter2';
|
type = 'shutter2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5860,7 +5860,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
if (role == 'temperature' || role == 'value.temperature' || role == 'thermostat') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['snowflake-thermometer', 'sun-thermometer', 'thermometer']);
|
||||||
} else if (role == 'humidity' || role == 'value.humidity') {
|
} else if (role == 'humidity' || role == 'value.humidity') {
|
||||||
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert' , 'water-percent']);
|
iconId = determinePageItemStatusIcon(pageItem, val, iconId, ['water-off', 'water-percent-alert', 'water-percent']);
|
||||||
}
|
}
|
||||||
|
|
||||||
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
iconColor = GetIconColor(pageItem, parseInt(optVal), useColors);
|
||||||
@@ -5923,7 +5923,7 @@ function CreateEntity (pageItem: PageItem, placeId: number, useColors: boolean =
|
|||||||
if (!pageItem.useValue) iconId = pageItem.icon != undefined ? Icons.GetIcon(pageItem.icon) : iconId;
|
if (!pageItem.useValue) iconId = pageItem.icon != undefined ? Icons.GetIcon(pageItem.icon) : iconId;
|
||||||
iconColor = pageItem.onColor != undefined ? rgb_dec565(pageItem.onColor) : iconColor;
|
iconColor = pageItem.onColor != undefined ? rgb_dec565(pageItem.onColor) : iconColor;
|
||||||
} else {
|
} else {
|
||||||
if(!pageItem.useValue) iconId = pageItem.icon2 != undefined ? Icons.GetIcon(pageItem.icon2) : iconId;
|
if (!pageItem.useValue) iconId = pageItem.icon2 != undefined ? Icons.GetIcon(pageItem.icon2) : iconId;
|
||||||
iconColor = pageItem.offColor != undefined ? rgb_dec565(pageItem.offColor) : iconColor;
|
iconColor = pageItem.offColor != undefined ? rgb_dec565(pageItem.offColor) : iconColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7158,6 +7158,7 @@ function subscribeMediaSubscriptionsSonosAdd (id: string): void {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates media aliases for a specific media device and adapter player instance.
|
* Creates media aliases for a specific media device and adapter player instance.
|
||||||
*
|
*
|
||||||
@@ -8014,9 +8015,9 @@ function GenerateMediaPage (page: NSPanel.PageMedia): NSPanel.Payload[] {
|
|||||||
page.items[0].playList = getState(page.items[0].adapterPlayerInstance + 'playlists.playlistListString').val.split(';');
|
page.items[0].playList = getState(page.items[0].adapterPlayerInstance + 'playlists.playlistListString').val.split(';');
|
||||||
} else if (v2Adapter == 'mpd') {
|
} else if (v2Adapter == 'mpd') {
|
||||||
let tempPL = getState(page.items[0].adapterPlayerInstance + 'listplaylists').val;
|
let tempPL = getState(page.items[0].adapterPlayerInstance + 'listplaylists').val;
|
||||||
tempPL = tempPL.replace('[','');
|
tempPL = tempPL.replace('[', '');
|
||||||
tempPL = tempPL.replace(']','');
|
tempPL = tempPL.replace(']', '');
|
||||||
tempPL = tempPL.replaceAll('"','');
|
tempPL = tempPL.replaceAll('"', '');
|
||||||
page.items[0].playList = tempPL.split(',');
|
page.items[0].playList = tempPL.split(',');
|
||||||
}
|
}
|
||||||
playListIconCol = rgb_dec565(HMIOn);
|
playListIconCol = rgb_dec565(HMIOn);
|
||||||
@@ -9099,6 +9100,7 @@ function triggerButton (id: string): boolean {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// End Monobutton
|
// End Monobutton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13919,6 +13921,7 @@ on({id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESUL
|
|||||||
log('error Trigger reading senor-data: ' + err.message, 'warn');
|
log('error Trigger reading senor-data: ' + err.message, 'warn');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//------------------End Read Internal Sensor Data
|
//------------------End Read Internal Sensor Data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14366,6 +14369,7 @@ function determineStatusIcon (
|
|||||||
if (min === undefined || max === undefined) {
|
if (min === undefined || max === undefined) {
|
||||||
return iconId;
|
return iconId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickIcon(iconKey?: string, defIndex?: number): string {
|
function pickIcon(iconKey?: string, defIndex?: number): string {
|
||||||
return (
|
return (
|
||||||
(iconKey && existsState(iconKey) && Icons.GetIcon(getState(iconKey).val)) ||
|
(iconKey && existsState(iconKey) && Icons.GetIcon(getState(iconKey).val)) ||
|
||||||
@@ -14406,6 +14410,7 @@ function spotifyGetDeviceID (vDeviceString: string): string {
|
|||||||
let strDevID = arrayDeviceListIds[indexPos];
|
let strDevID = arrayDeviceListIds[indexPos];
|
||||||
return strDevID;
|
return strDevID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Join arguments with ~ and return the string;
|
* Join arguments with ~ and return the string;
|
||||||
* @param tokens unlimited numbers of strings
|
* @param tokens unlimited numbers of strings
|
||||||
@@ -14481,6 +14486,7 @@ function _schedule (time: {hour?: number; minute?: number} | undefined | number,
|
|||||||
const timeout = targetTime - new Date().getTime();
|
const timeout = targetTime - new Date().getTime();
|
||||||
scheduleList[ref] = setTimeout(_schedule, timeout, time, ref, repeatTime, callback);
|
scheduleList[ref] = setTimeout(_schedule, timeout, time, ref, repeatTime, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears a scheduled task based on the reference ID.
|
* Clears a scheduled task based on the reference ID.
|
||||||
*
|
*
|
||||||
@@ -14495,6 +14501,7 @@ function _clearSchedule (ref: number): null {
|
|||||||
delete scheduleList[ref];
|
delete scheduleList[ref];
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ArrayPlayerTypeWithMediaDevice = ['alexa2', 'sonos', 'squeezeboxrpc'] as const;
|
const ArrayPlayerTypeWithMediaDevice = ['alexa2', 'sonos', 'squeezeboxrpc'] as const;
|
||||||
const ArrayPlayerTypeWithOutMediaDevice = ['spotify-premium', 'volumio', 'bosesoundtouch', 'mpd'] as const;
|
const ArrayPlayerTypeWithOutMediaDevice = ['spotify-premium', 'volumio', 'bosesoundtouch', 'mpd'] as const;
|
||||||
|
|
||||||
@@ -14510,6 +14517,7 @@ const ArrayPlayerTypeWithOutMediaDevice = ['spotify-premium', 'volumio', 'boseso
|
|||||||
function isPlayerWithMediaDevice (F: string | NSPanel._PlayerTypeWithMediaDevice): F is NSPanel._PlayerTypeWithMediaDevice {
|
function isPlayerWithMediaDevice (F: string | NSPanel._PlayerTypeWithMediaDevice): F is NSPanel._PlayerTypeWithMediaDevice {
|
||||||
return ArrayPlayerTypeWithMediaDevice.indexOf(F as NSPanel._PlayerTypeWithMediaDevice) != -1;
|
return ArrayPlayerTypeWithMediaDevice.indexOf(F as NSPanel._PlayerTypeWithMediaDevice) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** check if NSPanel.adapterPlayerInstanceType has all Playertypes */
|
/** check if NSPanel.adapterPlayerInstanceType has all Playertypes */
|
||||||
function checkSortedPlayerType (F: NSPanel.notSortedPlayerType) {
|
function checkSortedPlayerType (F: NSPanel.notSortedPlayerType) {
|
||||||
const test: NSPanel.adapterPlayerInstanceType = F;
|
const test: NSPanel.adapterPlayerInstanceType = F;
|
||||||
@@ -14595,10 +14603,12 @@ function isPopupType (F: NSPanel.PopupType | string): F is NSPanel.PopupType {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If u get a error here u forgot something in PagetypeType or PageType
|
// If u get a error here u forgot something in PagetypeType or PageType
|
||||||
function checkPageType (F: NSPanel.PagetypeType, A: NSPanel.PageType) {
|
function checkPageType (F: NSPanel.PagetypeType, A: NSPanel.PageType) {
|
||||||
A.type = F;
|
A.type = F;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPageMediaItem (F: NSPanel.PageItem | NSPanel.PageMediaItem): F is NSPanel.PageMediaItem {
|
function isPageMediaItem (F: NSPanel.PageItem | NSPanel.PageMediaItem): F is NSPanel.PageMediaItem {
|
||||||
return 'adapterPlayerInstance' in F;
|
return 'adapterPlayerInstance' in F;
|
||||||
}
|
}
|
||||||
@@ -14610,6 +14620,7 @@ function isPageThermoItem (F: PageItem | NSPanel.PageThermoItem): F is NSPanel.P
|
|||||||
function isPageMedia (F: NSPanel.PageType | NSPanel.PageMedia): F is NSPanel.PageMedia {
|
function isPageMedia (F: NSPanel.PageType | NSPanel.PageMedia): F is NSPanel.PageMedia {
|
||||||
return F.type == 'cardMedia';
|
return F.type == 'cardMedia';
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPagePower (F: NSPanel.PageType | NSPanel.PagePower): F is NSPanel.PagePower {
|
function isPagePower (F: NSPanel.PageType | NSPanel.PagePower): F is NSPanel.PagePower {
|
||||||
return F.type == 'cardPower';
|
return F.type == 'cardPower';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user