@frank579
WebAdmin Passwort im Tasmota vergeben ?
das war mein Thema
NEWS
Best posts made by egal
-
RE: SONOFF NSPanel mit Lovelace UI
-
RE: SONOFF NSPanel mit Lovelace UI
@tabeus said in SONOFF NSPanel mit Lovelace UI:
Ach und was abseits der Software, meine Thermostate sind leider Aufputz, weißt du ob es für das Panel einen passenden/schönen Aufputzrahmen für das Panel gibt?
Der hier sollte gut z.B. passen, 85x85x35mm sollten es für optisch bündigen Abschluß schon sein
-
RE: SONOFF NSPanel mit Lovelace UI
Hallo,
so langsam bekommt das Teil so 'richtigen' Nutzen aka WAF ;-D
Habe mal die MediaCard für den Volumio-Player angepaßt (relevente Routinen erweitert), funkt soweit ganz gut inkl. dynamischer Playlist (Mißbrauch des Shuffle-Buttons für den Refresh-Init hierfür)let VolumioBoss: PageMedia = { 'type': 'cardMedia', 'heading': 'Volumio-Büro', 'useColor': true, 'subPage': false, 'parent': undefined, 'items': [<PageItem>{ id: 'alias.0.NSPanel.Volumio-Boss', adapterPlayerInstance: 'volumio.0.', speakerList: [], /* this must, no function */ playList: [], /* empty for dynamic reading */ colorMediaIcon: colorSpotify, colorMediaTitle: colorSpotify, colorMediaArtist: Yellow, autoCreateALias : true }] }; let VolumioMobil: PageMedia = { 'type': 'cardMedia', 'heading': 'Volumio-Mobil', 'useColor': true, 'subPage': false, 'parent': undefined, 'items': [<PageItem>{ id: 'alias.0.NSPanel.Volumio-Mobil', adapterPlayerInstance: 'volumio.1.', speakerList: [], /* this must, no function */ playList: [], /* empty for dynamic reading */ colorMediaIcon: Yellow, colorMediaTitle: Yellow, colorMediaArtist: Gray, autoCreateALias : true }] };
Bloß der volumio-Adapter ist ziemlich empfindlich (schmiert häufig ab, wenn man zu schnell tastet), und mehrer Adapter beeinflussen sich bei den Events: Titel/Artistwechsel gehen an alle Instanzen ?!?
Hat irgend jemand hier noch Volumios im Einsatz ?
-
RE: SONOFF NSPanel mit Lovelace UI
@armilar
so, die Erweiterungen für den Volumio-Player:async function createAutoMediaAlias(id: string, mediaDevice: string, adapterPlayerInstance: string) { ... + + /* Volumio */ + if (adapterPlayerInstance.startsWith('volumio')) { + if (existsObject(id) == false){ + console.log('Volumio Alias ' + id + ' existiert nicht - wird jetzt angelegt') + + let dpPath: string = adapterPlayerInstance; + try { + setObject(id, {_id: id, type: 'channel', common: {role: 'media', name:'media'}, native: {}}); + await createAliasAsync(id + '.ACTUAL', dpPath + 'playbackInfo.volume', true, <iobJS.StateCommon>{ type: 'number', role: 'value.volume', name: 'ACTUAL' }); + await createAliasAsync(id + '.ALBUM', dpPath + 'playbackInfo.album', true, <iobJS.StateCommon>{ type: 'string', role: 'media.album', name: 'ALBUM' }); + await createAliasAsync(id + '.ARTIST', dpPath + 'playbackInfo.artist', true, <iobJS.StateCommon>{ type: 'string', role: 'media.artist', name: 'ARTIST' }); + await createAliasAsync(id + '.TITLE', dpPath + 'playbackInfo.title', true, <iobJS.StateCommon>{ type: 'string', role: 'media.title', name: 'TITLE' }); + await createAliasAsync(id + '.NEXT', dpPath + 'player.next', true, <iobJS.StateCommon>{ type: 'boolean', role: 'button.next', name: 'NEXT' }); + await createAliasAsync(id + '.PREV', dpPath + 'player.prev', true, <iobJS.StateCommon>{ type: 'boolean', role: 'button.prev', name: 'PREV' }); + await createAliasAsync(id + '.PLAY', dpPath + 'player.play', true, <iobJS.StateCommon>{ type: 'boolean', role: 'button.play', name: 'PLAY' }); + await createAliasAsync(id + '.PAUSE', dpPath + 'player.toggle', true, <iobJS.StateCommon>{ type: 'boolean', role: 'button.pause', name: 'PAUSE' }); + await createAliasAsync(id + '.STOP', dpPath + 'player.stop', true, <iobJS.StateCommon>{ type: 'boolean', role: 'button.stop', name: 'STOP' }); + await createAliasAsync(id + '.STATE', dpPath + 'playbackInfo.status', true, <iobJS.StateCommon>{ type: 'boolean', role: 'media.state', name: 'STATE' }); + await createAliasAsync(id + '.VOLUME', dpPath + 'playbackInfo.volume', true, <iobJS.StateCommon>{ type: 'number', role: 'level.volume', name: 'VOLUME' }); + await createAliasAsync(id + '.REPEAT', dpPath + 'playbackInfo.repeat', true, <iobJS.StateCommon>{ type: 'number', role: 'media.mode.repeat', name: 'REPEAT' }); + await createAliasAsync(id + '.SHUFFLE', dpPath + 'queue.shuffle', true, <iobJS.StateCommon>{ type: 'boolean', role: 'media.mode.shuffle', name: 'SHUFFLE' }); + await createAliasAsync(id + '.status', dpPath + 'playbackInfo.status', true, <iobJS.StateCommon>{ type: 'string', role: 'media.state', name: 'status' }); + } catch (err) { + console.warn('function createAutoMediaAlias: ' + err.message); + } + } + } + ... } function GenerateMediaPage(page: PageMedia): Payload[] { ... + + //Volumio + if (v2Adapter == 'volumio') { + if (name != undefined) { author = author + " [" + name + "]"; } + name = getState(vInstance + 'info.name').val; /* page.heading; + getState(id + '.TRACK').val; */ + } + ... + if (v2Adapter == 'volumio') { shuffle_icon = Icons.GetIcon('refresh'); } //Volumio: refresh playlist ... + + //Ausnahme Volumio: status = string: play, pause, stop usw. + if (v2Adapter == 'volumio') { + if (getState(id + '.status').val == 'play') { + onoffbutton = 65535; + iconplaypause = Icons.GetIcon('pause'); //pause + } else { + iconplaypause = Icons.GetIcon('play'); //play + } + } + ... //InSel Playlist let playListString: string = '~~~~~~' let playListIconCol = rgb_dec565(HMIOff); if (page.items[0].playList != undefined) { + /* Volumio: get actual playlist if empty */ + if (v2Adapter == 'volumio') { + if (page.items[0].playList.length == 0) { + request({ url: `${getState(vInstance+'info.host').val}/api/listplaylists`, headers: {'User-Agent': 'ioBroker'} }, + async (error, response, result) => { + try { page.items[0].playList = JSON.parse(result); + //console.log(page.items[0].playList); + } + } catch (err) { console.log('get_volumio-playlist: ' + err.message); } + ); + } } ... } function HandleButtonEvent(words): void { ... case 'media-shuffle': + if ((findPageItem(id).adapterPlayerInstance).startsWith("volumio")) { findPageItem(id).playList = []; break; } //Volumio: empty playlist if (getState(id + '.SHUFFLE').val == 'off') { ... case 'mode-playlist': let pageItemPL = findPageItem(id); let adapterInstancePL = pageItemPL.adapterPlayerInstance; let adapterPL = adapterInstancePL.split('.') let deviceAdapterPL = adapterPL[0]; switch (deviceAdapterPL) { case 'spotify-premium': let strDevicePI = pageItemPL.playList[words[4]] console.log(strDevicePI) let playlistListString = (getState(adapterInstancePL + 'playlists.playlistListString').val).split(';'); let playlistListIds = (getState(adapterInstancePL + 'playlists.playlistListIds').val).split(';'); let playlistIndex = playlistListString.indexOf(strDevicePI); setState(adapterInstancePL + 'playlists.playlistList', playlistListIds[playlistIndex]); setTimeout(async function () { globalTracklist = (function () { try {return JSON.parse(getState(adapterInstancePL + 'player.playlist.trackListArray').val);} catch(e) {return {};}})(); }, 2000); break; case 'alexa2': let tempListItem = pageItemPL.playList[words[4]].split('.'); setState(adapterInstancePL + 'Echo-Devices.' + pageItemPL.mediaDevice + '.Music-Provider.' + tempListItem[0], tempListItem[1]); break; + case 'volumio': + let strDevicePL = pageItemPL.playList[words[4]]; + request({ url:`${getState(adapterInstancePL+'info.host').val}/api/commands/?cmd=playplaylist&name=${strDevicePL}`, headers: {'User-Agent': 'ioBroker'} }, + async (error, response, result)=>{}); /* nothing todo @ error */ + break; } ... } function GenerateDetailPage(type: string, optional: string, pageItem: PageItem): Payload[] { ... } else if (optional == 'playlist') { if (vAdapter == 'spotify-premium') { if (existsObject(pageItem.adapterPlayerInstance + 'player.playlist.name')) { actualState = formatInSelText(getState(pageItem.adapterPlayerInstance + 'player.playlist.name').val); } let tempPlayList = []; for (let i = 0; i < pageItem.playList.length; i++) { tempPlayList[i] = formatInSelText(pageItem.playList[i]); } optionalString = pageItem.playList != undefined ? tempPlayList.join('?') : '' } else if (vAdapter == 'alexa2') { //Todo Richtiges Device finden actualState = formatInSelText(getState(pageItem.adapterPlayerInstance + 'Echo-Devices.' + pageItem.mediaDevice + '.Player.currentAlbum').val); let tPlayList: any = [] for (let i = 0; i < pageItem.playList.length; i++) { console.log(pageItem.playList[i]); let tempItem = pageItem.playList[i].split('.'); tPlayList[i] = tempItem[1]; } let tempPlayList = []; for (let i = 0; i < tPlayList.length; i++) { tempPlayList[i] = formatInSelText(tPlayList[i]); } optionalString = pageItem.playList != undefined ? tempPlayList.join('?') : '' + } else if (vAdapter == 'volumio') { /* Volumio: limit 900 chars */ + actualState = ''; //todo: no actual playlistname saving + let tempPlayList = []; let tempPll = 0; + for (let i = 0; i < pageItem.playList.length; i++) { + tempPll += pageItem.playList[i].length; if (tempPll > 900) break; + tempPlayList[i] = formatInSelText(pageItem.playList[i]); + } + optionalString = pageItem.playList != undefined ? tempPlayList.join('?') : '' + } /**/ mode = 'playlist'; ... }
zur Vollständigkeit, die Funktionen nochmal in gänze:
NSPanel-Volumio-all.txtHinweis:
Die player-Buttonobjekte in der volumio-Instanz müssen 1malig initialisiert werden, bis dahin gibt es Warnings und sie tun netEdit: Shuffle-Button ergänzt
-
RE: SONOFF NSPanel mit Lovelace UI
@armilar
habe noch die Tracklist mit eingebaut:function GenerateDetailPage(type: string, optional: string, pageItem: PageItem): Payload[] { ... } else if (optional == 'tracklist') { actualState = ''; + /* Volumio: works for files */ + if (vAdapter == 'volumio') actualState = getState(pageItem.id + '.TITLE').val; + else /**/ actualState = getState(pageItem.adapterPlayerInstance + 'player.trackName').val; actualState = (actualState.replace('?','')).split(' -'); actualState = actualState[0].split(" ("); actualState = formatInSelText(actualState[0]); //Limit 900 Zeichen, danach Speicherüberlauf --> Soweit kürzen wie möglich let temp_array = []; //let trackArray = (function () { try {return JSON.parse(getState(pageItem.adapterPlayerInstance + 'player.playlist.trackListArray').val);} catch(e) {return {};}})(); for (let track_index=0; track_index < 45; track_index++) { let temp_cut_array = getAttr(globalTracklist, track_index + '.title'); + /* Volumio: @local/NAS no title -> name */ + if (temp_cut_array == undefined) temp_cut_array = getAttr(globalTracklist, track_index + '.name'); + if (Debug) console.log(temp_cut_array); /**/ if (temp_cut_array != undefined) { } function HandleButtonEvent(words): void { ... case 'mode-playlist': ... case 'volumio': let strDevicePL = pageItemPL.playList[words[4]]; request({ url:`${getState(adapterInstancePL+'info.host').val}/api/commands/?cmd=playplaylist&name=${strDevicePL}`, headers: {'User-Agent': 'ioBroker'} }, async (error, response, result)=>{}); /* nothing todo @ error */ + setTimeout(async function () { + request({ url: `${getState(adapterInstancePL+'info.host').val}/api/getQueue`, headers: {'User-Agent': 'ioBroker'} }, + async (error, response, result) => { + try { + const QUEUELIST = JSON.parse(result); + globalTracklist = QUEUELIST.queue; + if (Debug) { for (let i_index in QUEUELIST.queue) console.log(QUEUELIST.queue[i_index]); } + } catch (err) { + console.log('get_volumio-queue: ' + err.message); + } + } + ); + }, 2000); break; } break; case 'mode-tracklist': ... + case 'volumio': + request({ url:`${getState(adapterInstanceTL+'info.host').val}/api/commands/?cmd=play&N=${words[4]}`, headers: {'User-Agent': 'ioBroker'} }, + async (error, response, result)=>{}); /* nothing todo @ error */ + break; } break; ... }
-
RE: SONOFF NSPanel mit Lovelace UI
@armilar
super, funktioniert soweit erstmal, vielen Dank;
folgende Zeile ist zuviel/doppelt (deshalb Fehler/nofunction bei Volumio):function GenerateDetailPage(type: string, optional: string, pageItem: PageItem): Payload[] { ... } else if (optional == 'tracklist') { actualState = ''; /* Volumio: works for files */ if (vAdapter == 'volumio') { actualState = getState(pageItem.id + '.TITLE').val; } else { actualState = getState(pageItem.adapterPlayerInstance + 'player.trackName').val; } - actualState = getState(pageItem.adapterPlayerInstance + 'player.trackName').val; ... }
Habe mal mit diversen Sourcen (webradio, µPNP, airplay, NAS usw) gespielt,
falls es leere/keine Info zu Titel und/oder Artist (hier z.B. Linux-RAOP) gibt, ein bissi optimiert:function GenerateMediaPage(page: PageMedia): Payload[] { ... //Volumio if (v2Adapter == 'volumio') { + if (author == undefined) author = "---"; + if (title == '' && name == '') { title = "- no Info -"; name = "µPNP|airplay"; } if (name != undefined) { author = author + " [" + name + "]"; } name = getState(vInstance + 'info.name').val; /* page.heading; getState(id + '.TRACK').val; */ } ... }
Bei der µPNP-Steuerung (hier mConnectLite/HD) funktionieren sogar die FF/FW-Buttons in der Remote-Playlist,
das spart wirklich die Fernbedienung, sehr cool; bei airplay natürlich nicht, da funkt nur der Stop-Button.'pageItem.globalTracklist' ist neu, jeder Mediaplayer bekommt seine eigene Trackliste ?
-
RE: SONOFF NSPanel mit Lovelace UI
@armilar
ok, seperate Tracklist für jeden Volumio-Player:function GenerateMediaPage(page: PageMedia): Payload[] { ... //InSel Playlist let trackListString: string = '~~~~~~' let trackListIconCol = rgb_dec565(HMIOff); + if (v2Adapter == 'volumio') globalTracklist = page.items[0].globalTracklist; /* Volumio: local queues */ if (globalTracklist!= null && globalTracklist.length != 0) { ... } function HandleButtonEvent(words): void { ... switch (deviceAdapterPL) { case 'spotify-premium': let strDevicePI = pageItemPL.playList[words[4]] console.log(strDevicePI) let playlistListString = (getState(adapterInstancePL + 'playlists.playlistListString').val).split(';'); let playlistListIds = (getState(adapterInstancePL + 'playlists.playlistListIds').val).split(';'); let playlistIndex = playlistListString.indexOf(strDevicePI); setState(adapterInstancePL + 'playlists.playlistList', playlistListIds[playlistIndex]); setTimeout(async function () { globalTracklist = (function () { try {return JSON.parse(getState(adapterInstancePL + 'player.playlist.trackListArray').val);} catch(e) {return {};}})(); }, 2000); break; case 'alexa2': let tempListItem = pageItemPL.playList[words[4]].split('.'); setState(adapterInstancePL + 'Echo-Devices.' + pageItemPL.mediaDevice + '.Music-Provider.' + tempListItem[0], tempListItem[1]); break; case 'volumio': let strDevicePL = pageItemPL.playList[words[4]]; request({ url:`${getState(adapterInstancePL+'info.host').val}/api/commands/?cmd=playplaylist&name=${strDevicePL}`, headers: {'User-Agent': 'ioBroker'} }, async (error, response, result)=>{}); /* nothing todo @ error */ setTimeout(async function () { request({ url: `${getState(adapterInstancePL+'info.host').val}/api/getQueue`, headers: {'User-Agent': 'ioBroker'} }, async (error, response, result) => { try { const QUEUELIST = JSON.parse(result); -/+ pageItemPL.globalTracklist = QUEUELIST.queue; if (Debug) { for (let i_index in QUEUELIST.queue) console.log(QUEUELIST.queue[i_index]); } ... } function GenerateDetailPage(type: string, optional: string, pageItem: PageItem): Payload[] { ... } else if (optional == 'tracklist') { actualState = ''; /* Volumio: works for files */ if (vAdapter == 'volumio') { actualState = getState(pageItem.id + '.TITLE').val; + globalTracklist = pageItem.globalTracklist; } else { ... }
Ansonsten steht noch ein bissi was an zum umsetzen:
die Wärmpeumpen/Klimas funken soweit schonmal, den ECO-Zustand gibt es hier nicht, aber so gehts:
Für die Rollos muß ich mal gucken, das aus 2 Icons 1 wird, also <Navi> auf <Subpage Shutter> mit akt.Stellungszeige (+Farbe) ...
Und über die jetzt mögliche Strukutierung/Hierachien muß ich ersrmal schlafen ähm nachdenken
--
P.S.:
@egal said in SONOFF NSPanel mit Lovelace UI:.. und mehrer Adapter beeinflussen sich bei den Events: Titel/Artistwechsel gehen an alle Instanzen ?!?
Das hat sich geklärt, der 2. Adapter hatte zuerst denselben TCP-Port, das mosert er zwar an, aber die URL-Notification auf dem Volumio war schon eingetragen, Volumio-Neustart, erledigt
-
RE: SONOFF NSPanel mit Lovelace UI
@egal
bevor ich das vergesse, die letzten Erweiterungen zum Volumio Media-Player,
Repeat-Button ergänzt, Tracklist-Generierung verschoben, so das auch extern erstellte Tracklisten/Queues erfaßt werden:function GenerateMediaPage(page: PageMedia): Payload[] { ... //InSel Tracklist let trackListString: string = '~~~~~~' let trackListIconCol = rgb_dec565(HMIOff); + if (v2Adapter == 'volumio') { /* Volumio: get queue */ + setTimeout(async function () { + request({ url: `${getState(vInstance+'info.host').val}/api/getQueue`, headers: {'User-Agent': 'ioBroker'} }, + async (error, response, result) => { + try { + const QUEUELIST = JSON.parse(result); + page.items[0].globalTracklist = QUEUELIST.queue; + if (Debug) { for (let i_index in QUEUELIST.queue) console.log(QUEUELIST.queue[i_index]); } + } catch (err) { + console.log('get_volumio-queue: ' + err.message); + } + } + ); + }, 2000); + globalTracklist = page.items[0].globalTracklist; } ... //Repeat Control Button ... + } else if (v2Adapter == 'volumio') { /* Volumio: only Repeat true/false with API */ + if (getState(id + '.REPEAT').val == true) { + repeatIcon = Icons.GetIcon('repeat-variant'); + repeatIconCol = rgb_dec565(colMediaIcon); + } } - if (v2Adapter == 'spotify-premium' || v2Adapter == 'alexa2' || v2Adapter == 'sonos') { + if (v2Adapter == 'spotify-premium' || v2Adapter == 'alexa2' || v2Adapter == 'sonos' || v2Adapter == 'volumio') { ... } function HandleButtonEvent(words): void { ... switch (buttonAction) { ... case 'button': ... case 'media': if (tempid[1] == 'repeat') { ... switch (deviceAdapterRP) { ... + case 'volumio': + request({ url:`${getState(adapterInstanceRepeat+'info.host').val}/api/commands/?cmd=repeat`, headers: {'User-Agent': 'ioBroker'} }, + async (error, response, result)=>{}); /* nothing todo @ error */ + break; } ... // + die Tracklistgenerierung unten entfernt: case 'mode-playlist': ... case 'volumio': let strDevicePL = pageItemPL.playList[words[4]]; request({ url:`${getState(adapterInstancePL+'info.host').val}/api/commands/?cmd=playplaylist&name=${strDevicePL}`, headers: {'User-Agent': 'ioBroker'} }, async (error, response, result)=>{}); /* nothing todo @ error */ - /*setTimeout(async function () { - request({ url: `${getState(adapterInstancePL+'info.host').val}/api/getQueue`, headers: {'User-Agent': 'ioBroker'} }, - async (error, response, result) => { - try { - const QUEUELIST = JSON.parse(result); - pageItemPL.globalTracklist = QUEUELIST.queue; - if (Debug) { for (let i_index in QUEUELIST.queue) console.log(QUEUELIST.queue[i_index]); } - } catch (err) { - console.log('get_volumio-queue: ' + err.message); - } - } - ); - }, 2000); */ break; } ... }
-
RE: SONOFF NSPanel mit Lovelace UI
So, ihr seid schuld
jetzt mußte ich das Panel noch in Weiss fürs Wohnzimmer bestellen. -
RE: SONOFF NSPanel mit Lovelace UI
@armilar
das mit der Parmeterübergabe dynamisch getState() ist ja mal cool, damit geht dann ja auch sowas bei Page-Grid/-Entities:'items': [ <PageItem>{ id: "alias.0.NSPanel.Rollos.Büro", icon: "window-shutter", name: "Büro: " + getState('alias.0.NSPanel.Rollos.Büro.ACTUAL').val + "%", ...
funkt super, leider nur 1x nach Scriptstart (oder liegt das noch an der der Version 3.8.1)
Latest posts made by egal
-
RE: SONOFF NSPanel mit Lovelace UI
@whity sagte in SONOFF NSPanel mit Lovelace UI:
<PageItem>{ id: 'alias.0.Haus.Untergeschoss.Sensoren.Waschkueche_Feuer', icon: 'fire', offColor: MSGreen, onColor: MSRed, name: 'Waesche'}, ] } das Symbol wird angezeigt, aber ohne Name und schwarz (sorry für das verschwommene Bild)
das Komma zuviel hinter dem letzten Eintrag ?
-
RE: SONOFF NSPanel mit Lovelace UI
@armilar sagte in SONOFF NSPanel mit Lovelace UI:
"val === true ? false : true"
für Faule wie mich
"!val" -
RE: SONOFF NSPanel mit Lovelace UI
@armilar
die Farbskala paßt schon, der resultierende HUE-Wert+/- (= 12 Grundfarben) stimmt ja,
die Saturation ergänzend 3 stufig über den Farbtemperaturslider => 36 diskrete Wertepaare;
es geht eigentlich nur um die Umschaltung zwischen Farbe + Weiss. -
RE: SONOFF NSPanel mit Lovelace UI
@armilar
2 Modi: Weiss mit diskreter Farbtemperatur oder Farbe über diskrete/explizite HUE- + Saturation-Werte
Die letzten Werte hue/saturation bzw. temperature (über-)schreiben/wechseln den Modus:
Das kann man schon gut mit dem HUE-Farbrad + FarbtempSlider Panel umsetzen, ein bissi Scripting, um die diskreten Werte zu 'ermittlen' + zu setzen, Beispiel
{ "Info": [ "HUE", "SAT+", "SAT", "SAT-" ], "Rot": [ 358, 180, 112, 54 ], "Orange": [ 35, 214, 140, 72 ], "Gelb": [ 52, 153, 102, 51 ] // usw. }
Ich wollte halt keinen seperaten Schalter für die Weiss/Farbumschaltung, sondern über den 'weissen' Mittelpunkt des Farbrades.
InSel-modlist für die diskreten Zusände ginge natürlich auch, aber das Farbrad ist so schee -
RE: SONOFF NSPanel mit Lovelace UI
@mading
mit den o.g. Script-Änderungen die Definition:// own colors: const cCyanL: RGB = { red:50, green: 160, blue: 170 }; const cCyanD: RGB = { red:45, green: 145, blue: 155 }; const cViolD: RGB = { red:100, green: 50, blue: 120 }; const cViolL: RGB = { red:160, green: 80, blue: 200 }; let Temp_Innen: PageGrid = { "type": "cardGrid", "heading": "Temp+Feuchte °C", "useColor": true, .... "items": [ <PageItem>{ id: "alias.0.Temp+Feuchte.Temp-Büro", prefixName: 'Büro: ', name: "getState('alias.0.Temp+Feuchte.Temp-Büro.SECOND').val", suffixName: ' %', onColor: cViolD, useValue: true }, <PageItem>{ id: "alias.0.Temp+Feuchte.Temp-Uwe", name: 'Uwe ', onColor: cViolD, useValue: true }, <PageItem>{ id: "alias.0.Temp+Feuchte.Temp-Heike", prefixName: 'Heike: ', name: "getState('alias.0.Temp+Feuchte.Temp-Heike.SECOND').val", suffixName: ' %', onColor: cViolD, useValue: true }, <PageItem>{ id: "alias.0.Temp+Feuchte.Temp-WoZi", prefixName: 'WohnZi: ', name: "getState('alias.0.Temp+Feuchte.Temp-WoZi.SECOND').val", suffixName: ' %', onColor: cViolL, useValue: true }, <PageItem>{ id: "alias.0.Temp+Feuchte.Temp-FlurEG", prefixName: 'FlurEG: ', name: "getState('alias.0.Temp+Feuchte.Temp-FlurEG.SECOND').val", suffixName: ' %', onColor: cViolL, useValue: true }, <PageItem>{ id: "alias.0.Temp+Feuchte.Temp-Küche", prefixName: 'Küche: ', name: "getState('alias.0.Temp+Feuchte.Temp-Küche.SECOND').val", suffixName: ' %', onColor: cViolL, useValue: true } ]
-
RE: SONOFF NSPanel mit Lovelace UI
@armilar
Traum schon erfüllt, vielen Dank,
simple "Eventfänger" als javascript:on({id: "mqtt.0.Smarthome.NSPanel_WoZi.tele.RESULT", change: "ne"}, async function (obj) { const rtext = obj.state.val; // Temp+Feuchte .. if (rtext.indexOf('alias.0.Temp+Feuchte.Temp-Büro,button') > 0) { setState("0_userdata.0.NSPanel.1.PageNavi", "{ \"pagetype\": \"page\", \"pageId\": 1 }"); } // usw... });
so langsam werde ich mit mqtt noch warm,
mit dem ColorWheel 'mittig' könnte man die Farb-/Weissumstellung der Fritz500-LED auch realisieren ...
(und den ColorTempSilder im Farbmodus als Farb-Intensivregler benutzen), hmmm ...28.1.2023 16:47:06.113 {"CustomRecv":"event,buttonPress2,alias.0.NSPanel.Fritz500,colorWheel,77|90|160"} 28.1.2023 16:47:05.315 {"CustomRecv":"event,buttonPress2,alias.0.NSPanel.Fritz500,colorWheel,61|41|160"} 28.1.2023 16:47:04.911 {"CustomRecv":"event,buttonPress2,alias.0.NSPanel.Fritz500,colorWheel,27|66|160"} 28.1.2023 16:47:03.844 {"CustomRecv":"event,buttonPress2,alias.0.NSPanel.Fritz500,colorWheel,66|140|160"} 28.1.2023 16:47:03.424 {"CustomRecv":"event,buttonPress2,alias.0.NSPanel.Fritz500,colorWheel,104|137|160"} 28.1.2023 16:47:02.712 {"CustomRecv":"event,buttonPress2,alias.0.NSPanel.Fritz500,colorWheel,134|90|160"} 28.1.2023 16:46:58.720 {"CustomRecv":"event,buttonPress2,alias.0.NSPanel.Fritz500,colorWheel,82|91|160"}
-
RE: SONOFF NSPanel mit Lovelace UI
@armilar
wirklich cool, bis 12 Werte auf einer Page und der SecondValue des Temp.-Alias findet sinnvolle Verwendung:
<träum> wenn jetzt noch ein (Touch-)Sprung vom Wert direkt z.B. auf </träum> -
RE: SONOFF NSPanel mit Lovelace UI
@armilar
super, danke,
funktioniert bisher sehr gut -
RE: SONOFF NSPanel mit Lovelace UI
@armilar
das mit der Parmeterübergabe dynamisch getState() ist ja mal cool, damit geht dann ja auch sowas bei Page-Grid/-Entities:'items': [ <PageItem>{ id: "alias.0.NSPanel.Rollos.Büro", icon: "window-shutter", name: "Büro: " + getState('alias.0.NSPanel.Rollos.Büro.ACTUAL').val + "%", ...
funkt super, leider nur 1x nach Scriptstart (oder liegt das noch an der der Version 3.8.1)
-
RE: SONOFF NSPanel mit Lovelace UI
@tabeus said in SONOFF NSPanel mit Lovelace UI:
Ach und was abseits der Software, meine Thermostate sind leider Aufputz, weißt du ob es für das Panel einen passenden/schönen Aufputzrahmen für das Panel gibt?
Der hier sollte gut z.B. passen, 85x85x35mm sollten es für optisch bündigen Abschluß schon sein