iobroker.e3oncan 0.6.15 → 0.6.17
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 +13 -5
- package/admin/jsonConfig.json +1 -1
- package/io-package.json +27 -27
- package/lib/canCollect.js +4 -8
- package/lib/canUds.js +36 -37
- package/lib/codecs.test.js +1 -1
- package/lib/didsE3Writables.json +1442 -180
- package/lib/storage.js +7 -11
- package/lib/udsScan.js +9 -7
- package/main.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ In parallel **reading of datapoints** (ReadByDid) is supported. Informations not
|
|
|
21
21
|
|
|
22
22
|
**Writing of datapoints** via UDSonCAN (WriteByDid) is supported as well. By writing to datapoints it's possible to change setpoints, schedules and so on. It's even possible to add new schedules e.g. for domestic hot water circulation pump.
|
|
23
23
|
|
|
24
|
-
Writing of data is triggered by storing the corresponding state with `Acknowledged` not checked (ack=false) - yes, it's that simple! The datapoint will be read again from device and stored in the state
|
|
24
|
+
Writing of data is triggered by storing the corresponding state with `Acknowledged` not checked (ack=false) - yes, it's that simple! The datapoint will be read again from device and stored in the state 2.5 seconds after writing. If state not get's acknowledged, please take a look to the logs.
|
|
25
25
|
|
|
26
26
|
Writing is restricted to a set of datapoints using a **white list**. The list is stored in the info section of each device, e.g. at `e3oncan.0.vitocal.info.udsDidsWritable`. You can add more datapoints by editing this state. Make sure, **not** to check `Acknowledged` when saving the state.
|
|
27
27
|
|
|
@@ -39,13 +39,13 @@ A python based implementation of a pure listening approach using MQTT messaging
|
|
|
39
39
|
* Currently only Linux based systems are supported.
|
|
40
40
|
* CAN adapter is up and visible in system, e.g. as "can0" (use ifconfig to check).
|
|
41
41
|
* Refer to open3e project for further details
|
|
42
|
-
* **Make sure,
|
|
42
|
+
* **Make sure, no other UDSonCAN client (e.g. Open3Eclient.py) is running during initial setup!** This could cause communication errors in both applications.
|
|
43
43
|
|
|
44
44
|
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:
|
|
45
45
|
|
|
46
46
|
**Configuration**
|
|
47
47
|
* When installation of adapter has finished a confuration dialog will show up to configure up to two CAN bus adapters (tab "CAN ADAPTER")
|
|
48
|
-
* Edit name of adapter and check the "Connect to adapter" checkbox at least the external adapter
|
|
48
|
+
* Edit name of adapter and check the "Connect to adapter" checkbox at least for the external adapter
|
|
49
49
|
* 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.
|
|
50
50
|
* 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.
|
|
51
51
|
* 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.
|
|
@@ -65,11 +65,11 @@ You may use datapoints informations on tab "LIST OF DATAPOINTS" for reference (o
|
|
|
65
65
|
| ID | Data| Unit |
|
|
66
66
|
| ------|:--- |------|
|
|
67
67
|
| 0x250 | Active Power L1, L2, L3, Total | W |
|
|
68
|
-
| 0x252 | Reactive Power L1, L2, L3, Total |
|
|
68
|
+
| 0x252 | Reactive Power L1, L2, L3, Total | VA |
|
|
69
69
|
| 0x254 | Current, L1, L2, L3, cosPhi | A, - |
|
|
70
70
|
| 0x256 | Voltage, L1, L2, L3, Frequency | V, Hz |
|
|
71
71
|
| 0x258 | Cumulated Import, Export | kWh |
|
|
72
|
-
| 0x25A | Total Active Power, Total Reactive Power | W |
|
|
72
|
+
| 0x25A | Total Active Power, Total Reactive Power | W, VA |
|
|
73
73
|
| 0x25C | Cumulated Import | kWh |
|
|
74
74
|
|
|
75
75
|
# Hints and limitations
|
|
@@ -102,6 +102,14 @@ Yes, that is possible under certain conditions:
|
|
|
102
102
|
Placeholder for the next version (at the beginning of the line):
|
|
103
103
|
### **WORK IN PROGRESS**
|
|
104
104
|
-->
|
|
105
|
+
### 0.6.17 (2024-01-29)
|
|
106
|
+
* (MyHomeMyData) Added/removed datapoints to/from list of writable dids
|
|
107
|
+
* (MyHomeMyData) Preparations for device specific list of writable dids
|
|
108
|
+
|
|
109
|
+
### 0.6.16 (2024-01-27)
|
|
110
|
+
* (MyHomeMyData) Improvements based on findings in review as of 2024-01-25
|
|
111
|
+
* (MyHomeMyData) Checkbox for data collectiton on internal bus is now checked per default
|
|
112
|
+
|
|
105
113
|
### 0.6.15 (2024-01-23)
|
|
106
114
|
* (MyHomeMyData) Fix for Utf8 codec for handling of special characters, e.g. umlauts
|
|
107
115
|
|
package/admin/jsonConfig.json
CHANGED
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "e3oncan",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.17",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.6.17": {
|
|
7
|
+
"en": "Added/removed datapoints to/from list of writable dids\nPreparations for device specific list of writable dids",
|
|
8
|
+
"de": "Hinzugefügt/entfernte Datenpunkte zu/aus der Liste der schreibbaren Taten\nVorbereitungen für die gerätespezifische Liste der schreibbaren Taten",
|
|
9
|
+
"ru": "Добавлены/удалены точки данных в/из списка заслуживающих доверия дел\nПодготовка к конкретному списку реальных дел",
|
|
10
|
+
"pt": "Datapoints adicionados/removed para / da lista de dids writable\nPreparações para a lista específica do dispositivo de dids",
|
|
11
|
+
"nl": "Toegevoegd/verwijderde datapunten aan/van lijst van schrijfbare dids\nVoorbereidingen voor apparaatspecifieke lijst van schrijfbare dids",
|
|
12
|
+
"fr": "Ajout/retrait de points de données à la liste des dids en écriture\nPréparations pour la liste spécifique des dids à écrire",
|
|
13
|
+
"it": "Datapoint aggiunti/rimovibili da/per l'elenco di fazioni scrivibili\nPreparazioni per l'elenco specifico del dispositivo di fazioni scrivibili",
|
|
14
|
+
"es": "Puntos de datos añadidos/removidos a/desde la lista de didas\nPreparaciones para la lista específica del dispositivo de didas",
|
|
15
|
+
"pl": "Dodano / usunięto punkty danych do / z listy zapisanych did\nPreparaty do specyficznego dla urządzenia wykazu dysków pisanych",
|
|
16
|
+
"uk": "Додано/видалення точок даних до/з списку збитих\nПрепарати для пристрою специфічного переліку життєздатних",
|
|
17
|
+
"zh-cn": "已添加/删除数据点到/从可写作的列表中\n编写设备特定可写行为清单"
|
|
18
|
+
},
|
|
19
|
+
"0.6.16": {
|
|
20
|
+
"en": "Improvements based on findings in review as of 2024-01-25\nCheckbox for data collectiton on internal bus is now checked per default",
|
|
21
|
+
"de": "Verbesserungen auf der Grundlage der Ergebnisse in der Überprüfung ab 2024-01-25\nCheckbox für Datensammler im internen Bus wird nun standardmäßig überprüft",
|
|
22
|
+
"ru": "Совершенствование на основе результатов, рассмотренных на 2024-01-25 годы\nCheckbox для сбора данных на внутреннем автобусе теперь проверяется по умолчанию",
|
|
23
|
+
"pt": "Aperfeiçoamentos baseados em achados em revisão a partir de 2024-01-25\nCaixa de seleção para coleta de dados no ônibus interno é agora verificada por padrão",
|
|
24
|
+
"nl": "Verbeteringen op basis van de resultaten van het onderzoek per 2024-01-25\nCheckbox voor gegevensverzameling op interne bus is nu standaard aangevinkt",
|
|
25
|
+
"fr": "Améliorations fondées sur les conclusions de l'examen en 2024-01-25\nLa case à cocher pour les données collectiton sur le bus interne est maintenant cochée par défaut",
|
|
26
|
+
"it": "Miglioramenti basati sui risultati in esame a partire dal 2024-01-25\nLa casella di controllo per i dati collettivi sul bus interno è ora controllata per impostazione predefinita",
|
|
27
|
+
"es": "Mejoras basadas en los resultados examinados al 2024-01-25\nCheckbox for data collectiton on internal bus is now check per default",
|
|
28
|
+
"pl": "Poprawki oparte na ustaleniach w przeglądzie z 2024- 01- 25\nSkrzynka kontrolna dla kolekcji danych w autobusie wewnętrznym jest teraz sprawdzana na domyślnym",
|
|
29
|
+
"uk": "Удосконалення на основі пошуку в рецензії на 2024-01-25\nCheckbox для збору даних у внутрішньому автобусі тепер перевіряється за замовчуванням",
|
|
30
|
+
"zh-cn": "根据截至2024-01-25年审查结果作出的改进\n内部总线上数据集合的复选框现在按默认检查"
|
|
31
|
+
},
|
|
6
32
|
"0.6.15": {
|
|
7
33
|
"en": "Fix for Utf8 codec for handling of special characters, e.g. umlauts",
|
|
8
34
|
"de": "Fix für Utf8-Codec zum Umgang mit Sonderzeichen, z.B. umlauts",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "Ulepszony układ okna konfiguracji skanowania urządzenia",
|
|
68
94
|
"uk": "Покращений макет діалогу конфігурації для сканування пристроїв",
|
|
69
95
|
"zh-cn": "设备扫描配置对话框的改进版式"
|
|
70
|
-
},
|
|
71
|
-
"0.6.10": {
|
|
72
|
-
"en": "Removed code for Rawmode because it's never activated",
|
|
73
|
-
"de": "Entfernter Code für Rawmode, weil es nie aktiviert ist",
|
|
74
|
-
"ru": "Удаленный код для Rawmode, потому что он никогда не активирован",
|
|
75
|
-
"pt": "Código removido para Rawmode porque nunca foi ativado",
|
|
76
|
-
"nl": "Verwijderde code voor Rawmode omdat het nooit is geactiveerd",
|
|
77
|
-
"fr": "Code supprimé pour Rawmode car il n'est jamais activé",
|
|
78
|
-
"it": "Codice rimosso per Rawmode perché non è mai attivato",
|
|
79
|
-
"es": "Código eliminado para Rawmode porque nunca se activa",
|
|
80
|
-
"pl": "Usunięto kod dla Rawmode ponieważ nigdy nie jest aktywowany",
|
|
81
|
-
"uk": "Видалити код для Rawmode, тому що він ніколи не активований",
|
|
82
|
-
"zh-cn": "删除了Rawmode的代码,因为它从未被激活"
|
|
83
|
-
},
|
|
84
|
-
"0.6.9": {
|
|
85
|
-
"en": "Bugfix: Only Linux is supported",
|
|
86
|
-
"de": "Bugfix: Nur Linux wird unterstützt",
|
|
87
|
-
"ru": "Исправление: Только Linux поддерживается",
|
|
88
|
-
"pt": "Bugfix: Apenas o Linux é suportado",
|
|
89
|
-
"nl": "Bugfix: Alleen Linux wordt ondersteund",
|
|
90
|
-
"fr": "Correction : Seul Linux est pris en charge",
|
|
91
|
-
"it": "Bugfix: Solo Linux è supportato",
|
|
92
|
-
"es": "Bugfix: Sólo Linux es compatible",
|
|
93
|
-
"pl": "Bugfix: Tylko Linux jest obsługiwany",
|
|
94
|
-
"uk": "Помилки: Тільки Linux підтримується",
|
|
95
|
-
"zh-cn": "错误修正 : 仅支持 Linux"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"title": "Viessmann E3 CAN do",
|
package/lib/canCollect.js
CHANGED
|
@@ -57,7 +57,7 @@ class collect {
|
|
|
57
57
|
await this.storage.setOpMode('standby');
|
|
58
58
|
|
|
59
59
|
// Stop Timeout:
|
|
60
|
-
if (this.timeoutHandle) await clearTimeout(this.timeoutHandle);
|
|
60
|
+
if (this.timeoutHandle) await ctx.clearTimeout(this.timeoutHandle);
|
|
61
61
|
this.timeoutHandle = null;
|
|
62
62
|
|
|
63
63
|
this.stat.state = 'stopped';
|
|
@@ -71,10 +71,6 @@ class collect {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
sleep(milliseconds) {
|
|
75
|
-
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
74
|
async msgCollect(ctx, msg) {
|
|
79
75
|
|
|
80
76
|
if (await this.storage.getOpMode() == 'standby') return; // No communication in mode 'standby'
|
|
@@ -109,7 +105,7 @@ class collect {
|
|
|
109
105
|
this.data.databytes = this.data.databytes.concat(candata.slice(1));
|
|
110
106
|
if (this.data.databytes.length >= this.data.len) {
|
|
111
107
|
// All data received
|
|
112
|
-
if (this.timeoutHandle) await clearTimeout(this.timeoutHandle);
|
|
108
|
+
if (this.timeoutHandle) await ctx.clearTimeout(this.timeoutHandle);
|
|
113
109
|
this.stat.cntCommOk += 1;
|
|
114
110
|
if (!(this.data.did in this.ts)) { this.ts[this.data.did] = tsNow; }
|
|
115
111
|
if ( (this.config.delay == 0) || ((tsNow >= this.ts[this.data.did])) ) {
|
|
@@ -162,7 +158,7 @@ class collect {
|
|
|
162
158
|
this.data.databytes = candata.slice(5);
|
|
163
159
|
this.data.len = candata[4];
|
|
164
160
|
}
|
|
165
|
-
this.timeoutHandle = setTimeout(this.onTimeout, this.config.timeout, ctx, this);
|
|
161
|
+
this.timeoutHandle = ctx.setTimeout(this.onTimeout, this.config.timeout, ctx, this);
|
|
166
162
|
this.data.collecting = true;
|
|
167
163
|
break;
|
|
168
164
|
case 0xb5:
|
|
@@ -181,7 +177,7 @@ class collect {
|
|
|
181
177
|
this.data.D0expected = candata[0]+1;
|
|
182
178
|
this.data.databytes = candata.slice(4);
|
|
183
179
|
this.data.len = D3-0xb0;
|
|
184
|
-
this.timeoutHandle = setTimeout(this.onTimeout, this.config.timeout, ctx, this);
|
|
180
|
+
this.timeoutHandle = ctx.setTimeout(this.onTimeout, this.config.timeout, ctx, this);
|
|
185
181
|
this.data.collecting = true;
|
|
186
182
|
break;
|
|
187
183
|
default:
|
package/lib/canUds.js
CHANGED
|
@@ -9,21 +9,21 @@ class scheduleLoop {
|
|
|
9
9
|
this.schedHandle = null;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
async startSchedule() {
|
|
12
|
+
async startSchedule(ctx) {
|
|
13
13
|
if (this.schedule == 0) {
|
|
14
14
|
await this.ctxGlobal.log.silly('UDS schedule one time: '+this.ctxLocal.canIDhex+'.'+JSON.stringify(this.dids));
|
|
15
15
|
await this.ctxLocal.pushCmnd(this.ctxGlobal, 'read', this.dids);
|
|
16
16
|
this.schedHandle = null;
|
|
17
17
|
} else {
|
|
18
|
-
this.schedHandle = setInterval(async () => {
|
|
18
|
+
this.schedHandle = ctx.setInterval(async () => {
|
|
19
19
|
await this.loop();
|
|
20
20
|
}, this.schedule*1000);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
async stopSchedule() {
|
|
24
|
+
async stopSchedule(ctx) {
|
|
25
25
|
try {
|
|
26
|
-
if (this.schedHandle) await clearInterval(this.schedHandle);
|
|
26
|
+
if (this.schedHandle) await ctx.clearInterval(this.schedHandle);
|
|
27
27
|
await this.ctxGlobal.log.silly('UDS schedule stopped: '+String(this.schedule)+' '+this.ctxLocal.canIDhex+'.'+JSON.stringify(this.dids));
|
|
28
28
|
} catch (e) {
|
|
29
29
|
// Dod nothing
|
|
@@ -110,7 +110,6 @@ class uds {
|
|
|
110
110
|
type: 'channel',
|
|
111
111
|
common: {
|
|
112
112
|
name: this.config.stateBase+' commands',
|
|
113
|
-
role: 'device'
|
|
114
113
|
},
|
|
115
114
|
native: {},
|
|
116
115
|
});
|
|
@@ -139,7 +138,7 @@ class uds {
|
|
|
139
138
|
if (opMode == 'normal') {
|
|
140
139
|
for (const sched of Object.values(this.schedules)) {
|
|
141
140
|
// Start schedules on startup and do one-time schedules
|
|
142
|
-
await sched.startSchedule();
|
|
141
|
+
await sched.startSchedule(ctx);
|
|
143
142
|
}
|
|
144
143
|
}
|
|
145
144
|
if (opMode == 'normal') {
|
|
@@ -147,7 +146,7 @@ class uds {
|
|
|
147
146
|
} else {
|
|
148
147
|
await ctx.log.silly('UDS worker started in mode '+opMode+' on '+this.config.stateBase);
|
|
149
148
|
}
|
|
150
|
-
this.cmndsHandle = setInterval(async () => {
|
|
149
|
+
this.cmndsHandle = ctx.setInterval(async () => {
|
|
151
150
|
await this.cmndsLoop(ctx);
|
|
152
151
|
}, this.cmndsUpdateTime);
|
|
153
152
|
}
|
|
@@ -164,18 +163,18 @@ class uds {
|
|
|
164
163
|
|
|
165
164
|
// Stop loops:
|
|
166
165
|
for (const sched of Object.values(this.schedules)) {
|
|
167
|
-
await sched.stopSchedule();
|
|
166
|
+
await sched.stopSchedule(ctx);
|
|
168
167
|
}
|
|
169
|
-
if (this.cmndsHandle) await clearInterval(this.cmndsHandle);
|
|
168
|
+
if (this.cmndsHandle) await ctx.clearInterval(this.cmndsHandle);
|
|
170
169
|
|
|
171
170
|
// Stop Timeout:
|
|
172
|
-
if (this.timeoutHandle) await clearTimeout(this.timeoutHandle);
|
|
171
|
+
if (this.timeoutHandle) await ctx.clearTimeout(this.timeoutHandle);
|
|
173
172
|
this.timeoutHandle = null;
|
|
174
173
|
|
|
175
174
|
// Stop worker:
|
|
176
175
|
this.callback = null;
|
|
177
176
|
if (opMode == 'normal') {
|
|
178
|
-
|
|
177
|
+
ctx.unsubscribeStates(ctx.namespace+'.'+this.config.stateBase+'.*');
|
|
179
178
|
await ctx.log.info('UDS worker stopped on '+this.config.stateBase);
|
|
180
179
|
} else {
|
|
181
180
|
await ctx.log.silly('UDS worker stopped in mode '+opMode+' on '+this.config.stateBase);
|
|
@@ -201,12 +200,12 @@ class uds {
|
|
|
201
200
|
this.data.state = comState;
|
|
202
201
|
}
|
|
203
202
|
|
|
204
|
-
async setDidDone(coolDownTime) {
|
|
203
|
+
async setDidDone(ctx, coolDownTime) {
|
|
205
204
|
// Finalize communication for recent did
|
|
206
205
|
this.coolDownTs = new Date().getTime()+coolDownTime;
|
|
207
206
|
if (this.cmndsQueue.length == 0) this.busy = false;
|
|
208
207
|
await this.setComState(0);
|
|
209
|
-
if (this.timeoutHandle) await clearTimeout(this.timeoutHandle);
|
|
208
|
+
if (this.timeoutHandle) await ctx.clearTimeout(this.timeoutHandle);
|
|
210
209
|
}
|
|
211
210
|
|
|
212
211
|
async setDidStart(ctx, did, mode, len) {
|
|
@@ -228,9 +227,9 @@ class uds {
|
|
|
228
227
|
}
|
|
229
228
|
const tsNow = new Date().getTime();
|
|
230
229
|
const minWaiting = this.coolDownTs - tsNow;
|
|
231
|
-
if (minWaiting > 0) await this.sleep(minWaiting);
|
|
230
|
+
if (minWaiting > 0) await this.sleep(ctx, minWaiting);
|
|
232
231
|
this.busy = true;
|
|
233
|
-
this.timeoutHandle = await setTimeout(this.onTimeout, this.config.timeout, ctx, this);
|
|
232
|
+
this.timeoutHandle = await ctx.setTimeout(this.onTimeout, this.config.timeout, ctx, this);
|
|
234
233
|
this.data.did = did;
|
|
235
234
|
this.data.tsRequest = tsNow;
|
|
236
235
|
}
|
|
@@ -269,8 +268,8 @@ class uds {
|
|
|
269
268
|
}
|
|
270
269
|
}
|
|
271
270
|
|
|
272
|
-
sleep(milliseconds) {
|
|
273
|
-
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
271
|
+
sleep(ctx, milliseconds) {
|
|
272
|
+
return new Promise(resolve => ctx.setTimeout(resolve, milliseconds));
|
|
274
273
|
}
|
|
275
274
|
|
|
276
275
|
async cmndsLoop(ctx) {
|
|
@@ -309,7 +308,7 @@ class uds {
|
|
|
309
308
|
ctxLocal.stat.cntCommTimeoutPerDid[did] = 1;
|
|
310
309
|
}
|
|
311
310
|
if (ctxLocal.callback) await ctxLocal.callback(ctxGlobal, ctxLocal, ['timeout', {'did':ctxLocal.data.did,'didInfo':{'id':'','len':0},'val':''}]);
|
|
312
|
-
await ctxLocal.setDidDone(0);
|
|
311
|
+
await ctxLocal.setDidDone(ctxGlobal, 0);
|
|
313
312
|
}
|
|
314
313
|
|
|
315
314
|
async onUdsStateChange(ctx, ctxWorker, id, state) {
|
|
@@ -369,7 +368,7 @@ class uds {
|
|
|
369
368
|
byteArr = await this.storage.encodeDataCAN(ctx, this, did, await JSON.parse(state.val));
|
|
370
369
|
if (byteArr) {
|
|
371
370
|
await this.pushCmnd(ctx, 'write', [[did,byteArr]]);
|
|
372
|
-
setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,this,did); // Read value after 2500 ms
|
|
371
|
+
ctx.setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,this,did); // Read value after 2500 ms
|
|
373
372
|
} else {
|
|
374
373
|
ctx.log.error('User command UDS WriteByDid on '+this.config.stateBase+': Encoding of data failed.');
|
|
375
374
|
}
|
|
@@ -382,7 +381,7 @@ class uds {
|
|
|
382
381
|
byteArr = this.storage.toByteArray(await JSON.parse(state.val));
|
|
383
382
|
if (byteArr) {
|
|
384
383
|
await this.pushCmnd(ctx, 'write', [[did,byteArr]]);
|
|
385
|
-
setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,this,did); // Read value after 2500 ms
|
|
384
|
+
ctx.setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,this,did); // Read value after 2500 ms
|
|
386
385
|
} else {
|
|
387
386
|
ctx.log.error('User command UDS WriteByDid on '+this.config.stateBase+': Encoding of data failed.');
|
|
388
387
|
}
|
|
@@ -397,7 +396,7 @@ class uds {
|
|
|
397
396
|
byteArr = await this.storage.encodeDataCAN(ctx, this, did, await JSON.parse(state.val));
|
|
398
397
|
if (byteArr) {
|
|
399
398
|
await this.pushCmnd(ctx, 'write', [[did,byteArr]]);
|
|
400
|
-
setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,this,did); // Read value after 2500 ms
|
|
399
|
+
ctx.setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,this,did); // Read value after 2500 ms
|
|
401
400
|
} else {
|
|
402
401
|
ctx.log.error('User command UDS WriteByDid on '+this.config.stateBase+': Encoding of data failed.');
|
|
403
402
|
}
|
|
@@ -434,7 +433,7 @@ class uds {
|
|
|
434
433
|
byteArr = await ctxWorker.storage.encodeDataCAN(ctx, ctxWorker, did, treeDict);
|
|
435
434
|
if (byteArr) {
|
|
436
435
|
await ctxWorker.pushCmnd(ctx, 'write', [[did,byteArr]]);
|
|
437
|
-
setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,ctxWorker,did); // Read value after 2500 ms
|
|
436
|
+
ctx.setTimeout(function(ctxWorker,did){ctxWorker.cmndsQueue.push({'mode':'read', 'did': did});},2500,ctxWorker,did); // Read value after 2500 ms
|
|
438
437
|
} else {
|
|
439
438
|
ctx.log.error('User command UDS WriteByDid on '+ctxWorker.config.stateBase+': Encoding of data failed.');
|
|
440
439
|
}
|
|
@@ -540,7 +539,7 @@ class uds {
|
|
|
540
539
|
} else {
|
|
541
540
|
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));
|
|
542
541
|
}
|
|
543
|
-
await this.setDidDone(0);
|
|
542
|
+
await this.setDidDone(ctx, 0);
|
|
544
543
|
break;
|
|
545
544
|
}
|
|
546
545
|
if ( (candata.length == 8) && ((candata[0] >> 4) == 0) && (candata[1] == this.readByDidProt.SIDrx) ) {
|
|
@@ -554,7 +553,7 @@ class uds {
|
|
|
554
553
|
this.data.len = candata[0]-3;
|
|
555
554
|
this.data.databytes = candata.slice(4,4+this.data.len);
|
|
556
555
|
this.storage.decodeDataCAN(ctx, this, this.data.did, this.data.databytes.slice(0,this.data.len));
|
|
557
|
-
await this.setDidDone(0);
|
|
556
|
+
await this.setDidDone(ctx, 0);
|
|
558
557
|
break;
|
|
559
558
|
} else {
|
|
560
559
|
// Did does not match
|
|
@@ -564,7 +563,7 @@ class uds {
|
|
|
564
563
|
} else {
|
|
565
564
|
ctx.log.error('UDS worker on '+this.config.stateBase+': Did mismatch MF. Expected='+String(this.data.did)+'; Received='+String(didRx));
|
|
566
565
|
}
|
|
567
|
-
await this.setDidDone(1000);
|
|
566
|
+
await this.setDidDone(ctx, 1000);
|
|
568
567
|
break;
|
|
569
568
|
}
|
|
570
569
|
}
|
|
@@ -589,7 +588,7 @@ class uds {
|
|
|
589
588
|
} else {
|
|
590
589
|
ctx.log.error('UDS worker on '+this.config.stateBase+': Did mismatch MF. Expected='+String(this.data.did)+'; Received='+String(didRx));
|
|
591
590
|
}
|
|
592
|
-
await this.setDidDone(1000);
|
|
591
|
+
await this.setDidDone(ctx, 1000);
|
|
593
592
|
break;
|
|
594
593
|
}
|
|
595
594
|
}
|
|
@@ -600,7 +599,7 @@ class uds {
|
|
|
600
599
|
}
|
|
601
600
|
await this.calcStat();
|
|
602
601
|
this.stat.cntCommBadProtocol += 1;
|
|
603
|
-
await this.setDidDone(2500);
|
|
602
|
+
await this.setDidDone(ctx, 2500);
|
|
604
603
|
break;
|
|
605
604
|
|
|
606
605
|
case 2: // waitForCFrbd
|
|
@@ -614,7 +613,7 @@ class uds {
|
|
|
614
613
|
await this.calcStat();
|
|
615
614
|
ctx.log.silly('UDS worker on '+this.config.stateBase+': MF completed. candata: '+this.storage.arr2Hex(candata));
|
|
616
615
|
this.storage.decodeDataCAN(ctx, this, this.data.did, this.data.databytes.slice(0,this.data.len));
|
|
617
|
-
await this.setDidDone(0);
|
|
616
|
+
await this.setDidDone(ctx, 0);
|
|
618
617
|
} else {
|
|
619
618
|
// More data to come
|
|
620
619
|
this.data.D0 += 1;
|
|
@@ -628,7 +627,7 @@ class uds {
|
|
|
628
627
|
ctx.log.error('UDS worker on '+this.config.stateBase+': Bad frame. candata: '+this.storage.arr2Hex(candata));
|
|
629
628
|
}
|
|
630
629
|
this.stat.cntCommBadProtocol += 1;
|
|
631
|
-
await this.setDidDone(2500);
|
|
630
|
+
await this.setDidDone(ctx, 2500);
|
|
632
631
|
}
|
|
633
632
|
break;
|
|
634
633
|
|
|
@@ -637,7 +636,7 @@ class uds {
|
|
|
637
636
|
// Negative response
|
|
638
637
|
this.stat.cntCommNR += 1;
|
|
639
638
|
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));
|
|
640
|
-
await this.setDidDone(0);
|
|
639
|
+
await this.setDidDone(ctx, 0);
|
|
641
640
|
break;
|
|
642
641
|
}
|
|
643
642
|
if ( (candata.length == 8) && (candata[0] == 0x03) && (candata[1] == this.writeByDidProt.SIDrx) ) {
|
|
@@ -649,7 +648,7 @@ class uds {
|
|
|
649
648
|
ctx.log.silly('UDS worker on '+this.config.stateBase+': writeByDid SF confirmation received.');
|
|
650
649
|
await this.calcStat();
|
|
651
650
|
this.storage.storeStatistics(ctx, this, false);
|
|
652
|
-
await this.setDidDone(0);
|
|
651
|
+
await this.setDidDone(ctx, 0);
|
|
653
652
|
break;
|
|
654
653
|
} else {
|
|
655
654
|
// Did does not match
|
|
@@ -657,14 +656,14 @@ class uds {
|
|
|
657
656
|
ctx.log.error('UDS worker on '+this.config.stateBase+': Did mismatch writeByDid SF. Expected='+String(this.data.did)+'; Received='+String(didRx));
|
|
658
657
|
await this.calcStat();
|
|
659
658
|
this.storage.storeStatistics(ctx, this, true);
|
|
660
|
-
await this.setDidDone(1000);
|
|
659
|
+
await this.setDidDone(ctx, 1000);
|
|
661
660
|
break;
|
|
662
661
|
}
|
|
663
662
|
}
|
|
664
663
|
ctx.log.error('UDS worker on '+this.config.stateBase+': Bad frame for writeByDid SF. candata: '+this.storage.arr2Hex(candata));
|
|
665
664
|
this.stat.cntCommBadProtocol += 1;
|
|
666
665
|
await this.calcStat();
|
|
667
|
-
await this.setDidDone(2500);
|
|
666
|
+
await this.setDidDone(ctx, 2500);
|
|
668
667
|
break;
|
|
669
668
|
|
|
670
669
|
case 4: // waitForFFFwbd
|
|
@@ -672,7 +671,7 @@ class uds {
|
|
|
672
671
|
// Negative response
|
|
673
672
|
this.stat.cntCommNR += 1;
|
|
674
673
|
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));
|
|
675
|
-
await this.setDidDone(0);
|
|
674
|
+
await this.setDidDone(ctx, 0);
|
|
676
675
|
break;
|
|
677
676
|
}
|
|
678
677
|
if ( (candata.length == 8) && (candata[0] == 0x30) && (candata[1] == 0x00) ) {
|
|
@@ -682,7 +681,7 @@ class uds {
|
|
|
682
681
|
if ((ST<20) || (ST>127)) ST=50; // Accept ST 20 .. 127 ms. Default to 50 ms.
|
|
683
682
|
while (this.data.txPos < this.data.len) {
|
|
684
683
|
// More data to send
|
|
685
|
-
await this.sleep(ST);
|
|
684
|
+
await this.sleep(ctx, ST);
|
|
686
685
|
const frame = [this.data.D0].concat(this.data.databytes.slice(this.data.txPos,this.data.txPos+7));
|
|
687
686
|
await this.sendFrame(ctx, frame);
|
|
688
687
|
this.data.txPos += 7;
|
|
@@ -695,7 +694,7 @@ class uds {
|
|
|
695
694
|
ctx.log.error('UDS worker on '+this.config.stateBase+': Bad frame for writeByDid MF. candata: '+this.storage.arr2Hex(candata));
|
|
696
695
|
this.stat.cntCommBadProtocol += 1;
|
|
697
696
|
await this.calcStat();
|
|
698
|
-
await this.setDidDone(2500);
|
|
697
|
+
await this.setDidDone(ctx, 2500);
|
|
699
698
|
break;
|
|
700
699
|
|
|
701
700
|
default:
|
|
@@ -705,7 +704,7 @@ class uds {
|
|
|
705
704
|
} else {
|
|
706
705
|
ctx.log.error('UDS worker on '+this.config.stateBase+': Bad state value: '+String(await this.getComState()));
|
|
707
706
|
}
|
|
708
|
-
await this.setDidDone(2500);
|
|
707
|
+
await this.setDidDone(ctx, 2500);
|
|
709
708
|
}
|
|
710
709
|
this.commBusy = false;
|
|
711
710
|
}
|
package/lib/codecs.test.js
CHANGED
|
@@ -208,7 +208,7 @@ describe('codecs.js => O3EInt8().encode()', () => {
|
|
|
208
208
|
codecEncode('Positive Number, scale=10, signed=false', [0xfb], E3.O3Ecodecs.O3EInt8, 1, 'test5', {scale:10.0,signed:false,offset: 0}, 25.1);
|
|
209
209
|
});
|
|
210
210
|
|
|
211
|
-
describe('codecs.js => O3EInt16().
|
|
211
|
+
describe('codecs.js => O3EInt16().encode()', () => {
|
|
212
212
|
codecEncode('Positive Number, scale=10, signed=true ', [0x32,0x00], E3.O3Ecodecs.O3EInt16, 2, 'test1', {scale:10.0,signed:true, offset: 0}, 5);
|
|
213
213
|
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);
|
|
214
214
|
codecEncode('Negative Number, scale=10, signed=true ', [0x00,0x80], E3.O3Ecodecs.O3EInt16, 2, 'test3', {scale:10.0,signed:true, offset: 0}, -(2**15)/10);
|