mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2025-12-26 17:34:26 +01:00
Compare commits
34 Commits
Armilar-pa
...
Armilar-pa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e38d4f38d | ||
|
|
2344c9a9ed | ||
|
|
5180f0f869 | ||
|
|
b4f2789834 | ||
|
|
78c6029200 | ||
|
|
dca112e42b | ||
|
|
5ad16dd735 | ||
|
|
723be0735e | ||
|
|
a5bfb9388f | ||
|
|
9c6f24f984 | ||
|
|
59843ffea5 | ||
|
|
4de9c4a12f | ||
|
|
3eb05e5a84 | ||
|
|
5d7a7ed1a4 | ||
|
|
7124a22c38 | ||
|
|
fa4d65a383 | ||
|
|
d26306f892 | ||
|
|
9c0bb037fb | ||
|
|
4b73e20b9b | ||
|
|
3940a0c2e9 | ||
|
|
8f57d4a642 | ||
|
|
3979fdf6a0 | ||
|
|
4cd47126eb | ||
|
|
eb0dd79c80 | ||
|
|
3a39a8ca0e | ||
|
|
b5c4a2128b | ||
|
|
41f43fe5d0 | ||
|
|
f3f93b7136 | ||
|
|
2fb1855842 | ||
|
|
9a3627427f | ||
|
|
94fbf0a5f7 | ||
|
|
caddec1190 | ||
|
|
03367ea27d | ||
|
|
8e792ae8fc |
2
.github/workflows/builder.yaml
vendored
2
.github/workflows/builder.yaml
vendored
@@ -100,7 +100,7 @@ jobs:
|
||||
|
||||
- name: Build ${{ matrix.addon }} add-on
|
||||
if: steps.check.outputs.build_arch == 'true'
|
||||
uses: home-assistant/builder@2023.09.0
|
||||
uses: home-assistant/builder@2023.12.0
|
||||
with:
|
||||
args: |
|
||||
${{ env.BUILD_ARGS }} \
|
||||
|
||||
2
.github/workflows/docs-dev.yml
vendored
2
.github/workflows/docs-dev.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- run: pip install mkdocs-material mkdocs-video markdown-include mike
|
||||
|
||||
2
.github/workflows/docs-release.yml
vendored
2
.github/workflows/docs-release.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- run: pip install mkdocs-material mkdocs-video markdown-include mike
|
||||
|
||||
44
ioBroker/Blockly/Alarm_clock.ts
Normal file
44
ioBroker/Blockly/Alarm_clock.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
const dp_userdata: string = '0_userdata.0.NSPanel';
|
||||
const dp_alias: string = 'alias.0.NSPanel';
|
||||
|
||||
// dpAction wird wenn der Wecker gestellt wird auf false geschaltet
|
||||
// dpAction wird wenn die Weckzeit erreicht ist auf true geschaltet
|
||||
// Der nachfolgende Datenpunkt muss manuell erstellt werden...
|
||||
const dpAction: string = '0_userdata.0.example_boolean';
|
||||
|
||||
const Debug = true;
|
||||
|
||||
let time: number;
|
||||
let scheduleAlarmTime: any = null;
|
||||
on({ id: dp_userdata + '.AlarmTime.State', change: 'ne' }, async (obj) => {
|
||||
|
||||
time = getState(dp_userdata + '.AlarmTime.Time').val;
|
||||
if (Debug) log('Uhrzeit: ' + time, 'info');
|
||||
if ('paused' == obj.state.val) {
|
||||
(function () { if (scheduleAlarmTime) {
|
||||
clearSchedule(scheduleAlarmTime);
|
||||
scheduleAlarmTime = null;
|
||||
}
|
||||
});
|
||||
} else if ('active' == obj.state.val) {
|
||||
let stunde: number = Math.floor(time / 60);
|
||||
let minute: number = time % 60;
|
||||
if (Debug) log('Weckzeit: ' + ('0' + stunde).slice(-2) + ':' + ('0' + minute).slice(-2), 'info');
|
||||
scheduleAlarmTime = schedule(minute + ' ' + stunde + ' * * *', async () => {
|
||||
await setStateAsync(dpAction, <iobJS.State>{ val: true, ack: true });
|
||||
await setStateAsync(dp_userdata + '.AlarmTime.State', <iobJS.State>{ val: 'paused', ack: true });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async function Init_Datenpunkte() {
|
||||
if (existsState(dp_alias + '.AlarmTime.ACTUAL') == false) {
|
||||
await createStateAsync(dp_userdata + '.AlarmTime.Time', '0', { type: 'number' });
|
||||
await createStateAsync(dp_userdata + '.AlarmTime.State', 'paused', { type: 'string' });
|
||||
setObject(dp_alias + '.AlarmTime', { type: 'channel', common: { role: 'value.alarmtime', name: 'Alarmtime' }, native: {} });
|
||||
await createAliasAsync(dp_alias + '.AlarmTime.ACTUAL', dp_userdata + '.AlarmTime.Time', true, <iobJS.StateCommon>{ type: 'number', role: 'state', name: 'ACTUAL' });
|
||||
await createAliasAsync(dp_alias + '.AlarmTime.STATE', dp_userdata + '.AlarmTime.State', true, <iobJS.StateCommon>{ type: 'string', role: 'state', name: 'STATE' });
|
||||
log("<PageItem>{id: '"+ dp_alias + ".AlarmTime', name: 'Wecker', onColor: Red, offColor: Green, useColor: true}", 'info');
|
||||
}
|
||||
}
|
||||
Init_Datenpunkte();
|
||||
46
ioBroker/Blockly/Countdown_Timer.ts
Normal file
46
ioBroker/Blockly/Countdown_Timer.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
const dp_userdata: string = '0_userdata.0.NSPanel';
|
||||
const dp_alias: string = 'alias.0.NSPanel';
|
||||
|
||||
// Der nachfolgende Datenpunkt muss manuell angelegt werden
|
||||
const dpAction: string = '0_userdata.0.example_boolean'; // anpassen
|
||||
|
||||
const Debug = false;
|
||||
|
||||
let intervallCounter: any;
|
||||
|
||||
let sec_timer = getState(dp_userdata + '.Countdown.Time').val;
|
||||
on({ id: dp_userdata + '.Countdown.State', change: 'ne' }, async (obj) => {
|
||||
|
||||
switch (obj.state.val) {
|
||||
case 'active':
|
||||
if (intervallCounter) { clearInterval(intervallCounter); intervallCounter = null; };
|
||||
intervallCounter = setInterval(async () => {
|
||||
if (getState(dp_userdata + '.Countdown.Time').val > 0) {
|
||||
sec_timer = getState(dp_userdata + '.Countdown.Time').val;
|
||||
setState(dp_userdata + '.Countdown.Time', (sec_timer - 1), false);
|
||||
} else {
|
||||
setState(dp_userdata + '.Countdown.Time', 0, false);
|
||||
setState(dp_userdata + '.Countdown.State', 'idle', false);
|
||||
// An dieser Stelle kann auch noch eine Meldung an Alexa oder Telegram, etc. erfolgen
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
break;
|
||||
default:
|
||||
if (intervallCounter) { clearInterval(intervallCounter); intervallCounter = null; };
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
async function Init_Datenpunkte() {
|
||||
if (existsState(dp_alias + '.Countdown.ACTUAL') == false) {
|
||||
await createStateAsync(dp_userdata + '.Countdown.Time', '0', { type: 'number'});
|
||||
await createStateAsync(dp_userdata + '.Countdown.State', 'paused', { type: 'string' });
|
||||
setObject(dp_alias + '.Countdown', { type: 'channel', common: { role: 'level.timer', name: 'Countdown' }, native: {} });
|
||||
await createAliasAsync(dp_alias + '.Countdown.ACTUAL', dp_userdata + '.Countdown.Time', true, <iobJS.StateCommon>{ type: 'number', role: 'state', name: 'ACTUAL' });
|
||||
await createAliasAsync(dp_alias + '.Countdown.STATE', dp_userdata + '.Countdown.State', true, <iobJS.StateCommon>{ type: 'string', role: 'state', name: 'STATE' });
|
||||
log("<PageItem>{id: '"+ dp_alias + ".Countdown', name: 'Timer'}", 'info');
|
||||
}
|
||||
}
|
||||
Init_Datenpunkte();
|
||||
@@ -1,6 +1,6 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
TypeScript v4.3.3.18 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar / @TT-Tom / @Sternmiere / @Britzelpuf / @ravenS0ne
|
||||
- abgestimmt auf TFT 53 / v4.3.3 / BerryDriver 9 / Tasmota 13.2.0
|
||||
TypeScript v4.3.3.24 zur Steuerung des SONOFF NSPanel mit dem ioBroker by @Armilar / @TT-Tom / @Sternmiere / @Britzelpuf / @ravenS0ne
|
||||
- abgestimmt auf TFT 53 / v4.3.3 / BerryDriver 9 / Tasmota 13.3.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
|
||||
icon_mapping.ts: https://github.com/joBr99/nspanel-lovelace-ui/blob/main/ioBroker/icon_mapping.ts (TypeScript muss in global liegen)
|
||||
@@ -74,6 +74,13 @@ ReleaseNotes:
|
||||
- 04.12.2023 - v4.3.3.17 Add SEEK and CROSSFADE to Sonos cardMedia
|
||||
- 05.12.2023 - v4.3.3.18 Add (ELAPSED/DURATION) to v2Adapter alexa2
|
||||
- 06.12.2023 - v4.3.3.18 Replace missing Type console.log --> log(message, 'serverity')
|
||||
- 07.12.2023 - v4.3.3.19 Fix Trigger activeDimmodeBrightness if Dimmode = -1
|
||||
- 08.12.2023 - v4.3.3.20 add Role AlarmTime for Alarm Clock
|
||||
- 09.12.2023 - v4.3.3.21 Add createAutoAlias to popupTimer only for Time
|
||||
- 14.12.2023 - v4.3.3.22 Add UpdateMessage => disable the update messages
|
||||
- 14.12.2023 - v4.3.3.22 Fix name by static Navi Icon
|
||||
- 17.12.2023 - v4.3.3.23 Optimization of the blind control (enable or disable Up/Stop/Down)
|
||||
- 18.12.2023 - v4.3.3.24 Hotfix Update Message / Add Icon Colors to Entity Button
|
||||
|
||||
Todo:
|
||||
- XX.XX.XXXX - v5.0.0 Change the bottomScreensaverEntity (rolling) if more than 6 entries are defined
|
||||
@@ -247,6 +254,8 @@ let Debug: boolean = false;
|
||||
const DarkBlue: RGB = { red: 0, green: 0, blue: 136 };
|
||||
const Gray: RGB = { red: 136, green: 136, blue: 136 };
|
||||
const Black: RGB = { red: 0, green: 0, blue: 0 };
|
||||
const Cyan: RGB = { red: 0, green: 255, blue: 255 };
|
||||
const Magenta: RGB = { red: 255, green: 0, blue: 255 };
|
||||
const colorSpotify: RGB = { red: 30, green: 215, blue: 96 };
|
||||
const colorAlexa: RGB = { red: 49, green: 196, blue: 243 };
|
||||
const colorSonos: RGB = { red: 216, green: 161, blue: 88 };
|
||||
@@ -430,7 +439,8 @@ let NSPanel_Service_SubPage = <PageEntities>
|
||||
'items': [
|
||||
<PageItem>{ navigate: true, id: 'NSPanel_Wifi_Info_1', icon: 'wifi', offColor: Menu, onColor: Menu, name: findLocaleServMenu('wifi'), buttonText: findLocaleServMenu('more')},
|
||||
<PageItem>{ navigate: true, id: 'NSPanel_Sensoren', icon: 'memory', offColor: Menu, onColor: Menu, name: findLocaleServMenu('sensors_hardware'), buttonText: findLocaleServMenu('more')},
|
||||
<PageItem>{ navigate: true, id: 'NSPanel_IoBroker', icon: 'information-outline', offColor: Menu, onColor: Menu, name: findLocaleServMenu('info_iobroker'), buttonText: findLocaleServMenu('more')}
|
||||
<PageItem>{ navigate: true, id: 'NSPanel_IoBroker', icon: 'information-outline', offColor: Menu, onColor: Menu, name: findLocaleServMenu('info_iobroker'), buttonText: findLocaleServMenu('more')},
|
||||
<PageItem>{ id: AliasPath + 'Config.Update.UpdateMessage', name: findLocaleServMenu('update_message') ,icon: 'message-alert-outline', offColor: HMIOff, onColor: MSGreen},
|
||||
]
|
||||
};
|
||||
//Level_2
|
||||
@@ -757,7 +767,6 @@ export const config = <Config> {
|
||||
// Seiteneinteilung / Page division
|
||||
// Hauptseiten / Mainpages
|
||||
pages: [
|
||||
|
||||
NSPanel_Service, //Auto-Alias Service Page
|
||||
//Unlock_Service //Auto-Alias Service Page (Service Pages used with cardUnlock)
|
||||
],
|
||||
@@ -837,7 +846,7 @@ export const config = <Config> {
|
||||
},
|
||||
// bottomScreensaverEntity 4
|
||||
{
|
||||
ScreensaverEntity: 'accuweather.0.Current.WindDirection',
|
||||
ScreensaverEntity: 'accuweather.0.Current.WindDirectionText',
|
||||
ScreensaverEntityFactor: 1,
|
||||
ScreensaverEntityDecimalPlaces: 0,
|
||||
ScreensaverEntityIconOn: 'windsock',
|
||||
@@ -947,7 +956,7 @@ export const config = <Config> {
|
||||
// _________________________________ DE: Ab hier keine Konfiguration mehr _____________________________________
|
||||
// _________________________________ EN: No more configuration from here _____________________________________
|
||||
|
||||
const scriptVersion: string = 'v4.3.3.18';
|
||||
const scriptVersion: string = 'v4.3.3.24';
|
||||
const tft_version: string = 'v4.3.3';
|
||||
const desired_display_firmware_version = 53;
|
||||
const berry_driver_version = 9;
|
||||
@@ -967,6 +976,10 @@ const moment = require('moment');
|
||||
const parseFormat = require('moment-parseformat');
|
||||
moment.locale(getState(NSPanel_Path + 'Config.locale').val);
|
||||
|
||||
const globalTextColor: any = White;
|
||||
const Sliders2: number = 0;
|
||||
let checkBlindActive: boolean = false;
|
||||
|
||||
async function Init_dayjs() {
|
||||
try {
|
||||
//Loading dayjs
|
||||
@@ -976,10 +989,10 @@ async function Init_dayjs() {
|
||||
'fi','he','hr','hu','hy-am','id','is','lb','lt','ro',
|
||||
'sk','sl','sv','th','tr','uk','vi','zh-cn','zh-tw']
|
||||
for (let i=0; i<dayjsLanguages.length;i++) {
|
||||
require('dayjs/locale/'+ dayjsLanguages[i]);
|
||||
require('dayjs/locale/'+ dayjsLanguages[i]);
|
||||
}
|
||||
dayjs.locale(getDayjsLocale());
|
||||
} catch (err) {
|
||||
} catch (err) {
|
||||
log('error at function init_dayjs: ' + err.message,'warn');
|
||||
}
|
||||
}
|
||||
@@ -1394,6 +1407,8 @@ on({id: NSPanel_Path + 'Config.Screensaver.alternativeScreensaverLayout', change
|
||||
//go to Page X after bExit
|
||||
async function Init_bExit_Page_Change() {
|
||||
try {
|
||||
alwaysOn = false;
|
||||
pageCounter = 0;
|
||||
if (existsState(NSPanel_Path + 'ScreensaverInfo.bExitPage') == false ) {
|
||||
await createStateAsync(NSPanel_Path + 'ScreensaverInfo.bExitPage', -1, true, { type: 'number' });
|
||||
}
|
||||
@@ -1437,17 +1452,27 @@ InitActiveBrightness();
|
||||
on({id: [].concat(String(NSPanel_Path) + 'ScreensaverInfo.activeDimmodeBrightness'), change: "ne"}, async function (obj) {
|
||||
try {
|
||||
let active = getState(NSPanel_Path + 'ScreensaverInfo.activeBrightness').val;
|
||||
|
||||
if (obj.state.val != null && obj.state.val != -1) {
|
||||
if (obj.state.val < -1 || obj.state.val > 100) {
|
||||
log('activeDimmodeBrightness value only between -1 and 100', 'info');
|
||||
setStateAsync(NSPanel_Path + 'ScreensaverInfo.activeDimmodeBrightness', -1, true);
|
||||
alwaysOn = false;
|
||||
pageCounter = 0;
|
||||
useMediaEvents = false;
|
||||
screensaverEnabled = true;
|
||||
InitDimmode();
|
||||
HandleMessage('event', 'startup',undefined, undefined);
|
||||
} else {
|
||||
log('action at trigger activeDimmodeBrightness: ' + obj.state.val + ' - activeBrightness: ' + active, 'info');
|
||||
SendToPanel({ payload: 'dimmode~' + obj.state.val + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) });
|
||||
SendToPanel({ payload: 'dimmode~' + obj.state.val + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
}
|
||||
} else {
|
||||
alwaysOn = false;
|
||||
pageCounter = 0;
|
||||
useMediaEvents = false;
|
||||
screensaverEnabled = true;
|
||||
InitDimmode();
|
||||
HandleMessage('event', 'startup',undefined, undefined);
|
||||
}
|
||||
} catch (err) {
|
||||
log('error at trigger activeDimmodeBrightness: ' + err.message, 'warn');
|
||||
@@ -1458,7 +1483,7 @@ on({id: String(NSPanel_Path) + 'ScreensaverInfo.Trigger_Dimmode', change: "ne"},
|
||||
try {
|
||||
let active = getState(NSPanel_Path + 'ScreensaverInfo.activeBrightness').val;
|
||||
if (obj.state.val) {
|
||||
SendToPanel({ payload: 'dimmode~' + 100 + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) });
|
||||
SendToPanel({ payload: 'dimmode~' + 100 + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
} else {
|
||||
InitDimmode();
|
||||
}
|
||||
@@ -1761,7 +1786,7 @@ async function InitPageNavi() {
|
||||
try {
|
||||
if (!existsState(NSPanel_Path + 'PageNavi')) {
|
||||
await createStateAsync(NSPanel_Path + 'PageNavi', <iobJS.StateCommon>{ type: 'string' });
|
||||
await setStateAsync(NSPanel_Path + 'PageNavi', <iobJS.State>{ val: {"pagetype": "page","pageId": 0}, ack: true });
|
||||
await setStateAsync(NSPanel_Path + 'PageNavi', <iobJS.State>{ val: {"pagetype": "page","pageId": 0}, ack: true });
|
||||
}
|
||||
} catch (err) {
|
||||
log('error at function InitPageNavi: ' + err.message, 'warn');
|
||||
@@ -1798,18 +1823,18 @@ function ScreensaverDimmode(timeDimMode: DimMode) {
|
||||
}
|
||||
if (timeDimMode.dimmodeOn != undefined ? timeDimMode.dimmodeOn : false) {
|
||||
if (compareTime(timeDimMode.timeNight != undefined ? timeDimMode.timeNight : '22:00', timeDimMode.timeDay != undefined ? timeDimMode.timeDay : '07:00', 'not between', undefined)) {
|
||||
SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) });
|
||||
SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
if (Debug) {
|
||||
log('function ScreensaverDimmode -> Day Payload: ' + 'dimmode~' + timeDimMode.brightnessDay + '~' + active, 'info');
|
||||
}
|
||||
} else {
|
||||
SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) });
|
||||
SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
if (Debug) {
|
||||
log('function ScreensaverDimmode -> Night Payload: ' + 'dimmode~' + timeDimMode.brightnessNight + '~' + active, 'info');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SendToPanel({ payload: 'dimmode~' + dimmode + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) });
|
||||
SendToPanel({ payload: 'dimmode~' + dimmode + '~' + active + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
}
|
||||
} catch (err) {
|
||||
log('error at function ScreensaverDimmode: ' + err.message, 'warn');
|
||||
@@ -1895,10 +1920,14 @@ async function InitDimmode() {
|
||||
scheduleInitDimModeNight = schedule({ hour: getState(NSPanel_Path + 'NSPanel_Dimmode_hourNight').val, minute: 0 }, () => {
|
||||
ScreensaverDimmode(timeDimMode);
|
||||
});
|
||||
|
||||
if (getState(NSPanel_Path + 'ScreensaverInfo.activeDimmodeBrightness').val != null && getState(NSPanel_Path + 'ScreensaverInfo.activeDimmodeBrightness').val != -1) {
|
||||
SendToPanel({ payload: 'dimmode~' + getState(NSPanel_Path + 'ScreensaverInfo.activeDimmodeBrightness').val + '~' + getState(NSPanel_Path + 'ScreensaverInfo.activeBrightness').val + '~' + rgb_dec565(config.defaultBackgroundColor) });
|
||||
SendToPanel({ payload: 'dimmode~' + getState(NSPanel_Path + 'ScreensaverInfo.activeDimmodeBrightness').val + '~' + getState(NSPanel_Path + 'ScreensaverInfo.activeBrightness').val + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
} else {
|
||||
if (isDimTimeInRange(timeDimMode.timeDay,timeDimMode.timeNight)) {
|
||||
SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessDay + '~' + getState(NSPanel_Path + 'ScreensaverInfo.activeBrightness').val + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
} else {
|
||||
SendToPanel({ payload: 'dimmode~' + timeDimMode.brightnessNight + '~' + getState(NSPanel_Path + 'ScreensaverInfo.activeBrightness').val + '~' + rgb_dec565(config.defaultBackgroundColor) + '~' + rgb_dec565(globalTextColor) + '~' + Sliders2 });
|
||||
}
|
||||
ScreensaverDimmode(timeDimMode);
|
||||
}
|
||||
}
|
||||
@@ -1908,6 +1937,35 @@ async function InitDimmode() {
|
||||
}
|
||||
InitDimmode();
|
||||
|
||||
function currentDimDate() {
|
||||
let d = new Date();
|
||||
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
||||
}
|
||||
|
||||
function addDimTime(strTime) {
|
||||
let time = strTime.split(':');
|
||||
let d = currentDimDate();
|
||||
d.setHours(time[0]);
|
||||
d.setMinutes(time[1]);
|
||||
d.setSeconds(time[2]);
|
||||
return d;
|
||||
}
|
||||
|
||||
function isDimTimeInRange(strLower, strUpper) {
|
||||
let now = new Date();
|
||||
let lower = addDimTime(strLower);
|
||||
let upper = addDimTime(strUpper);
|
||||
let inRange = false;
|
||||
if (upper > lower) {
|
||||
// opens and closes in same day
|
||||
inRange = (now >= lower && now <= upper) ? true : false;
|
||||
} else {
|
||||
// closes in the following day
|
||||
inRange = (now >= upper && now <= lower) ? false : true;
|
||||
}
|
||||
return inRange;
|
||||
}
|
||||
|
||||
//--------------------End Dimmode
|
||||
|
||||
// Data points for message to screensaver
|
||||
@@ -2298,7 +2356,8 @@ async function check_updates() {
|
||||
if (Debug) log('Already the latest display firmware on NSPanel', 'info');
|
||||
}
|
||||
}
|
||||
if (Update) {
|
||||
let update_message: boolean = getState(NSPanel_Path + 'Config.Update.UpdateMessage').val;
|
||||
if (Update && update_message) {
|
||||
await setStateAsync(popupNotifyHeading, <iobJS.State>{ val: Headline, ack: false });
|
||||
await setStateAsync(popupNotifyHeadingColor, <iobJS.State>{ val: HeadlineColor, ack: false });
|
||||
await setStateAsync(popupNotifyButton1Text, <iobJS.State>{ val: Button1, ack: false });
|
||||
@@ -2309,6 +2368,10 @@ async function check_updates() {
|
||||
await setStateAsync(popupNotifyInternalName, <iobJS.State>{ val: InternalName, ack: false });
|
||||
await setStateAsync(popupNotifyLayout, <iobJS.State>{ val: Layout, ack: false });
|
||||
await setStateAsync(popupNotifyText, <iobJS.State>{ val: [formatDate(getDateObject((new Date().getTime())), 'TT.MM.JJJJ SS:mm:ss'), '\r\n', '\r\n', Text].join(''), ack: false });
|
||||
} else if (Update && !update_message) {
|
||||
log('Updates for NSPanel available', 'info');
|
||||
} else {
|
||||
log('No Updates for NSPanel available', 'info');
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
@@ -2347,6 +2410,12 @@ on({ id: NSPanel_Path + 'popupNotify.popupNotifyAction', change: 'any' }, async
|
||||
async function get_panel_update_data() {
|
||||
try {
|
||||
if (isSetOptionActive) {
|
||||
await createStateAsync(NSPanel_Path + 'Config.Update.UpdateMessage', true, <iobJS.StateCommon>{ read: true, write: true, name: 'Update-Message', type: 'boolean', def: true });
|
||||
if (autoCreateAlias) {
|
||||
setObject(AliasPath + 'Config.Update.UpdateMessage', {type: 'channel', common: {role: 'socket', name:'UpdateMesssage'}, native: {}});
|
||||
await createAliasAsync(AliasPath + 'Config.Update.UpdateMessage.ACTUAL', NSPanel_Path + 'Config.Update.UpdateMessage', true, <iobJS.StateCommon>{ type: 'boolean', role: 'switch', name: 'ACTUAL' });
|
||||
await createAliasAsync(AliasPath + 'Config.Update.UpdateMessage.SET', NSPanel_Path + 'Config.Update.UpdateMessage', true, <iobJS.StateCommon>{ type: 'boolean', role: 'switch', name: 'SET' });
|
||||
}
|
||||
await createStateAsync(NSPanel_Path + 'NSPanel_autoUpdate', false, <iobJS.StateCommon>{ read: true, write: true, name: 'Auto-Update', type: 'boolean', def: false });
|
||||
if (autoCreateAlias) {
|
||||
setObject(AliasPath + 'autoUpdate', {type: 'channel', common: {role: 'socket', name:'AutoUpdate'}, native: {}});
|
||||
@@ -3182,7 +3251,18 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
|
||||
let name: string;
|
||||
let buttonText: string = 'PRESS';
|
||||
let type: string;
|
||||
|
||||
|
||||
if (existsState(pageItem.id + '.ACTUAL') == false) {
|
||||
if (pageItem.popupTimerType == 'TimeCard' && pageItem.autoCreateALias == true) {
|
||||
log(NSPanel_Path + 'Userdata.' + pageItem.id + '.Time')
|
||||
createStateAsync(NSPanel_Path + 'Userdata.' + pageItem.id + '.Time', '0', { type: 'number' });
|
||||
createStateAsync(NSPanel_Path + 'Userdata.' + pageItem.id + '.State', 'idle', { type: 'string' });
|
||||
setObject(pageItem.id, { type: 'channel', common: { role: 'value.time', name: 'Time' }, native: {} });
|
||||
createAliasAsync(pageItem.id + '.ACTUAL', NSPanel_Path + 'Userdata.' + pageItem.id + '.Time', true, <iobJS.StateCommon>{ type: 'number', role: 'state', name: 'ACTUAL' });
|
||||
createAliasAsync(pageItem.id + '.STATE', NSPanel_Path + 'Userdata.' + pageItem.id + '.State', true, <iobJS.StateCommon>{ type: 'string', role: 'state', name: 'STATE' });
|
||||
}
|
||||
}
|
||||
|
||||
// ioBroker
|
||||
if (existsObject(pageItem.id) || pageItem.navigate === true) {
|
||||
|
||||
@@ -3249,7 +3329,7 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
|
||||
iconColor = GetIconColor(pageItem, true, useColors);
|
||||
|
||||
if (Debug) log('CreateEntity statisch Icon Navi ~' + type + '~' + 'navigate.' + pageItem.targetPage + '~' + iconId + '~' + iconColor + '~' + pageItem.name + '~' + buttonText, 'info')
|
||||
return '~' + type + '~' + 'navigate.' + pageItem.targetPage + '~' + iconId + '~' + iconColor + '~' + pageItem.name + '~' + buttonText;
|
||||
return '~' + type + '~' + 'navigate.' + pageItem.targetPage + '~' + iconId + '~' + iconColor + '~' + name + '~' + buttonText;
|
||||
|
||||
} else if (pageItem.id != null && pageItem.targetPage != undefined) {
|
||||
|
||||
@@ -3312,6 +3392,32 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
|
||||
iconColor = GetIconColor(pageItem, true, useColors);
|
||||
}
|
||||
}
|
||||
|
||||
if (pageItem.colorScale != undefined) {
|
||||
let iconvalmin = (pageItem.colorScale.val_min != undefined) ? pageItem.colorScale.val_min : 0 ;
|
||||
let iconvalmax = (pageItem.colorScale.val_max != undefined) ? pageItem.colorScale.val_max : 100 ;
|
||||
let iconvalbest = (pageItem.colorScale.val_best != undefined) ? pageItem.colorScale.val_best : iconvalmin ;
|
||||
let valueScale = val;
|
||||
|
||||
if (iconvalmin == 0 && iconvalmax == 1) {
|
||||
iconColor = (getState(pageItem.id).val == 1) ? rgb_dec565(colorScale0) : rgb_dec565(colorScale10);
|
||||
} else {
|
||||
if (iconvalbest == iconvalmin) {
|
||||
valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0);
|
||||
} else {
|
||||
if (valueScale < iconvalbest) {
|
||||
valueScale = scale(valueScale,iconvalmin, iconvalbest, 0, 10);
|
||||
} else if (valueScale > iconvalbest || iconvalbest != iconvalmin) {
|
||||
valueScale = scale(valueScale,iconvalbest, iconvalmax, 10, 0);
|
||||
} else {
|
||||
valueScale = scale(valueScale,iconvalmin, iconvalmax, 10, 0);
|
||||
}
|
||||
}
|
||||
let valueScaletemp = (Math.round(valueScale)).toFixed();
|
||||
iconColor = HandleColorScale(valueScaletemp);
|
||||
}
|
||||
}
|
||||
|
||||
if (val === true || val === 'true') { iconId = iconId2 };
|
||||
break;
|
||||
|
||||
@@ -3573,10 +3679,36 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
|
||||
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);
|
||||
|
||||
if (Debug) log('CreateEntity Icon role blind ~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~', 'info');
|
||||
return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~';
|
||||
|
||||
|
||||
let min_Level: number = 0;
|
||||
let max_Level: number = 100;
|
||||
if (pageItem.minValueLevel !== undefined && pageItem.maxValueLevel !== undefined) {
|
||||
min_Level = pageItem.minValueLevel;
|
||||
max_Level = pageItem.maxValueLevel;
|
||||
val = Math.trunc(scale(getState(pageItem.id + '.ACTUAL').val, pageItem.minValueLevel, pageItem.maxValueLevel, 100, 0));
|
||||
}
|
||||
|
||||
let icon_up = Icons.GetIcon('arrow-up');
|
||||
let icon_stop = Icons.GetIcon('stop');
|
||||
let icon_down = Icons.GetIcon('arrow-down');
|
||||
|
||||
if (Debug) log('pageItem.id: ' + getState(pageItem.id + '.ACTUAL').val, 'info');
|
||||
if (Debug) log('min_Level: ' + min_Level, 'info');
|
||||
if (Debug) log('max_Level: ' + max_Level, 'info');
|
||||
|
||||
let tempVal: number = getState(pageItem.id + '.ACTUAL').val
|
||||
let icon_up_status = tempVal === min_Level ? 'disable' : 'enable';
|
||||
let icon_stop_status = 'enable';
|
||||
if (tempVal === min_Level || tempVal === max_Level || checkBlindActive === false) {
|
||||
icon_stop_status = 'disable';
|
||||
}
|
||||
let icon_down_status = tempVal === max_Level ? 'disable' : 'enable';
|
||||
let value = icon_up + '|' + icon_stop + '|' + icon_down + '|' + icon_up_status + '|' + icon_stop_status + '|' + icon_down_status
|
||||
|
||||
if (Debug) log('CreateEntity Icon role blind ~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + value, 'info');
|
||||
|
||||
return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + value;
|
||||
|
||||
case 'gate':
|
||||
type = 'text';
|
||||
let gateState: string;
|
||||
@@ -3721,13 +3853,18 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
|
||||
|
||||
case 'button':
|
||||
type = 'button';
|
||||
|
||||
iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('gesture-tap-button');
|
||||
iconColor = GetIconColor(pageItem, true, useColors);
|
||||
if (val === false) {
|
||||
iconColor = GetIconColor(pageItem, false, useColors);
|
||||
}
|
||||
|
||||
let buttonText = pageItem.buttonText !== undefined ? pageItem.buttonText : 'PRESS';
|
||||
|
||||
if (Debug) log('CreateEntity Icon role button ~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + buttonText, 'info');
|
||||
return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + buttonText;
|
||||
|
||||
case 'value.time':
|
||||
case 'level.timer':
|
||||
type = 'timer';
|
||||
iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('gesture-tap-button');
|
||||
@@ -3739,9 +3876,27 @@ function CreateEntity(pageItem: PageItem, placeId: number, useColors: boolean =
|
||||
RegisterEntityWatcher(pageItem.id + '.STATE');
|
||||
}
|
||||
|
||||
if (Debug) log('CreateEntity Icon role level.timeer ~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + timerText, 'info');
|
||||
if (Debug) log('CreateEntity Icon role level.timer ~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + timerText, 'info');
|
||||
return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + timerText;
|
||||
|
||||
case 'value.alarmtime':
|
||||
type = 'timer';
|
||||
iconId = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('timer-outline');
|
||||
let alarmtimerText = pageItem.buttonText !== undefined ? pageItem.buttonText : 'PRESS';
|
||||
|
||||
if (existsState(pageItem.id + '.STATE')) {
|
||||
val = getState(pageItem.id + '.STATE').val;
|
||||
iconColor = (val == 'paused') ? rgb_dec565(colorScale10) : rgb_dec565(colorScale0);
|
||||
}
|
||||
|
||||
if (existsState(pageItem.id + '.ACTUAL')) {
|
||||
let timer_actual = getState(pageItem.id + '.ACTUAL').val
|
||||
name = ('0' + String(Math.floor(timer_actual / 60))).slice(-2) + ':' + ('0' + String(timer_actual % 60)).slice(-2);
|
||||
}
|
||||
|
||||
if (Debug) log('CreateEntity Icon role value.alarmtime ~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + alarmtimerText + ' ' + val, 'info');
|
||||
return '~' + type + '~' + pageItem.id + '~' + iconId + '~' + iconColor + '~' + name + '~' + alarmtimerText;
|
||||
|
||||
case 'level.mode.fan':
|
||||
|
||||
type = 'fan';
|
||||
@@ -6064,12 +6219,15 @@ function HandleButtonEvent(words: any): void {
|
||||
break;
|
||||
case 'up':
|
||||
setIfExists(id + '.OPEN', true);
|
||||
checkBlindActive = true;
|
||||
break;
|
||||
case 'stop':
|
||||
setIfExists(id + '.STOP', true);
|
||||
checkBlindActive = false;
|
||||
break;
|
||||
case 'down':
|
||||
setIfExists(id + '.CLOSE', true);
|
||||
checkBlindActive = true;
|
||||
break;
|
||||
case 'positionSlider':
|
||||
(function () { if (timeoutSlider) { clearTimeout(timeoutSlider); timeoutSlider = null; } })();
|
||||
@@ -6078,8 +6236,10 @@ function HandleButtonEvent(words: any): void {
|
||||
if (pageItem.minValueLevel != undefined && pageItem.maxValueLevel != undefined) {
|
||||
let sliderPos = Math.trunc(scale(parseInt(words[4]), 0, 100, pageItem.maxValueLevel, pageItem.minValueLevel));
|
||||
setIfExists(id + '.SET', sliderPos) ? true : setIfExists(id + '.ACTUAL', sliderPos);
|
||||
checkBlindActive = true;
|
||||
} else {
|
||||
setIfExists(id + '.SET', parseInt(words[4])) ? true : setIfExists(id + '.ACTUAL', parseInt(words[4]));
|
||||
checkBlindActive = true;
|
||||
}
|
||||
}, 250);
|
||||
break;
|
||||
@@ -7201,13 +7361,14 @@ function GenerateDetailPage(type: string, optional: string, pageItem: PageItem):
|
||||
}
|
||||
|
||||
if (type == 'popupShutter') {
|
||||
|
||||
icon = pageItem.icon !== undefined ? Icons.GetIcon(pageItem.icon) : Icons.GetIcon('window-open');
|
||||
if (existsState(id + '.ACTUAL')) {
|
||||
val = getState(id + '.ACTUAL').val;
|
||||
RegisterDetailEntityWatcher(id + '.ACTUAL', pageItem, type);
|
||||
} else if (existsState(id + '.SET')) {
|
||||
val = getState(id + '.SET').val;
|
||||
RegisterDetailEntityWatcher(id + '.SET', pageItem, type);
|
||||
//RegisterDetailEntityWatcher(id + '.SET', pageItem, type);
|
||||
}
|
||||
let tilt_position: any = 'disabled'
|
||||
if (existsState(id + '.TILT_ACTUAL')) {
|
||||
@@ -7215,7 +7376,7 @@ function GenerateDetailPage(type: string, optional: string, pageItem: PageItem):
|
||||
RegisterDetailEntityWatcher(id + '.TILT_ACTUAL', pageItem, type);
|
||||
} else if (existsState(id + '.TILT_SET')) {
|
||||
tilt_position = getState(id + '.TILT_SET').val;
|
||||
RegisterDetailEntityWatcher(id + '.TILT_SET', pageItem, type);
|
||||
//RegisterDetailEntityWatcher(id + '.TILT_SET', pageItem, type);
|
||||
}
|
||||
|
||||
let min_Level: number = 0;
|
||||
@@ -7241,9 +7402,13 @@ function GenerateDetailPage(type: string, optional: string, pageItem: PageItem):
|
||||
let icon_up = Icons.GetIcon('arrow-up');
|
||||
let icon_stop = Icons.GetIcon('stop');
|
||||
let icon_down = Icons.GetIcon('arrow-down');
|
||||
let icon_up_status = getState(id + '.ACTUAL').val != max_Level ? 'enable' : 'disable';
|
||||
let tempVal: number = getState(pageItem.id + '.ACTUAL').val
|
||||
let icon_up_status = tempVal === min_Level ? 'disable' : 'enable';
|
||||
let icon_stop_status = 'enable';
|
||||
let icon_down_status = getState(id + '.ACTUAL').val != min_Level ? 'enable' : 'disable';
|
||||
if (tempVal === min_Level || tempVal === max_Level || checkBlindActive === false) {
|
||||
icon_stop_status = 'disable';
|
||||
}
|
||||
let icon_down_status = tempVal === max_Level ? 'disable' : 'enable';
|
||||
let textTilt = '';
|
||||
let iconTiltLeft = '';
|
||||
let iconTiltStop = '';
|
||||
@@ -7359,6 +7524,18 @@ function GenerateDetailPage(type: string, optional: string, pageItem: PageItem):
|
||||
let min_remaining = 0;
|
||||
let sec_remaining = 0;
|
||||
if (existsState(id + '.STATE')) {
|
||||
|
||||
if (o.common.role == 'value.time') {
|
||||
if (getState(id + '.STATE').val == 'idle' || getState(id + '.STATE').val == 'paused') {
|
||||
min_remaining = Math.floor(timer_actual / 60);
|
||||
sec_remaining = timer_actual % 60;
|
||||
editable = 1;
|
||||
} else {
|
||||
min_remaining = Math.floor(timer_actual / 60);
|
||||
sec_remaining = timer_actual % 60;
|
||||
editable = 1;
|
||||
}
|
||||
} else if (o.common.role == 'level.timer') {
|
||||
if (getState(id + '.STATE').val == 'idle' || getState(id + '.STATE').val == 'paused') {
|
||||
min_remaining = Math.floor(timer_actual / 60);
|
||||
sec_remaining = timer_actual % 60;
|
||||
@@ -7375,22 +7552,37 @@ function GenerateDetailPage(type: string, optional: string, pageItem: PageItem):
|
||||
label1 = findLocale('timer', 'pause');
|
||||
label2 = findLocale('timer', 'cancel');
|
||||
label3 = findLocale('timer', 'finish');
|
||||
}
|
||||
} else if (o.common.role == 'value.alarmtime') {
|
||||
if (getState(id + '.STATE').val == 'paused') {
|
||||
min_remaining = Math.floor(timer_actual / 60);
|
||||
sec_remaining = timer_actual % 60;
|
||||
editable = 1;
|
||||
action2 = 'start';
|
||||
label2 = findLocale('timer', 'on');
|
||||
} else {
|
||||
min_remaining = Math.floor(timer_actual / 60);
|
||||
sec_remaining = timer_actual % 60;
|
||||
editable = 0;
|
||||
action2 = 'pause';
|
||||
label2 = findLocale('timer', 'off');
|
||||
}
|
||||
}
|
||||
|
||||
out_msgs.push({
|
||||
payload: 'entityUpdateDetail' + '~' //entityUpdateDetail
|
||||
+ id + '~~' //{entity_id}
|
||||
+ rgb_dec565(White) + '~' //{icon_color}~
|
||||
+ id + '~'
|
||||
+ min_remaining + '~'
|
||||
+ sec_remaining + '~'
|
||||
+ editable + '~'
|
||||
+ action1 + '~'
|
||||
+ action2 + '~'
|
||||
+ action3 + '~'
|
||||
+ label1 + '~'
|
||||
+ label2 + '~'
|
||||
+ label3
|
||||
out_msgs.push({
|
||||
payload: 'entityUpdateDetail' + '~' //entityUpdateDetail
|
||||
+ id + '~~' //{entity_id}
|
||||
+ rgb_dec565(White) + '~' //{icon_color}~
|
||||
+ id + '~'
|
||||
+ min_remaining + '~'
|
||||
+ sec_remaining + '~'
|
||||
+ editable + '~'
|
||||
+ action1 + '~'
|
||||
+ action2 + '~'
|
||||
+ action3 + '~'
|
||||
+ label1 + '~'
|
||||
+ label2 + '~'
|
||||
+ label3
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -9124,6 +9316,7 @@ type PageItem = {
|
||||
iconArray: (string[] | undefined),
|
||||
fontSize: (number | undefined),
|
||||
actionStringArray: (string[] | undefined),
|
||||
popupTimerType: (string | undefined),
|
||||
alwaysOnDisplay: (boolean | undefined),
|
||||
crossfade: (boolean | undefined),
|
||||
}
|
||||
|
||||
@@ -1047,6 +1047,14 @@
|
||||
"zh-CN":"空闲",
|
||||
"zh-TW":"暫停"
|
||||
},
|
||||
"on":{
|
||||
"en-US":"On",
|
||||
"de-DE":"Ein"
|
||||
},
|
||||
"off":{
|
||||
"en-US":"Off",
|
||||
"de-DE":"Aus"
|
||||
},
|
||||
"paused":{
|
||||
"en-US":"Paused",
|
||||
"de-DE":"pausiert",
|
||||
|
||||
@@ -2693,5 +2693,9 @@
|
||||
"update_nextion_tft":{
|
||||
"en-US":"Update Nextion TFT",
|
||||
"de-DE":"Nextion TFT Update"
|
||||
},
|
||||
"update_message":{
|
||||
"en-US":"Update Notifications",
|
||||
"de-DE":"Update Mitteilungen"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config
|
||||
name: NSPanel Lovelace UI Addon
|
||||
version: "4.7.72"
|
||||
version: "4.7.73"
|
||||
slug: nspanel-lovelace-ui
|
||||
description: NSPanel Lovelace UI Addon
|
||||
services:
|
||||
|
||||
@@ -52,6 +52,8 @@ class HAEntity(panel_cards.Entity):
|
||||
self.state = data.get("state")
|
||||
self.attributes = data.get("attributes", [])
|
||||
else:
|
||||
self.state = "not found"
|
||||
self.attributes = []
|
||||
return "~text~iid.404~X~6666~not found~"
|
||||
|
||||
# HA Entities
|
||||
@@ -188,7 +190,7 @@ class HAEntity(panel_cards.Entity):
|
||||
icon_char = value
|
||||
case 'binary_sensor':
|
||||
device_class = self.attributes.get("device_class", "")
|
||||
value = get_translation(self.locale, f"backend.component.binary_sensor.state.{device_class}.{entity.state}")
|
||||
value = get_translation(self.locale, f"backend.component.binary_sensor.state.{device_class}.{self.state}")
|
||||
case 'weather':
|
||||
attr = self.config.get("attribute", "temperature")
|
||||
value = str(self.attributes.get(attr, self.state))
|
||||
@@ -304,8 +306,6 @@ class QRCard(HACard):
|
||||
super().__init__(locale, config, panel)
|
||||
self.qrcode = config.get("qrCode", "https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
||||
def render(self):
|
||||
# TODO: Render QRCode as HomeAssistant Template
|
||||
#qrcode = apis.ha_api.render_template(qrcode)
|
||||
if self.qrcode.startswith("ha:"):
|
||||
self.qrcode = libs.home_assistant.get_template(self.qrcode)[3:]
|
||||
result = f"{self.title}~{self.gen_nav()}~{self.qrcode}"
|
||||
@@ -475,6 +475,8 @@ class AlarmCard(HACard):
|
||||
main_entity = self.entities[0]
|
||||
main_entity.render()
|
||||
|
||||
print(main_entity.state)
|
||||
|
||||
icon = get_icon_char("shield-off")
|
||||
color = rgb_dec565([255,255,255])
|
||||
supported_modes = []
|
||||
|
||||
@@ -8,6 +8,7 @@ def wait_for_ha_cache():
|
||||
while time.time() < mustend:
|
||||
if len(libs.home_assistant.home_assistant_entity_state_cache) == 0:
|
||||
time.sleep(0.1)
|
||||
time.sleep(1)
|
||||
|
||||
def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, screenBrightness, sleepOverride, return_involved_entities=False):
|
||||
dimmode = 10
|
||||
@@ -17,6 +18,12 @@ def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, scr
|
||||
if sleepBrightness:
|
||||
if isinstance(sleepBrightness, int):
|
||||
dimmode = sleepBrightness
|
||||
elif isinstance(sleepBrightness, list):
|
||||
logging.error("list style config for sleepBrightness no longer supported")
|
||||
elif sleepBrightness.startswith("ha:"):
|
||||
time.sleep(1)
|
||||
dimmode = int(float(libs.home_assistant.get_template(sleepBrightness)[3:]))
|
||||
involved_entities.extend(libs.home_assistant.get_template_listener_entities(sleepBrightness))
|
||||
elif libs.home_assistant.is_existent(sleepBrightness):
|
||||
involved_entities.append(sleepBrightness)
|
||||
dimmode = int(float(libs.home_assistant.get_entity_data(sleepBrightness).get('state', 10)))
|
||||
@@ -24,6 +31,12 @@ def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, scr
|
||||
if screenBrightness:
|
||||
if isinstance(screenBrightness, int):
|
||||
dimValueNormal = screenBrightness
|
||||
elif isinstance(screenBrightness, list):
|
||||
logging.error("list style config for screenBrightness no longer supported")
|
||||
elif screenBrightness.startswith("ha:"):
|
||||
time.sleep(1)
|
||||
dimValueNormal = int(float(libs.home_assistant.get_template(screenBrightness)[3:]))
|
||||
involved_entities.extend(libs.home_assistant.get_template_listener_entities(screenBrightness))
|
||||
elif libs.home_assistant.is_existent(screenBrightness):
|
||||
involved_entities.append(screenBrightness)
|
||||
dimValueNormal = int(float(libs.home_assistant.get_entity_data(screenBrightness).get('state', 100)))
|
||||
@@ -60,7 +73,7 @@ def handle_buttons(entity_id, btype, value, entity_config=None):
|
||||
case 'number-set':
|
||||
if entity_id.startswith('fan'):
|
||||
attr = libs.home_assistant.get_entity_data(entity_id).get('attributes', [])
|
||||
value = float(value) * float(attr.get(percentage_step, 0))
|
||||
value = float(value) * float(attr.get('percentage_step', 0))
|
||||
service_data = {
|
||||
"value": int(value)
|
||||
}
|
||||
@@ -217,30 +230,6 @@ def handle_buttons(entity_id, btype, value, entity_config=None):
|
||||
case _:
|
||||
logging.error("Not implemented: %s", btype)
|
||||
|
||||
|
||||
# # for cardUnlock
|
||||
# if button_type == "cardUnlock-unlock":
|
||||
# curCard = self._config.get_card_by_uuid(
|
||||
# entity_id.replace('navigate.', ''))
|
||||
# if curCard is not None:
|
||||
# if int(curCard.raw_config.get("pin")) == int(value):
|
||||
# dstCard = self._config.search_card(
|
||||
# curCard.raw_config.get("destination"))
|
||||
# if dstCard is not None:
|
||||
# if dstCard.hidden:
|
||||
# self._previous_cards.append(self._current_card)
|
||||
# self._current_card = dstCard
|
||||
# self._pages_gen.render_card(self._current_card)
|
||||
|
||||
# if button_type == "opnSensorNotify":
|
||||
# msg = ""
|
||||
# entity = apis.ha_api.get_entity(entity_id)
|
||||
# if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None:
|
||||
# for e in entity.attributes.open_sensors:
|
||||
# msg += f"- {apis.ha_api.get_entity(e).attributes.friendly_name}\r\n"
|
||||
# self._pages_gen.send_message_page(
|
||||
# "opnSensorNotifyRes", "", msg, "", "")
|
||||
|
||||
def call_ha_service(entity_id, service, service_data = {}):
|
||||
etype = entity_id.split(".")[0]
|
||||
libs.home_assistant.call_service(
|
||||
|
||||
@@ -232,7 +232,7 @@ def execute_script(entity_name: str, domain: str, service: str, service_data: di
|
||||
]
|
||||
}
|
||||
send_message(json.dumps(msg))
|
||||
# busy waiting for response with a timeout of 0.2 seconds - maybe there's a better way of doing this
|
||||
# busy waiting for response with a timeout of 0.4 seconds- maybe there's a better way of doing this
|
||||
mustend = time.time() + 0.4
|
||||
while time.time() < mustend:
|
||||
if response_buffer[call_id] == True:
|
||||
@@ -246,6 +246,8 @@ def execute_script(entity_name: str, domain: str, service: str, service_data: di
|
||||
return {}
|
||||
|
||||
def cache_template(template):
|
||||
if not template:
|
||||
raise Exception("Invalid template")
|
||||
global next_id, response_buffer
|
||||
try:
|
||||
call_id = next_id
|
||||
@@ -273,6 +275,18 @@ def get_template(template):
|
||||
else:
|
||||
return template_cache.get(template, []).get("result", "404")
|
||||
|
||||
def get_template_listener_entities(template):
|
||||
global template_cache
|
||||
if template in template_cache:
|
||||
return template_cache[template].get("listener-entities")
|
||||
else:
|
||||
mustend = time.time() + 0.5
|
||||
while time.time() < mustend:
|
||||
if template not in template_cache:
|
||||
time.sleep(0.0001)
|
||||
else:
|
||||
return template_cache.get(template, []).get("listener-entities", "404")
|
||||
|
||||
def get_entity_data(entity_id: str):
|
||||
if entity_id in home_assistant_entity_state_cache:
|
||||
return home_assistant_entity_state_cache[entity_id]
|
||||
|
||||
@@ -41,3 +41,7 @@ def entityUpdateDetail2(msg_out_queue, topic, data):
|
||||
|
||||
def statusUpdate(msg_out_queue, topic, data):
|
||||
custom_send(msg_out_queue, topic, f"statusUpdate~{data}")
|
||||
|
||||
def send_message_page(msg_out_queue, topic, ident, heading, msg, b1, b2):
|
||||
page_type(msg_out_queue, topic, "popupNotify")
|
||||
custom_send(msg_out_queue, topic, f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")
|
||||
@@ -7,7 +7,7 @@ from scheduler import Scheduler
|
||||
import scheduler.trigger as trigger
|
||||
import time
|
||||
import babel.dates
|
||||
from ha_cards import Screensaver, EntitiesCard, card_factory, detail_open
|
||||
from ha_cards import Screensaver, card_factory, detail_open
|
||||
import ha_control
|
||||
|
||||
class LovelaceUIPanel:
|
||||
@@ -76,6 +76,10 @@ class LovelaceUIPanel:
|
||||
ha_control.wait_for_ha_cache()
|
||||
|
||||
#request templates on cards
|
||||
if isinstance(self.settings.get("sleepBrightness",""), str) and self.settings.get("sleepBrightness", "").startswith("ha:"):
|
||||
libs.home_assistant.cache_template(self.settings.get("sleepBrightness"))
|
||||
if isinstance(self.settings.get("sleepBrightness",""), str) and self.settings.get("screenBrightness", "").startswith("ha:"):
|
||||
libs.home_assistant.cache_template(self.settings.get("screenBrightness"))
|
||||
for c in self.cards.values():
|
||||
if hasattr(c, "qrcode"):
|
||||
if c.qrcode.startswith("ha:"):
|
||||
@@ -242,12 +246,6 @@ class LovelaceUIPanel:
|
||||
self.render_current_page(switchPages=True)
|
||||
return
|
||||
|
||||
# replace iid with real entity id
|
||||
#if entity_id.startswith("iid."):
|
||||
# iid = entity_id.split(".")[1]
|
||||
# if iid in self.entity_iids:
|
||||
# entity_id = self.entity_iids[iid]
|
||||
|
||||
# replace iid with real entity id
|
||||
if entity_id.startswith("iid."):
|
||||
iid = entity_id.split(".")[1]
|
||||
|
||||
Reference in New Issue
Block a user