diff --git a/README.md b/README.md
index d638198e..644f4e0f 100644
--- a/README.md
+++ b/README.md
@@ -357,8 +357,7 @@ key | optional | type | default | description
-Possible configuration values for config key
-
+### Possible configuration values for config key
key | optional | type | default | description
-- | -- | -- | -- | --
@@ -424,8 +423,8 @@ key | optional | type | default | description
-Possible configuration values for a card in card config
-
+#### Possible configuration values for a card in card config
+
key | optional | type | default | description
-- | -- | -- | -- | --
@@ -436,11 +435,7 @@ key | optional | type | default | description
`key` | True | string | `None` | Used by navigate items
-
-
-
-Possible configuration values for screensaver config
-
+#### Possible configuration values for screensaver config
key | optional | type | default | description
-- | -- | -- | -- | --
@@ -484,11 +479,6 @@ It is possible to schedule a brightness change for the screen at specific times.
value: 0
```
-
-
-
-Overrides and Navigation
-
#### Override Icons or Names
@@ -522,13 +512,6 @@ will allow you to navigate to a cardGrid page with the configured key testKey
```
-
-
-
-
-
-
-
diff --git a/apps/nspanel-lovelace-ui/luibackend/pages.py b/apps/nspanel-lovelace-ui/luibackend/pages.py
index 4ce283f1..2dc12359 100644
--- a/apps/nspanel-lovelace-ui/luibackend/pages.py
+++ b/apps/nspanel-lovelace-ui/luibackend/pages.py
@@ -68,8 +68,10 @@ class LuiPagesGen(object):
text_cur = convert_temperature(we.attributes.temperature, unit)
forecastSkip = self._config._config_screensaver.raw_config.get(f"forecastSkip")+1
- # check if the first 2 forecast items are on the same day
- same_day = dp.parse(we.attributes.forecast[0]['datetime']).weekday() == dp.parse(we.attributes.forecast[forecastSkip]['datetime']).weekday()
+ # check if the difference between the first 2 forecast items is less than 24h
+ difference = (dp.parse(we.attributes.forecast[forecastSkip]['datetime']) - dp.parse(we.attributes.forecast[0]['datetime']))
+ total_seconds = difference.total_seconds()
+ same_day = total_seconds < 86400
weather_res = ""
for i in range(1,5):
wOF = self._config._config_screensaver.raw_config.get(f"weatherOverrideForecast{i}")
@@ -77,7 +79,7 @@ class LuiPagesGen(object):
fid = (i-1)*forecastSkip
if len(we.attributes.forecast) >= fid:
up = we.attributes.forecast[fid]['datetime']
- up = dp.parse(up)
+ up = dp.parse(up).astimezone()
if babel_spec is not None:
if same_day:
up = babel.dates.format_time(up, "H:mm", locale=self._locale)
diff --git a/ioBroker/NsPanelTs.ts b/ioBroker/NsPanelTs.ts
index 3c4c017b..46404666 100644
--- a/ioBroker/NsPanelTs.ts
+++ b/ioBroker/NsPanelTs.ts
@@ -13,6 +13,20 @@ const On: RGB = { red: 253, green: 216, blue: 53 };
const BatteryFull: RGB = { red: 96, green: 176, blue: 62 }
const BatteryEmpty: RGB = { red: 179, green: 45, blue: 25 }
+
+//----Ability to choose between Accu-Weather Forcast or self-defined values in the screensaver---------------------------------
+var weatherForecast = true; //true = WheatherForecast 5 Days --- false = Config --> firstScreensaverEntity - fourthScreensaverEntity ...
+
+//Alexa2-Instanz
+var alexaInstanz = "alexa2.0"
+var alexaDevice = "G0XXXXXXXXXXXXXX"; //Primär zu steuendes Device
+//If alexaSpeakerList is defined, then entries are used, otherwise all relevant devices from the ioBroker Alexa2 adapter
+const alexaSpeakerList = []; //Example ["Echo Spot Buero","Überall","Gartenhaus","Esszimmer","Heimkino"];
+
+//Datenpunkte für Nachricht an Screensaver
+var popupNotifyHeading = "0_userdata.0.NSPanel.1.popupNotifyHeading";
+var popupNotifyText = "0_userdata.0.NSPanel.1.popupNotifyText";
+
var Wohnen: PageEntities =
{
"type": "cardEntities",
@@ -52,6 +66,13 @@ var Müll: PageEntities =
]
};
+var Alexa: PageMedia =
+{
+ "type": "cardMedia",
+ "heading": "Alexa",
+ "useColor": true,
+ "items": [{ id: "alias.0.NSPanel_1.Alexa.PlayerBuero" }]
+};
var button1Page: PageGrid =
{
@@ -95,7 +116,7 @@ export const config: Config = {
defaultOnColor: On,
defaultColor: Off,
temperatureUnit: "°C",
- pages: [Wohnen, Strom, Müll,
+ pages: [Wohnen, Strom, Müll, Alexa,
{
"type": "cardThermo",
"heading": "Thermostat",
@@ -205,11 +226,14 @@ function GeneratePage(page: Page): void {
case "cardGrid":
SendToPanel(GenerateGridPage(page));
break;
+ case "cardMedia":
+ SendToPanel(GenerateMediaPage(page));
+ break;
}
}
function HandleHardwareButton(method: string): void {
- let page: (PageThermo | PageEntities | PageGrid);
+ let page: (PageThermo | PageMedia | PageEntities | PageGrid);
if (config.button1Page !== null && method == "button1") {
page = config.button1Page;
pageId = -1;
@@ -275,6 +299,9 @@ function GeneratePageElements(page: Page): string {
case "cardThermo":
maxItems = 1;
break;
+ case "cardMedia":
+ maxItems = 1;
+ break;
case "cardEntities":
maxItems = 4;
break;
@@ -517,6 +544,65 @@ function GenerateThermoPage(page: PageThermo): Payload[] {
return out_msgs
}
+function GenerateMediaPage(page: PageMedia): Payload[] {
+ var id = page.items[0].id
+ var out_msgs: Array = [];
+ out_msgs.push({ payload: "pageType~cardMedia" });
+ if (existsObject(id)) {
+ let name = getState(id + ".ALBUM").val;
+ let media_icon = Icons.GetIcon("playlist-music");
+ let title = getState(id + ".TITLE").val;
+ let author = getState(id + ".ARTIST").val;
+ let volume = getState(id + ".VOLUME").val;
+ var iconplaypause = Icons.GetIcon("pause"); //pause
+ var onoffbutton = 1374;
+ if (getState(id + ".STATE").val) {
+ onoffbutton = 65535;
+ iconplaypause = Icons.GetIcon("pause"); //pause
+ } else {
+ iconplaypause = Icons.GetIcon("play"); //play
+ }
+ let currentSpeaker = getState(([alexaInstanz,'.Echo-Devices.',alexaDevice,'.Info.name'].join(''))).val;
+ //console.log(id);
+
+//-------------------------------------------------------------------------------------------------------------
+// nachfolgend alle Alexa-Devices (ist Online / Player- und Commands-Verzeichnis vorhanden) auflisten und verketten
+// Wenn Konstante alexaSpeakerList mind. einen Eintrag enthält, wird die Konstante verwendet - ansonsten Alle Devices aus dem Alexa Adapter
+ let speakerlist = "";
+ if (alexaSpeakerList.length > 0) {
+ for (let i_index in alexaSpeakerList) {
+ speakerlist = speakerlist + alexaSpeakerList[i_index] + "?";
+ }
+ } else {
+ let i_list = Array.prototype.slice.apply($('[state.id="' + alexaInstanz + '.Echo-Devices.*.Info.name"]'));
+ for (let i_index in i_list) {
+ let i = i_list[i_index];
+ let deviceId = i;
+ deviceId = deviceId.split('.');
+ if (getState(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.online'].join(''))).val &&
+ existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Player'].join(''))) &&
+ existsObject(([alexaInstanz,'.Echo-Devices.',deviceId[3],'.Commands'].join('')))) {
+ speakerlist = speakerlist + getState(i).val + "?";
+ }
+ }
+ }
+ speakerlist = speakerlist.substring(0,speakerlist.length-1);
+//--------------------------------------------------------------------------------------------------------------
+ out_msgs.push({ payload: "entityUpd~" +
+ name + "~" +
+ id + "~" +
+ id + "~" + //????
+ media_icon + "~" +
+ title + "~" +
+ author + "~" +
+ volume + "~" +
+ iconplaypause + "~" +
+ currentSpeaker + "~" +
+ speakerlist + "~" +
+ onoffbutton});
+ }
+ return out_msgs
+}
function setIfExists(id: string, value: any, type: string | null = null): boolean {
if (type === null) {
@@ -600,6 +686,37 @@ function HandleButtonEvent(words): void {
case "brightnessSlider":
setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4]));
break;
+ case "media-back":
+ setIfExists(id + ".PREV", true)
+ break;
+ case "media-pause":
+ if (getState(id + ".STATE").val === true) {
+ setIfExists(id + ".PAUSE", true)
+ } else {
+ setIfExists(id + ".PLAY", true)
+ }
+ break;
+ case "media-next":
+ setIfExists(id + ".NEXT", true)
+ break;
+ case "volumeSlider":
+ setIfExists(id + ".VOLUME", parseInt(words[4]))
+ break;
+ case "speaker-sel":
+ let i_list = Array.prototype.slice.apply($('[state.id="' + alexaInstanz + '.Echo-Devices.*.Info.name"]'));
+ for (let i_index in i_list) {
+ let i = i_list[i_index];
+ if ((getState(i).val) === words[4]){
+ let deviceId = i;
+ deviceId = deviceId.split('.');
+ setIfExists(alexaInstanz + ".Echo-Devices." + alexaDevice + ".Commands.textCommand", "Schiebe meine Musik auf " + words[4]);
+ alexaDevice = deviceId[3]
+ }
+ }
+ break;
+ case "media-OnOff":
+ setIfExists(id + ".STOP", true)
+ break;
case "tempUpd":
setIfExists(id + ".SET", parseInt(words[4]) / 10)
break;
@@ -722,10 +839,22 @@ function HandleScreensaverUpdate(): void {
"weatherUpdate~" + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + "~"
+ temperature + " " + config.temperatureUnit + "~"
- payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
- payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
- payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
- payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
+ if (weatherForecast == true) {
+ // Accu-Weather Forecast Tag 2 - Tag 5 -- Wenn weatherForecast = true
+ for (let i = 2; i < 6; i++) {
+ let TempMax = getState("accuweather.0.Summary.TempMax_d" + i).val;
+ let DayOfWeek = getState("accuweather.0.Summary.DayOfWeek_d" + i).val;
+ let WeatherIcon = GetAccuWeatherIcon(getState("accuweather.0.Summary.WeatherIcon_d" + i).val);
+ payloadString += DayOfWeek + "~" + Icons.GetIcon(WeatherIcon) + "~" + TempMax + " °C~";
+ }
+ }
+ else {
+ //In Config definierte Zustände wenn weatherForecast = false
+ payloadString += GetScreenSaverEntityString(config.firstScreensaverEntity);
+ payloadString += GetScreenSaverEntityString(config.secondScreensaverEntity);
+ payloadString += GetScreenSaverEntityString(config.thirdScreensaverEntity);
+ payloadString += GetScreenSaverEntityString(config.fourthScreensaverEntity);
+ }
SendToPanel({ payload: payloadString });
}
@@ -869,6 +998,11 @@ interface PageThermo extends Page {
items: PageItem[],
};
+interface PageMedia extends Page {
+ type: "cardMedia",
+ items: PageItem[],
+};
+
type PageItem = {
id: string,
icon: (string | undefined),
@@ -901,9 +1035,9 @@ type Config = {
defaultColor: RGB,
defaultOnColor: RGB,
defaultOffColor: RGB,
- pages: (PageThermo | PageEntities | PageGrid)[],
- button1Page: (PageThermo | PageEntities | PageGrid | null),
- button2Page: (PageThermo | PageEntities | PageGrid | null),
+ pages: (PageThermo | PageMedia | PageEntities | PageGrid)[],
+ button1Page: (PageThermo | PageMedia | PageEntities | PageGrid | null),
+ button2Page: (PageThermo | PageMedia | PageEntities | PageGrid | null),
};
type ScreenSaverElement = {