-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathScreensaverMessage.ts
257 lines (236 loc) · 9.75 KB
/
ScreensaverMessage.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
export {}
/**
* Verwaltung von Nachrichten für Nspanel Screensaver.
* Nachrichten werden gesendet in dem ein Text oder Json in die Datenpunkt die auf IncomingMessage enden geschrieben wird.
*
* TEXT: Kann nach dem Muster headline#text verwendet werden. z.B. 'nur headline', '#nur text' oder 'headline#text'
*
* JSON: Das Json hat folgendes Format: {id: string, headline: string, msg: string, clear: number, change: number}
* Normale Nachricht: Alle Datenpunkte sind optional
* {
* headline: Die Überschrift 1. Zeile
* msg: Der Nachrichtentext 2. Zeile,
* clear: Zeit in Sekunden die die Nachricht angezeigt werden soll,
* change: Wenn mehrere Nachrichten für dieses Panel anstehen, die Zeit die diese Nachricht angezeigt werden soll, bevor die nächste angezeigt wird..
* }
*
* Nachrichten die permanent angezeigt werden sollen:
* Wenn eine Nachricht die Eigenschaft "id" hat, wird sie solange angezeigt bis einen leere Nachricht mit dieser ID geschickt wird. z.B. {id: 'Haustür steht offen'}
*
*/
/**
* Ein Array das auf die Ordnernamens ScreensaverInfo zeigt. In diesem Ordner liegen die Datenpunkte die auf 'popupNotifyHeading', 'popupNotifyText' enden.
*
*/
const nspanelPath: string[] = [
'0_userdata.0.NSPanel.1.ScreensaverInfo',
];
/**
* Datenpfad an dem Datenpunkte von diesem Skript erstellt werden. Es wird ein Unterordner unterhalb dieses Datenpunktes erstellt.
* Muss mit javascript oder 0_userdata.0 beginnen.
*/
const userPath: string = '0_userdata.0.NSPanel';
/**********************************************************************************************************************************
* Keine Konfiguration mehr ab hier
**********************************************************************************************************************************/
/**
* Zeit in Sekunden die eine Nachricht angezeigt werden soll.
*/
let clearTime: number = 30;
/**
* Zeit in Sekunden die eine Nachricht mindestens angezeigt werden soll, wenn weitere Nachricht auf die Anzeige warten.
*/
let changeTime: number = 10;
let messageDB: messageObjectType[] = []
const path = `${userPath}.screen_messages`
type messageObjectType = {id: string, panel: number, headline: string, msg: string, clear: number, change: number, set: number, setChange: number}
type messageArrivedType = Partial<Pick <messageObjectType,'id' | 'headline' | 'msg' | 'clear' | 'change'>>
let globalIndex: {[key: number]: messageObjectType | undefined} = {};
async function init() {
// check config
for (const dp of nspanelPath) {
for (const enddp of ['popupNotifyHeading', 'popupNotifyText']) {
const id = `${dp}.${enddp}`
if (!existsState(`${id}`)) {
log(`Error in configuration! ID in nspanelPath doesn't exist! Search for ${id} --- ${dp} is wrong!`, 'error');
log('Script stopped!', 'error')
stopScript(scriptName);
return;
}
}
}
if (!userPath.startsWith('javascript') && !userPath.startsWith('0_userdata.0')) {
log(`Error in configuration! userPath must start with javascript or 0_userdata.0! Your config value is ${userPath},`, 'error');
log('Script stopped!', 'error')
stopScript(scriptName);
return;
}
await extendObject(`${path}`, statesObjects.screen_messages);
await extendObject(`${path}.config`, statesObjects.config)
await extendObject(`${path}.config.clearTime`, statesObjects.clearTime)
await extendObject(`${path}.config.changeTime`, statesObjects.changeTime)
await sleep(200);
clearTime = getState(`${path}.config.clearTime`).val;
changeTime = getState(`${path}.config.changeTime`).val;
on({id: `${path}.config.clearTime`, change: 'any', ack: false}, (obj) => {
clearTime = obj.state.val;
setState(obj.id, obj.state.val, true);
})
on({id: `${path}.config.changeTime`, change: 'any', ack: false}, (obj) => {
changeTime = obj.state.val;
setState(obj.id, obj.state.val, true);
})
const obj = statesObjects.incomingMessage;
obj.common.name = 'Eingehende Nachrichten an Alle';
await extendObject(`${path}.globalPanelIncomingMessage`, obj);
await sleep(100);
on({id: `${path}.globalPanelIncomingMessage`, change: 'any', ack: false}, (obj) => {
nspanelPath.forEach((dp, i) => {
setState(`${path}.panel${i}IncomingMessage`, obj.state.val, false);
});
setState(obj.id, obj.state.val, true);
})
nspanelPath.forEach(async (dp, i) => {
const obj = statesObjects.incomingMessage;
obj.common.name = `Panel ${i+1} - Eingehende Nachrichten`;
await extendObject(`${path}.panel${i}IncomingMessage`, obj);
await sleep(100);
on({id: `${path}.panel${i}IncomingMessage`, change: 'any', ack: false}, (obj) => {
let value = obj.state.val as Partial<messageArrivedType>;
try {
value = JSON.parse(obj.state.val) as Partial<messageArrivedType>;
} catch (e) {
}
if (typeof value != 'object') {
value = {} as Partial<messageArrivedType>;
const rows = obj.state.val.split('#');
if (rows && rows.length > 2) {
const test = rows.slice(2);
log(`You add more as one # to the string message! Ignore this part "${test.join('#')}"!`, 'warn')
}
value.headline = rows[0] ? rows[0] : '';
value.msg = rows[1] ? rows[1] : '';
}
if ((value.id !== undefined || value.id != '') && !value.headline && !value.msg) {
const index = messageDB.findIndex(a=> a.id == value.id)
if (index != -1) {
messageDB[index].id = undefined;
messageDB[index].set = 1;
handleMessages(messageDB[index].panel)
return;
}
}
const n = obj.id.replace(`${path}.panel`, '').replace('IncomingMessage', '');
if (n == '' || n == undefined) return;
const panel = parseInt(n)
const newMsg: messageObjectType = {
id: value.id || undefined,
panel: panel,
headline: value.headline || '',
msg: value.msg || '',
clear: value.clear || clearTime,
change: value.change || changeTime,
set: 0,
setChange: 0,
}
const index = globalIndex[panel] ? messageDB.indexOf(globalIndex[panel]) : -1;
if (index == -1 || index == messageDB.length -1) {
messageDB.push(newMsg);
} else {
messageDB.splice(index+1,0,newMsg);
}
setState(obj.id, obj.state.val, true);
handleMessages(panel)
})
});
}
async function handleMessages(panel: number) {
if (panel != -1) {
messageDB = messageDB.filter(a => a.id || a.panel != panel || !(a.panel == panel && a.set != 0 && a.set < new Date().getTime()));
const messages = messageDB.filter(a => a.panel == panel);
let oldMessage: messageObjectType | undefined = undefined;
if (globalIndex[panel] !== undefined) {
oldMessage = globalIndex[panel];
if (messages.length > 0 && oldMessage.setChange > new Date().getTime() && messageDB.indexOf(oldMessage) != -1) {
return;
}
}
if (messages.length > 0) {
let index = messages.indexOf(oldMessage);
index = (index + 1) % messages.length;
const msg = messages[index];
if (msg.set == 0) {
msg.set = new Date().getTime() + messageDB[index].clear * 1000 + 1;
setTimeout(handleMessages, msg.set - new Date().getTime(), msg.panel);
}
msg.setChange = new Date().getTime() + msg.change * 1000 + 1;
setTimeout(handleMessages, msg.setChange - new Date().getTime(), msg.panel);
globalIndex[panel] = msg;
await setStateAsync(`${nspanelPath[msg.panel]}.popupNotifyHeading`, msg.headline, false);
await setStateAsync(`${nspanelPath[msg.panel]}.popupNotifyText`, msg.msg, false);
return;
}
await setStateAsync(`${nspanelPath[panel]}.popupNotifyHeading`, '', false);
await setStateAsync(`${nspanelPath[panel]}.popupNotifyText`, '', false);
}
}
const statesObjects: {[key: string]: iobJS.StateObject | iobJS.ChannelObject | iobJS.DeviceObject} = {
screen_messages: {
_id: '',
type: 'device',
common: {
name: 'Nachrichtenverwaltung für Nspanel'
},
native: {}
},
config: {
_id: '',
type: 'channel',
common: {
name: 'Standardzeiteinstellungen'
},
native: {}
},
incomingMessage: {
_id: '',
type: 'state',
common: {
name: 'Eingehende Nachrichten',
type: 'string',
role: 'json',
def: '{}',
read: true,
write: true
},
native:{}
},
clearTime: {
_id: '',
type: 'state',
common: {
name: 'Wartezeit bevor Löschung',
type: 'number',
role: 'value',
def: clearTime,
unit: 's',
read: true,
write: true
},
native:{}
},
changeTime: {
_id: '',
type: 'state',
common: {
name: 'Wartezeit bevor Wechsel',
type: 'number',
role: 'value',
unit: 's',
def: changeTime,
read: true,
write: true
},
native:{}
},
}
init();