iobroker.lovelace 4.0.4 → 4.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -471,6 +471,14 @@ After that checkout modified version in `./build` folder. Then.
471
471
  PLACEHOLDER for next version:
472
472
  ### **WORK IN PROGRESS**
473
473
  -->
474
+ ### 4.0.6 (2023-12-09)
475
+ * (Garfonso) fixed: thermostat card for thermostats without mode / off state
476
+ * (Garfonso) fixed: history and history graph missing for some stuff
477
+
478
+ ### 4.0.5 (2023-12-09)
479
+ * (Garfonso) revert shopping list
480
+ * (Garfonso) prevent invalid date error
481
+
474
482
  ### 4.0.4 (2023-12-09)
475
483
  * (Garfonso) fix: crash
476
484
 
@@ -480,20 +488,6 @@ After that checkout modified version in `./build` folder. Then.
480
488
  ### 4.0.2 (2023-12-09)
481
489
  * (Garfonso) fix: crash
482
490
 
483
- ### 4.0.1 (2023-12-08)
484
- * (Garfonso) fix: hideHeader object is writable
485
-
486
- ### 4.0.0 (2023-12-08)
487
- * (Garfonso) Breaking: Update frontent to 2023.12.08.1
488
- * (Garfonso) Breaking: all states default to string now. Added some exceptions (like timestamps). Check your filters.
489
- * (Garfonso) Use better random numbers for tokens.
490
- * (Garfonso) Support media_play_pause (mini-media-player card play / pause) again.
491
- * (Garfonso) Support for input_select
492
- * (Garfonso) Improve support for sensor with device_class=date
493
- * (Garfonso) Remove hideToolbar from settings. Now using browser_mod to allow per instance control.
494
- * (Garfonso) repaired persistent notifications.
495
- * (Garfonso) Use browser_mod to hide sidebar.
496
-
497
491
  ## License
498
492
 
499
493
  Copyright 2019-2023, bluefox <dogafox@gmail.com>
package/io-package.json CHANGED
@@ -1,8 +1,25 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lovelace",
4
- "version": "4.0.4",
4
+ "version": "4.0.6",
5
5
  "news": {
6
+ "4.0.6": {
7
+ "en": "fixed: thermostat card for thermostats without mode / off state\nfixed: history and history graph missing for some stuff",
8
+ "de": "repariert: thermostatkarte für thermostate ohne modus / aus zustand\nrepariert: history und history diagramm fehlt für einige sachen"
9
+ },
10
+ "4.0.5": {
11
+ "en": "revert shopping list (not working right now)\nprevent invalid date error",
12
+ "de": "Shoppignlist Änderungen rückgängig gemacht (funktionieren nicht)\nungültiger datumsfehler verhindern",
13
+ "ru": "перевернуть список покупок\nпредотвратить недопустимую ошибку",
14
+ "pt": "lista de compras reverter\nevitar erro de data inválido",
15
+ "nl": "revert shoppen\nongeldige datum fout",
16
+ "fr": "retourner la liste des courses\nprévenir l'erreur de date invalide",
17
+ "it": "rifare la lista della spesa\nprevenire errore di data non valido",
18
+ "es": "revertir la lista de compras\nprevenir el error de fecha inválida",
19
+ "pl": "lista zakupów\nzapobieganie błędom",
20
+ "uk": "перевернути список покупок\nзапобігання недійсної помилки дати",
21
+ "zh-cn": "回购单\n防止无效日期"
22
+ },
6
23
  "4.0.4": {
7
24
  "en": "fix: crash",
8
25
  "de": "fix: absturz",
@@ -58,32 +75,6 @@
58
75
  "pl": "Przełom: Przedstawienie do 2023.12.08.1\nZłamanie: wszystkie stany domyślają się do strun. Wyróżnia się kilka wyjątków (np. znaczki czasowe). Wszystko filtruje.\nUżycie lepszych liczb losowych dla tokenów.\nMedia_pause (mini-media-player card play / pause) (ang.).\nWsparcie dla indeksu\nPoprawione wsparcie dla czujnika z urządzenie_class=date\nPrzewidywać się Toolbar from the settings (ang.). Zastosowanie przeglądarki_mod pozwala na kontrolę instancji.\nzremasterowane aktualizacje.\nUżycie przeglądarki_mod do ukrycia bocznego.",
59
76
  "uk": "Перерва: Оновлення переднього до 2023.12.08.1\nПерерва: всі стани за замовчуванням, щоб рядок зараз. Додайте деякі винятки (наприклад, мітки часу). Перевірити фільтри.\nВикористовуйте кращі випадкові номери для жетонів.\nПідтримка медіа_play_pause (міні-медійно-плеєрна картка / пауза) знову.\nПідтримка вхідних_select\nПокращення підтримки датчика з пристроєм_class=date\nВидалити приховати Клапан інструментів з налаштувань. Тепер за допомогою браузера_mod для керування екземпляром.\nвідремонтовані постійні повідомлення.\nВикористовуйте браузер_mod для приховувати бічні панелі.",
60
77
  "zh-cn": "处理:最新战线到2023.12.08.1\n打破:所有国家现在都拖欠会费。 增加一些例外(与时间限制)。 检查你的过滤。.\n使用较随机的数字。.\n支助媒体:互动_pause(媒体角色卡)再次发挥/作用。.\n投入支助\nA. 改善对传感器的支助\n移离掩护 2. 不受环境伤害。 现在使用“代行”来控制。.\n修理了持续通知。.\n使用缩写:为掩护。."
61
- },
62
- "3.0.1": {
63
- "en": "do not crash if no history instance selected.\nnotifications working again.\nrepaired color temperature handling.",
64
- "de": "nicht abstürzen, wenn keine History-Instanz ausgewählt wird.\nBenachrichtigungen funktionieren wieder.\nReparatur der Farbtemperatursteuerung.",
65
- "ru": "не мешайте, если не выбрана пример истории.\nуведомления, которые снова работают.\nотремонтированная обработка цветовой температуры.",
66
- "pt": "não travar se nenhuma instância do histórico selecionada.\nnotificações trabalhando novamente.\ntratamento de temperatura de cor reparado.",
67
- "nl": "niet crashen als geen geschiedenis instance geselecteerd is.\nde berichten werken weer.\ngerepareerde kleurtemperatuur.",
68
- "fr": "ne pas s'écraser si aucune instance historique n'est sélectionnée.\nles notifications fonctionnent à nouveau.\nla manipulation de la température de couleur réparée.",
69
- "it": "non crash se non viene selezionato un'istanza di storia.\nnotifiche che funzionano di nuovo.\ngestione della temperatura del colore riparato.",
70
- "es": "no se estrellen si no se selecciona ningún caso histórico.\nnotificaciones que funcionan de nuevo.\nmanejo de temperatura de color reparado.",
71
- "pl": "nie dochodzi do skutku, jeśli nie zostanie wybrana historia.\nponowne wyniki pracują ponownie.\nremontowany kolorową temperaturę.",
72
- "uk": "не вдається, якщо вибрано екземпляр історії.\nповідомлення про роботу знову.\nобробка кольорової температури.",
73
- "zh-cn": "如果没有选择过历史的事例,就不会发生事故。.\n再次发出通知。.\n修理的气温处理。."
74
- },
75
- "3.0.0": {
76
- "en": "added: per instance language support\nchanged: updated frontend to 20221027.0. Needs theme adjustment (add code-editor-background-color) and probably card updates\nadded: browser_mod (2.1.3) is now integrated. Please remove manual installed versions of custom browser_mod card.\nadded: 'instances.refresh' can be used to reload page in connected browsers.\nremoved: lovelace_reload and window_reload states\nremoved: name state, not supported by browser_mod anymore\nadded: Support for toasts with action button (either json or ;-string)\nadded: activity state will show if user is currently using a certain browser\nadded: Support for subfolders in /cards/ for images and stuff custom cards load (please keep cards in root folder).",
77
- "de": "hinzugefügt: per Instanz sprachunterstützung\ngeändert: aktualisiertes Frontend auf 20221027.0 Benötigt Thema Anpassung (z.B. neu code-editor-background-color) und wahrscheinlich Karten-Updates\nadd: browser_mod (2.1.3) ist jetzt integriert. Bitte entfernen Sie manuell installierte Versionen der browser_mod-Karte.\nhinzugefügt: instances.refresh kann verwendet werden, um die Seite in verbundenen Browsern neu zu laden.\nentfernt: lovelace_reload und windows_reload\nentfernt: name-State, nicht mehr von browser_mod unterstützt\nadded: Unterstützung für Toasts mit Aktionsknopf (entweder json oder -;string)\nadded: Aktivitätszustand, der anzeigt, ob der Nutzer derzeit einen bestimmten Browser bedient\nadded: Unterstützung für Unterordner in /cards/ für Bilder und Materialien benutzerdefinierte Karten (bitte die Karten selber im Wurzelordner lassen).",
78
- "ru": "добавлено: в пример языковой поддержки\nизменено: обновление frontend до 20221027.0 Нужна настройка темы (add code-editor-background-color) и, вероятно, обновления карты\nдобавлено: browser_mod (2.1.3) теперь интегрирован. Пожалуйста, удалите вручную установленные версии пользовательского браузера_mod карты.\nдобавлено: instances.refresh можно использовать для перезагрузки страницы в подключенных браузерах.\nудалено: lovelace_reload and window_reload состояния\nудалено: имя состояние, не поддерживается браузером_mod более\nдобавлено: Поддержка тостов с кнопкой действия (либо json или -;string)\nдобавлено: состояние активности покажет, если пользователь в настоящее время использует определенный браузер\nдобавлено: Поддержка субпастеров в картах для загрузки изображений и настраиваемых карт (пожалуйста, держите карты в папке root).",
79
- "pt": "adicionado: por exemplo suporte de idioma\nalterado: frontend atualizado para 20221027.0 Precisa de ajuste de tema (add code-editor-background-color) e, provavelmente, atualizações de cartão\nadicionado: browser_mod (2.1.3) agora está integrado. Por favor, remova as versões manuais instaladas do cartão browser_mod personalizado.\nadicionado: instances.refresh a atualização pode ser usada para recarregar a página em navegadores conectados.\nremovido: lovelace_reload and window_reload states\nremovido: name state, não suportado pelo browser_mod mais\nadicionado: Suporte para torradas com botão de ação (quer json ou -;string)\nadicionado: estado de atividade irá mostrar se o usuário está usando um determinado navegador\nadicionado: Suporte para subpastas em cartões para imagens e coisas cartões personalizados de carga (por favor, mantenha cartões na pasta raiz).",
80
- "nl": "vertaling:\nverandering: Heeft thema aanpassing nodig (add code-aditor-background-color) en waarschijnlijk kaart updates\ntoegevoegd: browsermod (2.1.3) is nu geïntegreerd. Verwijder handmatig geïnstalleerde versies van de gewone browsermod kaart.\ntoegevoegd: instances.refresh kan gebruikt worden om pagina te herladen in verbonden browsers.\n_\nverwijdert: naam staat, niet ondersteund door browsermod\nversterking voor toasts met actieknop\nde activiteitsstaat laat zien of gebruiker momenteel een bepaalde browser gebruikt\nsteun voor subfolders in kaarten voor foto's en klantenkaarten laden in wortelvouder.",
81
- "fr": "ajouté: par exemple le soutien linguistique\nchangé: mise à jour du frontend à 20221027.0 Besoins réglage de thème (add code-editor-background-color) et probablement mises à jour de carte\najouté: browser_mod (2.1.3) est maintenant intégré. Veuillez supprimer les versions manuelles installées de la carte personnalisée browser_mod.\najouté: instances. rafraîchissement peut être utilisé pour recharger la page dans les navigateurs connectés.\nsupprimé: lovelace_reload et windows_reload états\nenlevé: état de nom, non pris en charge par browser_mod plus\najouté: Support pour les toasts avec bouton d'action (soit json ou -;string)\najouté: état d'activité montrera si l'utilisateur utilise actuellement un certain navigateur\najouté: Support pour les sous-dossiers dans les cartes pour les images et la charge de cartes personnalisées (veuillez garder les cartes dans le dossier racine).",
82
- "it": "aggiunto: per esempio supporto linguistico\nmodificato: frontend aggiornato a 20221027.0 Ha bisogno di regolazione del tema (add code-editor-background-color) e probabilmente aggiornamenti della carta\naggiunto: browser_mod (2.1.3) è ora integrato. Si prega di rimuovere le versioni di browser_mod personalizzato.\naggiunto: instances.refresh può essere utilizzato per ricaricare la pagina nei browser collegati.\nrimosso: lovelace_reload e window_reload stati\nrimosso: nome stato, non supportato da browser_mod più\naggiunto: Supporto per toast con pulsante d'azione (sia json che -;string)\naggiunto: lo stato di attività mostrerà se l'utente sta attualmente utilizzando un certo browser\naggiunto: Supporto per le sottocartelle nelle schede per immagini e roba carico di carte personalizzate (mantenere le carte nella cartella principale).",
83
- "es": "añadido: por ejemplo apoyo al idioma\ncambiado: actualización de frontend a 20221027.0 Necesidades de ajuste de tema (add code-editor-background-color) y probablemente actualizaciones de tarjetas\nañadido: browser_mod (2.1.3) está ahora integrado. Por favor, retire las versiones instaladas manualmente de la tarjeta browser_mod personalizada.\nañadido: instances.refresh se puede utilizar para recargar página en los navegadores conectados.\neliminados: estados lovelace_reload y window_reload\neliminado: estado de nombre, no soportado por browser_mod más\nañadido: Soporte para tostadas con botón de acción (ya sea json o -;string)\nañadido: estado de actividad mostrará si el usuario está utilizando un determinado navegador\nañadido: Soporte para subcarpetas en tarjetas para la carga de imágenes y material de tarjetas personalizadas (por favor, mantenga las tarjetas en la carpeta raíz).",
84
- "pl": "upoważnianie języka\nzmieniło się: zaktualizowano front do 20221027. Konstrukcja tematu (dodawanie kod-editor-ground-color) oraz prawdopodobnie aktualizacja kart\ndodano: przeglądarkę_mod (2.1.3). Zastosowanie ręcznych wersji karty przeglądarki_mod.\ndostęp: instances.refresh być używany do przeładowania strony w połączonych przeglądarkach.\nusunięte: miłość_reload and window_reload\nusunięta: nazwa nie jest wspierana przez przeglądarkę_mod anymore\ndodał: Wspieranie toastów z przyciskiem (json lub -;string)\ndodano: stan aktywności pokazuje, że użytkownik jest obecnie używany przez określoną przeglądarkę\ndodał: Wsparcie dla subklerów w kartach dla obrazów i kart przechowywania kart (please keep cards in root folder).",
85
- "uk": "додано: підтримка мови екземпляра\nзмінено: оновлений фронтенд до 20221027.0 Потрібні налаштування теми (add code-editor-phone-color) і, ймовірно, оновлення карт\nдодано: браузер_mod (2.1.3) тепер інтегрований. Будь ласка, видаліть ручні встановлені версії користувацького браузера_mod карти.\nдодано: instances.refresh перезавантажити сторінку в підключених браузерах.\nвидалити: lovelace_reload і windows_reload стани\nвидалити: стан імен, не підтримується браузером_mod додатково\nдоданий: Підтримка тастів з кнопкою дії (або json або -;string)\nдодано: стан роботи покаже, якщо користувач наразі використовує певний браузер\nдодано: Підтримка підпапок у картках для зображень та начинок на замовлення, завантаження карт (збережіть картки у папці кореневих).",
86
- "zh-cn": "增加:每一类语文支助\n修改:更新前线到20221027.0。 需求专题调整(附加编码的外地领地)以及可能提供最新资料\n增加:现正在综合编(2.1.3)。 请取消制造的习俗包件的手册。.\n增加:情况。 可以用来复制连带代的页。.\n删除:亲王:重载和窗口。\n删除:姓名国,未获括号内的支持;莫斯·马约尔\n增加:支持以行动、但顿(既不是 json,也不是;示范)\n增加:如果用户目前使用某些代行,活动国将显示活动情况。\n增加:支持在图像和制成品的卡里的投影器(装有根带的卡)。."
87
78
  }
88
79
  },
89
80
  "title": "Visualization with Lovelace-UI",
@@ -476,6 +476,15 @@ function fillClimateEntityFromStates(states, objects, entity, iobType) {
476
476
  attr.historyParser = (id, val) => { return translateModeNameForLovelace(attr.states ? (attr.states[val] || val) : val); };
477
477
  }
478
478
 
479
+ //add minimal hvac_modes, if none were found from the states above:
480
+ if (!entity.attributes.hvac_modes) {
481
+ if (iobType === typeDetector.Types.airCondition) {
482
+ entity.attributes.hvac_modes = ['cool'];
483
+ } else {
484
+ entity.attributes.hvac_modes = ['heat'];
485
+ }
486
+ }
487
+
479
488
  //defaults:
480
489
  entity.attributes.min_temp = 7;
481
490
  entity.attributes.max_temp = 35;
@@ -1,3 +1,54 @@
1
+ exports.numericDeviceClasses = [
2
+ 'voltage',
3
+ 'sulphur_dioxide',
4
+ 'carbon_dioxide',
5
+ 'current',
6
+ 'volume_storage',
7
+ 'volume',
8
+ 'ozone',
9
+ 'speed',
10
+ 'atmospheric_pressure',
11
+ 'carbon_monoxide',
12
+ 'aqi',
13
+ 'pm25',
14
+ 'nitrogen_monoxide',
15
+ 'power_factor',
16
+ 'pm1',
17
+ 'precipitation',
18
+ 'volatile_organic_compounds',
19
+ 'humidity',
20
+ 'pressure',
21
+ 'battery',
22
+ 'irradiance',
23
+ 'wind_speed',
24
+ 'pm10',
25
+ 'ph',
26
+ 'reactive_power',
27
+ 'temperature',
28
+ 'precipitation_intensity',
29
+ 'sound_pressure',
30
+ 'data_rate',
31
+ 'frequency',
32
+ 'volatile_organic_compounds_parts',
33
+ 'energy',
34
+ 'apparent_power',
35
+ 'weight',
36
+ 'duration',
37
+ 'gas',
38
+ 'water',
39
+ 'power',
40
+ 'monetary',
41
+ 'signal_strength',
42
+ 'data_size',
43
+ 'energy_storage',
44
+ 'nitrogen_dioxide',
45
+ 'nitrous_oxide',
46
+ 'illuminance',
47
+ 'moisture',
48
+ 'distance'
49
+ ];
50
+
51
+ const numericDeviceClassesIob = exports.numericDeviceClasses.concat(['timestamp']);
1
52
 
2
53
  exports.iobState2EntityState = function (entity, val, attribute) {
3
54
  let type = entity.context.type;
@@ -10,10 +61,11 @@ exports.iobState2EntityState = function (entity, val, attribute) {
10
61
  return val ? 'on' : 'off';
11
62
  } else if (type === 'binary_sensor') {
12
63
  return val ? 'on' : 'off';
13
- } else if (typeof val === 'number' && entity.attributes && ['timestamp'].includes(entity.attributes.device_class)) {
14
- return val; //do not convert timestamps.
64
+ } else if (typeof val === 'number' && entity.attributes && (numericDeviceClassesIob.includes(entity.attributes.device_class) || entity.attributes.unit_of_measurement)) {
65
+ return val; //do not convert timestamps or values that have a unit of measurement..
15
66
  } else if (typeof val === 'number' && entity.attributes && ['date'].includes(entity.attributes.device_class)) {
16
- return new Date(val).toDateString(); //convert to date string
67
+ const dateStr = new Date(val).toDateString(); //convert to date string
68
+ return dateStr === 'Invalid Date' ? 'unknown' : dateStr;
17
69
  } else if (type === 'lock') {
18
70
  return val ? 'unlocked' : 'locked';
19
71
  } else if (typeof val === 'boolean' && type !== 'media_player') {
@@ -446,22 +446,28 @@ function updateTimestamps(entity, state) {
446
446
  }
447
447
 
448
448
  try {
449
- new Date(lc).getTime();
449
+ const ts = new Date(lc).getTime();
450
+ if (isNaN(ts)) {
451
+ throw 'Invalid Date';
452
+ }
450
453
  } catch (e) {
451
454
  entityData.adapter.log.debug('Invalid lc time for ' + state._id + ' in ' + entity.entity_id + ': ' + e);
452
455
  lc = Date.now();
453
456
  }
454
457
  try {
455
- new Date(lu).getTime();
458
+ const ts = new Date(lc).getTime();
459
+ if (isNaN(ts)) {
460
+ throw 'Invalid Date';
461
+ }
456
462
  } catch (e) {
457
463
  entityData.adapter.log.debug('Invalid lu time for ' + state._id + ' in ' + entity.entity_id + ': ' + e);
458
464
  lu = Date.now();
459
465
  }
460
466
 
461
- if (lc / 1000 > entity.last_changed) {
467
+ if (lc / 1000 > entity.last_changed || isNaN(entity.last_changed) || new Date(entity.last_changed * 1000).toString() === 'Invalid Date') {
462
468
  entity.last_changed = lc / 1000;
463
469
  }
464
- if (lu / 1000 > entity.last_updated) {
470
+ if (lu / 1000 > entity.last_updated || isNaN(entity.last_updated) || new Date(entity.last_updated * 1000).toString() === 'Invalid Date') {
465
471
  entity.last_updated = lu / 1000;
466
472
  }
467
473
  }
@@ -1,18 +1,5 @@
1
1
  const iobState2EntityState = require('../converters/genericConverter').iobState2EntityState;
2
-
3
- /**
4
- * convert .ts of state e to ISOString with try/catch and now as fallback.
5
- * @param {ioBroker.state} e
6
- * @returns {string}
7
- * @private
8
- */
9
- function _convertStateTStoISOString(e) {
10
- try {
11
- return new Date(e.ts).toISOString();
12
- } catch (error) {
13
- return new Date().toISOString();
14
- }
15
- }
2
+ const updateTimestamps = require('../entities/utils').updateTimestamps;
16
3
 
17
4
  /**
18
5
  * getHistory from history instances.
@@ -62,8 +49,16 @@ async function getHistory(adapter, entities, start, end, noAttributes, user) {
62
49
  }
63
50
  }
64
51
 
65
- //match attributes to states by ts:
66
- const getAttributeValues = (ts, attributesResult, attributesUsed = [], attributeValues = {}) => {
52
+ /**
53
+ * match attributes to states by ts:
54
+ * @param state {ioBroker.State}
55
+ * @param attributesResult
56
+ * @param attributesUsed
57
+ * @param attributeValues
58
+ * @returns {{}}
59
+ */
60
+ const getAttributeValues = (state, attributesResult, attributesUsed = [], attributeValues = {}) => {
61
+ const ts = state.ts;
67
62
  if (entity.context.ATTRIBUTES) {
68
63
  for (const attribute of entity.context.ATTRIBUTES) {
69
64
  if (attributesUsed.indexOf(attribute.attribute) >= 0) {
@@ -75,7 +70,7 @@ async function getHistory(adapter, entities, start, end, noAttributes, user) {
75
70
  const results = attributesResult[attribute.attribute].result;
76
71
  for (const result of results) {
77
72
  if (result.val !== null) {
78
- const diff = Math.abs(result.ts - new Date(ts).getTime());
73
+ const diff = Math.abs(result.ts - ts);
79
74
  if (diff < bestDiff) {
80
75
  best = result;
81
76
  bestDiff = diff;
@@ -104,16 +99,16 @@ async function getHistory(adapter, entities, start, end, noAttributes, user) {
104
99
  const attributesUsed = [];
105
100
  for (const e of stateResult.result) {
106
101
  if (e.val !== null) {
107
- const ts = _convertStateTStoISOString(e);
108
102
  const result = {
109
103
  entity_id: entity.entity_id,
110
104
  state: typeof entity.context.STATE.historyParser === 'function' ?
111
105
  entity.context.STATE.historyParser(id, e.val).toString() :
112
106
  iobState2EntityState(entity, e.val).toString(),
113
- last_changed: ts,
114
- last_updated: ts,
115
- attributes: getAttributeValues(ts, attributesResult, attributesUsed)
107
+ last_changed: 0,
108
+ last_updated: 0,
109
+ attributes: getAttributeValues(e, attributesResult, attributesUsed)
116
110
  };
111
+ updateTimestamps(result, e);
117
112
  arr.push(result);
118
113
  }
119
114
  }
@@ -125,17 +120,17 @@ async function getHistory(adapter, entities, start, end, noAttributes, user) {
125
120
  for (const result of results) {
126
121
  if (result.val !== null && !result.used) {
127
122
  const attributeValues = {};
128
- const ts = _convertStateTStoISOString(result);
129
123
  attributeValues[attribute.attribute] = typeof attribute.historyParser === 'function' ? attribute.historyParser(id, result.val) : result.val;
130
124
  result.used = true;
131
125
  //fill in other attributes:
132
126
  const data = {
133
127
  entity_id: entity.entity_id,
134
128
  //state: null,
135
- last_changed: ts,
136
- last_updated: ts,
137
- attributes: getAttributeValues(ts, attributesResult, attributesUsed, attributeValues)
129
+ last_changed: 0,
130
+ last_updated: 0,
131
+ attributes: getAttributeValues(result, attributesResult, attributesUsed, attributeValues)
138
132
  };
133
+ updateTimestamps(data, result);
139
134
  arr.push(data);
140
135
  }
141
136
  }
@@ -174,8 +169,8 @@ function convertHistoryResultToWebsocketApi(entities, result) {
174
169
  const entityHistoryState = {
175
170
  s: res.state,
176
171
  a: res.attributes,
177
- lc: new Date(res.last_changed).getTime() / 1000,
178
- lu: new Date(res.last_updated).getTime() / 1000
172
+ lc: res.last_changed, //changed that already in old code.
173
+ lu: res.last_updated
179
174
  };
180
175
  entityHistoryStates.push(entityHistoryState);
181
176
  }
package/lib/server.js CHANGED
@@ -31,6 +31,7 @@ const entityData = require('./dataSingleton');
31
31
  const bindings = require('./bindings');
32
32
  const getFriendlyName = require('./entities/friendly_name').getFriendlyName;
33
33
  const iobState2EntityState = require('./converters/genericConverter').iobState2EntityState;
34
+ const NUMERIC_DEVICE_CLASSES = require('./converters/genericConverter').numericDeviceClasses;
34
35
  const HistoryModule = require('./modules/history');
35
36
  const ConversationModule = require('./modules/conversation');
36
37
  const LogbookModule = require('./modules/logbook');
@@ -918,17 +919,16 @@ class WebServer {
918
919
  }
919
920
  entityHome.attributes.latitude = parseFloat(this.systemConfig.latitude);
920
921
  entityHome.attributes.longitude = parseFloat(this.systemConfig.longitude);
921
- entityHome.last_changed = this.systemConfig.ts;
922
- entityHome.last_updated = this.systemConfig.ts;
922
+ entityHome.last_changed = (this.systemConfig.ts || Date.now()) / 1000;
923
+ entityHome.last_updated = (this.systemConfig.ts || Date.now()) / 1000;
923
924
 
924
925
  //shoppindlist:
925
- let entityShoppingList = entityData.entityId2Entity['todo.shoppinglist'];
926
+ /*let entityShoppingList = entityData.entityId2Entity['todo.shoppinglist'];
926
927
  if (!entityShoppingList) {
927
928
  entityShoppingList = {
928
929
  'entity_id': 'todo.shoppinglist',
929
930
  'state': 'unknown',
930
931
  'attributes': {
931
- 'hidden': true,
932
932
  'friendly_name': 'Shopping List',
933
933
  'icon': 'mdi:cart'
934
934
  },
@@ -940,7 +940,7 @@ class WebServer {
940
940
  };
941
941
  entityData.entities.push(entityShoppingList);
942
942
  entityData.entityId2Entity[entityShoppingList.entity_id] = entityShoppingList;
943
- }
943
+ }*/
944
944
  }
945
945
 
946
946
  /**
@@ -2473,6 +2473,9 @@ class WebServer {
2473
2473
  };
2474
2474
  ws.send(JSON.stringify(t));
2475
2475
  });
2476
+ } else if (message.type === 'sensor/numeric_device_classes') {
2477
+ //it seems frontend now asks backend for what device_classes are numeric. Ok. Let's use that. ;-)
2478
+ this._sendResponse(ws, message.id, { numeric_device_classes: NUMERIC_DEVICE_CLASSES });
2476
2479
  } else if (message.type.startsWith('browser_mod')) {
2477
2480
  await this._browserMod.processBrowserModMessage(ws, message);
2478
2481
  } else if (message.type.startsWith('history/')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lovelace",
3
- "version": "4.0.4",
3
+ "version": "4.0.6",
4
4
  "description": "With this adapter you can build visualization for ioBroker with Home Assistant Lovelace UI",
5
5
  "author": {
6
6
  "name": "bluefox",