diff --git a/README.md b/README.md index 13b31bd4..2b481606 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,6 @@ The adapter can control the mower and you can change config params like mowtimes - (Lucky-ESA) Added Vision cut over slabs - (Lucky-ESA) Node 18 required - (Lucky-ESA) Catch aws_cer error and use old mqtt connection -- (Lucky-ESA) Added rain wait countdown - (Lucky-ESA) Added Vision Multi Zone ### 2.3.4 (2023-10-19) diff --git a/docs/de/README.md b/docs/de/README.md index 2de49f32..88c5a99a 100644 --- a/docs/de/README.md +++ b/docs/de/README.md @@ -303,11 +303,11 @@ - `multiZone.passages.passage_01.tagIdTo`: RFID id von z2 - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) - `multiZone.passages.passage_01.zoneIdFrom`: Zone von (muss z1 < z2) - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) - `multiZone.passages.passage_01.zoneIdTo`: Zone zu (muss z2 > z1) - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) - - `multiZone.zones.zone_1.borderDistance`: Kantenschnitt in mm - erlaubt 10mm, 15mm und 20mm - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) + - `multiZone.zones.zone_1.borderDistance`: Kantenschnitt in mm - erlaubt 50mm, 100mm, 150mm und 20mm - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) - `multiZone.zones.zone_1.chargingStation`: 1 Wenn sich die Ladestation in diese Zone gefindet. 0 für keine Ladestation - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) - `multiZone.zones.zone_1.cutOverBorder`: 1 zum Überfahren von Platten, wenn diese erkannt werden, ansonsten 0.Unterschiedliche Werte pro Zone sind nicht zulässig - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) - - `multiZone.zones.zone_1.zone_id`: Nummerierung - Start mit 1 - Mit Blockly ohne Verzögerung setzen - Änderung wird in `multiZone.multiZone` geschrieben (Vision/änderbar) - - `multiZone.rfid`: Anzahl Zonen (nur lesen) + - `multiZone.zones.zone_1.zone_id`: Nummerierung - Start mit 1 - geschrieben (Vision/nur lesen) + - `multiZone.rfid`: Anzahl RF (nur lesen) - `multiZone.multiZone`: Multizone JSON (Vision/änderbar) [Beispiel](#beispiel-blockly-startsequence-vision) - `multiZone.sendMultiZoneJson`: Änderungen an Worx senden mit mit einer Verzögerung von 1,1 Sekunden (Vision/änderbar) diff --git a/docs/de/img/areas_vision.png b/docs/de/img/areas_vision.png index a769a5a5..5c592c67 100644 Binary files a/docs/de/img/areas_vision.png and b/docs/de/img/areas_vision.png differ diff --git a/docs/en/README.md b/docs/en/README.md index 3eff2e23..6371e369 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -303,11 +303,11 @@ - `multiZone.passages.passage_01.tagIdTo`: RFID id of z2 - Set with Blockly without delay - Change is written to `multiZone.multiZone` (vision/changeable) - `multiZone.passages.passage_01.zoneIdFrom`: Zone from (must z1 < z2) - Set with Blockly without delay - Change is written to `multiZone.multiZone` (vision/changeable) - `multiZone.passages.passage_01.zoneIdTo`: Zone closed (must z2 > z1) - Set with Blockly without delay - Change is written to `multiZone.multiZone` (vision/changeable) - - `multiZone.zones.zone_1.borderDistance`: Edge cut in mm - allowed 10mm, 15mm and 20mm - Set with Blockly without delay - Change is written in `multiZone.multiZone` (vision/changeable) + - `multiZone.zones.zone_1.borderDistance`: Edge cut in mm - allowed 50mm, 100mm, 150mm and 20mm - Set with Blockly without delay - Change is written in `multiZone.multiZone` (vision/changeable) - `multiZone.zones.zone_1.chargingStation`: 1 If the charging station is found in this zone. 0 for no charging station - Set with Blockly without delay - Change is written to `multiZone.multiZone` (vision/changeable) - `multiZone.zones.zone_1.cutOverBorder`: 1 to drive over plates if they are detected, otherwise 0. Different values ​​per zone are not permitted - Set with Blockly without delay - Change is written to `multiZone.multiZone` (Vision /changeable) - - `multiZone.zones.zone_1.zone_id`: Numbering - Start with 1 - Set with Blockly without delay - Change is written to `multiZone.multiZone` (vision/changeable) - - `multiZone.rfid`: Total Areas (readonly) + - `multiZone.zones.zone_1.zone_id`: Numbering - Start with 1 - (vision/readonly) + - `multiZone.rfid`: Total RF (readonly) - `multiZone.multiZone`: Multizone JSON (Vision/changeable) [Example](#example-blockly-startsequence-vision) - `multiZone.sendMultiZoneJson`: Send changes to Worx with a delay of 1.1 seconds (vision/changeable) diff --git a/docs/en/img/areas_vision.png b/docs/en/img/areas_vision.png index 5ef2686a..20fe386f 100644 Binary files a/docs/en/img/areas_vision.png and b/docs/en/img/areas_vision.png differ diff --git a/lib/helper.js b/lib/helper.js index f8e72664..316d1892 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -405,10 +405,10 @@ module.exports = { await this.createDataPoint(`${mower.serial_number}.${o._id}`, o.common, o.type, o.native); } for (const o of objects.zones_channel) { - await this.createDataPoint(`${mower.serial_number}.multiZone.${o._id}`, o.common, o.type, o.native); + await this.createDataPoint(`${mower.serial_number}.multiZonen.${o._id}`, o.common, o.type, o.native); } for (const o of objects.passage_channel) { - await this.createDataPoint(`${mower.serial_number}.multiZone.${o._id}`, o.common, o.type, o.native); + await this.createDataPoint(`${mower.serial_number}.multiZonen.${o._id}`, o.common, o.type, o.native); } await this.evaluateVisionMultiZone(mower, true); states_cmd = { @@ -439,7 +439,7 @@ module.exports = { def: 0, desc: `Mowing zone detection`, }; - await this.createDataPoint(`${mower.serial_number}.multiZone.rfid`, common, "state"); + await this.createDataPoint(`${mower.serial_number}.multiZonen.rfid`, common, "state"); common = { name: { en: "Add new mowing time", @@ -551,7 +551,7 @@ module.exports = { read: true, write: true, }; - await this.createDataPoint(`${mower.serial_number}.multiZone.multiZone`, common, "state"); + await this.createDataPoint(`${mower.serial_number}.multiZonen.multiZonen`, common, "state"); common = { type: "boolean", role: "button", @@ -573,7 +573,7 @@ module.exports = { write: true, def: false, }; - await this.createDataPoint(`${mower.serial_number}.multiZone.sendMultiZoneJson`, common, "state"); + await this.createDataPoint(`${mower.serial_number}.multiZonen.sendmultiZonenJson`, common, "state"); } else { common = { name: { @@ -1778,7 +1778,7 @@ module.exports = { data.cfg.sc.slots = await this.evaluateVisionCalendar(mower, data.cfg.sc.slots); } if (data.dat && data.dat.rfid) { - await this.setStateAsync(`${mower.serial_number}.multiZone.rfid`, { + await this.setStateAsync(`${mower.serial_number}.multiZonen.rfid`, { val: data.dat.rfid.status, ack: true, }); @@ -1839,7 +1839,7 @@ module.exports = { }); } if (data.cfg.mz != null) { - await this.setStateAsync(`${mower.serial_number}.multiZone.multiZone`, { + await this.setStateAsync(`${mower.serial_number}.multiZonen.multiZonen`, { val: JSON.stringify(data.cfg.mz), ack: true, }); diff --git a/lib/objects.js b/lib/objects.js index 2d2798b6..64447ce2 100644 --- a/lib/objects.js +++ b/lib/objects.js @@ -1,20 +1,20 @@ module.exports = { multiZones: [ { - _id: "multiZone", + _id: "multiZonen", type: "channel", common: { name: { - en: "Multizone", - de: "Multizone", - ru: "Мультизон", - pt: "Multizona", - nl: "Multizone", + en: "Multizonen", + de: "Multizonen", + ru: "Multizonen", + pt: "Multizonas", + nl: "Multizonen", fr: "Multizone", - it: "Multizona", - es: "Multizona", - pl: "Multizon", - uk: "Мультизон", + it: "Multizonen", + es: "Multizonen", + pl: "Multizonen", + uk: "Мультизонні", "zh-cn": "多区", }, }, @@ -86,17 +86,9 @@ module.exports = { type: "number", role: "value", read: true, - write: true, - min: 1, - max: 4, + write: false, def: 1, desc: "Zonen ID", - states: { - 1: "Zone 1", - 2: "Zone 2", - 3: "Zone 3", - 4: "Zone 4", - }, }, native: {}, }, @@ -153,11 +145,17 @@ module.exports = { role: "value", read: true, write: true, - min: 5, - max: 600, + min: 50, + max: 200, unit: "mm", def: 50, desc: "Border Distance in mm", + states: { + 50: "50 mm", + 100: "100 mm", + 150: "150 mm", + 200: "200 mm", + }, }, native: {}, }, @@ -260,16 +258,8 @@ module.exports = { role: "value", read: true, write: true, - min: 1, - max: 4, - def: 0, + def: 1, desc: "The mower cut border today", - states: { - 1: "Zone 1", - 2: "Zone 2", - 3: "Zone 3", - 4: "Zone 4", - }, }, native: {}, }, @@ -294,16 +284,8 @@ module.exports = { role: "value", read: true, write: true, - min: 1, - max: 4, - def: 0, + def: 2, desc: "Zone Id to", - states: { - 1: "Zone 1", - 2: "Zone 2", - 3: "Zone 3", - 4: "Zone 4", - }, }, native: {}, }, diff --git a/main.js b/main.js index 52c2a775..73587418 100644 --- a/main.js +++ b/main.js @@ -479,12 +479,12 @@ class Worx extends utils.Adapter { */ async evaluateVisionMultiZone(mower, first) { const all_zones = await this.getObjectListAsync({ - startkey: `${this.namespace}.${mower.serial_number}.multiZone.zones.`, - endkey: `${this.namespace}.${mower.serial_number}.multiZone.zones.\u9999`, + startkey: `${this.namespace}.${mower.serial_number}.multiZonen.zones.`, + endkey: `${this.namespace}.${mower.serial_number}.multiZonen.zones.\u9999`, }); const all_passages = await this.getObjectListAsync({ - startkey: `${this.namespace}.${mower.serial_number}.multiZone.passages.`, - endkey: `${this.namespace}.${mower.serial_number}.multiZone.passages.\u9999`, + startkey: `${this.namespace}.${mower.serial_number}.multiZonen.passages.`, + endkey: `${this.namespace}.${mower.serial_number}.multiZonen.passages.\u9999`, }); const count_zone_obj = all_zones.rows.length / 5; const count_passage_obj = all_passages.rows.length / 5; @@ -493,7 +493,7 @@ class Worx extends utils.Adapter { const count_zone_current = mower.last_status.payload.cfg.mz.s.length; const count_passages_current = mower.last_status.payload.cfg.mz.p.length; this.log.debug(`Count Receive Zone: ${count_zone_current} - Count Receive Passage: ${count_passages_current}`); - let count_zone = 1; + let count_zone = 0; if ( mower.last_status && mower.last_status.payload && @@ -507,17 +507,17 @@ class Worx extends utils.Adapter { this.log.info(`Found Zone, Create Zones State`); } count_zone = 1; - for (let a = 1; a <= mower.last_status.payload.cfg.mz.s.length; a++) { + for (let a = 0; a <= mower.last_status.payload.cfg.mz.s.length - 1; a++) { const state_value = JSON.parse(JSON.stringify(objects.zones[0]).replace(/%s/gi, count_zone.toString())); await this.createDataPoint( - `${mower.serial_number}.multiZone.zones.${state_value._id}${count_zone}`, + `${mower.serial_number}.multiZonen.zones.${state_value._id}${a}`, state_value.common, state_value.type, state_value.native, ); for (const o of objects.zones_states) { await this.createDataPoint( - `${mower.serial_number}.multiZone.zones.zone_${count_zone}.${o._id}`, + `${mower.serial_number}.multiZonen.zones.zone_${a}.${o._id}`, o.common, o.type, o.native, @@ -531,9 +531,9 @@ class Worx extends utils.Adapter { } } if (count_zone_obj > count_zone_current) { - for (let a = count_zone_current + 1; a <= count_zone_obj; a++) { - this.log.debug(`Delete Zone: ${mower.serial_number}.multiZone.zones.zone_${a}`); - await this.delObjectAsync(`${mower.serial_number}.multiZone.zones.zone_${a}`, { + for (let a = count_zone_current; a <= count_zone_obj - 1; a++) { + this.log.debug(`Delete Zone: ${mower.serial_number}.multiZonen.zones.zone_${a}`); + await this.delObjectAsync(`${mower.serial_number}.multiZonen.zones.zone_${a}`, { recursive: true, }); } @@ -551,19 +551,19 @@ class Worx extends utils.Adapter { this.log.info(`Found Passages, Create Passages State`); } count_zone = 1; - for (let a = 1; a <= mower.last_status.payload.cfg.mz.p.length; a++) { + for (let a = 0; a <= mower.last_status.payload.cfg.mz.p.length - 1; a++) { const state_value = JSON.parse( JSON.stringify(objects.passage[0]).replace(/%s/gi, count_zone.toString()), ); await this.createDataPoint( - `${mower.serial_number}.multiZone.passages.${state_value._id}${("0" + count_zone).slice(-2)}`, + `${mower.serial_number}.multiZonen.passages.${state_value._id}${("0" + a).slice(-2)}`, state_value.common, state_value.type, state_value.native, ); for (const o of objects.passage_states) { await this.createDataPoint( - `${mower.serial_number}.multiZone.passages.passage_${("0" + count_zone).slice(-2)}.${o._id}`, + `${mower.serial_number}.multiZonen.passages.passage_${("0" + a).slice(-2)}.${o._id}`, o.common, o.type, o.native, @@ -577,11 +577,11 @@ class Worx extends utils.Adapter { } } if (count_passage_obj > count_passages_current) { - for (let a = count_passages_current + 1; a <= count_passage_obj; a++) { + for (let a = count_passages_current; a <= count_passage_obj - 1; a++) { this.log.debug( - `Delete Passage: ${mower.serial_number}.multiZone.passages.passage_${("0" + a).slice(-2)}`, + `Delete Passage: ${mower.serial_number}.multiZonen.passages.passage_${("0" + a).slice(-2)}`, ); - await this.delObjectAsync(`${mower.serial_number}.multiZone.passages.passage_${("0" + a).slice(-2)}`, { + await this.delObjectAsync(`${mower.serial_number}.multiZonen.passages.passage_${("0" + a).slice(-2)}`, { recursive: true, }); } @@ -589,44 +589,42 @@ class Worx extends utils.Adapter { if (!first) { this.log.debug(`Write multi zone: ${JSON.stringify(mower.last_status.payload.cfg.mz)}`); if (count_zone_current > 0) { - for (let a = 1; a <= count_zone_current; a++) { - const array_id = a - 1; - await this.setStateAsync(`${mower.serial_number}.multiZone.zones.zone_${a}.zone_id`, { - val: mower.last_status.payload.cfg.mz.s[array_id].id, + for (let a = 0; a <= count_zone_current - 1; a++) { + await this.setStateAsync(`${mower.serial_number}.multiZonen.zones.zone_${a}.zone_id`, { + val: mower.last_status.payload.cfg.mz.s[a].id, ack: true, }); - await this.setStateAsync(`${mower.serial_number}.multiZone.zones.zone_${a}.chargingStation`, { - val: mower.last_status.payload.cfg.mz.s[array_id].c, + await this.setStateAsync(`${mower.serial_number}.multiZonen.zones.zone_${a}.chargingStation`, { + val: mower.last_status.payload.cfg.mz.s[a].c, ack: true, }); - await this.setStateAsync(`${mower.serial_number}.multiZone.zones.zone_${a}.borderDistance`, { - val: mower.last_status.payload.cfg.mz.s[array_id].cfg.cut.bd, + await this.setStateAsync(`${mower.serial_number}.multiZonen.zones.zone_${a}.borderDistance`, { + val: mower.last_status.payload.cfg.mz.s[a].cfg.cut.bd, ack: true, }); - await this.setStateAsync(`${mower.serial_number}.multiZone.zones.zone_${a}.cutOverBorder`, { - val: mower.last_status.payload.cfg.mz.s[array_id].cfg.cut.ob, + await this.setStateAsync(`${mower.serial_number}.multiZonen.zones.zone_${a}.cutOverBorder`, { + val: mower.last_status.payload.cfg.mz.s[a].cfg.cut.ob, ack: true, }); } } if (count_passages_current > 0) { - for (let a = 1; a <= count_passages_current; a++) { + for (let a = 0; a <= count_passages_current - 1; a++) { const slot = ("0" + a).slice(-2); - const array_id = a - 1; - await this.setStateAsync(`${mower.serial_number}.multiZone.passages.passage_${slot}.zoneIdFrom`, { - val: mower.last_status.payload.cfg.mz.p[array_id].z1, + await this.setStateAsync(`${mower.serial_number}.multiZonen.passages.passage_${slot}.zoneIdFrom`, { + val: mower.last_status.payload.cfg.mz.p[a].z1, ack: true, }); - await this.setStateAsync(`${mower.serial_number}.multiZone.passages.passage_${slot}.zoneIdTo`, { - val: mower.last_status.payload.cfg.mz.p[array_id].z2, + await this.setStateAsync(`${mower.serial_number}.multiZonen.passages.passage_${slot}.zoneIdTo`, { + val: mower.last_status.payload.cfg.mz.p[a].z2, ack: true, }); - await this.setStateAsync(`${mower.serial_number}.multiZone.passages.passage_${slot}.tagIdFrom`, { - val: mower.last_status.payload.cfg.mz.p[array_id].t1, + await this.setStateAsync(`${mower.serial_number}.multiZonen.passages.passage_${slot}.tagIdFrom`, { + val: mower.last_status.payload.cfg.mz.p[a].t1, ack: true, }); - await this.setStateAsync(`${mower.serial_number}.multiZone.passages.passage_${slot}.tagIdTo`, { - val: mower.last_status.payload.cfg.mz.p[array_id].t2, + await this.setStateAsync(`${mower.serial_number}.multiZonen.passages.passage_${slot}.tagIdTo`, { + val: mower.last_status.payload.cfg.mz.p[a].t2, ack: true, }); } @@ -2097,11 +2095,11 @@ class Worx extends utils.Adapter { }); } else if (command === "firmware_update_start" && state.val) { this.checkfirmware(mower); - } else if (command === "multiZone" && state.val) { + } else if (command === "multiZonen" && state.val) { await this.setStateAsync(id, { ack: true, }); - } else if (command === "sendMultiZoneJson" && state.val) { + } else if (command === "sendmultiZonenJson" && state.val) { this.startSequencesVision(id, state.val, mower, true); } else if ( command === "zone_id" || @@ -2214,9 +2212,9 @@ class Worx extends utils.Adapter { * @param {boolean} send */ async startSequencesVision(id, state, mower, send) { - const load_mz = await this.getStateAsync(`${mower.serial_number}.multiZone.multiZone`); + const load_mz = await this.getStateAsync(`${mower.serial_number}.multiZonen.multiZonen`); if (!load_mz || !load_mz.val) { - this.log.warn(`Cannot load json multiZone: ${JSON.stringify(load_mz)}`); + this.log.warn(`Cannot load json multiZonen: ${JSON.stringify(load_mz)}`); return; } let mz = {}; @@ -2224,7 +2222,7 @@ class Worx extends utils.Adapter { try { mz = JSON.parse(load_mz.val); } catch (e) { - this.log.warn(`Cannot parse json multiZone: ${JSON.stringify(load_mz)}`); + this.log.warn(`Cannot parse json multiZonen: ${JSON.stringify(load_mz)}`); return; } if (send) { @@ -2328,21 +2326,31 @@ class Worx extends utils.Adapter { const third = id.split(".")[4]; const att = third == "zones" ? "s" : "p"; const second = id.split(".")[5]; - let array_pos = parseInt(second.split("_")[1]); - --array_pos; + const array_pos = parseInt(second.split("_")[1]); const command = id.split(".").pop(); if (mz && mz[att] && mz[att][array_pos]) { switch (command) { case "zone_id": - mz[att][array_pos].id = state; - break; + return; case "chargingStation": + if (state != 0 && state != 1) { + this.log.warn(`Only 0 or 1 possible - ${state}`); + return; + } mz[att][array_pos].c = state; break; case "borderDistance": + if (state != 50 && state != 100 && state != 150 && state != 200) { + this.log.warn(`Possible distance is 50, 100, 150 and 200. - ${state}`); + return; + } mz[att][array_pos].cfg.cut.bd = state; break; case "cutOverBorder": + if (state != 0 && state != 1) { + this.log.warn(`Only 0 or 1 possible - ${state}`); + return; + } mz[att][array_pos].cfg.cut.ob = state; break; case "zoneIdFrom": @@ -2361,7 +2369,7 @@ class Worx extends utils.Adapter { this.log.warn(`Cannot found command ${command}`); return; } - await this.setStateAsync(`${mower.serial_number}.multiZone.multiZone`, { + await this.setStateAsync(`${mower.serial_number}.multiZonen.multiZonen`, { val: JSON.stringify(mz), ack: true, });