iobroker.e3oncan 0.6.10 → 0.6.13

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
@@ -40,18 +40,18 @@ A scan for datapoints of each device is also available and should be done during
40
40
  All services provided by this adapter are based on device list of your specific Viessmann E3 setup. Therefore you have to follow following steps for first setup:
41
41
 
42
42
  **Configuration**
43
- * When installation od adapter has finished a confuration dialog will show up to configure up to two CAN bus adapters (tab "CAN ADAPTER")
43
+ * When installation of adapter has finished a confuration dialog will show up to configure up to two CAN bus adapters (tab "CAN ADAPTER")
44
44
  * Edit name of adapter and check the "Connect to adapter" checkbox at least the external adapter
45
- * When you're done, press "SAVE" button to apply the changes. This step is **mandatory**. The instance will restart, connect to the CAN adapter and do a scan for devices available on bus. **Please be patient** - this may take up to 20 seconds. You may watch the activities in a 2nd browser tab by looking on the logging info of the adapter.
46
- * When scan was successful new tabs will get visible in adapter confuration: "LIST OF UDS DEVICES", "LIST OF DATAPOINTS" and "ASSIGNMENTS TO EXTERNAL CAN ADAPTER".
47
- * Go to the "LIST OF UDS DEVICES" and check the list of devices. You may change the naming on 2nd column. Those names will be used to store all collected data in ioBoker's object tree. Again press "SAVE" button when you did your changes. Again this step is **mandatory**.
48
- * Instance will restart again and after a few seconds you are ready to a scan for available datapoints. Go to tab "LIST OF DATAPOINTS", press button "Start scan ..." and confirm with "OK" to start the scan. Again, **please be patient** - this may take **up to 5 minutes**. You may watch the progress in a 2nd browser tab by looking on the logging info of the adapter.
45
+ * When you're done, press "SAVE" button to apply the changes. This step is **mandatory**. The instance will restart and connect to the CAN adapter.
46
+ * Go to tab "LIST OF UDS DEVICES" and do a scan for devices available on bus by pressing the scan button. **This will take a few seconds.** You may watch the activities in a 2nd browser tab by looking on the logging info of the adapter.
47
+ * You may change the naming of the devices at 2nd column. Those names will be used to store all collected data in ioBoker's object tree. Again press "SAVE" button when you did your changes.
48
+ * Instance will restart again and after a few seconds you are ready to do a scan for available datapoints. Go to tab "LIST OF DATAPOINTS", press button "Start scan ..." and confirm with "OK". **Please be patient** - this may take **up to 5 minutes**. You may watch the progress in a 2nd browser tab by looking on the logging info of the adapter.
49
49
  This step is not mandatory but strongly recomended. If you would like to write to datapoints you need to do a datapoint scan first.
50
- * When datapoint scan was completed successfully, the datapoints are available in object tree for each device. You may view the datapoints in configuration by selecting a device and pressing button "Update list of datapoints". Press filter symbol and type search pattern to filter for name and/or codec. This is for your information only. Please deactivate filtering before selecting another device to avoid error messages.
50
+ * When datapoint scan was completed successfully, the datapoints are available in the object tree for each device. You may view the datapoints in configuration by selecting a device and pressing button "Update list of datapoints". Press filter symbol and type search pattern to filter for name and/or codec. This is for your information only. Please deactivate filtering before selecting another device to avoid error messages.
51
51
  * Last step is to configure schedules for collecting data on tab "ASSIGNMENTS TO EXTERNAL CAN ADAPTER".
52
52
  * For **energy meter E380** (if available in your setup) you just can activate or not. Please notice the value "Min. update time (s)". Updates to single datapoints are done no faster than the given value (default is 5 seconds). By choosing zero every received data will be stored. Since E380 is sending data very fast (more than 20 values per second), it's recommended not to use zero here. This would put a high load on the ioBroker system.
53
53
  * If you have connected E3 devices via CAN bus, e.g. Vitocal and VX3, you can collect data exchanged between those devices in realtime by listening. Press "+" to add a line, check "active" chackbox, select a device and edit "Min. update time (s)". It's feasable to use 0s here, however, I recommend to keep to the 5s.
54
- * Finally, you may add schedules for requesting data via UDSonCAN protocol. Again press "+" button and edit the setting. You may have several schedules with different (!) timings. By this you can request some datapoints more often than others. Default value of 0 for "Schedule (s)" means, those datapoints will be requested just once during startup of the instance.
54
+ * Finally, you may add schedules for requesting data via UDSonCAN protocol. Again press "+" button and edit the settings. You may have several schedules on each device. By this you can request some datapoints more often than others. Default value of 0 for "Schedule (s)" means, those datapoints will be requested just once during startup of the instance.
55
55
  You may use datapoints informations on tab "LIST OF DATAPOINTS" for reference (opening on 2nd tab could help).
56
56
  * If you have configured a CAN adapter connected to the **internal CAN bus**, a tab "ASSIGNMENTS TO INTERNAL CAN ADAPTER" is visible. Please configure the devices for colletion there. UDSonCAN is not supported on internal CAN bus by E3 devices.
57
57
  * That's it. Press "SAVE & CLOSE" button and check the data collected in object tree.
@@ -81,15 +81,14 @@ You may use datapoints informations on tab "LIST OF DATAPOINTS" for reference (o
81
81
  * Therfore from my point of view, combination of both methods is best approach.
82
82
 
83
83
  ## Limitation of collecting data
84
- * At present, the communication protocol is known only for Vitocal (listener on CAN id 0x693) and Vitocharge VX3 (listener on CAN id 0x451).
84
+ * At present, the communication protocol is known only for Vitocal (listener on CAN id 0x693), Vitocharge VX3 and Vitoair (both listener on CAN id 0x451).
85
85
 
86
86
  ## What is different to open3e project?
87
- * Obviously, the main differece is the direct integration to ioBroker. Configuration can be done via dialogs, data get's directly listed in object tree.
88
- * **WriteByDid is supported for all data types** but restricted to datapoints on device specific white list, see info section of device. You need to do a datapoint scan to enable writing. Writing of data is triggered by storing the datapoint with ack=false - yes, it's that simple! The datapoint will be read again from device two seconds after writing. If datapoint not get's acknowledged, please take a look to the logs.
89
- * A scan for datapoints per device (as depict tool of open3e is doing) is available now. After a successful scan, device specific datapoints are listed in object tree.
90
- * In addation to open3e real time collecting of data via listening is supported.
87
+ * Obviously, the main differece is the direct integration to ioBroker. Configuration can be done via dialogs, data get's directly listed in object trees.
88
+ * **WriteByDid is supported for all data types** but restricted to datapoints on device specific white list, see info section of devices. You need to do a datapoint scan to enable writing. Writing of data is triggered by storing the datapoint with ack=false - yes, it's that simple! The datapoint will be read again from device two seconds after writing. If datapoint not get's acknowledged, please take a look to the logs.
89
+ * In addition to open3e real time collecting of data via listening is supported.
91
90
 
92
- ## May open3 be used in parallel?
91
+ ## May open3e be used in parallel?
93
92
  Yes, that is possible under certain conditions:
94
93
  * If you only use data collecting here, you can use open3e with no limitiations.
95
94
  * If you use UDSonCAN here, it's important not to do this for the same devices as open3e does. If you would do so, you will have sporadic communications errors.
@@ -99,6 +98,19 @@ Yes, that is possible under certain conditions:
99
98
  Placeholder for the next version (at the beginning of the line):
100
99
  ### **WORK IN PROGRESS**
101
100
  -->
101
+ ### 0.6.13 (2024-01-20)
102
+ * (MyHomeMyData) Now supports multiple definitions of same schedule on a device
103
+ * (MyHomeMyData) Added unit test cases for codecs
104
+
105
+ ### 0.6.12 (2024-01-19)
106
+ * (MyHomeMyData) Added datapoints to list writable dids
107
+ * (MyHomeMyData) Added unit test cases for codecs
108
+ * (MyHomeMyData) Improved speed of codes for numerical values
109
+ * (MyHomeMyData) Improved error messages on UDS negative response
110
+
111
+ ### 0.6.11 (2024-01-17)
112
+ * (MyHomeMyData) Improved layout of configuration dialog for device scan
113
+
102
114
  ### 0.6.10 (2024-01-15)
103
115
  * (MyHomeMyData) Removed code for Rawmode because it's never activated
104
116
 
@@ -56,5 +56,6 @@
56
56
  "Separate by comma! All given datapoints will be requested with specified schedule and ECU address.": "Durch Komma trennen! Alle angegebenen Datenpunkte werden mit der angegebenen Wiederholungszeit von der ECU-Adresse angefordert.",
57
57
  "Assignments to Internal CAN Adapter": "Zuordnungen zum internen CAN-Adapter",
58
58
  "Collecting Data on Internal CAN Adapter": "Sammeln von Daten auf dem internen CAN-Adapter",
59
- "Update list of datapoints": "Liste der Datenpunkte aktualisieren"
59
+ "Update list of datapoints": "Liste der Datenpunkte aktualisieren",
60
+ "Start scan to update list of devices": "Scan starten, um die Liste der UDS-Geräte zu aktualisieren"
60
61
  }
@@ -56,5 +56,6 @@
56
56
  "Separate by comma! All given datapoints will be requested with specified schedule and ECU address.":"Separate by comma! All given datapoints will be requested with specified schedule and ECU address.",
57
57
  "Assignments to Internal CAN Adapter":"Assignments to Internal CAN Adapter",
58
58
  "Collecting Data on Internal CAN Adapter":"Collecting Data on Internal CAN Adapter",
59
- "Update list of datapoints":"Update list of datapoints"
59
+ "Update list of datapoints":"Update list of datapoints",
60
+ "Start scan to update list of devices":"Start scan to update list of devices"
60
61
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Recopilación de datos en el adaptador CAN interno",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Escuche los datos sobre las direcciones que figuran en esta tabla. No se puede escribir en el bus CAN.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Dispositivos para la recogida de datos. No se puede escribir en el bus CAN. Presione '+' para agregar el dispositivo.",
61
- "Update list of datapoints": "Actualizar lista de puntos de datos"
61
+ "Update list of datapoints": "Actualizar lista de puntos de datos",
62
+ "Start scan to update list of devices": "Iniciar escaneo para actualizar la lista de dispositivos"
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Collecte de données sur l'adaptateur CAN interne",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Écoutez les données sur les adresses indiquées dans ce tableau. Pas d'écriture sur le bus CAN.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Appareils de collecte de données. Pas d'écriture sur le bus CAN. Appuyez sur « + » pour ajouter un appareil.",
61
- "Update list of datapoints": "Mettre à jour la liste des points de données"
61
+ "Update list of datapoints": "Mettre à jour la liste des points de données",
62
+ "Start scan to update list of devices": "Démarrer l'analyse pour mettre à jour la liste des appareils"
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Raccolta dati sull'adattatore CAN interno",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Ascoltare i dati sugli indirizzi forniti in questa tabella. Nessuna scrittura sul bus CAN.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Dispositivi per la raccolta dei dati. Nessuna scrittura sul bus CAN. Premi \"+\" per aggiungere il dispositivo.",
61
- "Update list of datapoints": "Aggiorna l'elenco dei punti dati"
61
+ "Update list of datapoints": "Aggiorna l'elenco dei punti dati",
62
+ "Start scan to update list of devices": "Avvia la scansione per aggiornare l'elenco dei dispositivi"
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Gegevens verzamelen over de interne CAN-adapter",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Luister naar gegevens over adressen in deze tabel. Geen schrijven naar CAN-bus.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Apparaten voor het verzamelen van gegevens. Geen schrijven naar CAN-bus. Druk op '+' om apparaat toe te voegen.",
61
- "Update list of datapoints": "Lijst met datapunten bijwerken"
61
+ "Update list of datapoints": "Lijst met datapunten bijwerken",
62
+ "Start scan to update list of devices": "Start de scan om de lijst met apparaten bij te werken"
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Zbieranie danych na wewnętrznym adapterze CAN",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Posłuchaj danych o adresach podanych w tej tabeli. Brak zapisu do magistrali CAN.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Urządzenia do gromadzenia danych. Brak zapisu do magistrali CAN. Naciśnij „+”, aby dodać urządzenie.",
61
- "Update list of datapoints": "Zaktualizuj listę punktów danych"
61
+ "Update list of datapoints": "Zaktualizuj listę punktów danych",
62
+ "Start scan to update list of devices": "Rozpocznij skanowanie, aby zaktualizować listę urządzeń"
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Coletando dados no adaptador CAN interno",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Ouça os dados sobre os endereços fornecidos nesta tabela. Não há gravação no barramento CAN.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Dispositivos para coleta de dados. Não há gravação no barramento CAN. Pressione '+' para adicionar dispositivo.",
61
- "Update list of datapoints": "Atualizar lista de pontos de dados"
61
+ "Update list of datapoints": "Atualizar lista de pontos de dados",
62
+ "Start scan to update list of devices": "Inicie a verificação para atualizar a lista de dispositivos"
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Сбор данных о внутреннем CAN-адаптере",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Прослушайте данные по адресам, указанным в этой таблице. Нет записи в CAN-шину.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Устройства для сбора данных. Нет записи в CAN-шину. Нажмите «+», чтобы добавить устройство.",
61
- "Update list of datapoints": "Обновить список точек данных"
61
+ "Update list of datapoints": "Обновить список точек данных",
62
+ "Start scan to update list of devices": "Запустите сканирование, чтобы обновить список устройств."
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "Збір даних про внутрішній адаптер CAN",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "Прослухайте дані за адресами, наведені в цій таблиці. Немає запису на шину CAN.",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "Пристрої для збору даних. Немає запису на шину CAN. Натисніть «+», щоб додати пристрій.",
61
- "Update list of datapoints": "Оновити список точок даних"
61
+ "Update list of datapoints": "Оновити список точок даних",
62
+ "Start scan to update list of devices": "Почніть сканування, щоб оновити список пристроїв"
62
63
  }
@@ -58,5 +58,6 @@
58
58
  "Collecting Data on Internal CAN Adapter": "收集内部 CAN 适配器的数据",
59
59
  "Listen for data on addresses given in this table. No writing to CAN bus.": "侦听此表中给出的地址上的数据。不写入 CAN 总线。",
60
60
  "Devices for collecting data. No writing to CAN bus. Press '+' to add device.": "用于收集数据的设备。不写入 CAN 总线。按“+”添加设备。",
61
- "Update list of datapoints": "更新数据点列表"
61
+ "Update list of datapoints": "更新数据点列表",
62
+ "Start scan to update list of devices": "开始扫描以更新设备列表"
62
63
  }
@@ -99,15 +99,6 @@
99
99
  "hidden": "if ((data.tableUdsDevices) && (data.tableUdsDevices.length > 0)) { return true; } else {return false; }",
100
100
  "newLine": true
101
101
  },
102
- "introTableScanIsActiveTxt": {
103
- "type": "staticText",
104
- "text": "UDS device scan is ongoing. This may take up to 20 seconds.",
105
- "newLine": true,
106
- "hidden": "if ((data.tableUdsDevices) && (data.tableUdsDevices.length > 0)) { return true; } else {return false; }",
107
- "style": {
108
- "color": "red"
109
- }
110
- },
111
102
  "introTableNoEmptyDevNameTxt": {
112
103
  "type": "staticText",
113
104
  "text": "'Device state name' must not be blank!",
@@ -126,11 +117,23 @@
126
117
  "color": "red"
127
118
  }
128
119
  },
120
+ "tableUdsDevicesButton": {
121
+ "type": "sendTo",
122
+ "label": "Start scan to update list of devices",
123
+ "variant": "outlined",
124
+ "showProcess": true,
125
+ "command": "getUdsDevices",
126
+ "jsonData": "{}",
127
+ "useNative": true,
128
+ "hidden": "!_alive",
129
+ "newLine": true,
130
+ "sm": 12,
131
+ "md": 12,
132
+ "lg": 12
133
+ },
129
134
 
130
135
  "tableUdsDevices": {
131
136
  "type": "table",
132
- "defaultSendTo": "getUdsDevices",
133
- "jsonData": "${JSON.stringify(data.tableUdsDevices)}",
134
137
  "uniqueColumns": ["devStateName"],
135
138
  "newLine": true,
136
139
  "sm": 12,
@@ -206,9 +209,6 @@
206
209
  "label": "Start scan for datapoints of all devices",
207
210
  "variant": "outlined",
208
211
  "showProcess": true,
209
- "style": {
210
- "align": "right"
211
- },
212
212
  "jsonData": "{}",
213
213
  "command": "startDidScan",
214
214
  "confirm": {
package/io-package.json CHANGED
@@ -1,8 +1,47 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "e3oncan",
4
- "version": "0.6.10",
4
+ "version": "0.6.13",
5
5
  "news": {
6
+ "0.6.13": {
7
+ "en": "Now supports multiple definitions of same schedule on a device \nAdded unit test cases for codecs",
8
+ "de": "Jetzt unterstützt mehrere Definitionen desselben Zeitplans auf einem Gerät\nHinzugefügte Einheit Testfälle für Codecs",
9
+ "ru": "Теперь поддерживает несколько определений одного и того же расписания на устройстве\n4.1.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.1.2.1.2.1.1.2.1.1.2.1.1.1.1.1.2.1.1.1.1.1.1.1.1.2.2.1.1.1.1.1.2.1.1.1.1.1.1.1.2.2.2.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.2.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1",
10
+ "pt": "Agora suporta várias definições da mesma programação em um dispositivo\nAdicionados casos de teste de unidade para codecs",
11
+ "nl": "Nu ondersteunt meerdere definities van hetzelfde schema op een apparaat\nToegevoegde testcases per eenheid voor codecs",
12
+ "fr": "Maintenant prend en charge plusieurs définitions de même horaire sur un appareil\nAjout de cas de test unitaire pour codecs",
13
+ "it": "Ora supporta più definizioni dello stesso programma su un dispositivo\nAggiunti casi di prova unità per codecs",
14
+ "es": "Ahora soporta múltiples definiciones del mismo horario en un dispositivo\nCasos de prueba de unidad adicionales para codecs",
15
+ "pl": "Teraz obsługuje wiele definicji tego samego harmonogramu na urządzeniu\nDodano jednostkowe przypadki badań kodeków",
16
+ "uk": "Тепер підтримує декілька визначень одного графіка на пристрої\nДодані випадки тестування блоку для кодеків",
17
+ "zh-cn": "现在支持设备上同一时刻表的多个定义\n为解码器添加单位测试例"
18
+ },
19
+ "0.6.12": {
20
+ "en": "Added datapoints to list writable dids\nAdded unit test cases for codecs\nImproved speed of codes for numerical values\nImproved error messages on UDS negative response",
21
+ "de": "Datenpunkte zur Liste der schreibbaren Dossiers hinzugefügt\nHinzugefügte Einheit Testfälle für Codecs\nVerbesserte Geschwindigkeit von Codes für Zahlenwerte\nVerbesserte Fehlermeldungen auf UDS negative Antwort",
22
+ "ru": "Добавлены точки данных в список значимых дел\n4.1.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.1.2.1.2.1.1.2.1.1.2.1.1.1.1.1.2.1.1.1.1.1.1.1.1.2.2.1.1.1.1.1.2.1.1.1.1.1.1.1.2.2.2.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.2.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1\nПовышение скорости кодов для численных значений\nУлучшенные сообщения об ошибках в негативном ответе на СОД",
23
+ "pt": "Adicionado datapoints para lista writable dids\nAdicionados casos de teste de unidade para codecs\nVelocidade melhorada de códigos para valores numéricos\nMensagens de erro melhoradas na resposta negativa do UDS",
24
+ "nl": "Toegevoegd datapunten aan lijst schrijfbare does\nToegevoegde testcases per eenheid voor codecs\nVerbeterde snelheid van codes voor numerieke waarden\nVerbeterde foutmeldingen op UDS-negatieve reactie",
25
+ "fr": "Ajout de points de données pour lister les dids en écriture\nAjout de cas de test unitaire pour codecs\nAmélioration de la vitesse des codes pour les valeurs numériques\nMessages d'erreur améliorés sur la réponse négative UDS",
26
+ "it": "Aggiunti i datapoints per elencare i fatti scrivibili\nAggiunti casi di prova unità per codecs\nVelocità migliorata dei codici per i valori numerici\nMessaggi di errore migliorati sulla risposta negativa UDS",
27
+ "es": "Puntos de datos añadidos a la lista de hechos\nCasos de prueba de unidad adicionales para codecs\nMejora de la velocidad de los códigos para los valores numéricos\nMensajes de error mejorados en respuesta negativa UDS",
28
+ "pl": "Dodano punkty danych do listy zapisanych didów\nDodano jednostkowe przypadki badań kodeków\nZwiększona prędkość kodów dla wartości numerycznych\nUlepszone komunikaty błędów w odpowiedzi negatywnej UDS",
29
+ "uk": "Додано точки даних для списання збитих даних\nДодані випадки тестування блоку для кодеків\nПокращена швидкість кодів для чисельних значень\nПокращуйте повідомлення про помилки у UDS",
30
+ "zh-cn": "添加数据点到列表可写作的\n为解码器添加单位测试例\n数字值代码速度提高\nUDS 负面响应上改进错误信息"
31
+ },
32
+ "0.6.11": {
33
+ "en": "Improved layout of configuration dialog for device scan",
34
+ "de": "Verbessertes Layout des Konfigurationsdialogs für den Gerätescan",
35
+ "ru": "Улучшен диалог настройки для сканирования устройства",
36
+ "pt": "Melhor layout da caixa de diálogo de configuração para verificação do dispositivo",
37
+ "nl": "Verbeterde lay-out van configuratiedialoog voor apparaatscans",
38
+ "fr": "Mise en page améliorée de la boîte de dialogue de configuration pour l'analyse des périphériques",
39
+ "it": "Miglioramento del layout della finestra di dialogo di configurazione per la scansione del dispositivo",
40
+ "es": "Diseño mejorado del diálogo de configuración para el análisis del dispositivo",
41
+ "pl": "Ulepszony układ okna konfiguracji skanowania urządzenia",
42
+ "uk": "Покращений макет діалогу конфігурації для сканування пристроїв",
43
+ "zh-cn": "设备扫描配置对话框的改进版式"
44
+ },
6
45
  "0.6.10": {
7
46
  "en": "Removed code for Rawmode because it's never activated",
8
47
  "de": "Entfernter Code für Rawmode, weil es nie aktiviert ist",
package/lib/canUds.js CHANGED
@@ -1,11 +1,11 @@
1
1
  const storage = require('./storage');
2
2
 
3
3
  class scheduleLoop {
4
- constructor(ctxGlobal, ctxLocal, schedule, dids) {
4
+ constructor(ctxGlobal, ctxLocal, schedule) {
5
5
  this.ctxGlobal = ctxGlobal;
6
6
  this.ctxLocal = ctxLocal;
7
7
  this.schedule = schedule;
8
- this.dids = dids;
8
+ this.dids = [];
9
9
  this.schedHandle = null;
10
10
  }
11
11
 
@@ -30,6 +30,11 @@ class scheduleLoop {
30
30
  }
31
31
  }
32
32
 
33
+ async addDids(dids) {
34
+ const didsArr = dids.replace(' ','').split(',');
35
+ this.dids = this.dids.concat(didsArr.map(function(str) { return parseInt(str); }));
36
+ }
37
+
33
38
  async loop() {
34
39
  await this.ctxGlobal.log.silly('UDS schedule: '+String(this.schedule)+' '+this.ctxLocal.canIDhex+'.'+JSON.stringify(this.dids));
35
40
  await this.ctxLocal.pushCmnd(this.ctxGlobal, 'read', this.dids);
@@ -244,13 +249,13 @@ class uds {
244
249
  }
245
250
 
246
251
  async addSchedule(ctx, schedule, dids) {
247
- if (!Object.keys(this.schedules).includes(schedule)) {
248
- const didsArr = dids.replace(' ','').split(',');
249
- this.schedules[schedule] = new scheduleLoop(ctx, this, schedule, didsArr.map(function(str) { return parseInt(str); }));
250
- ctx.log.silly('UDS worker on '+this.config.stateBase+': Added schedule '+String(schedule)+'s '+JSON.stringify(didsArr));
251
- } else {
252
- ctx.log.warn('UDS worker warning on '+this.config.stateBase+': Multiple definiton of schedule:'+String(schedule)+'s');
252
+ if (!Object.keys(this.schedules).includes(String(schedule))) {
253
+ // New schedule
254
+ this.schedules[schedule] = new scheduleLoop(ctx, this, schedule);
255
+ await ctx.log.silly('UDS worker on '+this.config.stateBase+': Added schedule '+String(schedule)+'s.');
253
256
  }
257
+ await this.schedules[schedule].addDids(dids);
258
+ await ctx.log.silly('UDS worker on '+this.config.stateBase+': Added dids to schedule '+String(schedule)+'s '+JSON.stringify(this.schedules[schedule].dids));
254
259
  }
255
260
 
256
261
  async pushCmnd(ctx, mode, dids) {
@@ -536,7 +541,7 @@ class uds {
536
541
  if (this.callback) {
537
542
  this.callback(ctx, this, ['negative response', {'did':this.data.did,'didInfo':{'id':'','len':0},'val':''}]);
538
543
  } else {
539
- ctx.log.error('UDS worker error on '+this.config.stateBase+': Negative response on device '+this.canIDhex+'. Code=0x'+Number(candata[3]).toString(16));
544
+ ctx.log.error('UDS worker error on '+this.config.stateBase+': Negative response reading did '+String(this.data.did)+'. Code=0x'+Number(candata[3]).toString(16));
540
545
  }
541
546
  await this.setDidDone(0);
542
547
  break;
@@ -634,7 +639,7 @@ class uds {
634
639
  if ( (candata[0] == 0x03) && (candata[1] == 0x7F) && (candata[2] == this.writeByDidProt.SIDtx) ) {
635
640
  // Negative response
636
641
  this.stat.cntCommNR += 1;
637
- ctx.log.error('UDS worker error on '+this.config.stateBase+': Negative response on device '+this.canIDhex+'. Code=0x'+Number(candata[3]).toString(16));
642
+ ctx.log.error('UDS worker error on '+this.config.stateBase+': Negative response writing did '+String(this.data.did)+'. Code=0x'+Number(candata[3]).toString(16));
638
643
  await this.setDidDone(0);
639
644
  break;
640
645
  }
@@ -669,7 +674,7 @@ class uds {
669
674
  if ( (candata[0] == 0x03) && (candata[1] == 0x7F) && (candata[2] == this.writeByDidProt.SIDtx) ) {
670
675
  // Negative response
671
676
  this.stat.cntCommNR += 1;
672
- ctx.log.error('UDS worker error on '+this.config.stateBase+': Negative response on device '+this.canIDhex+'. Code=0x'+Number(candata[3]).toString(16));
677
+ ctx.log.error('UDS worker error on '+this.config.stateBase+': Negative response writing did '+String(this.data.did)+'. Code=0x'+Number(candata[3]).toString(16));
673
678
  await this.setDidDone(0);
674
679
  break;
675
680
  }
package/lib/codecs.js CHANGED
@@ -1,6 +1,13 @@
1
1
 
2
2
  const enums = require('./enums');
3
3
 
4
+ const C2POW08 = 0x100;
5
+ const C2POW15 = 0x08000;
6
+ const C2POW16 = 0x10000;
7
+ const C2POW24 = 0x1000000;
8
+ const C2POW31 = 0x080000000;
9
+ const C2POW32 = 0x100000000;
10
+
4
11
  function arr2Hex(arr) {
5
12
  // Convert byte array to hex string
6
13
  let hs = '';
@@ -31,22 +38,22 @@ function sint08toVal(j, ofs=0) {
31
38
  }
32
39
 
33
40
  function uint16toVal(j, ofs=0) {
34
- return Math.pow(2,8)*j[ofs+1]+j[ofs];
41
+ return C2POW08*j[ofs+1]+j[ofs];
35
42
  }
36
43
 
37
44
  function sint16toVal(j, ofs=0) {
38
- let v = Math.pow(2,8)*j[ofs+1]+j[ofs];
39
- if (v >= Math.pow(2,15)) { v -= Math.pow(2,16); }
45
+ let v = C2POW08*j[ofs+1]+j[ofs];
46
+ if (v >= C2POW15) { v -= C2POW16; }
40
47
  return v;
41
48
  }
42
49
 
43
50
  function uint32toVal(j, ofs=0) {
44
- return Math.pow(2,24)*j[ofs+3]+Math.pow(2,16)*j[ofs+2]+Math.pow(2,8)*j[ofs+1]+j[ofs];
51
+ return C2POW24*j[ofs+3]+C2POW16*j[ofs+2]+C2POW08*j[ofs+1]+j[ofs];
45
52
  }
46
53
 
47
54
  function sint32toVal(j, ofs=0) {
48
- let v = Math.pow(2,24)*j[ofs+3]+Math.pow(2,16)*j[ofs+2]+Math.pow(2,8)*j[ofs+1]+j[ofs];
49
- if (v >= Math.pow(2,31)) { v -= Math.pow(2,32); }
55
+ let v = C2POW24*j[ofs+3]+C2POW16*j[ofs+2]+C2POW08*j[ofs+1]+j[ofs];
56
+ if (v >= C2POW31) { v -= C2POW32; }
50
57
  return v;
51
58
  }
52
59
 
@@ -67,7 +74,7 @@ function int2val(j, ofs = 0, signed = false) {
67
74
  function val2byteArr(v, byte_width, scale = 1, signed = false) {
68
75
  // Convert int08, int16, int32 to byte array. Signed or unsigned.
69
76
  let val = Math.round(eval(v) * scale);
70
- if ( (signed) && (val < 0) ) { val += Math.pow(2,8*byte_width); }
77
+ if ( (signed) && (val < 0) ) { val += (2**(8*byte_width)); }
71
78
  const string_bin = toByteArray(toHex(val, byte_width*2));
72
79
  return string_bin.reverse();
73
80
  }
@@ -586,5 +593,6 @@ const O3Ecodecs = {
586
593
  module.exports = {
587
594
  O3Ecodecs,
588
595
  arr2Hex,
589
- toByteArray
596
+ toByteArray,
597
+ val2byteArr
590
598
  };
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Tests for codecs
5
+ *
6
+ * It's automatically excluded from npm and its build output is excluded from both git and npm.
7
+ * It is advised to test all your modules with accompanying *.test.js-files
8
+ */
9
+
10
+ // tslint:disable:no-unused-expression
11
+
12
+ const { expect } = require('chai');
13
+ const E3 = require('./codecs');
14
+ const E3DidsDict = require('./didsE3.json');
15
+
16
+ function toByteArray(hs) {
17
+ // Convert hex string, e.g. '21A8' to byte array: [33,168]
18
+ const ba = [];
19
+ for (let i=0; i<hs.length/2; i++) {
20
+ ba.push(parseInt(hs.slice(2*i,2*i+2), 16));
21
+ }
22
+ return ba;
23
+ }
24
+
25
+ function codecDecode(descr, expected, codec, len, id, args, val) {
26
+ it(`${descr} ${JSON.stringify(expected)}`, () => {
27
+ const f = new codec(len,id,args);
28
+ const result = f.decode(val);
29
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
30
+ });
31
+ }
32
+
33
+ function codecEncode(descr, expected, codec, len, id, args, val) {
34
+ it(`${descr} ${JSON.stringify(expected)}`, () => {
35
+ const f = new codec(len,id,args);
36
+ const result = f.encode(val);
37
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
38
+ });
39
+ }
40
+
41
+ // val2byteArray:
42
+ describe('codecs.js => val2byteArr()', () => {
43
+ let val = -1;
44
+ let expected = [0xff];
45
+ it(`sint08 ${JSON.stringify(expected)}`, () => {
46
+ const result = E3.val2byteArr(val, 4, 1, true);
47
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
48
+ });
49
+ val = 2**7-1;
50
+ expected = [0x7f];
51
+ it(`sint08 ${JSON.stringify(expected)}`, () => {
52
+ const result = E3.val2byteArr(val, 4, 1, true);
53
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
54
+ });
55
+ val = -(2**7);
56
+ expected = [0x80];
57
+ it(`sint08 ${JSON.stringify(expected)}`, () => {
58
+ const result = E3.val2byteArr(val, 4, 1, true);
59
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
60
+ });
61
+ val = 2**8-1;
62
+ expected = [0xff];
63
+ it(`uint08 ${JSON.stringify(expected)}`, () => {
64
+ const result = E3.val2byteArr(val, 4, 1, false);
65
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
66
+ });
67
+
68
+ val = -1;
69
+ expected = [0xff,0xff];
70
+ it(`sint16 ${JSON.stringify(expected)}`, () => {
71
+ const result = E3.val2byteArr(val, 4, 1, true);
72
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
73
+ });
74
+ val = 2**15-1;
75
+ expected = [0xff,0x7f];
76
+ it(`sint16 ${JSON.stringify(expected)}`, () => {
77
+ const result = E3.val2byteArr(val, 4, 1, true);
78
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
79
+ });
80
+ val = -(2**15);
81
+ expected = [0x00,0x80];
82
+ it(`sint16 ${JSON.stringify(expected)}`, () => {
83
+ const result = E3.val2byteArr(val, 4, 1, true);
84
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
85
+ });
86
+ val = 2**16-1;
87
+ expected = [0xff,0xff];
88
+ it(`uint16 ${JSON.stringify(expected)}`, () => {
89
+ const result = E3.val2byteArr(val, 4, 1, false);
90
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
91
+ });
92
+
93
+ val = -1;
94
+ expected = [0xff,0xff,0xff,0xff];
95
+ it(`sint32 ${JSON.stringify(expected)}`, () => {
96
+ const result = E3.val2byteArr(val, 4, 1, true);
97
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
98
+ });
99
+ val = 2**31-1;
100
+ expected = [0xff,0xff,0xff,0x7f];
101
+ it(`sint32 ${JSON.stringify(expected)}`, () => {
102
+ const result = E3.val2byteArr(val, 4, 1, true);
103
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
104
+ });
105
+ val = -(2**31);
106
+ expected = [0x00,0x00,0x00,0x80];
107
+ it(`sint32 ${JSON.stringify(expected)}`, () => {
108
+ const result = E3.val2byteArr(val, 4, 1, true);
109
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
110
+ });
111
+ val = 2**32-1;
112
+ expected = [0xff,0xff,0xff,0xff];
113
+ it(`uint32 ${JSON.stringify(expected)}`, () => {
114
+ const result = E3.val2byteArr(val, 4, 1, false);
115
+ expect(JSON.stringify(result)).to.equal(JSON.stringify(expected));
116
+ });
117
+ });
118
+
119
+ // Integer DECODER:
120
+ describe('codecs.js => O3EInt8().decode()', () => {
121
+ codecDecode('Positive Number, scale=10, signed=true ', 5, E3.O3Ecodecs.O3EInt8, 1, 'test1', {scale:10.0,signed:true, offset: 0}, [0x32]);
122
+ codecDecode('Positive Number, scale=10, signed=true ', (2**7-1)/10, E3.O3Ecodecs.O3EInt8, 1, 'test2', {scale:10.0,signed:true, offset: 0}, [0x7f]);
123
+ codecDecode('Negative Number, scale=10, signed=true ', -(2**7)/10, E3.O3Ecodecs.O3EInt8, 1, 'test3', {scale:10.0,signed:true, offset: 0}, [0x80]);
124
+ codecDecode('Negative Number, scale= 1, signed=true ', -5, E3.O3Ecodecs.O3EInt8, 1, 'test4', {scale:1.0, signed:true, offset: 0}, [0xfb]);
125
+ codecDecode('Positive Number, scale=10, signed=false', 25.1, E3.O3Ecodecs.O3EInt8, 1, 'test5', {scale:10.0,signed:false,offset: 0}, [0xfb]);
126
+ });
127
+
128
+ describe('codecs.js => O3EInt16().decode()', () => {
129
+ codecDecode('Positive Number, scale=10, signed=true ', 5, E3.O3Ecodecs.O3EInt16, 2, 'test1', {scale:10.0,signed:true, offset: 0}, [0x32,0x00]);
130
+ codecDecode('Positive Number, scale=10, signed=true ', (2**15-1)/10, E3.O3Ecodecs.O3EInt16, 2, 'test2', {scale:10.0,signed:true, offset: 0}, [0xff,0x7f]);
131
+ codecDecode('Negative Number, scale=10, signed=true ', -(2**15)/10, E3.O3Ecodecs.O3EInt16, 2, 'test3', {scale:10.0,signed:true, offset: 0}, [0x00,0x80]);
132
+ codecDecode('Negative Number, scale= 1, signed=true ', -5, E3.O3Ecodecs.O3EInt16, 2, 'test4', {scale:1.0, signed:true, offset: 0}, [0xfb,0xff]);
133
+ codecDecode('Positive Number, scale=10, signed=false', (2**16-1)/10, E3.O3Ecodecs.O3EInt16, 2, 'test5', {scale:10.0,signed:false,offset: 0}, [0xff,0xff]);
134
+ codecDecode('Positive Number, scale=10, signed=false', 25.1, E3.O3Ecodecs.O3EInt16, 2, 'test6', {scale:10.0,signed:false,offset: 0}, [0xfb,0x00]);
135
+ });
136
+
137
+ describe('codecs.js => O3EInt32().decode()', () => {
138
+ codecDecode('Positive Number, scale=10, signed=true ', 5, E3.O3Ecodecs.O3EInt32, 4, 'test1', {scale:10.0,signed:true, offset: 0}, [0x32,0x00,0x00,0x00]);
139
+ codecDecode('Positive Number, scale=10, signed=true ', (2**31-1)/10, E3.O3Ecodecs.O3EInt32, 4, 'test2', {scale:10.0,signed:true, offset: 0}, [0xff,0xff,0xff,0x7f]);
140
+ codecDecode('Negative Number, scale=10, signed=true ', -(2**31)/10, E3.O3Ecodecs.O3EInt32, 4, 'test3', {scale:10.0,signed:true, offset: 0}, [0x00,0x00,0x00,0x80]);
141
+ codecDecode('Negative Number, scale= 1, signed=true ', -5, E3.O3Ecodecs.O3EInt32, 4, 'test4', {scale:1.0, signed:true, offset: 0}, [0xfb,0xff,0xff,0xff]);
142
+ codecDecode('Positive Number, scale=10, signed=false', (2**32-1)/10, E3.O3Ecodecs.O3EInt32, 4, 'test5', {scale:10.0,signed:false,offset: 0}, [0xff,0xff,0xff,0xff]);
143
+ codecDecode('Positive Number, scale=10, signed=false', 25.1, E3.O3Ecodecs.O3EInt32, 4, 'test6', {scale:10.0,signed:false,offset: 0}, [0xfb,0x00,0x00,0x00]);
144
+ });
145
+
146
+ // Integer ENCODER:
147
+ describe('codecs.js => O3EInt8().encode()', () => {
148
+ codecEncode('Positive Number, scale=10, signed=true ', [0x32], E3.O3Ecodecs.O3EInt8, 1, 'test1', {scale:10.0,signed:true, offset: 0}, 5);
149
+ codecEncode('Positive Number, scale=10, signed=true ', [0x7f], E3.O3Ecodecs.O3EInt8, 1, 'test2', {scale:10.0,signed:true, offset: 0}, (2**7-1)/10);
150
+ codecEncode('Negative Number, scale=10, signed=true ', [0x80], E3.O3Ecodecs.O3EInt8, 1, 'test3', {scale:10.0,signed:true, offset: 0}, -(2**7)/10);
151
+ codecEncode('Negative Number, scale= 1, signed=true ', [0xfb], E3.O3Ecodecs.O3EInt8, 1, 'test4', {scale:1.0, signed:true, offset: 0}, -5);
152
+ codecEncode('Positive Number, scale=10, signed=false', [0xfb], E3.O3Ecodecs.O3EInt8, 1, 'test5', {scale:10.0,signed:false,offset: 0}, 25.1);
153
+ });
154
+
155
+ describe('codecs.js => O3EInt16().decode()', () => {
156
+ codecEncode('Positive Number, scale=10, signed=true ', [0x32,0x00], E3.O3Ecodecs.O3EInt16, 2, 'test1', {scale:10.0,signed:true, offset: 0}, 5);
157
+ codecEncode('Positive Number, scale=10, signed=true ', [0xff,0x7f], E3.O3Ecodecs.O3EInt16, 2, 'test2', {scale:10.0,signed:true, offset: 0}, (2**15-1)/10);
158
+ codecEncode('Negative Number, scale=10, signed=true ', [0x00,0x80], E3.O3Ecodecs.O3EInt16, 2, 'test3', {scale:10.0,signed:true, offset: 0}, -(2**15)/10);
159
+ codecEncode('Negative Number, scale= 1, signed=true ', [0xfb,0xff], E3.O3Ecodecs.O3EInt16, 2, 'test4', {scale:1.0, signed:true, offset: 0}, -5);
160
+ codecEncode('Positive Number, scale=10, signed=false', [0xff,0xff], E3.O3Ecodecs.O3EInt16, 2, 'test5', {scale:10.0,signed:false,offset: 0}, (2**16-1)/10);
161
+ codecEncode('Positive Number, scale=10, signed=false', [0xfb,0x00], E3.O3Ecodecs.O3EInt16, 2, 'test6', {scale:10.0,signed:false,offset: 0}, 25.1);
162
+ });
163
+
164
+ describe('codecs.js => O3EInt32().encode()', () => {
165
+ codecEncode('Positive Number, scale=10, signed=true ', [0x32,0x00,0x00,0x00], E3.O3Ecodecs.O3EInt32, 4, 'test1', {scale:10.0,signed:true, offset: 0}, 5);
166
+ codecEncode('Positive Number, scale=10, signed=true ', [0xff,0xff,0xff,0x7f], E3.O3Ecodecs.O3EInt32, 4, 'test2', {scale:10.0,signed:true, offset: 0}, (2**31-1)/10);
167
+ codecEncode('Negative Number, scale=10, signed=true ', [0x00,0x00,0x00,0x80], E3.O3Ecodecs.O3EInt32, 4, 'test3', {scale:10.0,signed:true, offset: 0}, -(2**31)/10);
168
+ codecEncode('Negative Number, scale= 1, signed=true ', [0xfb,0xff,0xff,0xff], E3.O3Ecodecs.O3EInt32, 4, 'test4', {scale:1.0, signed:true, offset: 0}, -5);
169
+ codecEncode('Positive Number, scale=10, signed=false', [0xff,0xff,0xff,0xff], E3.O3Ecodecs.O3EInt32, 4, 'test5', {scale:10.0,signed:false,offset: 0}, (2**32-1)/10);
170
+ codecEncode('Positive Number, scale=10, signed=false', [0xfb,0x00,0x00,0x00], E3.O3Ecodecs.O3EInt32, 4, 'test6', {scale:10.0,signed:false,offset: 0}, 25.1);
171
+ });
172
+
173
+ // Complex data structures
174
+ // Do testing for specific dids to cover all available codecs
175
+ describe('codecs.js => O3EComplexType()', () => {
176
+ const raw_hex = '3b0206004700fd01c30801000300f9013001020030303030303030303030303030383135';
177
+ const raw_arr = toByteArray(raw_hex);
178
+ const js = {'BusAddress':59,'BusType':{'ID':2,'Text':'CanInternal'},'DeviceProperty':{'ID':6,'Text':'HMI'},'DeviceFunction':{'ID':0,'Text':'NOTHING'},'SW-Version':'71.509.2243.1','HW-Version':'3.505.304.2','VIN':'0000000000000815'};
179
+ const cdi = E3DidsDict[256];
180
+ codecDecode('Decoding did 256 ', js, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, raw_arr);
181
+ // Encoding makes no sense for this did in real life, but testing helps to improve codec robustness
182
+ codecEncode('Encoding did 256 ', raw_arr, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, js);
183
+ });
184
+
185
+ describe('codecs.js => O3EList()', () => {
186
+ const raw_hex = '0a00b001f30314170b12050e3a313602f30314170b12050e390c3602f30314170b12050e2f273602f30314170b12050d2b063602f30314170b12050d2a233602f30314170b12050d27383602f30314170b12050d26033602f30314170b12050d242d3602f30314170b12050d1f043602f30314170b12050d1e133602';
187
+ const raw_arr = toByteArray(raw_hex);
188
+ const js = {'Count':10,'GrandTotal':432,'ListEntries':[{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 14:58:49','Timestamp':1700315929000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 14:57:12','Timestamp':1700315832000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 14:47:39','Timestamp':1700315259000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 13:43:06','Timestamp':1700311386000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 13:42:35','Timestamp':1700311355000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 13:39:56','Timestamp':1700311196000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 13:38:03','Timestamp':1700311083000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 13:36:45','Timestamp':1700311005000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 13:31:04','Timestamp':1700310664000},'Unknown':566},{'Error':{'ID':1011,'Text':'FailureCompressorOutletPressureSensor'},'DateTime':{'DateTime':'18/11/2023, 13:30:19','Timestamp':1700310619000},'Unknown':566}]};
189
+ const cdi = E3DidsDict[266];
190
+ codecDecode('Decoding did 266 ', js, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, raw_arr);
191
+ // Encoding makes no sense for this did in real life, but testing helps to improve codec robustness
192
+ codecEncode('Encoding did 266 ', raw_arr, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, js);
193
+ });
194
+
195
+ describe('codecs.js => O3EComplexType()', () => {
196
+ const raw_hex = '8c01c1007a027e0100';
197
+ const raw_arr = toByteArray(raw_hex);
198
+ const js = {'Actual':39.6,'Minimum':19.3,'Maximum':63.4,'Average':38.2,'Unknown':0};
199
+ const cdi = E3DidsDict[268];
200
+ codecDecode('Decoding did 268 ', js, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, raw_arr);
201
+ // Encoding makes no sense for this did in real life, but testing helps to improve codec robustness
202
+ codecEncode('Encoding did 268 ', raw_arr, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, js);
203
+ });
204
+
205
+ describe('codecs.js => O3EList()', () => {
206
+ const raw_hex = '020800091e0000030f001100000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
207
+ const raw_arr = toByteArray(raw_hex);
208
+ const js = {'Count':2,'Schedules':[{'Start':'08:00:00','Stop':'09:30:00','Unknown':'0000','Mode':3},{'Start':'15:00:00','Stop':'17:00:00','Unknown':'0000','Mode':3}]};
209
+ const cdi = E3DidsDict[726];
210
+ codecDecode('Decoding did 726 ', js, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, raw_arr);
211
+ codecEncode('Encoding did 726 ', raw_arr, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, js);
212
+ });
213
+
214
+ describe('codecs.js => O3EComplexType()', () => {
215
+ const raw_hex = '38004f0068005c004b0045005400650059000602780090003c004c004b007400840058000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000028002f004200';
216
+ const raw_arr = toByteArray(raw_hex);
217
+ const js = {'CurrentMonth':{'10':51.8,'11':12,'12':14.4,'13':6,'14':7.6,'15':7.5,'16':11.6,'17':13.2,'18':8.8,'19':0,'20':0,'21':0,'22':0,'23':0,'24':0,'25':0,'26':0,'27':0,'28':0,'29':0,'30':0,'31':0,'01':5.6,'02':7.9,'03':10.4,'04':9.2,'05':7.5,'06':6.9,'07':8.4,'08':10.1,'09':8.9},'LastMonth':{'10':0,'11':0,'12':0,'13':0,'14':0,'15':0,'16':0.4,'17':0,'18':0,'19':0,'20':0,'21':0,'22':0,'23':0,'24':0,'25':0,'26':0,'27':0,'28':0,'29':4,'30':4.7,'31':6.6,'01':0,'02':0,'03':0,'04':0,'05':0,'06':0,'07':0,'08':0,'09':0}};
218
+ const cdi = E3DidsDict[1294];
219
+ codecDecode('Decoding did 1294 ', js, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, raw_arr);
220
+ // Encoding makes no sense for this did in real life, but testing helps to improve codec robustness
221
+ codecEncode('Encoding did 1294 ', raw_arr, E3.O3Ecodecs[cdi.codec], cdi.len, cdi.id, cdi.args, js);
222
+ });
@@ -15,6 +15,8 @@
15
15
  "436": "MixerSevenCircuitRoomTemperatureSetpoint",
16
16
  "438": "MixerEightCircuitRoomTemperatureSetpoint",
17
17
  "451": "ExternalAlternatingCurrentPowerSetpoint",
18
+ "491": "DomesticHotWaterCirculationPump",
19
+ "497": "DomesticHotWaterCirculationPumpMode",
18
20
  "504": "DomesticHotWaterSetpointMetaData",
19
21
  "508": "UniversalTimeCoordinatedOffset",
20
22
  "524": "ModulationTargetSetpoint",
@@ -79,7 +81,23 @@
79
81
  "1009": "MixerTwoCircuitTargetQuickMode",
80
82
  "1010": "MixerThreeCircuitTargetQuickMode",
81
83
  "1011": "MixerFourCircuitTargetQuickMode",
84
+ "1084": "FlowTemperatureMinimumMaximumLimit",
85
+ "1100": "CentralHeatingPumpMinimumMaximumLimit",
86
+ "1101": "DomesticHotWaterPumpMinimumMaximumLimit",
87
+ "1102": "MixerOneCircuitPumpMinimumMaximumLimit",
88
+ "1103": "MixerTwoCircuitPumpMinimumMaximumLimit",
89
+ "1104": "MixerThreeCircuitPumpMinimumMaximumLimit",
90
+ "1105": "MixerFourCircuitPumpMinimumMaximumLimit",
91
+ "1118": "SolarCircuitPumpMinimumMaximumLimit",
82
92
  "1167": "ExternalDomesticHotWaterTemperatureSetpoint",
93
+ "1192": "MixerOneCircuitFlowTemperatureMinimumMaximumLimit",
94
+ "1193": "MixerTwoCircuitFlowTemperatureMinimumMaximumLimit",
95
+ "1194": "MixerThreeCircuitFlowTemperatureMinimumMaximumLimit",
96
+ "1195": "MixerFourCircuitFlowTemperatureMinimumMaximumLimit",
97
+ "1196": "MixerFiveCircuitFlowTemperatureMinimumMaximumLimit",
98
+ "1197": "MixerSixCircuitFlowTemperatureMinimumMaximumLimit",
99
+ "1198": "MixerSevenCircuitFlowTemperatureMinimumMaximumLimit",
100
+ "1199": "MixerEightCircuitFlowTemperatureMinimumMaximumLimit",
83
101
  "1265": "FanTargetSpeedMeta",
84
102
  "1363": "FuelCellTargetOperationMode",
85
103
  "1394": "SolarChargingDomesticHotWaterSetpoint",
package/main.js CHANGED
@@ -1,5 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ /*
4
+ * Unveil life data of Viessmann E3 series devices via CAN bus
5
+ *
6
+ * Based on project open3e: https://github.com/open3e/open3e
7
+ *
8
+ */
9
+
3
10
  /*
4
11
  * Created with @iobroker/create-adapter v2.5.0
5
12
  */
@@ -8,9 +15,7 @@
8
15
  // you need to create an adapter
9
16
  const utils = require('@iobroker/adapter-core');
10
17
 
11
- // Load your modules here, e.g.:
12
- // const fs = require("fs");
13
-
18
+ // Loading modules:
14
19
  const can = require('socketcan');
15
20
  const storage = require('./lib/storage');
16
21
  const collect = require('./lib/canCollect');
@@ -28,7 +33,7 @@ class E3oncan extends utils.Adapter {
28
33
  name: 'e3oncan',
29
34
  });
30
35
 
31
- this.e380Collect = null; // E380 alway is assigned to external bus
36
+ this.e380Collect = null; // E380 always is assigned to external bus
32
37
  this.E3CollectInt = {}; // Dict of collect devices on internal bus
33
38
  this.E3CollectExt = {}; // Dict of collect devices on external bus
34
39
  this.collectTimeout = 1500; // Timeout (ms) for collecting data
@@ -46,7 +51,6 @@ class E3oncan extends utils.Adapter {
46
51
  this.udsDidForScan = 256; // Busidentification is in this id
47
52
  this.udsScanWorker = new udsScan.udsScan();
48
53
  this.udsScanDevices = []; // UDS devices found during scan
49
- this.doUdsDevScan = false;
50
54
  this.udsDevAddrs = [];
51
55
  this.udsDevStateNames = [];
52
56
  this.udsDidsMaxNmbr = 3000; // Max. number of dids per device for scan
@@ -80,10 +84,6 @@ class E3oncan extends utils.Adapter {
80
84
  this.udsDevStateNames.push(dev.devStateName);
81
85
  }
82
86
 
83
- // Check for required scan for UDS devices
84
- this.doUdsDevScan = (this.config.tableUdsDevices.length == 0);
85
- if (this.doUdsDevScan) await this.log.info('UDS device scan is required.');
86
-
87
87
  // Setup external CAN bus if required
88
88
  // ==================================
89
89
 
@@ -326,25 +326,18 @@ class E3oncan extends utils.Adapter {
326
326
  if (obj.command === 'getUdsDevices') {
327
327
  if (obj.callback) {
328
328
  if (!this.udsDevScanIsRunning) {
329
- if (this.doUdsDevScan) {
330
- let success = false;
331
- this.udsDevScanIsRunning = true;
332
- await this.log.silly(`Received data - ${JSON.stringify(obj)}`);
333
- //this.udsScanDevices = obj.message.udsDevices;
334
- success = await this.udsScanWorker.scanUdsDevices(this);
335
- await this.sendTo(obj.from, obj.command, this.udsDevices, obj.callback);
336
- if (success) this.doUdsDevScan = false;
337
- this.udsDevScanIsRunning = false;
338
- } else {
339
- // Scan not required. Do nothing
340
- this.sendTo(obj.from, obj.command, obj.message, obj.callback);
341
- }
329
+ this.udsDevScanIsRunning = true;
330
+ await this.log.silly(`Received data - ${JSON.stringify(obj)}`);
331
+ await this.udsScanWorker.scanUdsDevices(this);
332
+ await this.log.silly(`Data to send - ${JSON.stringify({native: {tableUdsDevices: this.udsDevices}})}`);
333
+ await this.sendTo(obj.from, obj.command, {native: {tableUdsDevices: this.udsDevices}}, obj.callback);
334
+ this.udsDevScanIsRunning = false;
342
335
  } else {
343
336
  await this.log.debug('Request "getUdsDevice" during running UDS scan!');
344
- this.sendTo(obj.from, obj.command, obj.message, obj.callback);
337
+ this.sendTo(obj.from, obj.command, {native: {tableUdsDevices: this.udsDevices}}, obj.callback);
345
338
  }
346
339
  } else {
347
- this.sendTo(obj.from, obj.command, [], obj.callback);
340
+ this.sendTo(obj.from, obj.command, {native: {tableUdsDevices: []}}, obj.callback);
348
341
  }
349
342
  }
350
343
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.e3oncan",
3
- "version": "0.6.10",
3
+ "version": "0.6.13",
4
4
  "description": "Collect data on CAN bus for Viessmann E3 devices, e.g. Vitocal, Vitocharge, Energy Meter E380",
5
5
  "author": {
6
6
  "name": "Juergen",
@@ -18,7 +18,7 @@
18
18
  ],
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "git@github.com:MyHomeMyData/ioBroker.e3oncan.git"
21
+ "url": "https://github.com/MyHomeMyData/ioBroker.e3oncan.git"
22
22
  },
23
23
  "engines": {
24
24
  "node": ">= 16"