NEWS
Sonoff NSPanel
-
@mameier1234 sagte in Sonoff NSPanel:
@armilar ```
{
"type": "state",
"common": {
"type": "number",
"read": true,
"write": true,
"min": 0,
"max": 100,
"unit": "%",
"role": "level.blind",
"name": "core:TargetClosureState"
},
"native": {},
"from": "system.adapter.tahoma.0",
"user": "system.user.admin",
"ts": 1617964742851,
"_id": "tahoma.0.devices.Markiese.states.core:TargetClosureState",
"acl": {
"object": 1636,
"state": 1636,
"owner": "system.user.admin",
"ownerGroup": "system.group.administrator"
}
}ich habe da leider keine Idee mehr - kann das Problem nicht nachvollziehen - sieht für mich alles richtig aus
Vielleicht hat @britzelpuf noch ne Idee oder hatte irgendjemand ebenfalls das Problem, dass sich die Detail-Page nicht mehr schließen lässt?
-
@armilar Was ganz komisch ist.. mit Button 1 oder 2 ... komme ich auf die Unterseite... von dort geht es auch per Timeout dann wieder in den Screensafer.. geht so als kleiner Workarround...
-
@mameier1234 sagte in Sonoff NSPanel:
@armilar Was ganz komisch ist.. mit Button 1 oder 2 ... komme ich auf die Unterseite... von dort geht es auch per Timeout dann wieder in den Screensafer.. geht so als kleiner Workarround...
Wenn du aus der Detailpage mit dem Slider nicht rauskommst, gibt es dann einen Error in der iobroker JavaScript-Console? oder ioBroker Protokolle?
-
@armilar @mameier1234 Moin moin, leider ist das Wetter zu gut und meine Zeit wird im Garten verplant.
Normalerweise schickt das Panel ein event,buttonPress2,popupShutter,bExit wenn die Zeit in der Detailpage abgelaufen ist.Die Zeile sollte darauf reagieren:
https://github.com/joBr99/nspanel-lovelace-ui/blob/main/ioBroker/NsPanelTs.ts#L540Kann es sein, dass du screenSaverDoubleClick auf True im Config Element hast? Dann wäre da ein Bug
-
@armilar Das ist sehr cool, habe ich auch gleich mal installiert, allerdings zeigt mein IoBroker keine Alexas mehr an. Musste den mal neu installieren und der Alexa Adapter verbindet sich zwar, aber Echo-Devices bleiben leer. Vielleicht mach ich da mal ein Downgrade, "früher" ging das ja.
-
@armilar ja ist limitiert auf 200 chars, hab das mal angepasst, in der aktuellen dev firmware (
FlashNextion http://nspanel.pky.eu/lui.tft
) sollten es 400 sein. -
@britzelpuf sagte in Sonoff NSPanel:
Kann es sein, dass du screenSaverDoubleClick auf True im Config Element hast? Dann wäre da ein Bug
Ja.. das kann sein
-
@jobr99 sagte in Sonoff NSPanel:
@armilar ja ist limitiert auf 200 chars, hab das mal angepasst, in der aktuellen dev firmware (
FlashNextion http://nspanel.pky.eu/lui.tft
) sollten es 400 sein.Danke, Update läuft - ich hab sie jetzt alle in der Liste
-
@britzelpuf sagte in Sonoff NSPanel:
@armilar Das ist sehr cool, habe ich auch gleich mal installiert, allerdings zeigt mein IoBroker keine Alexas mehr an. Musste den mal neu installieren und der Alexa Adapter verbindet sich zwar, aber Echo-Devices bleiben leer. Vielleicht mach ich da mal ein Downgrade, "früher" ging das ja.
Ich erinnere mich, dass ich die Echo-Devices irgendwann nicht mehr im Adapter gesehen habe. Kann mich aber auch nicht mehr erinnern wie ich das Problem gelöst habe
Benutze immer die aktuellsten Adapter - Alexa2 = 3.12.0 - da kann ich sie sehen. Aber eventuell hilft ein Downgrade mit einem Upgrade um irgendeinen Knoten zu lösen -
@armilar Auf welcher Version vom Script setzt du da auf?
Wenn ich die Funktion tauschen bekomme ich folgenden Fehler:08:52:30.900 error javascript.0 (2989) script.js.common.NS_Panel: TypeScript compilation failed: unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'. unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'. unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'. unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'.
Die Zeilen meckert er an:
if (existsState(pageItem.id + ".ON_ACTUAL")) { optVal = getState(pageItem.id + ".ON_ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ACTUAL")) { optVal = getState(pageItem.id + ".ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ACTUAL"); }
-
@holgerwolf sagte in Sonoff NSPanel:
@armilar Auf welcher Version vom Script setzt du da auf?
Wenn ich die Funktion tauschen bekomme ich folgenden Fehler:08:52:30.900 error javascript.0 (2989) script.js.common.NS_Panel: TypeScript compilation failed: unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'. unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'. unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'. unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); ^ ERROR: Property 'unit' does not exist on type 'PageItem'.
Die Zeilen meckert er an:
if (existsState(pageItem.id + ".ON_ACTUAL")) { optVal = getState(pageItem.id + ".ON_ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ACTUAL")) { optVal = getState(pageItem.id + ".ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ACTUAL"); }
Ah ja du hast ja die letzten Änderungen des Scriptes noch nicht drin
Ganz unten im Script mal unit erweitern:
type PageItem = { id: string, icon: (string | undefined), onColor: (RGB | undefined), offColor: (RGB | undefined), useColor: (boolean | undefined), interpolateColor: (boolean | undefined), minValue: (number | undefined), maxValue: (number | undefined), name: (string | undefined), unit: (string | undefined) }
oder nach dem config Block alles austauschen
var subscriptions: any = {}; var screensaverEnabled : boolean = false; var pageId = 0; schedule("* * * * *", function () { SendTime(); }); schedule("0 * * * *", function () { SendDate(); }); // Only monitor the extra nodes if present var updateArray: string[] = []; if (config.firstScreensaverEntity !== null && config.firstScreensaverEntity.ScreensaverEntity != null && existsState(config.firstScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.firstScreensaverEntity.ScreensaverEntity) } if (config.secondScreensaverEntity !== null && config.secondScreensaverEntity.ScreensaverEntity != null && existsState(config.secondScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.secondScreensaverEntity.ScreensaverEntity) } if (config.thirdScreensaverEntity !== null && config.thirdScreensaverEntity.ScreensaverEntity != null && existsState(config.thirdScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.thirdScreensaverEntity.ScreensaverEntity) } if (config.fourthScreensaverEntity !== null && config.fourthScreensaverEntity.ScreensaverEntity != null && existsState(config.fourthScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.fourthScreensaverEntity.ScreensaverEntity) } if (updateArray.length > 0) { on(updateArray, function () { HandleScreensaverUpdate(); }) } on({ id: config.panelRecvTopic }, function (obj) { if (obj.state.val.startsWith('\{"CustomRecv":')) { var json = JSON.parse(obj.state.val); var split = json.CustomRecv.split(","); HandleMessage(split[0], split[1], parseInt(split[2]), split); } }); function SendToPanel(val: Payload | Payload[]): void { if (Array.isArray(val)) { val.forEach(function (id, i) { setState(config.panelSendTopic, id.payload); }); } else setState(config.panelSendTopic, val.payload); } function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void { if (typ == "event") { switch (method) { case "startup": screensaverEnabled = false; UnsubscribeWatcher(); HandleStartupProcess(); pageId = 0; GeneratePage(config.pages[0]); break; case "sleepReached": screensaverEnabled = true; if (pageId < 0) pageId = 0; HandleScreensaver(); break; case "pageOpenDetail": screensaverEnabled = false; UnsubscribeWatcher(); let pageItem = config.pages[pageId].items.find(e => e.id === words[3]); if (pageItem !== undefined) SendToPanel(GenerateDetailPage(words[2], pageItem)); case "buttonPress2": screensaverEnabled = false; HandleButtonEvent(words); break; case "button1": case "button2": screensaverEnabled = false; HandleHardwareButton(method); default: break; } } } function GeneratePage(page: Page): void { switch (page.type) { case "cardEntities": SendToPanel(GenerateEntitiesPage(<PageEntities>page)); break; case "cardThermo": SendToPanel(GenerateThermoPage(<PageThermo>page)); break; case "cardGrid": SendToPanel(GenerateGridPage(<PageGrid>page)); break; case "cardMedia": SendToPanel(GenerateMediaPage(<PageMedia>page)); break; case "cardAlarm": SendToPanel(GenerateAlarmPage(<PageAlarm>page)); break; } } function HandleHardwareButton(method: string): void { let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid); if (config.button1Page !== null && method == "button1") { page = config.button1Page; pageId = -1; } else if (config.button2Page !== null && method == "button2") { page = config.button2Page; pageId = -2; } else { return; } GeneratePage(page); } function HandleStartupProcess(): void { SendDate(); SendTime(); SendToPanel({ payload: "timeout~" + config.timeoutScreensaver }); SendToPanel({ payload: "dimmode~" + config.dimmode }); } function SendDate(): void { var d = new Date(); var day = Days[d.getDay()]; var date = d.getDate(); var month = Months[d.getMonth()]; var year = d.getFullYear(); var _sendDate = "date~" + day + " " + date + " " + month + " " + year; SendToPanel(<Payload>{ payload: _sendDate }); } function SendTime(): void { var d = new Date(); var hr = d.getHours().toString(); var min = d.getMinutes().toString(); if (d.getHours() < 10) { hr = "0" + d.getHours().toString(); } if (d.getMinutes() < 10) { min = "0" + d.getMinutes().toString(); } SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min }); } function GenerateEntitiesPage(page: PageEntities): Payload[] { var out_msgs: Array<Payload> = []; out_msgs = [{ payload: "pageType~cardEntities" }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } function GenerateGridPage(page: PageGrid): Payload[] { var out_msgs: Array<Payload> = []; out_msgs = [{ payload: "pageType~cardGrid" }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } function GeneratePageElements(page: Page): string { let maxItems = 0; switch (page.type) { case "cardThermo": maxItems = 1; break; case "cardAlarm": maxItems = 1; break; case "cardMedia": maxItems = 1; break; case "cardEntities": maxItems = 4; break; case "cardGrid": maxItems = 6; break; } let pageData = "entityUpd~" + page.heading + "~" + GetNavigationString(pageId) for (let index = 0; index < maxItems; index++) { if (page.items[index] !== undefined) { pageData += CreateEntity(page.items[index], index + 1, page.useColor); } else { pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1); } } return pageData; } function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string { var iconId = "0" if (pageItem.id == "delete") { return "~delete~~~~~" } var name: string; var type: string; // ioBroker if (existsObject(pageItem.id)) { let o = getObject(pageItem.id) var val = null; name = pageItem.name !== undefined ? pageItem.name : o.common.name.de if (existsState(pageItem.id + ".GET")) { val = getState(pageItem.id + ".GET").val; RegisterEntityWatcher(pageItem.id + ".GET"); } else if (existsState(pageItem.id + ".SET")) { val = getState(pageItem.id + ".SET").val; RegisterEntityWatcher(pageItem.id + ".SET"); } var iconColor = rgb_dec565(config.defaultColor); switch (o.common.role) { case "light": type = "light" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == "socket" ? Icons.GetIcon("power-socket-de") : Icons.GetIcon("lightbulb"); var optVal = "0" if (val === true || val === "true") { optVal = "1" iconColor = GetIconColor(pageItem, true, useColors); } // Else-Zweig für definierte offColor - Armilar else { iconColor = GetIconColor(pageItem, false, useColors); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; case "dimmer": type = "light" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("lightbulb"); var optVal = "0" if (existsState(pageItem.id + ".ON_ACTUAL")) { val = getState(pageItem.id + ".ON_ACTUAL").val; RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ON_SET")) { val = getState(pageItem.id + ".ON_SET").val; RegisterEntityWatcher(pageItem.id + ".ON_SET"); } if (val === true || val === "true") { optVal = "1" iconColor = GetIconColor(pageItem, existsState(pageItem.id + ".ACTUAL") ? getState(pageItem.id + ".ACTUAL").val : true, useColors); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; case "blind": type = "shutter" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("window-open"); iconColor = GetIconColor(pageItem, existsState(pageItem.id + ".ACTUAL") ? getState(pageItem.id + ".ACTUAL").val : true, useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" case "window": type = "text"; if (existsState(pageItem.id + ".ACTUAL")) { if (getState(pageItem.id + ".ACTUAL").val) { iconId = Icons.GetIcon("window-open-variant"); iconColor = GetIconColor(pageItem, false, useColors); var windowState = "opened" } else { iconId = Icons.GetIcon("window-closed-variant"); iconColor = GetIconColor(pageItem, true, useColors); var windowState = "closed" } RegisterEntityWatcher(pageItem.id + ".ACTUAL"); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState; case "info": case "value.temperature": case "thermostat": type = "text"; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == "value.temperature" || o.common.role == "thermostat" ? Icons.GetIcon("thermometer") : Icons.GetIcon("information-outline"); let unit = ""; var optVal = "0" if (existsState(pageItem.id + ".ON_ACTUAL")) { optVal = getState(pageItem.id + ".ON_ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ACTUAL")) { optVal = getState(pageItem.id + ".ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ACTUAL"); } if (o.common.role == "value.temperature") { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("thermometer"); } iconColor = GetIconColor(pageItem, parseInt(optVal), useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal + " " + unit; case "button": type = "button"; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("gesture-tap-button"); let buttonText = pageItem.name !== undefined ? pageItem.name : "PRESS"; iconColor = GetIconColor(pageItem, true, useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + buttonText; case "warning": type = "text"; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("alert-outline"); iconColor = getState(([pageItem.id,'.LEVEL'].join(''))).val; let itemName = getState(([pageItem.id,'.TITLE'].join(''))).val; let itemInfo = getState(([pageItem.id,'.INFO'].join(''))).val; return "~" + type + "~" + itemName + "~" + iconId + "~" + iconColor + "~" + itemName + "~" + itemInfo; default: return "~delete~~~~~"; } } return "~delete~~~~~" } function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number { // dimmer if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") { let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100; let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0; value = value > maxValue ? maxValue : value; value = value < minValue ? minValue : value; return rgb_dec565( Interpolate( pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor, pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor, scale(value, minValue, maxValue, 0, 1) )); } if ((pageItem.useColor || useColors) && ((typeof (value) === "boolean" && value) || value > (pageItem.minValue !== undefined ? pageItem.minValue : 0))) { return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor) } return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor); } function RegisterEntityWatcher(id: string): void { if (subscriptions.hasOwnProperty(id)) { return; } subscriptions[id] = (on({ id: id, change: 'any' }, function (data) { if(pageId >= 0) SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) }); if(pageId == -1 && config.button1Page != undefined) SendToPanel({ payload: GeneratePageElements(config.button1Page) }); if(pageId == -2 && config.button2Page != undefined) SendToPanel({ payload: GeneratePageElements(config.button2Page) }); })) } function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void { if (subscriptions.hasOwnProperty(id)) { return; } subscriptions[id] = (on({ id: id, change: 'any' }, function () { SendToPanel(GenerateDetailPage(type, pageItem)); })) } function GetUnitOfMeasurement(id: string): string { if (!existsObject(id)) return ""; let obj = getObject(id); if (typeof obj.common.unit !== 'undefined') { return obj.common.unit } if (typeof obj.common.alias !== 'undefined' && typeof obj.common.alias.id !== 'undefined') { return GetUnitOfMeasurement(obj.common.alias.id); } return ""; } function GenerateThermoPage(page: PageThermo): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardThermo" }); // ioBroker if (existsObject(id)) { let o = getObject(id) let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de let currentTemp = 0; if (existsState(id + ".ACTUAL")) currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10; let destTemp = 0; if (existsState(id + ".SET")) { destTemp = getState(id + ".SET").val.toFixed(2) * 10; } let status = "" if (existsState(id + ".MODE")) status = getState(id + ".MODE").val; let minTemp = 50 //Min Temp 5°C let maxTemp = 300 //Max Temp 30°C let stepTemp = 5 //0-4 verwendet bei ungerader Anzahl Parametern let bt0 = "~~~~"; //verwendet bei ungleichen Parametern let bt1 = "~~~~"; //verwendet bei ungleichen Parametern let bt2 = "~~~~"; //verwendet bei ungleichen Parametern let bt3 = "~~~~"; //verwendet bei ungleichen Parametern let bt4 = "~~~~"; //verwendet bei ungleichen Parametern //5-8 verwendet bei gerader Anzahl Parametern let bt5 = Icons.GetIcon("water-percent") + "~0~1~~"; let bt6 = Icons.GetIcon("fire") + "~0~1~~"; let bt7 = Icons.GetIcon("wifi") + "~0~1~~"; let bt8 = Icons.GetIcon("battery-high") + "~0~1~~"; if (existsState(id + ".HUMIDITY")){ bt5 = Icons.GetIcon("water-percent") + "~2016~1~bt8~"; if (parseInt(getState(id + ".HUMIDITY").val) < 40) { bt5 = Icons.GetIcon("water-percent") + "~65504~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) { bt5 = Icons.GetIcon("water-percent") + "~63488~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) { bt5 = Icons.GetIcon("water-percent") + "~65504~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) { bt5 = Icons.GetIcon("water-percent") + "~63488~1~bt8~"; } } if (existsState(id + ".MAINTAIN")){ if (getState(id + ".MAINTAIN").val >> .1) { bt6 = Icons.GetIcon("fire") + "~60897~1~bt8~"; } else { bt6 = Icons.GetIcon("fire") + "~33840~0~bt8~"; } } if (existsState(id + ".UNREACH")){ if (getState(id + ".UNREACH").val) { bt7 = Icons.GetIcon("wifi-off") + "~63488~1~bt8~"; } else { bt7 = Icons.GetIcon("wifi") + "~2016~1~bt8~"; } } if (existsState(id + ".LOWBAT")){ if (getState(id + ".LOWBAT").val) { bt8 = Icons.GetIcon("battery-low") + "~63488~1~bt8~"; } else { bt8 = Icons.GetIcon("battery-high") + "~2016~1~bt8~"; } } let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8; out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res}) } return out_msgs } function GenerateMediaPage(page: PageMedia): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardMedia" }); if (existsObject(id)) { let name = getState(id + ".ALBUM").val; let media_icon = Icons.GetIcon("amazon-alexa"); let title = getState(id + ".TITLE").val; let author = getState(id + ".ARTIST").val; let volume = getState(id + ".VOLUME").val; var iconplaypause = Icons.GetIcon("pause"); //pause if (getState(id + ".STATE").val) { 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); // Limitierung im NSPanel auf 200 Zeichen???? --> joBR99 //-------------------------------------------------------------------------------------------------------------- let onoffbutton = 1; out_msgs.push({ payload: "entityUpd~" + name + "~" + id + "~" + id + "~" + //???? media_icon + "~" + title + "~" + author + "~" + volume + "~" + iconplaypause + "~" + currentSpeaker + "~" + speakerlist + "~" + onoffbutton}); } return out_msgs } function GenerateAlarmPage(page: PageAlarm): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardAlarm" }); var armed: boolean = true; if (armed) { var arm1 = "Deaktivieren"; //arm1*~* var arm1ActionName = "D1"; //arm1ActionName*~* var arm2 = ""; //arm2*~* var arm2ActionName = ""; //arm2ActionName*~* var arm3 = ""; //arm3*~* var arm3ActionName = ""; //arm3ActionName*~* var arm4 = ""; //arm4*~* var arm4ActionName = ""; //arm4ActionName*~* var icon = Icons.GetIcon("shield-home"); //icon*~* var iconcolor = 63488; //iconcolor*~* var numpadStatus = 1; //numpadStatus*~* var flashing = 1; //flashing* } else { var arm1 = "Alarm 1"; //arm1*~* var arm1ActionName = "A1"; //arm1ActionName*~* var arm2 = "Alarm 2"; //arm2*~* var arm2ActionName = "A2"; //arm2ActionName*~* var arm3 = "Alarm 3"; //arm3*~* var arm3ActionName = "A3"; //arm3ActionName*~* var arm4 = "Alarm 4"; //arm4*~* var arm4ActionName = "A4"; //arm4ActionName*~* var icon = Icons.GetIcon("shield-off"); //icon*~* var iconcolor = 2016; //iconcolor*~* var numpadStatus = 1; //numpadStatus*~* var flashing = 1; //flashing* } out_msgs.push({ payload: "entityUpd~" + //entityUpd~* id + "~" + //internalNameEntity*~* //navigation*~* "~" + //??? arm1 + "~" + //arm1*~* arm1ActionName + "~" + //arm1ActionName*~* arm2 + "~" + //arm2*~* arm2ActionName + "~" + //arm2ActionName*~* arm3 + "~" + //arm3*~* arm3ActionName + "~" + //arm3ActionName*~* arm4 + "~" + //arm4*~* arm4ActionName + "~" + //arm4ActionName*~* icon + "~" + //icon*~* 39=Disarmed 35=Shield_Home, 40 iconcolor + "~" + //iconcolor*~* 2016=green 63488=red numpadStatus + "~" + //numpadStatus*~* flashing}); //flashing* return out_msgs } function setIfExists(id: string, value: any, type: string | null = null): boolean { if (type === null) { if (existsState(id)) { setState(id, value); return true; } } else { let obj = getObject(id); if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) { setState(id, value); return true; } } return false; } function toggleState(id: string): boolean { let obj = getObject(id); if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") { setState(id, !getState(id).val); return true; } return false; } function HandleButtonEvent(words): void { let id = words[2] let buttonAction = words[3]; switch (buttonAction) { case "bNext": var pageNum = ((pageId + 1) % config.pages.length); pageId = Math.abs(pageNum); UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case "bPrev": var pageNum = ((pageId - 1) % config.pages.length); pageId = Math.abs(pageNum); UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case "bExit": if (config.screenSaverDoubleClick) { if (words[4] == 2) GeneratePage(config.pages[pageId]); } else GeneratePage(config.pages[pageId]); break; case "OnOff": if (existsObject(id)) { var action = false if (words[4] == "1") action = true let o = getObject(id) switch (o.common.role) { case "light": setIfExists(id + ".SET", action); break; case "dimmer": setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action); } } break; case "up": setIfExists(id + ".OPEN", true) break; case "stop": setIfExists(id + ".STOP", true) break; case "down": setIfExists(id + ".CLOSE", true) break; case "button": toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET") break; case "positionSlider": case "brightnessSlider": setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4])); break; case "tempUpd": setIfExists(id + ".SET", parseInt(words[4]) / 10) 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 "A1": //Alarm-Page Alarm 1 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A2": //Alarm-Page Alarm 2 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A3": //Alarm-Page Alarm 3 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A4": //Alarm-Page Alarm 4 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "D1": //Alarm-Page Alarm Deaktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; default: break; } } function GetNavigationString(pageId: number): string { switch (pageId) { case 0: return "0|1"; case config.pages.length - 1: return "1|0"; case -1: return "0|0"; default: return "1|1"; } } function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { var out_msgs: Array<Payload> = []; let id = pageItem.id if (existsObject(id)) { var o = getObject(id) var val: (boolean | number) = 0; let icon = Icons.GetIcon("lightbulb"); var iconColor = rgb_dec565(config.defaultColor); if (type == "popupLight") { let switchVal = "0" if (o.common.role == "light") { if (existsState(id + ".GET")) { val = getState(id + ".GET").val; RegisterDetailEntityWatcher(id + ".GET", pageItem, type); } else if (existsState(id + ".SET")) { val = getState(id + ".SET").val; RegisterDetailEntityWatcher(id + ".SET", pageItem, type); } if (val) { switchVal = "1"; iconColor = GetIconColor(pageItem, true, false); } out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" }) } if (o.common.role == "dimmer") { if (existsState(id + ".ON_ACTUAL")) { val = getState(id + ".ON_ACTUAL").val; RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type); } else if (existsState(id + ".ON_SET")) { val = getState(id + ".ON_SET").val; RegisterDetailEntityWatcher(id + ".ON_SET", pageItem, type); } if (val === true) { var iconColor = GetIconColor(pageItem, val, false); switchVal = "1" } let brightness = 0; if (existsState(id + ".ACTUAL")) { brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, 0, 100, 0, 100)) iconColor = GetIconColor(pageItem, brightness, false); RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type); } let colorTemp = "disable" let colorMode = "disable" //let attr_support_color = attr.supported_color_modes //if (attr_support_color.includes("color_temp")) // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100)) out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode }) } } if (type == "popupShutter") { if (existsState(id + ".ACTUAL")) val = getState(id + ".ACTUAL").val; else if (existsState(id + ".SET")) val = getState(id + ".SET").val; out_msgs.push({ payload: "entityUpdateDetail," + val }) } } return out_msgs } function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number { return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; } function UnsubscribeWatcher(): void { for (const [key, value] of Object.entries(subscriptions)) { unsubscribe(value); delete subscriptions[key] } } function HandleScreensaver(): void { SendToPanel({ payload: "pageType~screensaver"}) UnsubscribeWatcher(); HandleScreensaverUpdate(); } function HandleScreensaverUpdate(): void { if (screensaverEnabled && config.weatherEntity != null && existsObject(config.weatherEntity)) { var icon = getState(config.weatherEntity + ".ICON").val; let temperature: string = existsState(config.weatherEntity + ".ACTUAL") ? getState(config.weatherEntity + ".ACTUAL").val : existsState(config.weatherEntity + ".TEMP") ? getState(config.weatherEntity + ".TEMP").val : "null"; let payloadString = "weatherUpdate~" + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + "~" + temperature + " " + config.temperatureUnit + "~" /*-------------------------------------------------------------------------------------------------------------------------------------*/ 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>{ payload: payloadString }); } } function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string { if (configElement != null && configElement.ScreensaverEntity != null && existsState(configElement.ScreensaverEntity)) { let u1 = getState(configElement.ScreensaverEntity).val; return configElement.ScreensaverEntityText + "~" + Icons.GetIcon(configElement.ScreensaverEntityIcon) + "~" + u1 + " " + configElement.ScreensaverEntityUnitText + "~"; } else { return "~~~"; } } function GetAccuWeatherIcon(icon: number): string { switch (icon) { case 24: // Ice case 30: // Hot case 31: // Cold return "window-open"; // exceptional case 7: // Cloudy case 8: // Dreary (Overcast) case 38: // Mostly Cloudy return "weather-cloudy"; // cloudy case 11: // fog return "weather-fog"; // fog case 25: // Sleet return "weather-hail"; // Hail case 15: // T-Storms return "weather-lightning"; // lightning case 16: // Mostly Cloudy w/ T-Storms case 17: // Partly Sunny w/ T-Storms case 41: // Partly Cloudy w/ T-Storms case 42: // Mostly Cloudy w/ T-Storms return "weather-lightning-rainy"; // lightning-rainy case 33: // Clear case 34: // Mostly Clear case 37: // Hazy Moonlight return "weather-night"; case 3: // Partly Sunny case 4: // Intermittent Clouds case 6: // Mostly Cloudy case 35: // Partly Cloudy case 36: // Intermittent Clouds return "weather-partly-cloudy"; // partlycloudy case 18: // pouring return "weather-pouring"; // pouring case 12: // Showers case 13: // Mostly Cloudy w/ Showers case 14: // Partly Sunny w/ Showers case 26: // Freezing Rain case 39: // Partly Cloudy w/ Showers case 40: // Mostly Cloudy w/ Showers return "weather-rainy"; // rainy case 19: // Flurries case 20: // Mostly Cloudy w/ Flurries case 21: // Partly Sunny w/ Flurries case 22: // Snow case 23: // Mostly Cloudy w/ Snow case 43: // Mostly Cloudy w/ Flurries case 44: // Mostly Cloudy w/ Snow return "weather-snowy"; // snowy case 29: // Rain and Snow return "weather-snowy-rainy"; // snowy-rainy case 1: // Sunny case 2: // Mostly Sunny case 5: // Hazy Sunshine return "weather-sunny"; // sunny case 32: // windy return "weather-windy"; // windy default: return "alert-circle-outline"; } } function GetBlendedColor(percentage: number): RGB { if (percentage < 50) return Interpolate(config.defaultOffColor, config.defaultOnColor, percentage / 50.0); return Interpolate(Red, White, (percentage - 50) / 50.0); } function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { var r: number = InterpolateNum(color1.red, color2.red, fraction); var g: number = InterpolateNum(color1.green, color2.green, fraction); var b: number = InterpolateNum(color1.blue, color2.blue, fraction); return <RGB>{ red: Math.round(r), green: Math.round(g), blue: Math.round(b) }; } function InterpolateNum(d1: number, d2: number, fraction: number): number { return d1 + (d2 - d1) * fraction; } function rgb_dec565(rgb: RGB): number { return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31))); } type RGB = { red: number, green: number, blue: number }; type Payload = { payload: string; }; type Page = { type: string, heading: string, items: PageItem[], useColor: boolean }; interface PageEntities extends Page { type: "cardEntities", items: PageItem[], }; interface PageGrid extends Page { type: "cardGrid", items: PageItem[], }; interface PageThermo extends Page { type: "cardThermo", items: PageItem[], }; interface PageMedia extends Page { type: "cardMedia", items: PageItem[], }; interface PageAlarm extends Page { type: "cardAlarm", items: PageItem[], }; type PageItem = { id: string, icon: (string | undefined), onColor: (RGB | undefined), offColor: (RGB | undefined), useColor: (boolean | undefined), interpolateColor: (boolean | undefined), minValue: (number | undefined), maxValue: (number | undefined), name: (string | undefined), unit: (string | undefined) } type Config = { panelRecvTopic: string, panelSendTopic: string, timeoutScreensaver: number, dimmode: number, //brightnessScreensaver: locale: string, timeFormat: string, dateFormat: string, weatherEntity: string | null, screenSaverDoubleClick: boolean, temperatureUnit: string, firstScreensaverEntity: ScreenSaverElement | null, secondScreensaverEntity: ScreenSaverElement | null, thirdScreensaverEntity: ScreenSaverElement | null, fourthScreensaverEntity: ScreenSaverElement | null, defaultColor: RGB, defaultOnColor: RGB, defaultOffColor: RGB, pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[], button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), }; type ScreenSaverElement = { ScreensaverEntity: string | null, ScreensaverEntityIcon: string | null, ScreensaverEntityText: string | null, ScreensaverEntityUnitText: string | null, }
Dann wären die letzten Änderungen von Britzelpuf und MacSchlack auch drin
-
-
@armilar Nöh, das hatte ich schon alles drin.
Edit: Stop, muss ich nochmal ran...
Zur Sicherheit mal hier mein aktuelles Script:
var Icons = new IconsSelector(); const Months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]; const Days = ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]; const Red: RGB = { red: 255, green: 0, blue: 0 }; const White: RGB = { red: 255, green: 255, blue: 255 }; const Off: RGB = { red: 68, green: 115, blue: 158 }; 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 } //----Möglichkeit, im Screensaver zwischen Accu-Weather Forcast oder selbstdefinierten Werten zu wählen--------------------------------- var weatherForecast = false; //true = WheatherForecast 5 Days --- false = Config --> firstScreensaverEntity - fourthScreensaverEntity ... //Spotify Instanz var spotifyInstanz = "spotify-premium.0" var Wohnen: PageGrid = { "type": "cardGrid", "heading": "Fenster", "useColor": true, "items": [ <PageItem>{ id: "alias.0.StudioSued", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordLinks", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordRechts", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Gaeste", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Bad", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Schlaf", icon: "window-closed", offColor: Off, onColor: Red } ] }; var Strom: PageEntities = { "type": "cardEntities", "heading": "Strom", "useColor": false, "items": [ <PageItem>{ id: "alias.0.PV", icon: "solar-power", interpolateColor: true, offColor: BatteryFull}, <PageItem>{ id: "alias.0.Verbrauch", icon: "power-plug", interpolateColor: true, offColor: Red}, <PageItem>{ id: "alias.0.Auto-SoC", icon: "car-electric", offColor: Off} ] }; var button1Page: PageGrid = { "type": "cardGrid", "heading": "Fenster", "useColor": true, "items": [ <PageItem>{ id: "alias.0.StudioSued", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordLinks", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordRechts", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Gaeste", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Bad", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Schlaf", icon: "window-closed", offColor: Off, onColor: Red } ] }; export const config: Config = { panelRecvTopic: "mqtt.1.tele.tasmota_7BC490.RESULT", //anpassen panelSendTopic: "mqtt.1.cmnd.tasmota_7BC490.CustomSend", //anpassen firstScreensaverEntity: { ScreensaverEntity: "zigbee.0.00158d0002c77840.temperature", ScreensaverEntityIcon: "thermometer", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "°C" }, secondScreensaverEntity: { ScreensaverEntity: "accuweather.0.Daily.Day1.Day.RainProbability", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" }, thirdScreensaverEntity: { ScreensaverEntity: "mqtt.0.openWB.lp.1.%Soc", ScreensaverEntityIcon: "car-electric", ScreensaverEntityText: "SoC", ScreensaverEntityUnitText: "%" }, fourthScreensaverEntity: { ScreensaverEntity: "javascript.0.Photovoltaik.Leistung_DC_komplett", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "PV", ScreensaverEntityUnitText: "W" }, timeoutScreensaver: 15, dimmode: 8, screenSaverDoubleClick: true, locale: "de_DE", timeFormat: "%H:%M", dateFormat: "%A, %d. %B %Y", weatherEntity: "alias.0.Weather", defaultOffColor: Off, defaultOnColor: On, defaultColor: Off, temperatureUnit: "°C", pages: [Wohnen, Strom ], button1Page: button1Page, button2Page: button1Page }; // _________________________________ Ab hier keine Konfiguration mehr _____________________________________ var subscriptions: any = {}; var screensaverEnabled : boolean = false; var pageId = 0; schedule("* * * * *", function () { SendTime(); }); schedule("0 * * * *", function () { SendDate(); }); // Only monitor the extra nodes if present var updateArray: string[] = []; if (config.firstScreensaverEntity !== null && config.firstScreensaverEntity.ScreensaverEntity != null && existsState(config.firstScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.firstScreensaverEntity.ScreensaverEntity) } if (config.secondScreensaverEntity !== null && config.secondScreensaverEntity.ScreensaverEntity != null && existsState(config.secondScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.secondScreensaverEntity.ScreensaverEntity) } if (config.thirdScreensaverEntity !== null && config.thirdScreensaverEntity.ScreensaverEntity != null && existsState(config.thirdScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.thirdScreensaverEntity.ScreensaverEntity) } if (config.fourthScreensaverEntity !== null && config.fourthScreensaverEntity.ScreensaverEntity != null && existsState(config.fourthScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.fourthScreensaverEntity.ScreensaverEntity) } if (updateArray.length > 0) { on(updateArray, function () { HandleScreensaverUpdate(); }) } on({ id: config.panelRecvTopic }, function (obj) { if (obj.state.val.startsWith('\{"CustomRecv":')) { var json = JSON.parse(obj.state.val); var split = json.CustomRecv.split(","); HandleMessage(split[0], split[1], parseInt(split[2]), split); } }); function SendToPanel(val: Payload | Payload[]): void { if (Array.isArray(val)) { val.forEach(function (id, i) { setState(config.panelSendTopic, id.payload); }); } else setState(config.panelSendTopic, val.payload); } function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void { if (typ == "event") { switch (method) { case "startup": screensaverEnabled = false; UnsubscribeWatcher(); HandleStartupProcess(); pageId = 0; GeneratePage(config.pages[0]); break; case "sleepReached": screensaverEnabled = true; HandleScreensaver(); break; case "pageOpenDetail": screensaverEnabled = false; UnsubscribeWatcher(); let pageItem = config.pages[pageId].items.find(e => e.id === words[3]); if (pageItem !== undefined) SendToPanel(GenerateDetailPage(words[2], pageItem)); case "buttonPress2": screensaverEnabled = false; HandleButtonEvent(words); break; case "button1": case "button2": screensaverEnabled = false; HandleHardwareButton(method); default: break; } } } function GeneratePage(page: Page): void { switch (page.type) { case "cardEntities": SendToPanel(GenerateEntitiesPage(<PageEntities>page)); break; case "cardThermo": SendToPanel(GenerateThermoPage(<PageThermo>page)); break; case "cardGrid": SendToPanel(GenerateGridPage(<PageGrid>page)); break; case "cardMedia": SendToPanel(GenerateMediaPage(<PageMedia>page)); break; case "cardAlarm": SendToPanel(GenerateAlarmPage(<PageAlarm>page)); break; } } function HandleHardwareButton(method: string): void { let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid); if (config.button1Page !== null && method == "button1") { page = config.button1Page; } else if (config.button2Page !== null && method == "button2") { page = config.button2Page; } else { return; } // Set pageId to -1, because of the navigation arrows let tempPageId = pageId; pageId = -1; GeneratePage(page); pageId = tempPageId; } function HandleStartupProcess(): void { SendDate(); SendTime(); SendToPanel({ payload: "timeout~" + config.timeoutScreensaver }); SendToPanel({ payload: "dimmode~" + config.dimmode }); } function SendDate(): void { var d = new Date(); var day = Days[d.getDay()]; var date = d.getDate(); var month = Months[d.getMonth()]; var year = d.getFullYear(); var _sendDate = "date~" + day + " " + date + " " + month + " " + year; SendToPanel(<Payload>{ payload: _sendDate }); } function SendTime(): void { var d = new Date(); var hr = d.getHours().toString(); var min = d.getMinutes().toString(); if (d.getHours() < 10) { hr = "0" + d.getHours().toString(); } if (d.getMinutes() < 10) { min = "0" + d.getMinutes().toString(); } SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min }); } function GenerateEntitiesPage(page: PageEntities): Payload[] { var out_msgs: Array<Payload> = []; out_msgs = [{ payload: "pageType~cardEntities" }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } function GenerateGridPage(page: PageGrid): Payload[] { var out_msgs: Array<Payload> = []; out_msgs = [{ payload: "pageType~cardGrid" }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } function GeneratePageElements(page: Page): string { let maxItems = 0; switch (page.type) { case "cardThermo": maxItems = 1; break; case "cardAlarm": maxItems = 1; break; case "cardMedia": maxItems = 1; break; case "cardEntities": maxItems = 4; break; case "cardGrid": maxItems = 6; break; } let pageData = "entityUpd~" + page.heading + "~" + GetNavigationString(pageId) for (let index = 0; index < maxItems; index++) { if (page.items[index] !== undefined) { pageData += CreateEntity(page.items[index], index + 1, page.useColor); } else { pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1); } } return pageData; } function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string { var iconId = "0" if (pageItem.id == "delete") { return "~delete~~~~~" } var name: string; var type: string; if (existsObject(pageItem.id)) { let o = getObject(pageItem.id) var val = null; name = pageItem.name !== undefined ? pageItem.name : o.common.name.de if (existsState(pageItem.id + ".GET")) { val = getState(pageItem.id + ".GET").val; RegisterEntityWatcher(pageItem.id + ".GET"); } else if (existsState(pageItem.id + ".SET")) { val = getState(pageItem.id + ".SET").val; RegisterEntityWatcher(pageItem.id + ".SET"); } var iconColor = rgb_dec565(config.defaultColor); switch (o.common.role) { case "light": type = "light" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == "socket" ? Icons.GetIcon("power-socket-de") : Icons.GetIcon("lightbulb"); var optVal = "0" if (val === true || val === "true") { optVal = "1" iconColor = GetIconColor(pageItem, true, useColors); } else { iconColor = GetIconColor(pageItem, false, useColors); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; case "dimmer": type = "light" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("lightbulb"); var optVal = "0" if (existsState(pageItem.id + ".ON_ACTUAL")) { val = getState(pageItem.id + ".ON_ACTUAL").val; RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ON_SET")) { val = getState(pageItem.id + ".ON_SET").val; RegisterEntityWatcher(pageItem.id + ".ON_SET"); } if (val === true || val === "true") { optVal = "1" iconColor = GetIconColor(pageItem, existsState(pageItem.id + ".ACTUAL") ? getState(pageItem.id + ".ACTUAL").val : true, useColors); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; case "blind": type = "shutter" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("window-open"); iconColor = GetIconColor(pageItem, existsState(pageItem.id + ".ACTUAL") ? getState(pageItem.id + ".ACTUAL").val : true, useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" case "window": type = "text"; if (existsState(pageItem.id + ".ACTUAL")) { if (getState(pageItem.id + ".ACTUAL").val) { iconId = Icons.GetIcon("window-open-variant"); iconColor = GetIconColor(pageItem, false, useColors); var windowState = "opened" } else { iconId = Icons.GetIcon("window-closed-variant"); iconColor = GetIconColor(pageItem, true, useColors); var windowState = "closed" } RegisterEntityWatcher(pageItem.id + ".ACTUAL"); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState; case "info": case "value.temperature": case "thermostat": type = "text"; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == "value.temperature" || o.common.role == "thermostat" ? Icons.GetIcon("thermometer") : Icons.GetIcon("information-outline"); let unit = ""; var optVal = "0" if (existsState(pageItem.id + ".ON_ACTUAL")) { optVal = getState(pageItem.id + ".ON_ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ACTUAL")) { optVal = getState(pageItem.id + ".ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ACTUAL"); } if (o.common.role == "value.temperature") { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("thermometer"); } iconColor = GetIconColor(pageItem, parseInt(optVal), useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal + " " + unit; case "button": type = "button"; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("gesture-tap-button"); let buttonText = pageItem.name !== undefined ? pageItem.name : "PRESS"; iconColor = GetIconColor(pageItem, true, useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + buttonText; default: return "~delete~~~~~"; } } return "~delete~~~~~" } function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number { // dimmer if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") { let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100; let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0; value = value > maxValue ? maxValue : value; value = value < minValue ? minValue : value; return rgb_dec565( Interpolate( pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor, pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor, scale(value, minValue, maxValue, 0, 1) )); } if ((pageItem.useColor || useColors) && ((typeof (value) === "boolean" && value) || value > (pageItem.minValue !== undefined ? pageItem.minValue : 0))) { return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor) } return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor); } function RegisterEntityWatcher(id: string): void { if (subscriptions.hasOwnProperty(id)) { return; } subscriptions[id] = (on({ id: id, change: 'any' }, function (data) { SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) }); })) } function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void { if (subscriptions.hasOwnProperty(id)) { return; } subscriptions[id] = (on({ id: id, change: 'any' }, function () { SendToPanel(GenerateDetailPage(type, pageItem)); })) } function GetUnitOfMeasurement(id: string): string { if (!existsObject(id)) return ""; let obj = getObject(id); if (typeof obj.common.unit !== 'undefined') { return obj.common.unit } if (typeof obj.common.alias !== 'undefined' && typeof obj.common.alias.id !== 'undefined') { return GetUnitOfMeasurement(obj.common.alias.id); } return ""; } function GenerateThermoPage(page: PageThermo): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardThermo" }); // ioBroker if (existsObject(id)) { let o = getObject(id) let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de let currentTemp = 0; if (existsState(id + ".ACTUAL")) currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10; let destTemp = 0; if (existsState(id + ".SET")) { destTemp = getState(id + ".SET").val.toFixed(2) * 10; log(id + ".SET " + destTemp) } let status = "" if (existsState(id + ".MODE")) status = getState(id + ".MODE").val; let minTemp = 50 //Min Temp 5°C let maxTemp = 300 //Max Temp 30°C let stepTemp = 5 //0-4 verwendet bei ungerader Anzahl Parametern let bt0 = "~~~~"; //verwendet bei ungleichen Parametern let bt1 = "~~~~"; //verwendet bei ungleichen Parametern let bt2 = "~~~~"; //verwendet bei ungleichen Parametern let bt3 = "~~~~"; //verwendet bei ungleichen Parametern let bt4 = "~~~~"; //verwendet bei ungleichen Parametern //5-8 verwendet bei gerader Anzahl Parametern let bt5 = Icons.GetIcon("water-percent") + "~0~1~~"; let bt6 = Icons.GetIcon("fire") + "~0~1~~"; let bt7 = Icons.GetIcon("wifi") + "~0~1~~"; let bt8 = Icons.GetIcon("battery-high") + "~0~1~~"; if (existsState(id + ".HUMIDITY")){ console.log(parseInt(getState(id + ".HUMIDITY").val)); bt5 = Icons.GetIcon("water-percent") + "~2016~1~bt8~"; if (parseInt(getState(id + ".HUMIDITY").val) < 40) { bt5 = Icons.GetIcon("water-percent") + "~65504~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) { bt5 = Icons.GetIcon("water-percent") + "~63488~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) { bt5 = Icons.GetIcon("water-percent") + "~65504~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) { bt5 = Icons.GetIcon("water-percent") + "~63488~1~bt8~"; } } if (existsState(id + ".MAINTAIN")){ if (getState(id + ".MAINTAIN").val >> .1) { bt6 = Icons.GetIcon("fire") + "~60897~1~bt8~"; } else { bt6 = Icons.GetIcon("fire") + "~33840~0~bt8~"; } } if (existsState(id + ".UNREACH")){ if (getState(id + ".UNREACH").val) { bt7 = Icons.GetIcon("wifi-off") + "~63488~1~bt8~"; } else { bt7 = Icons.GetIcon("wifi") + "~2016~1~bt8~"; } } if (existsState(id + ".LOWBAT")){ if (getState(id + ".LOWBAT").val) { bt8 = Icons.GetIcon("battery-low") + "~63488~1~bt8~"; } else { bt8 = Icons.GetIcon("battery-high") + "~2016~1~bt8~"; } } let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8; out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res}) } return out_msgs } function GenerateMediaPage(page: PageMedia): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardMedia" }); if (existsObject(id)) { let o = getObject(id); //let name = o.common.name.de; let name = getState(spotifyInstanz + ".player.contextDescription").val; let media_icon = Icons.GetIcon("spotify"); let title = getState(spotifyInstanz + ".player.trackName").val; let author = getState(spotifyInstanz + ".player.artistName").val let volume = getState(spotifyInstanz + ".player.volume").val; var iconplaypause = Icons.GetIcon("pause"); //pause if (getState(spotifyInstanz + ".player.isPlaying").val) { iconplaypause = Icons.GetIcon("pause"); //pause } else { iconplaypause = Icons.GetIcon("play"); //play } let currentSpeaker = getState(spotifyInstanz + ".player.device.name").val let speakerlist = getState(spotifyInstanz + ".devices.deviceListString").val.replace(/;/g,"?"); let onoffbutton = 1; out_msgs.push({ payload: "entityUpd~" + name + "~" + id + "~" + "~" + //???? media_icon + "~" + title + "~" + author + "~" + volume + "~" + iconplaypause + "~" + currentSpeaker + "~" + speakerlist + "~" + onoffbutton}); } return out_msgs } function GenerateAlarmPage(page: PageAlarm): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardAlarm" }); var armed: boolean = false; if (armed) { var arm1 = "Deaktivieren"; //arm1*~* var arm1ActionName = "D1"; //arm1ActionName*~* var arm2 = ""; //arm2*~* var arm2ActionName = ""; //arm2ActionName*~* var arm3 = ""; //arm3*~* var arm3ActionName = ""; //arm3ActionName*~* var arm4 = ""; //arm4*~* var arm4ActionName = ""; //arm4ActionName*~* var icon = Icons.GetIcon("shield-home"); //icon*~* var iconcolor = 63488; //iconcolor*~* var numpadStatus = 1; //numpadStatus*~* var flashing = 1; //flashing* } else { var arm1 = "Alarm 1"; //arm1*~* var arm1ActionName = "A1"; //arm1ActionName*~* var arm2 = "Alarm 2"; //arm2*~* var arm2ActionName = "A2"; //arm2ActionName*~* var arm3 = "Alarm 3"; //arm3*~* var arm3ActionName = "A3"; //arm3ActionName*~* var arm4 = "Alarm 4"; //arm4*~* var arm4ActionName = "A4"; //arm4ActionName*~* var icon = Icons.GetIcon("shield-off"); //icon*~* var iconcolor = 2016; //iconcolor*~* var numpadStatus = 1; //numpadStatus*~* var flashing = 1; //flashing* } out_msgs.push({ payload: "entityUpd~" + //entityUpd~* id + "~" + //internalNameEntity*~* //navigation*~* "~" + //??? arm1 + "~" + //arm1*~* arm1ActionName + "~" + //arm1ActionName*~* arm2 + "~" + //arm2*~* arm2ActionName + "~" + //arm2ActionName*~* arm3 + "~" + //arm3*~* arm3ActionName + "~" + //arm3ActionName*~* arm4 + "~" + //arm4*~* arm4ActionName + "~" + //arm4ActionName*~* icon + "~" + //icon*~* 39=Disarmed 35=Shield_Home, 40 iconcolor + "~" + //iconcolor*~* 2016=green 63488=red numpadStatus + "~" + //numpadStatus*~* flashing}); //flashing* return out_msgs } function setIfExists(id: string, value: any, type: string | null = null): boolean { if (type === null) { if (existsState(id)) { setState(id, value); return true; } } else { let obj = getObject(id); if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) { setState(id, value); return true; } } return false; } function toggleState(id: string): boolean { let obj = getObject(id); if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") { setState(id, !getState(id).val); return true; } return false; } function HandleButtonEvent(words): void { let id = words[2] let buttonAction = words[3]; switch (buttonAction) { case "bNext": var pageNum = ((pageId + 1) % config.pages.length); pageId = Math.abs(pageNum); UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case "bPrev": var pageNum = ((pageId - 1) % config.pages.length); pageId = Math.abs(pageNum); UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case "bExit": if (config.screenSaverDoubleClick) { if (words[4] == 2) GeneratePage(config.pages[pageId]); } else GeneratePage(config.pages[pageId]); break; case "OnOff": if (existsObject(id)) { var action = false if (words[4] == "1") action = true let o = getObject(id) switch (o.common.role) { case "light": setIfExists(id + ".SET", action); break; case "dimmer": setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action); } } break; case "up": setIfExists(id + ".OPEN", true) break; case "stop": setIfExists(id + ".STOP", true) break; case "down": setIfExists(id + ".CLOSE", true) break; case "button": toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET") break; case "positionSlider": case "brightnessSlider": setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4])); break; case "tempUpd": setIfExists(id + ".SET", parseInt(words[4]) / 10) break; case "media-back": setIfExists(spotifyInstanz + ".player.skipMinus", true) break; case "media-pause": if (getState(spotifyInstanz + ".player.isPlaying").val === true) { setIfExists(spotifyInstanz + ".player.pause", true) } else { setIfExists(spotifyInstanz + ".player.play", true) } break; case "media-next": setIfExists(spotifyInstanz + ".player.skipPlus", true) break; case "volumeSlider": setIfExists(spotifyInstanz + ".player.volume", parseInt(words[4])) break; case "speaker-sel": console.log("auf mediaCard - speaker-sel - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A1": //Alarm-Page Alarm 1 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A2": //Alarm-Page Alarm 2 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A3": //Alarm-Page Alarm 3 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A4": //Alarm-Page Alarm 4 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "D1": //Alarm-Page Alarm Deaktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; default: break; } } function GetNavigationString(pageId: number): string { switch (pageId) { case 0: return "0|1"; case config.pages.length - 1: return "1|0"; case -1: return "0|0"; default: return "1|1"; } } function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { var out_msgs: Array<Payload> = []; let id = pageItem.id if (existsObject(id)) { var o = getObject(id) var val: (boolean | number) = 0; let icon = Icons.GetIcon("lightbulb"); var iconColor = rgb_dec565(config.defaultColor); if (type == "popupLight") { let switchVal = "0" if (o.common.role == "light") { if (existsState(id + ".GET")) { val = getState(id + ".GET").val; RegisterDetailEntityWatcher(id + ".GET", pageItem, type); } else if (existsState(id + ".SET")) { val = getState(id + ".SET").val; RegisterDetailEntityWatcher(id + ".SET", pageItem, type); } if (val) { switchVal = "1"; iconColor = GetIconColor(pageItem, true, false); } out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" }) } if (o.common.role == "dimmer") { if (existsState(id + ".ON_ACTUAL")) { val = getState(id + ".ON_ACTUAL").val; RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type); } else if (existsState(id + ".ON_SET")) { val = getState(id + ".ON_SET").val; RegisterDetailEntityWatcher(id + ".ON_SET", pageItem, type); } if (val === true) { var iconColor = GetIconColor(pageItem, val, false); switchVal = "1" } let brightness = 0; if (existsState(id + ".ACTUAL")) { brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, 0, 100, 0, 100)) iconColor = GetIconColor(pageItem, brightness, false); RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type); } let colorTemp = "disable" let colorMode = "disable" //let attr_support_color = attr.supported_color_modes //if (attr_support_color.includes("color_temp")) // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100)) out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode }) } } if (type == "popupShutter") { if (existsState(id + ".ACTUAL")) val = getState(id + ".ACTUAL").val; else if (existsState(id + ".SET")) val = getState(id + ".SET").val; out_msgs.push({ payload: "entityUpdateDetail," + val }) } } return out_msgs } function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number { return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; } function UnsubscribeWatcher(): void { for (const [key, value] of Object.entries(subscriptions)) { unsubscribe(value); delete subscriptions[key] } } function HandleScreensaver(): void { SendToPanel({ payload: "pageType~screensaver"}) UnsubscribeWatcher(); HandleScreensaverUpdate(); } function HandleScreensaverUpdate(): void { if (screensaverEnabled && config.weatherEntity != null && existsObject(config.weatherEntity)) { var icon = getState(config.weatherEntity + ".ICON").val; let temperature: string = existsState(config.weatherEntity + ".ACTUAL") ? getState(config.weatherEntity + ".ACTUAL").val : existsState(config.weatherEntity + ".TEMP") ? getState(config.weatherEntity + ".TEMP").val : "null"; let payloadString = "weatherUpdate~" + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + "~" + temperature + " " + config.temperatureUnit + "~" /*-------------------------------------------------------------------------------------------------------------------------------------*/ 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>{ payload: payloadString }); } } function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string { if (configElement != null && configElement.ScreensaverEntity != null && existsState(configElement.ScreensaverEntity)) { let u1 = getState(configElement.ScreensaverEntity).val; return configElement.ScreensaverEntityText + "~" + Icons.GetIcon(configElement.ScreensaverEntityIcon) + "~" + u1 + " " + configElement.ScreensaverEntityUnitText + "~"; } else { return "~~~"; } } function GetAccuWeatherIcon(icon: number): string { switch (icon) { case 24: // Ice case 30: // Hot case 31: // Cold return "window-open"; // exceptional case 7: // Cloudy case 8: // Dreary (Overcast) case 38: // Mostly Cloudy return "weather-cloudy"; // cloudy case 11: // fog return "weather-fog"; // fog case 25: // Sleet return "weather-hail"; // Hail case 15: // T-Storms return "weather-lightning"; // lightning case 16: // Mostly Cloudy w/ T-Storms case 17: // Partly Sunny w/ T-Storms case 41: // Partly Cloudy w/ T-Storms case 42: // Mostly Cloudy w/ T-Storms return "weather-lightning-rainy"; // lightning-rainy case 33: // Clear case 34: // Mostly Clear case 37: // Hazy Moonlight return "weather-night"; case 3: // Partly Sunny case 4: // Intermittent Clouds case 6: // Mostly Cloudy case 35: // Partly Cloudy case 36: // Intermittent Clouds return "weather-partly-cloudy"; // partlycloudy case 18: // pouring return "weather-pouring"; // pouring case 12: // Showers case 13: // Mostly Cloudy w/ Showers case 14: // Partly Sunny w/ Showers case 26: // Freezing Rain case 39: // Partly Cloudy w/ Showers case 40: // Mostly Cloudy w/ Showers return "weather-rainy"; // rainy case 19: // Flurries case 20: // Mostly Cloudy w/ Flurries case 21: // Partly Sunny w/ Flurries case 22: // Snow case 23: // Mostly Cloudy w/ Snow case 43: // Mostly Cloudy w/ Flurries case 44: // Mostly Cloudy w/ Snow return "weather-snowy"; // snowy case 29: // Rain and Snow return "weather-snowy-rainy"; // snowy-rainy case 1: // Sunny case 2: // Mostly Sunny case 5: // Hazy Sunshine return "weather-sunny"; // sunny case 32: // windy return "weather-windy"; // windy default: return "alert-circle-outline"; } } function GetBlendedColor(percentage: number): RGB { if (percentage < 50) return Interpolate(config.defaultOffColor, config.defaultOnColor, percentage / 50.0); return Interpolate(Red, White, (percentage - 50) / 50.0); } function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { var r: number = InterpolateNum(color1.red, color2.red, fraction); var g: number = InterpolateNum(color1.green, color2.green, fraction); var b: number = InterpolateNum(color1.blue, color2.blue, fraction); return <RGB>{ red: Math.round(r), green: Math.round(g), blue: Math.round(b) }; } function InterpolateNum(d1: number, d2: number, fraction: number): number { return d1 + (d2 - d1) * fraction; } function rgb_dec565(rgb: RGB): number { return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31))); } type RGB = { red: number, green: number, blue: number }; type Payload = { payload: string; }; type Page = { type: string, heading: string, items: PageItem[], useColor: boolean }; interface PageEntities extends Page { type: "cardEntities", items: PageItem[], }; interface PageGrid extends Page { type: "cardGrid", items: PageItem[], }; interface PageThermo extends Page { type: "cardThermo", items: PageItem[], }; interface PageMedia extends Page { type: "cardMedia", items: PageItem[], }; interface PageAlarm extends Page { type: "cardAlarm", items: PageItem[], }; type PageItem = { id: string, icon: (string | undefined), onColor: (RGB | undefined), offColor: (RGB | undefined), useColor: (boolean | undefined), interpolateColor: (boolean | undefined), minValue: (number | undefined), maxValue: (number | undefined), name: (string | undefined) } type Config = { panelRecvTopic: string, panelSendTopic: string, timeoutScreensaver: number, dimmode: number, //brightnessScreensaver: locale: string, timeFormat: string, dateFormat: string, weatherEntity: string | null, screenSaverDoubleClick: boolean, temperatureUnit: string, firstScreensaverEntity: ScreenSaverElement | null, secondScreensaverEntity: ScreenSaverElement | null, thirdScreensaverEntity: ScreenSaverElement | null, fourthScreensaverEntity: ScreenSaverElement | null, defaultColor: RGB, defaultOnColor: RGB, defaultOffColor: RGB, pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[], button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), }; type ScreenSaverElement = { ScreensaverEntity: string | null, ScreensaverEntityIcon: string | null, ScreensaverEntityText: string | null, ScreensaverEntityUnitText: string | null, }
-
@holgerwolf sagte in Sonoff NSPanel:
@armilar Nöh, das hatte ich schon alles drin.
Edit: Stop, muss ich nochmal ran...
Zur Sicherheit mal hier mein aktuelles Script:
var Icons = new IconsSelector(); const Months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]; const Days = ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]; const Red: RGB = { red: 255, green: 0, blue: 0 }; const White: RGB = { red: 255, green: 255, blue: 255 }; const Off: RGB = { red: 68, green: 115, blue: 158 }; 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 } //----Möglichkeit, im Screensaver zwischen Accu-Weather Forcast oder selbstdefinierten Werten zu wählen--------------------------------- var weatherForecast = false; //true = WheatherForecast 5 Days --- false = Config --> firstScreensaverEntity - fourthScreensaverEntity ... //Spotify Instanz var spotifyInstanz = "spotify-premium.0" var Wohnen: PageGrid = { "type": "cardGrid", "heading": "Fenster", "useColor": true, "items": [ <PageItem>{ id: "alias.0.StudioSued", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordLinks", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordRechts", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Gaeste", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Bad", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Schlaf", icon: "window-closed", offColor: Off, onColor: Red } ] }; var Strom: PageEntities = { "type": "cardEntities", "heading": "Strom", "useColor": false, "items": [ <PageItem>{ id: "alias.0.PV", icon: "solar-power", interpolateColor: true, offColor: BatteryFull}, <PageItem>{ id: "alias.0.Verbrauch", icon: "power-plug", interpolateColor: true, offColor: Red}, <PageItem>{ id: "alias.0.Auto-SoC", icon: "car-electric", offColor: Off} ] }; var button1Page: PageGrid = { "type": "cardGrid", "heading": "Fenster", "useColor": true, "items": [ <PageItem>{ id: "alias.0.StudioSued", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordLinks", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.StudioNordRechts", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Gaeste", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Bad", icon: "window-closed", offColor: Off, onColor: Red }, <PageItem>{ id: "alias.0.Schlaf", icon: "window-closed", offColor: Off, onColor: Red } ] }; export const config: Config = { panelRecvTopic: "mqtt.1.tele.tasmota_7BC490.RESULT", //anpassen panelSendTopic: "mqtt.1.cmnd.tasmota_7BC490.CustomSend", //anpassen firstScreensaverEntity: { ScreensaverEntity: "zigbee.0.00158d0002c77840.temperature", ScreensaverEntityIcon: "thermometer", ScreensaverEntityText: "Luft", ScreensaverEntityUnitText: "°C" }, secondScreensaverEntity: { ScreensaverEntity: "accuweather.0.Daily.Day1.Day.RainProbability", ScreensaverEntityIcon: "weather-pouring", ScreensaverEntityText: "Regen", ScreensaverEntityUnitText: "%" }, thirdScreensaverEntity: { ScreensaverEntity: "mqtt.0.openWB.lp.1.%Soc", ScreensaverEntityIcon: "car-electric", ScreensaverEntityText: "SoC", ScreensaverEntityUnitText: "%" }, fourthScreensaverEntity: { ScreensaverEntity: "javascript.0.Photovoltaik.Leistung_DC_komplett", ScreensaverEntityIcon: "solar-power", ScreensaverEntityText: "PV", ScreensaverEntityUnitText: "W" }, timeoutScreensaver: 15, dimmode: 8, screenSaverDoubleClick: true, locale: "de_DE", timeFormat: "%H:%M", dateFormat: "%A, %d. %B %Y", weatherEntity: "alias.0.Weather", defaultOffColor: Off, defaultOnColor: On, defaultColor: Off, temperatureUnit: "°C", pages: [Wohnen, Strom ], button1Page: button1Page, button2Page: button1Page }; // _________________________________ Ab hier keine Konfiguration mehr _____________________________________ var subscriptions: any = {}; var screensaverEnabled : boolean = false; var pageId = 0; schedule("* * * * *", function () { SendTime(); }); schedule("0 * * * *", function () { SendDate(); }); // Only monitor the extra nodes if present var updateArray: string[] = []; if (config.firstScreensaverEntity !== null && config.firstScreensaverEntity.ScreensaverEntity != null && existsState(config.firstScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.firstScreensaverEntity.ScreensaverEntity) } if (config.secondScreensaverEntity !== null && config.secondScreensaverEntity.ScreensaverEntity != null && existsState(config.secondScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.secondScreensaverEntity.ScreensaverEntity) } if (config.thirdScreensaverEntity !== null && config.thirdScreensaverEntity.ScreensaverEntity != null && existsState(config.thirdScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.thirdScreensaverEntity.ScreensaverEntity) } if (config.fourthScreensaverEntity !== null && config.fourthScreensaverEntity.ScreensaverEntity != null && existsState(config.fourthScreensaverEntity.ScreensaverEntity)) { updateArray.push(config.fourthScreensaverEntity.ScreensaverEntity) } if (updateArray.length > 0) { on(updateArray, function () { HandleScreensaverUpdate(); }) } on({ id: config.panelRecvTopic }, function (obj) { if (obj.state.val.startsWith('\{"CustomRecv":')) { var json = JSON.parse(obj.state.val); var split = json.CustomRecv.split(","); HandleMessage(split[0], split[1], parseInt(split[2]), split); } }); function SendToPanel(val: Payload | Payload[]): void { if (Array.isArray(val)) { val.forEach(function (id, i) { setState(config.panelSendTopic, id.payload); }); } else setState(config.panelSendTopic, val.payload); } function HandleMessage(typ: string, method: string, page: number, words: Array<string>): void { if (typ == "event") { switch (method) { case "startup": screensaverEnabled = false; UnsubscribeWatcher(); HandleStartupProcess(); pageId = 0; GeneratePage(config.pages[0]); break; case "sleepReached": screensaverEnabled = true; HandleScreensaver(); break; case "pageOpenDetail": screensaverEnabled = false; UnsubscribeWatcher(); let pageItem = config.pages[pageId].items.find(e => e.id === words[3]); if (pageItem !== undefined) SendToPanel(GenerateDetailPage(words[2], pageItem)); case "buttonPress2": screensaverEnabled = false; HandleButtonEvent(words); break; case "button1": case "button2": screensaverEnabled = false; HandleHardwareButton(method); default: break; } } } function GeneratePage(page: Page): void { switch (page.type) { case "cardEntities": SendToPanel(GenerateEntitiesPage(<PageEntities>page)); break; case "cardThermo": SendToPanel(GenerateThermoPage(<PageThermo>page)); break; case "cardGrid": SendToPanel(GenerateGridPage(<PageGrid>page)); break; case "cardMedia": SendToPanel(GenerateMediaPage(<PageMedia>page)); break; case "cardAlarm": SendToPanel(GenerateAlarmPage(<PageAlarm>page)); break; } } function HandleHardwareButton(method: string): void { let page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid); if (config.button1Page !== null && method == "button1") { page = config.button1Page; } else if (config.button2Page !== null && method == "button2") { page = config.button2Page; } else { return; } // Set pageId to -1, because of the navigation arrows let tempPageId = pageId; pageId = -1; GeneratePage(page); pageId = tempPageId; } function HandleStartupProcess(): void { SendDate(); SendTime(); SendToPanel({ payload: "timeout~" + config.timeoutScreensaver }); SendToPanel({ payload: "dimmode~" + config.dimmode }); } function SendDate(): void { var d = new Date(); var day = Days[d.getDay()]; var date = d.getDate(); var month = Months[d.getMonth()]; var year = d.getFullYear(); var _sendDate = "date~" + day + " " + date + " " + month + " " + year; SendToPanel(<Payload>{ payload: _sendDate }); } function SendTime(): void { var d = new Date(); var hr = d.getHours().toString(); var min = d.getMinutes().toString(); if (d.getHours() < 10) { hr = "0" + d.getHours().toString(); } if (d.getMinutes() < 10) { min = "0" + d.getMinutes().toString(); } SendToPanel(<Payload>{ payload: "time~" + hr + ":" + min }); } function GenerateEntitiesPage(page: PageEntities): Payload[] { var out_msgs: Array<Payload> = []; out_msgs = [{ payload: "pageType~cardEntities" }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } function GenerateGridPage(page: PageGrid): Payload[] { var out_msgs: Array<Payload> = []; out_msgs = [{ payload: "pageType~cardGrid" }] out_msgs.push({ payload: GeneratePageElements(page) }); return out_msgs } function GeneratePageElements(page: Page): string { let maxItems = 0; switch (page.type) { case "cardThermo": maxItems = 1; break; case "cardAlarm": maxItems = 1; break; case "cardMedia": maxItems = 1; break; case "cardEntities": maxItems = 4; break; case "cardGrid": maxItems = 6; break; } let pageData = "entityUpd~" + page.heading + "~" + GetNavigationString(pageId) for (let index = 0; index < maxItems; index++) { if (page.items[index] !== undefined) { pageData += CreateEntity(page.items[index], index + 1, page.useColor); } else { pageData += CreateEntity(<PageItem>{ id: "delete" }, index + 1); } } return pageData; } function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean = false): string { var iconId = "0" if (pageItem.id == "delete") { return "~delete~~~~~" } var name: string; var type: string; if (existsObject(pageItem.id)) { let o = getObject(pageItem.id) var val = null; name = pageItem.name !== undefined ? pageItem.name : o.common.name.de if (existsState(pageItem.id + ".GET")) { val = getState(pageItem.id + ".GET").val; RegisterEntityWatcher(pageItem.id + ".GET"); } else if (existsState(pageItem.id + ".SET")) { val = getState(pageItem.id + ".SET").val; RegisterEntityWatcher(pageItem.id + ".SET"); } var iconColor = rgb_dec565(config.defaultColor); switch (o.common.role) { case "light": type = "light" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == "socket" ? Icons.GetIcon("power-socket-de") : Icons.GetIcon("lightbulb"); var optVal = "0" if (val === true || val === "true") { optVal = "1" iconColor = GetIconColor(pageItem, true, useColors); } else { iconColor = GetIconColor(pageItem, false, useColors); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; case "dimmer": type = "light" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("lightbulb"); var optVal = "0" if (existsState(pageItem.id + ".ON_ACTUAL")) { val = getState(pageItem.id + ".ON_ACTUAL").val; RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ON_SET")) { val = getState(pageItem.id + ".ON_SET").val; RegisterEntityWatcher(pageItem.id + ".ON_SET"); } if (val === true || val === "true") { optVal = "1" iconColor = GetIconColor(pageItem, existsState(pageItem.id + ".ACTUAL") ? getState(pageItem.id + ".ACTUAL").val : true, useColors); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal; case "blind": type = "shutter" iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("window-open"); iconColor = GetIconColor(pageItem, existsState(pageItem.id + ".ACTUAL") ? getState(pageItem.id + ".ACTUAL").val : true, useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" case "window": type = "text"; if (existsState(pageItem.id + ".ACTUAL")) { if (getState(pageItem.id + ".ACTUAL").val) { iconId = Icons.GetIcon("window-open-variant"); iconColor = GetIconColor(pageItem, false, useColors); var windowState = "opened" } else { iconId = Icons.GetIcon("window-closed-variant"); iconColor = GetIconColor(pageItem, true, useColors); var windowState = "closed" } RegisterEntityWatcher(pageItem.id + ".ACTUAL"); } return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + windowState; case "info": case "value.temperature": case "thermostat": type = "text"; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : o.common.role == "value.temperature" || o.common.role == "thermostat" ? Icons.GetIcon("thermometer") : Icons.GetIcon("information-outline"); let unit = ""; var optVal = "0" if (existsState(pageItem.id + ".ON_ACTUAL")) { optVal = getState(pageItem.id + ".ON_ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ON_ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ON_ACTUAL"); } else if (existsState(pageItem.id + ".ACTUAL")) { optVal = getState(pageItem.id + ".ACTUAL").val; unit = pageItem.unit !== undefined ? pageItem.unit : GetUnitOfMeasurement(pageItem.id + ".ACTUAL"); RegisterEntityWatcher(pageItem.id + ".ACTUAL"); } if (o.common.role == "value.temperature") { iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("thermometer"); } iconColor = GetIconColor(pageItem, parseInt(optVal), useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + optVal + " " + unit; case "button": type = "button"; iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon("gesture-tap-button"); let buttonText = pageItem.name !== undefined ? pageItem.name : "PRESS"; iconColor = GetIconColor(pageItem, true, useColors); return "~" + type + "~" + pageItem.id + "~" + iconId + "~" + iconColor + "~" + name + "~" + buttonText; default: return "~delete~~~~~"; } } return "~delete~~~~~" } function GetIconColor(pageItem: PageItem, value: (boolean | number), useColors: boolean): number { // dimmer if ((pageItem.useColor || useColors) && pageItem.interpolateColor && typeof (value) === "number") { let maxValue = pageItem.maxValue !== undefined ? pageItem.maxValue : 100; let minValue = pageItem.minValue !== undefined ? pageItem.minValue : 0; value = value > maxValue ? maxValue : value; value = value < minValue ? minValue : value; return rgb_dec565( Interpolate( pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor, pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor, scale(value, minValue, maxValue, 0, 1) )); } if ((pageItem.useColor || useColors) && ((typeof (value) === "boolean" && value) || value > (pageItem.minValue !== undefined ? pageItem.minValue : 0))) { return rgb_dec565(pageItem.onColor !== undefined ? pageItem.onColor : config.defaultOnColor) } return rgb_dec565(pageItem.offColor !== undefined ? pageItem.offColor : config.defaultOffColor); } function RegisterEntityWatcher(id: string): void { if (subscriptions.hasOwnProperty(id)) { return; } subscriptions[id] = (on({ id: id, change: 'any' }, function (data) { SendToPanel({ payload: GeneratePageElements(config.pages[pageId]) }); })) } function RegisterDetailEntityWatcher(id: string, pageItem: PageItem, type: string): void { if (subscriptions.hasOwnProperty(id)) { return; } subscriptions[id] = (on({ id: id, change: 'any' }, function () { SendToPanel(GenerateDetailPage(type, pageItem)); })) } function GetUnitOfMeasurement(id: string): string { if (!existsObject(id)) return ""; let obj = getObject(id); if (typeof obj.common.unit !== 'undefined') { return obj.common.unit } if (typeof obj.common.alias !== 'undefined' && typeof obj.common.alias.id !== 'undefined') { return GetUnitOfMeasurement(obj.common.alias.id); } return ""; } function GenerateThermoPage(page: PageThermo): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardThermo" }); // ioBroker if (existsObject(id)) { let o = getObject(id) let name = page.items[0].name !== undefined ? page.items[0].name : o.common.name.de let currentTemp = 0; if (existsState(id + ".ACTUAL")) currentTemp = (Math.round(parseFloat(getState(id + ".ACTUAL").val) * 10)/10)*10; let destTemp = 0; if (existsState(id + ".SET")) { destTemp = getState(id + ".SET").val.toFixed(2) * 10; log(id + ".SET " + destTemp) } let status = "" if (existsState(id + ".MODE")) status = getState(id + ".MODE").val; let minTemp = 50 //Min Temp 5°C let maxTemp = 300 //Max Temp 30°C let stepTemp = 5 //0-4 verwendet bei ungerader Anzahl Parametern let bt0 = "~~~~"; //verwendet bei ungleichen Parametern let bt1 = "~~~~"; //verwendet bei ungleichen Parametern let bt2 = "~~~~"; //verwendet bei ungleichen Parametern let bt3 = "~~~~"; //verwendet bei ungleichen Parametern let bt4 = "~~~~"; //verwendet bei ungleichen Parametern //5-8 verwendet bei gerader Anzahl Parametern let bt5 = Icons.GetIcon("water-percent") + "~0~1~~"; let bt6 = Icons.GetIcon("fire") + "~0~1~~"; let bt7 = Icons.GetIcon("wifi") + "~0~1~~"; let bt8 = Icons.GetIcon("battery-high") + "~0~1~~"; if (existsState(id + ".HUMIDITY")){ console.log(parseInt(getState(id + ".HUMIDITY").val)); bt5 = Icons.GetIcon("water-percent") + "~2016~1~bt8~"; if (parseInt(getState(id + ".HUMIDITY").val) < 40) { bt5 = Icons.GetIcon("water-percent") + "~65504~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) < 30) { bt5 = Icons.GetIcon("water-percent") + "~63488~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 65) { bt5 = Icons.GetIcon("water-percent") + "~65504~1~bt8~"; } else if (parseInt(getState(id + ".HUMIDITY").val) > 75) { bt5 = Icons.GetIcon("water-percent") + "~63488~1~bt8~"; } } if (existsState(id + ".MAINTAIN")){ if (getState(id + ".MAINTAIN").val >> .1) { bt6 = Icons.GetIcon("fire") + "~60897~1~bt8~"; } else { bt6 = Icons.GetIcon("fire") + "~33840~0~bt8~"; } } if (existsState(id + ".UNREACH")){ if (getState(id + ".UNREACH").val) { bt7 = Icons.GetIcon("wifi-off") + "~63488~1~bt8~"; } else { bt7 = Icons.GetIcon("wifi") + "~2016~1~bt8~"; } } if (existsState(id + ".LOWBAT")){ if (getState(id + ".LOWBAT").val) { bt8 = Icons.GetIcon("battery-low") + "~63488~1~bt8~"; } else { bt8 = Icons.GetIcon("battery-high") + "~2016~1~bt8~"; } } let icon_res = bt0 + bt1 + bt2 + bt3 + bt4 + bt5 + bt6 + bt7 + bt8; out_msgs.push({ payload: "entityUpd~" + name + "~" + GetNavigationString(pageId) + "~" + id + "~" + currentTemp + "~" + destTemp + "~" + status + "~" + minTemp + "~" + maxTemp + "~" + stepTemp + "~" +icon_res}) } return out_msgs } function GenerateMediaPage(page: PageMedia): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardMedia" }); if (existsObject(id)) { let o = getObject(id); //let name = o.common.name.de; let name = getState(spotifyInstanz + ".player.contextDescription").val; let media_icon = Icons.GetIcon("spotify"); let title = getState(spotifyInstanz + ".player.trackName").val; let author = getState(spotifyInstanz + ".player.artistName").val let volume = getState(spotifyInstanz + ".player.volume").val; var iconplaypause = Icons.GetIcon("pause"); //pause if (getState(spotifyInstanz + ".player.isPlaying").val) { iconplaypause = Icons.GetIcon("pause"); //pause } else { iconplaypause = Icons.GetIcon("play"); //play } let currentSpeaker = getState(spotifyInstanz + ".player.device.name").val let speakerlist = getState(spotifyInstanz + ".devices.deviceListString").val.replace(/;/g,"?"); let onoffbutton = 1; out_msgs.push({ payload: "entityUpd~" + name + "~" + id + "~" + "~" + //???? media_icon + "~" + title + "~" + author + "~" + volume + "~" + iconplaypause + "~" + currentSpeaker + "~" + speakerlist + "~" + onoffbutton}); } return out_msgs } function GenerateAlarmPage(page: PageAlarm): Payload[] { var id = page.items[0].id var out_msgs: Array<Payload> = []; out_msgs.push({ payload: "pageType~cardAlarm" }); var armed: boolean = false; if (armed) { var arm1 = "Deaktivieren"; //arm1*~* var arm1ActionName = "D1"; //arm1ActionName*~* var arm2 = ""; //arm2*~* var arm2ActionName = ""; //arm2ActionName*~* var arm3 = ""; //arm3*~* var arm3ActionName = ""; //arm3ActionName*~* var arm4 = ""; //arm4*~* var arm4ActionName = ""; //arm4ActionName*~* var icon = Icons.GetIcon("shield-home"); //icon*~* var iconcolor = 63488; //iconcolor*~* var numpadStatus = 1; //numpadStatus*~* var flashing = 1; //flashing* } else { var arm1 = "Alarm 1"; //arm1*~* var arm1ActionName = "A1"; //arm1ActionName*~* var arm2 = "Alarm 2"; //arm2*~* var arm2ActionName = "A2"; //arm2ActionName*~* var arm3 = "Alarm 3"; //arm3*~* var arm3ActionName = "A3"; //arm3ActionName*~* var arm4 = "Alarm 4"; //arm4*~* var arm4ActionName = "A4"; //arm4ActionName*~* var icon = Icons.GetIcon("shield-off"); //icon*~* var iconcolor = 2016; //iconcolor*~* var numpadStatus = 1; //numpadStatus*~* var flashing = 1; //flashing* } out_msgs.push({ payload: "entityUpd~" + //entityUpd~* id + "~" + //internalNameEntity*~* //navigation*~* "~" + //??? arm1 + "~" + //arm1*~* arm1ActionName + "~" + //arm1ActionName*~* arm2 + "~" + //arm2*~* arm2ActionName + "~" + //arm2ActionName*~* arm3 + "~" + //arm3*~* arm3ActionName + "~" + //arm3ActionName*~* arm4 + "~" + //arm4*~* arm4ActionName + "~" + //arm4ActionName*~* icon + "~" + //icon*~* 39=Disarmed 35=Shield_Home, 40 iconcolor + "~" + //iconcolor*~* 2016=green 63488=red numpadStatus + "~" + //numpadStatus*~* flashing}); //flashing* return out_msgs } function setIfExists(id: string, value: any, type: string | null = null): boolean { if (type === null) { if (existsState(id)) { setState(id, value); return true; } } else { let obj = getObject(id); if (existsState(id) && obj.common.type !== undefined && obj.common.type === type) { setState(id, value); return true; } } return false; } function toggleState(id: string): boolean { let obj = getObject(id); if (existsState(id) && obj.common.type !== undefined && obj.common.type === "boolean") { setState(id, !getState(id).val); return true; } return false; } function HandleButtonEvent(words): void { let id = words[2] let buttonAction = words[3]; switch (buttonAction) { case "bNext": var pageNum = ((pageId + 1) % config.pages.length); pageId = Math.abs(pageNum); UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case "bPrev": var pageNum = ((pageId - 1) % config.pages.length); pageId = Math.abs(pageNum); UnsubscribeWatcher(); GeneratePage(config.pages[pageId]); break; case "bExit": if (config.screenSaverDoubleClick) { if (words[4] == 2) GeneratePage(config.pages[pageId]); } else GeneratePage(config.pages[pageId]); break; case "OnOff": if (existsObject(id)) { var action = false if (words[4] == "1") action = true let o = getObject(id) switch (o.common.role) { case "light": setIfExists(id + ".SET", action); break; case "dimmer": setIfExists(id + ".ON_SET", action) ? true : setIfExists(id + ".ON_ACTUAL", action); } } break; case "up": setIfExists(id + ".OPEN", true) break; case "stop": setIfExists(id + ".STOP", true) break; case "down": setIfExists(id + ".CLOSE", true) break; case "button": toggleState(id + ".SET") ? true : toggleState(id + ".ON_SET") break; case "positionSlider": case "brightnessSlider": setIfExists(id + ".SET", parseInt(words[4])) ? true : setIfExists(id + ".ACTUAL", parseInt(words[4])); break; case "tempUpd": setIfExists(id + ".SET", parseInt(words[4]) / 10) break; case "media-back": setIfExists(spotifyInstanz + ".player.skipMinus", true) break; case "media-pause": if (getState(spotifyInstanz + ".player.isPlaying").val === true) { setIfExists(spotifyInstanz + ".player.pause", true) } else { setIfExists(spotifyInstanz + ".player.play", true) } break; case "media-next": setIfExists(spotifyInstanz + ".player.skipPlus", true) break; case "volumeSlider": setIfExists(spotifyInstanz + ".player.volume", parseInt(words[4])) break; case "speaker-sel": console.log("auf mediaCard - speaker-sel - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A1": //Alarm-Page Alarm 1 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A2": //Alarm-Page Alarm 2 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A3": //Alarm-Page Alarm 3 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "A4": //Alarm-Page Alarm 4 aktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; case "D1": //Alarm-Page Alarm Deaktivieren console.log("auf mediaAlarm - Alarm 1 - Wert: " + words[4] + " - reagieren - noch nicht implementiert"); break; default: break; } } function GetNavigationString(pageId: number): string { switch (pageId) { case 0: return "0|1"; case config.pages.length - 1: return "1|0"; case -1: return "0|0"; default: return "1|1"; } } function GenerateDetailPage(type: string, pageItem: PageItem): Payload[] { var out_msgs: Array<Payload> = []; let id = pageItem.id if (existsObject(id)) { var o = getObject(id) var val: (boolean | number) = 0; let icon = Icons.GetIcon("lightbulb"); var iconColor = rgb_dec565(config.defaultColor); if (type == "popupLight") { let switchVal = "0" if (o.common.role == "light") { if (existsState(id + ".GET")) { val = getState(id + ".GET").val; RegisterDetailEntityWatcher(id + ".GET", pageItem, type); } else if (existsState(id + ".SET")) { val = getState(id + ".SET").val; RegisterDetailEntityWatcher(id + ".SET", pageItem, type); } if (val) { switchVal = "1"; iconColor = GetIconColor(pageItem, true, false); } out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + + iconColor + "~" + switchVal + ",disable,disable,disable" }) } if (o.common.role == "dimmer") { if (existsState(id + ".ON_ACTUAL")) { val = getState(id + ".ON_ACTUAL").val; RegisterDetailEntityWatcher(id + ".ON_ACTUAL", pageItem, type); } else if (existsState(id + ".ON_SET")) { val = getState(id + ".ON_SET").val; RegisterDetailEntityWatcher(id + ".ON_SET", pageItem, type); } if (val === true) { var iconColor = GetIconColor(pageItem, val, false); switchVal = "1" } let brightness = 0; if (existsState(id + ".ACTUAL")) { brightness = Math.trunc(scale(getState(id + ".ACTUAL").val, 0, 100, 0, 100)) iconColor = GetIconColor(pageItem, brightness, false); RegisterDetailEntityWatcher(id + ".ACTUAL", pageItem, type); } let colorTemp = "disable" let colorMode = "disable" //let attr_support_color = attr.supported_color_modes //if (attr_support_color.includes("color_temp")) // colortemp = Math.trunc(scale(attr.color_temp, attr.min_mireds, attr.max_mireds, 0, 100)) out_msgs.push({ payload: "entityUpdateDetail~" + icon + "~" + iconColor + "~" + switchVal + "~" + brightness + "~" + colorTemp + "~" + colorMode }) } } if (type == "popupShutter") { if (existsState(id + ".ACTUAL")) val = getState(id + ".ACTUAL").val; else if (existsState(id + ".SET")) val = getState(id + ".SET").val; out_msgs.push({ payload: "entityUpdateDetail," + val }) } } return out_msgs } function scale(number: number, inMin: number, inMax: number, outMin: number, outMax: number): number { return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; } function UnsubscribeWatcher(): void { for (const [key, value] of Object.entries(subscriptions)) { unsubscribe(value); delete subscriptions[key] } } function HandleScreensaver(): void { SendToPanel({ payload: "pageType~screensaver"}) UnsubscribeWatcher(); HandleScreensaverUpdate(); } function HandleScreensaverUpdate(): void { if (screensaverEnabled && config.weatherEntity != null && existsObject(config.weatherEntity)) { var icon = getState(config.weatherEntity + ".ICON").val; let temperature: string = existsState(config.weatherEntity + ".ACTUAL") ? getState(config.weatherEntity + ".ACTUAL").val : existsState(config.weatherEntity + ".TEMP") ? getState(config.weatherEntity + ".TEMP").val : "null"; let payloadString = "weatherUpdate~" + Icons.GetIcon(GetAccuWeatherIcon(parseInt(icon))) + "~" + temperature + " " + config.temperatureUnit + "~" /*-------------------------------------------------------------------------------------------------------------------------------------*/ 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>{ payload: payloadString }); } } function GetScreenSaverEntityString(configElement: ScreenSaverElement | null): string { if (configElement != null && configElement.ScreensaverEntity != null && existsState(configElement.ScreensaverEntity)) { let u1 = getState(configElement.ScreensaverEntity).val; return configElement.ScreensaverEntityText + "~" + Icons.GetIcon(configElement.ScreensaverEntityIcon) + "~" + u1 + " " + configElement.ScreensaverEntityUnitText + "~"; } else { return "~~~"; } } function GetAccuWeatherIcon(icon: number): string { switch (icon) { case 24: // Ice case 30: // Hot case 31: // Cold return "window-open"; // exceptional case 7: // Cloudy case 8: // Dreary (Overcast) case 38: // Mostly Cloudy return "weather-cloudy"; // cloudy case 11: // fog return "weather-fog"; // fog case 25: // Sleet return "weather-hail"; // Hail case 15: // T-Storms return "weather-lightning"; // lightning case 16: // Mostly Cloudy w/ T-Storms case 17: // Partly Sunny w/ T-Storms case 41: // Partly Cloudy w/ T-Storms case 42: // Mostly Cloudy w/ T-Storms return "weather-lightning-rainy"; // lightning-rainy case 33: // Clear case 34: // Mostly Clear case 37: // Hazy Moonlight return "weather-night"; case 3: // Partly Sunny case 4: // Intermittent Clouds case 6: // Mostly Cloudy case 35: // Partly Cloudy case 36: // Intermittent Clouds return "weather-partly-cloudy"; // partlycloudy case 18: // pouring return "weather-pouring"; // pouring case 12: // Showers case 13: // Mostly Cloudy w/ Showers case 14: // Partly Sunny w/ Showers case 26: // Freezing Rain case 39: // Partly Cloudy w/ Showers case 40: // Mostly Cloudy w/ Showers return "weather-rainy"; // rainy case 19: // Flurries case 20: // Mostly Cloudy w/ Flurries case 21: // Partly Sunny w/ Flurries case 22: // Snow case 23: // Mostly Cloudy w/ Snow case 43: // Mostly Cloudy w/ Flurries case 44: // Mostly Cloudy w/ Snow return "weather-snowy"; // snowy case 29: // Rain and Snow return "weather-snowy-rainy"; // snowy-rainy case 1: // Sunny case 2: // Mostly Sunny case 5: // Hazy Sunshine return "weather-sunny"; // sunny case 32: // windy return "weather-windy"; // windy default: return "alert-circle-outline"; } } function GetBlendedColor(percentage: number): RGB { if (percentage < 50) return Interpolate(config.defaultOffColor, config.defaultOnColor, percentage / 50.0); return Interpolate(Red, White, (percentage - 50) / 50.0); } function Interpolate(color1: RGB, color2: RGB, fraction: number): RGB { var r: number = InterpolateNum(color1.red, color2.red, fraction); var g: number = InterpolateNum(color1.green, color2.green, fraction); var b: number = InterpolateNum(color1.blue, color2.blue, fraction); return <RGB>{ red: Math.round(r), green: Math.round(g), blue: Math.round(b) }; } function InterpolateNum(d1: number, d2: number, fraction: number): number { return d1 + (d2 - d1) * fraction; } function rgb_dec565(rgb: RGB): number { return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31))); } type RGB = { red: number, green: number, blue: number }; type Payload = { payload: string; }; type Page = { type: string, heading: string, items: PageItem[], useColor: boolean }; interface PageEntities extends Page { type: "cardEntities", items: PageItem[], }; interface PageGrid extends Page { type: "cardGrid", items: PageItem[], }; interface PageThermo extends Page { type: "cardThermo", items: PageItem[], }; interface PageMedia extends Page { type: "cardMedia", items: PageItem[], }; interface PageAlarm extends Page { type: "cardAlarm", items: PageItem[], }; type PageItem = { id: string, icon: (string | undefined), onColor: (RGB | undefined), offColor: (RGB | undefined), useColor: (boolean | undefined), interpolateColor: (boolean | undefined), minValue: (number | undefined), maxValue: (number | undefined), name: (string | undefined) } type Config = { panelRecvTopic: string, panelSendTopic: string, timeoutScreensaver: number, dimmode: number, //brightnessScreensaver: locale: string, timeFormat: string, dateFormat: string, weatherEntity: string | null, screenSaverDoubleClick: boolean, temperatureUnit: string, firstScreensaverEntity: ScreenSaverElement | null, secondScreensaverEntity: ScreenSaverElement | null, thirdScreensaverEntity: ScreenSaverElement | null, fourthScreensaverEntity: ScreenSaverElement | null, defaultColor: RGB, defaultOnColor: RGB, defaultOffColor: RGB, pages: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid)[], button1Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), button2Page: (PageThermo | PageMedia | PageAlarm | PageEntities | PageGrid | null), }; type ScreenSaverElement = { ScreensaverEntity: string | null, ScreensaverEntityIcon: string | null, ScreensaverEntityText: string | null, ScreensaverEntityUnitText: string | null, }
Ist nicht drin... Siehe Screenshot
Erst wenn da auch unit drin ist, bin ich zufrieden
-
@armilar Ja, Copy-Pasta-Fehler.
Das Script läuft wieder. Da waren ja auch noch die Änderungen bzgl Alexa anzupassen. Das hatte ich alles nicht mitgemacht.
Den Alias habe ich angelegt und verlinkt:
Und so im Script übernommen:
<PageItem>{ id: "alias.0.FensterBad", offColor: Red, onColor: Off, name: "Bad"},
Leider kommt jetzt kein Icon sondern nur eine "Null":
-
@holgerwolf Die 0 kommt wenn kein Icon gefunden wurde. Ich glaube wenn du unter die Zeile 361 noch ein
case "sensor.window":
hinzufügst dann könnte es schon gehen
-
Sehr schön
-
@holgerwolf sagte in Sonoff NSPanel:
@armilar Ja, Copy-Pasta-Fehler.
Das Script läuft wieder. Da waren ja auch noch die Änderungen bzgl Alexa anzupassen. Das hatte ich alles nicht mitgemacht.
Den Alias habe ich angelegt und verlinkt:
Und so im Script übernommen:
<PageItem>{ id: "alias.0.FensterBad", offColor: Red, onColor: Off, name: "Bad"},
Leider kommt jetzt kein Icon sondern nur eine "Null":
Ist der Alias wirklich vom Typ "Fenster"? Oh wer lesen kann ist klar im Vorteil.
-
Hallo, wäre es eigentlich möglich so ne Art Alarmmeldung (push) in das Script einzubauen ?
zb : wenn Einfahrtstor offen das ne MEldung an das PAnel gesendet wird , sich eine bestimmte Ansicht
Öffnet ??Mit freundlichen Grüßen
Mikewolf -
@mikewolf sagte in Sonoff NSPanel:
Hallo, wäre es eigentlich möglich so ne Art Alarmmeldung (push) in das Script einzubauen ?
zb : wenn Einfahrtstor offen das ne MEldung an das PAnel gesendet wird , sich eine bestimmte Ansicht
Öffnet ??Mit freundlichen Grüßen
MikewolfEs gibt da im Panel:
popupNotify Page
entityUpdateDetail~internalName~tHeading~tHeadingColor~b1~tB1Color~b2~tB2Color~tText~tTextColor~sleepTimeoutexitPopup
Ist aber noch nicht implementiert - könnte man verwenden