diff --git a/ioBroker/NsPanelTs_without_Examples.ts b/ioBroker/NsPanelTs_without_Examples.ts index d7269503..b089fb5d 100644 --- a/ioBroker/NsPanelTs_without_Examples.ts +++ b/ioBroker/NsPanelTs_without_Examples.ts @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------- -TypeScript v3.5.0.4 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Sternmiere/@Britzelpuf +TypeScript v3.5.0.5 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar/@Britzelpuf - abgestimmt auf TFT 43 / v3.5.0 / BerryDriver 4 / Tasmota 12.2.0 @joBr99 Projekt: https://github.com/joBr99/nspanel-lovelace-ui/tree/main/ioBroker NsPanelTs.ts (dieses TypeScript in ioBroker) Stable: https://github.com/joBr99/nspanel-lovelace-ui/blob/main/ioBroker/NsPanelTs.ts @@ -7,6 +7,7 @@ icon_mapping.ts: https://github.com/joBr99/nspanel-lovelace-ui/blob/main/ioBroke ioBroker-Unterstützung: https://forum.iobroker.net/topic/50888/sonoff-nspanel WIKI zu diesem Projekt unter: https://github.com/joBr99/nspanel-lovelace-ui/wiki (siehe Sidebar) Icons unter: https://htmlpreview.github.io/?https://github.com/jobr99/Generate-HASP-Fonts/blob/master/cheatsheet.html + ******************************************************************************* Achtung Änderung des Sonoff ESP-Temperatursensors !!! Bitte "SetOption146 1" in der Tasmota-Console ausführen !!! @@ -63,11 +64,22 @@ ReleaseNotes: - 27.10.2022 - v3.5.0.2 Applied Boy Scout Rule (Fixed some typos, changed var to let, fixed min/max colorTemp Bug) - 30.10.2022 - v3.5.0.3 Fixed Media Play/Pause icon for alexa (and others) devices - 31.10.2022 - v3.5.0.4 Reengineering Media Subscriptions + - 02.11.2022 - v3.5.0.5 Page navigation continues with page 0 from the last page + - 04.11.2022 - v3.5.0.5 Create Auto-Alias for Service Pages + - 07.11.2022 - v3.5.0.5 Create Auto-Alias for Alexa2, Spotify-Premium, Sonos + - 08.11.2022 - v3.5.0.5 Create Auto-Alias for Wheather-Forcast (Screensaver Big-Icon) + +***************************************************************************************************************** +* Falls Aliase durch das Skript erstellt werden sollen, muss in der JavaScript Instanz "setObect" gesetzt sein! * +***************************************************************************************************************** + Wenn Rule definiert, dann können die Hardware-Tasten ebenfalls für Seitensteuerung (dann nicht mehr als Relais) genutzt werden + Tasmota Konsole: Rule2 on Button1#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button1"} endon on Button2#state do Publish %topic%/%prefix%/RESULT {"CustomRecv":"event,button2"} endon Rule2 1 (Rule aktivieren) Rule2 0 (Rule deaktivieren) + Mögliche Seiten-Ansichten: screensaver Page - wird nach definiertem Zeitraum (config) mit Dimm-Modus aktiv (Uhrzeit, Datum, Aktuelle Temperatur mit Symbol) (die 4 kleineren Icons können als Wetter-Vorschau + 4Tage (Symbol + Höchsttemperatur) oder zur Anzeige definierter Infos konfiguriert werden) @@ -77,11 +89,13 @@ Mögliche Seiten-Ansichten: cardMedia Page - Mediaplayer - Ausnahme: Alias sollte mit Alias-Manager automatisch über Alexa-Verzeichnis Player angelegt werden cardAlarm Page - Alarmseite mit Zustand und Tastenfeld cardPower Page - Energiefluss + Popup-Pages: popupLight Page - in Abhängigkeit zum gewählten Alias werden "Helligkeit", "Farbtemperatur" und "Farbauswahl" bereitgestellt popupShutter Page - die Shutter-Position (Rollo, Jalousie, Markise, Leinwand, etc.) kann über einen Slider verändert werden. popupNotify Page - Info - Seite mit Headline Text und Buttons - Intern für manuelle Updates / Extern zur Befüllung von Datenpunkten unter 0_userdata screensaver Notify - Über zwei externe Datenpunkte in 0_userdata können "Headline" und "Text" an den Screensaver zur Info gesendet werden + Mögliche Aliase: (Vorzugsweise mit ioBroker-Adapter "Geräte verwalten" konfigurieren, da SET, GET, ACTUAL, etc. verwendet werden) Info - Werte aus Datenpunkt Schieberegler - Slider numerische Werte (SET/ACTUAL) @@ -106,6 +120,7 @@ Mögliche Aliase: (Vorzugsweise mit ioBroker-Adapter "Geräte verwalten" konfigu Feuchtigkeit - Anzeige von Humidity - Datenpunkten, analog Info Medien - Steuerung von Alexa - Über Alias-Manager im Verzeichnis Player automatisch anlegen (Geräte-Manager funktioniert nicht) Wettervorhersage - Aktuelle Außen-Temperatur (Temp) und aktuelles AccuWeather-Icon (Icon) für Screensaver + Interne Sonoff-Sensoren (über Tasmota): ESP-Temperatur - wird in 0_userdata.0. abgelegt, kann als Alias importiert werden --> SetOption146 1 Temperatur - Raumtemperatur - wird in 0_userdata.0. abgelegt, kann als Alias importiert werden @@ -114,13 +129,16 @@ Interne Sonoff-Sensoren (über Tasmota): Timestamp - wird in 0_userdata.0. Zeitpunkt der letzten Sensorübertragung Tasmota-Status0 - (zyklische Ausführung) liefert relevanten Tasmota-Informationen und kann bei Bedarf in "function get_tasmota_status0()" erweitert werden. Daten werden in 0_userdata.0. abgelegt + Erforderliche Adapter: + AccuWeather: - Bei Nutzung der Wetterfunktionen (und zur Icon-Konvertierung) im Screensaver Alexa2: - Bei Nutzung der dynamischen SpeakerList in der cardMedia Geräte verwalten - Für Erstellung der Aliase Alias-Manager - !!! ausschließlich für MEDIA-Alias MQTT-Adapter - Für Kommunikation zwischen Skript und Tasmota JavaScript-Adapter + Upgrades in Konsole: Tasmota BerryDriver : Backlog UpdateDriverVersion https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; Restart 1 TFT EU STABLE Version : FlashNextion http://nspanel.pky.eu/lovelace-ui/github/nspanel-v3.5.0.tft @@ -129,9 +147,12 @@ Upgrades in Konsole: let Icons = new IconsSelector(); let timeoutSlider: any; let manually_Update = false; +const autoCreateAlias = true; //Für diese Option muss der Haken in setObjects in deiner javascript.X. Instanz gesetzt sein. const NSPanel_Path = '0_userdata.0.NSPanel.1.'; const NSPanel_Alarm_Path = '0_userdata.0.NSPanel.'; //Neuer Pfad für gemeinsame Nutzung durch mehrere Panels (bei Nutzung der cardAlarm) + +let AliasPath: string = 'alias.0.' + NSPanel_Path.substring(13, NSPanel_Path.length); const Debug = false; // Variablen zur Steuerung der Wettericons auf dem Screensaver (Steuerung in 0_userdata.0.XPANELX.ScreensaverInfo) @@ -262,6 +283,27 @@ const request = require('request'); let useMediaEvents: boolean = false; let timeoutMedia: any; +// Create atomatically Wheather-Alias, if exists accuweather.0. and is not exists Config-Wheather-Alias +async function CreateWeatherAlias () { + if (autoCreateAlias) { + try { + if (!existsState(config.weatherEntity + '.ICON') && existsState('accuweather.0.Current.WeatherIcon')) { + console.log('Wetter-Alias existiert noch nicht, wird jetzt angelegt'); + setObject(config.weatherEntity, {_id: config.weatherEntity, type: 'channel', common: {role: 'weatherCurrent', name:'media'}, native: {}}); + await createAliasAsync(config.weatherEntity + '.ICON', 'accuweather.0.Current.WeatherIcon', true, { type: 'number', role: 'value', name: 'ICON' }); + await createAliasAsync(config.weatherEntity + '.TEMP', 'accuweather.0.Current.Temperature', true, { type: 'number', role: 'value.temperature', name: 'TEMP' }); + await createAliasAsync(config.weatherEntity + '.TEMP_MIN', 'accuweather.0.Daily.Day1.Temperature.Minimum', true, { type: 'number', role: 'value.temperature.forecast.0', name: 'TEMP_MIN' }); + await createAliasAsync(config.weatherEntity + '.TEMP_MAX', 'accuweather.0.Daily.Day1.Temperature.Maximum', true, { type: 'number', role: 'value.temperature.max.forecast.0', name: 'TEMP_MAX' }); + } else { + console.log('Wetter-Alias existiert bereits'); + } + } catch (err) { + console.log('function InitPageNavi: ' + err.message); + } + } +} +CreateWeatherAlias(); + //---------------------Begin PageNavi async function InitPageNavi() { try { @@ -340,21 +382,33 @@ async function InitDimmode() { if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay')) { await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay', { type: 'number' }); await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessDay', { val: 8, ack: true }); + setObject(AliasPath + 'Dimmode.brightnessDay', {type: 'channel', common: {role: 'slider', name:'brightnessDay'}, native: {}}); + await createAliasAsync(AliasPath + 'Dimmode.brightnessDay.ACTUAL', NSPanel_Path + 'NSPanel_Dimmode_brightnessDay', true, { type: 'number', role: 'value', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Dimmode.brightnessDay.SET', NSPanel_Path + 'NSPanel_Dimmode_brightnessDay', true, { type: 'number', role: 'level', name: 'SET' }); } if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_hourDay')) { await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourDay', { type: 'number' }); await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourDay', { val: 7, ack: true }); + setObject(AliasPath + 'Dimmode.hourDay', {type: 'channel', common: {role: 'slider', name:'hourDay'}, native: {}}); + await createAliasAsync(AliasPath + 'Dimmode.hourDay.ACTUAL', NSPanel_Path + 'NSPanel_Dimmode_hourDay', true, { type: 'number', role: 'value', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Dimmode.hourDay.SET', NSPanel_Path + 'NSPanel_Dimmode_hourDay', true, { type: 'number', role: 'level', name: 'SET' }); } if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight')) { await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight', { type: 'number' }); await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_brightnessNight', { val: 1, ack: true }); + setObject(AliasPath + 'Dimmode.brightnessNight', {type: 'channel', common: {role: 'slider', name:'brightnessNight'}, native: {}}); + await createAliasAsync(AliasPath + 'Dimmode.brightnessNight.ACTUAL', NSPanel_Path + 'NSPanel_Dimmode_brightnessNight', true, { type: 'number', role: 'value', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Dimmode.brightnessNight.SET', NSPanel_Path + 'NSPanel_Dimmode_brightnessNight', true, { type: 'number', role: 'level', name: 'SET' }); } if (!existsState(NSPanel_Path + 'NSPanel_Dimmode_hourNight')) { await createStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourNight', { type: 'number' }); await setStateAsync(NSPanel_Path + 'NSPanel_Dimmode_hourNight', { val: 22, ack: true }); + setObject(AliasPath + 'Dimmode.hourNight', {type: 'channel', common: {role: 'slider', name:'hourNight'}, native: {}}); + await createAliasAsync(AliasPath + 'Dimmode.hourNight.ACTUAL', NSPanel_Path + 'NSPanel_Dimmode_hourNight', true, { type: 'number', role: 'value', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Dimmode.hourNight.SET', NSPanel_Path + 'NSPanel_Dimmode_hourNight', true, { type: 'number', role: 'level', name: 'SET' }); } const vTimeDay = getState(NSPanel_Path + 'NSPanel_Dimmode_hourDay').val; @@ -773,10 +827,17 @@ on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async async function get_panel_update_data() { try { await createStateAsync(NSPanel_Path + 'NSPanel_autoUpdate', false, { read: true, write: true, name: 'Auto-Update', type: 'boolean', def: false }); - + if (autoCreateAlias) { + setObject(AliasPath + 'autoUpdate', {type: 'channel', common: {role: 'socket', name:'AutoUpdate'}, native: {}}); + await createAliasAsync(AliasPath + 'autoUpdate.ACTUAL', NSPanel_Path + 'NSPanel_autoUpdate', true, { type: 'boolean', role: 'switch', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'autoUpdate.SET', NSPanel_Path + 'NSPanel_autoUpdate', true, { type: 'boolean', role: 'switch', name: 'SET' }); + } await createStateAsync(NSPanel_Path + 'NSPanel_ipAddress', { type: 'string' }); await setStateAsync(NSPanel_Path + 'NSPanel_ipAddress', { val: get_current_tasmota_ip_address(), ack: true }); - + if (autoCreateAlias) { + setObject(AliasPath + 'ipAddress', {type: 'channel', common: {role: 'info', name:'ipAddress'}, native: {}}); + await createAliasAsync(AliasPath + 'ipAddress.ACTUAL', NSPanel_Path + 'NSPanel_ipAddress', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + } get_online_tasmota_firmware_version(); get_current_berry_driver_version(); get_online_berry_driver_version(); @@ -843,6 +904,10 @@ function get_current_berry_driver_version() { try { await createStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', { type: 'number' }); await setStateAsync(NSPanel_Path + 'Berry_Driver.currentVersion', { val: JSON.parse(result).nlui_driver_version, ack: true }); + if (autoCreateAlias) { + setObject(AliasPath + 'Display.BerryDriver', {type: 'channel', common: {role: 'info', name: 'Berry Driver'}, native: {}}); + await createAliasAsync(AliasPath + 'Display.BerryDriver.ACTUAL', NSPanel_Path + 'Berry_Driver.currentVersion', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + } } catch (err) { console.warn('get_current_berry_driver_version: ' + err.message); } @@ -893,6 +958,28 @@ function get_tasmota_status0() { } catch (err) { console.warn('get_tasmota_status0' + err.message); } + if (autoCreateAlias) { + setObject(AliasPath + 'Tasmota.Uptime', {type: 'channel', common: {role: 'info', name: 'Uptime'}, native: {}}); + setObject(AliasPath + 'Tasmota.Version', {type: 'channel', common: {role: 'info', name:'Version'}, native: {}}); + setObject(AliasPath + 'Tasmota.Hardware', {type: 'channel', common: {role: 'info', name: 'Hardware'}, native: {}}); + setObject(AliasPath + 'Tasmota.Wifi.AP', {type: 'channel', common: {role: 'info', name:'AP'}, native: {}}); + setObject(AliasPath + 'Tasmota.Wifi.SSId', {type: 'channel', common: {role: 'info', name:'SSId'}, native: {}}); + setObject(AliasPath + 'Tasmota.Wifi.BSSId', {type: 'channel', common: {role: 'info', name: 'BSSId'}, native: {}}); + setObject(AliasPath + 'Tasmota.Wifi.Channel', {type: 'channel', common: {role: 'info', name:'Channel'}, native: {}}); + setObject(AliasPath + 'Tasmota.Wifi.Mode', {type: 'channel', common: {role: 'info', name: 'Mode'}, native: {}}); + setObject(AliasPath + 'Tasmota.Wifi.RSSI', {type: 'channel', common: {role: 'info', name:'RSSI'}, native: {}}); + setObject(AliasPath + 'Tasmota.Wifi.Signal', {type: 'channel', common: {role: 'info', name:'Signal'}, native: {}}); + await createAliasAsync(AliasPath + 'Tasmota.Uptime.ACTUAL', NSPanel_Path + 'Tasmota.Uptime', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Version.ACTUAL', NSPanel_Path + 'Tasmota.Version', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Hardware.ACTUAL', NSPanel_Path + 'Tasmota.Hardware', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Wifi.AP.ACTUAL', NSPanel_Path + 'Tasmota.Wifi.AP', true, { type: 'number', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Wifi.SSId.ACTUAL', NSPanel_Path + 'Tasmota.Wifi.SSId', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Wifi.BSSId.ACTUAL', NSPanel_Path + 'Tasmota.Wifi.BSSId', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Wifi.Channel.ACTUAL', NSPanel_Path + 'Tasmota.Wifi.Channel', true, { type: 'number', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Wifi.Mode.ACTUAL', NSPanel_Path + 'Tasmota.Wifi.Mode', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Wifi.RSSI.ACTUAL', NSPanel_Path + 'Tasmota.Wifi.RSSI', true, { type: 'number', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Tasmota.Wifi.Signal.ACTUAL', NSPanel_Path + 'Tasmota.Wifi.Signal', true, { type: 'number', role: 'state', name: 'ACTUAL' }); + } }); } catch (err) { console.warn('error requesting firmware in function get_tasmota_status0: ' + err.message); @@ -992,6 +1079,13 @@ on({ id: config.panelRecvTopic }, async (obj) => { await setStateAsync(NSPanel_Path + 'Display_Firmware.currentVersion', { val: split[2], ack: true }); await setStateAsync(NSPanel_Path + 'NSPanel_Version', { val: split[3], ack: true }); + + if (autoCreateAlias) { + setObject(AliasPath + 'Display.TFTVersion', {type: 'channel', common: {role: 'info', name:'Display.TFTVersion'}, native: {}}); + setObject(AliasPath + 'Display.Model', {type: 'channel', common: {role: 'info', name:'Display.Model'}, native: {}}); + await createAliasAsync(AliasPath + 'Display.TFTVersion.ACTUAL', NSPanel_Path + 'Display_Firmware.currentVersion', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + await createAliasAsync(AliasPath + 'Display.Model.ACTUAL', NSPanel_Path + 'NSPanel_Version', true, { type: 'string', role: 'state', name: 'ACTUAL' }); + } } } catch (err) { console.warn('error rceiving CustomRecv: ' + err.message); @@ -2091,6 +2185,16 @@ function unsubscribeMediaSubscriptions(): void { unsubscribe(mediaID + '.VOLUME') } } + for (let i = 0; i < config.subPages.length; i++) { + if (config.subPages[i].type == 'cardMedia') { + let mediaID = config.subPages[i].items[0].id; + unsubscribe(mediaID + '.STATE') + unsubscribe(mediaID + '.ARTIST') + unsubscribe(mediaID + '.TITLE') + unsubscribe(mediaID + '.ALBUM') + unsubscribe(mediaID + '.VOLUME') + } + } } function subscribeMediaSubscriptions(id: string): void { @@ -2104,6 +2208,91 @@ function subscribeMediaSubscriptions(id: string): void { }); } +async function createAutoMediaAlias(id: string, mediaDevice: string, adapterPlayerInstance: string) { + if (autoCreateAlias) { + + if (adapterPlayerInstance == 'alexa2.0.') { + if (existsObject(id) == false){ + console.log('Alexa Alias ' + id + ' existiert nicht - wird jetzt angelegt') + + let dpPath: string = adapterPlayerInstance + 'Echo-Devices.' + mediaDevice; + try { + + setObject(id, {_id: id, type: 'channel', common: {role: 'media', name:'media'}, native: {}}); + await createAliasAsync(id + '.ACTUAL', dpPath + '.Player.volume', true, { type: 'number', role: 'value.volume', name: 'ACTUAL' }); + await createAliasAsync(id + '.ALBUM', dpPath + '.Player.currentAlbum', true, { type: 'string', role: 'media.album', name: 'ALBUM' }); + await createAliasAsync(id + '.ARTIST', dpPath + '.Player.currentArtist', true, { type: 'string', role: 'media.artist', name: 'ARTIST' }); + await createAliasAsync(id + '.TITLE', dpPath + '.Player.currentTitle', true, { type: 'string', role: 'media.title', name: 'TITLE' }); + await createAliasAsync(id + '.NEXT', dpPath + '.Player.controlNext', true, { type: 'boolean', role: 'button.next', name: 'NEXT' }); + await createAliasAsync(id + '.PREV', dpPath + '.Player.controlPrevious', true, { type: 'boolean', role: 'button.prev', name: 'PREV' }); + await createAliasAsync(id + '.PLAY', dpPath + '.Player.controlPlay', true, { type: 'boolean', role: 'button.play', name: 'PLAY' }); + await createAliasAsync(id + '.PAUSE', dpPath + '.Player.controlPause', true, { type: 'boolean', role: 'button.pause', name: 'PAUSE' }); + await createAliasAsync(id + '.STOP', dpPath + '.Commands.deviceStop', true, { type: 'boolean', role: 'button.stop', name: 'STOP' }); + await createAliasAsync(id + '.STATE', dpPath + '.Player.currentState', true, { type: 'boolean', role: 'media.state', name: 'STATE' }); + await createAliasAsync(id + '.VOLUME', dpPath + '.Player.volume', true, { type: 'number', role: 'level.volume', name: 'VOLUME' }); + + } catch (err) { + console.warn('function createAutoMediaAlias: ' + err.message); + } + } + } + + if (adapterPlayerInstance == 'spotify-premium.0.') { + if (existsObject(id) == false){ + console.log('Spotify Alias ' + id + ' existiert nicht - wird jetzt angelegt') + + let dpPath: string = adapterPlayerInstance; + try { + + setObject(id, {_id: id + 'player', type: 'channel', common: {role: 'media', name:'media'}, native: {}}); + await createAliasAsync(id + '.ACTUAL', dpPath + 'player.volume', true, { type: 'number', role: 'value.volume', name: 'ACTUAL' }); + await createAliasAsync(id + '.ALBUM', dpPath + 'player.album', true, { type: 'string', role: 'media.album', name: 'ALBUM' }); + await createAliasAsync(id + '.ARTIST', dpPath + 'player.artistName', true, { type: 'string', role: 'media.artist', name: 'ARTIST' }); + await createAliasAsync(id + '.TITLE', dpPath + 'player.trackName', true, { type: 'string', role: 'media.title', name: 'TITLE' }); + await createAliasAsync(id + '.CONTEXT_DESCRIPTION', dpPath + 'player.contextDescription', true, { type: 'string', role: 'media.station', name: 'CONTEXT_DESCRIPTION' }); + await createAliasAsync(id + '.NEXT', dpPath + 'player.skipPlus', true, { type: 'boolean', role: 'button.next', name: 'NEXT' }); + await createAliasAsync(id + '.PREV', dpPath + 'player.skipMinus', true, { type: 'boolean', role: 'button.prev', name: 'PREV' }); + await createAliasAsync(id + '.PLAY', dpPath + 'player.play', true, { type: 'boolean', role: 'button.play', name: 'PLAY' }); + await createAliasAsync(id + '.PAUSE', dpPath + 'player.pause', true, { type: 'boolean', role: 'button.pause', name: 'PAUSE' }); + await createAliasAsync(id + '.STOP', dpPath + 'player.pause', true, { type: 'boolean', role: 'button.stop', name: 'STOP' }); + await createAliasAsync(id + '.STATE', dpPath + 'player.isPlaying', true, { type: 'boolean', role: 'media.state', name: 'STATE' }); + await createAliasAsync(id + '.VOLUME', dpPath + 'player.volume', true, { type: 'number', role: 'level.volume', name: 'VOLUME' }); + + } catch (err) { + console.warn('function createAutoMediaAlias: ' + err.message); + } + } + } + + if (adapterPlayerInstance == 'sonos.0.') { + if (existsObject(id) == false){ + console.log('Sonos Alias ' + id + ' existiert nicht - wird jetzt angelegt') + + let dpPath: string = adapterPlayerInstance + 'root.' + mediaDevice; + try { + + setObject(id, {_id: id, type: 'channel', common: {role: 'media', name:'media'}, native: {}}); + await createAliasAsync(id + '.ACTUAL', dpPath + '.volume', true, { type: 'number', role: 'value.volume', name: 'ACTUAL' }); + await createAliasAsync(id + '.ALBUM', dpPath + '.current_album', true, { type: 'string', role: 'media.album', name: 'ALBUM' }); + await createAliasAsync(id + '.ARTIST', dpPath + '.current_artist', true, { type: 'string', role: 'media.artist', name: 'ARTIST' }); + await createAliasAsync(id + '.TITLE', dpPath + '.current_title', true, { type: 'string', role: 'media.title', name: 'TITLE' }); + await createAliasAsync(id + '.CONTEXT_DESCRIPTION', dpPath + '.current_station', true, { type: 'string', role: 'media.station', name: 'CONTEXT_DESCRIPTION' }); + await createAliasAsync(id + '.NEXT', dpPath + '.next', true, { type: 'boolean', role: 'button.next', name: 'NEXT' }); + await createAliasAsync(id + '.PREV', dpPath + '.prev', true, { type: 'boolean', role: 'button.prev', name: 'PREV' }); + await createAliasAsync(id + '.PLAY', dpPath + '.play', true, { type: 'boolean', role: 'button.play', name: 'PLAY' }); + await createAliasAsync(id + '.PAUSE', dpPath + '.pause', true, { type: 'boolean', role: 'button.pause', name: 'PAUSE' }); + await createAliasAsync(id + '.STOP', dpPath + '.stop', true, { type: 'boolean', role: 'button.stop', name: 'STOP' }); + await createAliasAsync(id + '.STATE', dpPath + '.state_simple', true, { type: 'boolean', role: 'media.state', name: 'STATE' }); + await createAliasAsync(id + '.VOLUME', dpPath + '.volume', true, { type: 'number', role: 'level.volume', name: 'VOLUME' }); + + } catch (err) { + console.warn('function createAutoMediaAlias: ' + err.message); + } + } + } + } +} + function GenerateMediaPage(page: PageMedia): Payload[] { try { let id = page.items[0].id @@ -2114,6 +2303,11 @@ function GenerateMediaPage(page: PageMedia): Payload[] { subscribeMediaSubscriptions(id); + if (page.items[0].autoCreateALias) { + let vMediaDevice = (page.items[0].mediaDevice != undefined) ? page.items[0].mediaDevice : ''; + createAutoMediaAlias(id, vMediaDevice, page.items[0].adapterPlayerInstance); + } + out_msgs.push({ payload: 'pageType~cardMedia' }); if (existsObject(id)) { let name = getState(id + '.ALBUM').val; @@ -3030,6 +3224,7 @@ function HandleButtonEvent(words): void { } } +//Determination of page navigation (CustomSend-Payload) function GetNavigationString(pageId: number): string { try { @@ -3037,14 +3232,20 @@ function GetNavigationString(pageId: number): string { console.log(pageId); } + // left navigation arrow | right navigation arrow + // X|X + // 0 = no arrow + // 1 = right or left navigation arrow + // 2 = up navigation arrow + if (activePage.subPage) return '1|0'; switch (pageId) { case 0: - return '0|1'; + return '1|1'; case config.pages.length - 1: - return '1|0'; + return '1|1'; case -1: return '2|0'; case -2: @@ -3052,6 +3253,7 @@ function GetNavigationString(pageId: number): string { default: return '1|1'; } + } catch (err) { console.log('function GetNavigationString: ' + err.message); } @@ -4170,6 +4372,13 @@ on({ id: config.panelRecvTopic.substring(0, config.panelRecvTopic.length - 'RESU await setStateAsync(NSPanel_Path + 'Sensor.TempUnit', { val: '°' + Tasmota_Sensor.TempUnit, ack: true }); await setStateAsync(NSPanel_Path + 'Sensor.ANALOG.Temperature', { val: parseFloat(Tasmota_Sensor.ANALOG.Temperature1), ack: true }); await setStateAsync(NSPanel_Path + 'Sensor.ESP32.Temperature', { val: parseFloat(Tasmota_Sensor.ESP32.Temperature), ack: true }); + + if (autoCreateAlias) { + setObject(AliasPath + 'Sensor.ANALOG.Temperature', {type: 'channel', common: {role: 'info', name: ''}, native: {}}); + setObject(AliasPath + 'Sensor.ESP32.Temperature', {type: 'channel', common: {role: 'info', name:''}, native: {}}); + await createAliasAsync(AliasPath + 'Sensor.ANALOG.Temperature.ACTUAL', NSPanel_Path + 'Sensor.ANALOG.Temperature', true, { type: 'number', 'unit': '°C' }); + await createAliasAsync(AliasPath + 'Sensor.ESP32.Temperature.ACTUAL', NSPanel_Path + 'Sensor.ESP32.Temperature', true, { type: 'number', 'unit': '°C' }); + } } catch (err) { console.warn('error with reading senor-data: '+ err.message); } @@ -4390,7 +4599,8 @@ type PageItem = { mediaDevice: (string | undefined), targetPage: (string | undefined), speakerList: (string[] | undefined), - hidePassword: (boolean | undefined) + hidePassword: (boolean | undefined), + autoCreateALias: (boolean | undefined) } type DimMode = {