From 30f2c6e7a54145181660c93bd78270a5042c5fe0 Mon Sep 17 00:00:00 2001 From: raph666 Date: Tue, 31 Mar 2026 18:42:22 +0200 Subject: [PATCH] Create arkteos_reg3_nodered.json add node-red flow --- arkteos_reg3_nodered.json | 248 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 arkteos_reg3_nodered.json diff --git a/arkteos_reg3_nodered.json b/arkteos_reg3_nodered.json new file mode 100644 index 0000000..37b8e41 --- /dev/null +++ b/arkteos_reg3_nodered.json @@ -0,0 +1,248 @@ +[ + { + "id": "arkteos_flow", + "type": "tab", + "label": "Arkteos REG3", + "disabled": false, + "info": "Intégration PAC Arkteos Zuran 4 via addon proxy.\nStreaming permanent sur :9641.\nPublication MQTT avec discovery automatique HA.\nTrames 163 bytes (frigo), 227 bytes (régulation).\nRemplacer par l'IP de Home Assistant dans le nœud PAC via proxy." + }, + { + "id": "arkteos_mqtt_broker", + "type": "mqtt-broker", + "name": "Mosquitto local", + "broker": "core-mosquitto", + "port": "1883", + "clientid": "nodered_arkteos", + "usetls": false, + "compatmode": false, + "keepalive": "60", + "cleansession": true, + "birthTopic": "", + "birthQos": "0", + "birthPayload": "", + "closeTopic": "", + "closeQos": "0", + "closePayload": "", + "willTopic": "", + "willQos": "0", + "willPayload": "", + "credentials": { + "user": "", + "password": "" + } + }, + { + "id": "arkteos_tcp_in", + "type": "tcp in", + "z": "arkteos_flow", + "name": "PAC via proxy", + "server": "", + "port": "9641", + "datamode": "stream", + "datatype": "buffer", + "newline": "", + "topic": "", + "trim": false, + "base64": false, + "tls": "", + "x": 160, + "y": 100, + "wires": [["arkteos_parse_frame"]] + }, + { + "id": "arkteos_parse_frame", + "type": "function", + "z": "arkteos_flow", + "name": "Parse frame", + "func": "const buf = msg.payload;\nif (!Buffer.isBuffer(buf) || buf.length === 0) return null;\n\nconst size = buf.length;\n\nfunction read16s(b, i) {\n const v = b[i] + b[i + 1] * 256;\n return v >= 32768 ? v - 65536 : v;\n}\nfunction read16u(b, i) {\n return b[i] + b[i + 1] * 256;\n}\nfunction read8(b, i) {\n return b[i];\n}\n\nif (size === 163) {\n msg.payload = {\n frame_type: 'frigo',\n exterieur_temp: read16s(buf, 24) / 10,\n freq_comp_actuelle: read16u(buf, 52),\n dc_voltage: read16u(buf, 62)\n };\n return msg;\n}\n\nif (size === 227) {\n msg.payload = {\n frame_type: 'regulation',\n puissance_inst_produite: read16u(buf, 16) / 10,\n puissance_inst_consommee: read16u(buf, 18) / 10,\n primaire_temp_eau_aller: read16s(buf, 54) / 10,\n primaire_temp_eau_retour: read16s(buf, 56) / 10,\n primaire_pression: read8(buf, 62) / 10,\n zone1_temp_interieur: read16s(buf, 68) / 10,\n zone1_consigne: read16s(buf, 70) / 10,\n ecs_temp_eau_milieu: read16s(buf, 108) / 10,\n ecs_temp_eau_bas: read16s(buf, 110) / 10\n };\n return msg;\n}\n\nreturn null;\n", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 380, + "y": 100, + "wires": [["arkteos_route"]] + }, + { + "id": "arkteos_route", + "type": "switch", + "z": "arkteos_flow", + "name": "Route par type", + "property": "payload.frame_type", + "propertyType": "msg", + "rules": [ + { "t": "eq", "v": "frigo", "vt": "str" }, + { "t": "eq", "v": "regulation", "vt": "str" } + ], + "checkall": "false", + "repair": false, + "outputs": 2, + "x": 580, + "y": 100, + "wires": [ + ["arkteos_debug_frigo_parsed", "arkteos_publish_frigo"], + ["arkteos_debug_regulation_parsed", "arkteos_publish_regulation"] + ] + }, + { + "id": "arkteos_debug_frigo_parsed", + "type": "debug", + "z": "arkteos_flow", + "name": "Frigo parsé", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 810, + "y": 40, + "wires": [] + }, + { + "id": "arkteos_debug_regulation_parsed", + "type": "debug", + "z": "arkteos_flow", + "name": "Regulation parsée", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 830, + "y": 160, + "wires": [] + }, + { + "id": "arkteos_publish_frigo", + "type": "function", + "z": "arkteos_flow", + "name": "Publish frigo", + "func": "const data = msg.payload;\nconst msgs = [];\n\nconst sensors = [\n { topic: 'arkteos/frigo/exterieur_temp', value: data.exterieur_temp },\n { topic: 'arkteos/frigo/freq_comp_actuelle', value: data.freq_comp_actuelle },\n { topic: 'arkteos/frigo/dc_voltage', value: data.dc_voltage }\n];\n\nfor (const s of sensors) {\n msgs.push({ topic: s.topic, payload: String(s.value), qos: 0, retain: true });\n}\n\nreturn [msgs];\n", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 800, + "y": 80, + "wires": [["arkteos_debug_frigo_published", "arkteos_mqtt_out"]] + }, + { + "id": "arkteos_publish_regulation", + "type": "function", + "z": "arkteos_flow", + "name": "Publish regulation", + "func": "const data = msg.payload;\nconst msgs = [];\n\nconst sensors = [\n { topic: 'arkteos/regulation/puissance_inst_produite', value: data.puissance_inst_produite },\n { topic: 'arkteos/regulation/puissance_inst_consommee', value: data.puissance_inst_consommee },\n { topic: 'arkteos/regulation/primaire_temp_eau_aller', value: data.primaire_temp_eau_aller },\n { topic: 'arkteos/regulation/primaire_temp_eau_retour', value: data.primaire_temp_eau_retour },\n { topic: 'arkteos/regulation/primaire_pression', value: data.primaire_pression },\n { topic: 'arkteos/regulation/zone1_temp_interieur', value: data.zone1_temp_interieur },\n { topic: 'arkteos/regulation/zone1_consigne', value: data.zone1_consigne },\n { topic: 'arkteos/regulation/ecs_temp_eau_milieu', value: data.ecs_temp_eau_milieu },\n { topic: 'arkteos/regulation/ecs_temp_eau_bas', value: data.ecs_temp_eau_bas }\n];\n\nfor (const s of sensors) {\n msgs.push({ topic: s.topic, payload: String(s.value), qos: 0, retain: true });\n}\n\nreturn [msgs];\n", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 800, + "y": 200, + "wires": [["arkteos_debug_regulation_published", "arkteos_mqtt_out"]] + }, + { + "id": "arkteos_debug_frigo_published", + "type": "debug", + "z": "arkteos_flow", + "name": "Frigo MQTT publié", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1040, + "y": 40, + "wires": [] + }, + { + "id": "arkteos_debug_regulation_published", + "type": "debug", + "z": "arkteos_flow", + "name": "Regulation MQTT publiée", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1060, + "y": 240, + "wires": [] + }, + { + "id": "arkteos_mqtt_out", + "type": "mqtt out", + "z": "arkteos_flow", + "name": "MQTT publish", + "topic": "", + "qos": "0", + "retain": "true", + "broker": "arkteos_mqtt_broker", + "x": 1060, + "y": 140, + "wires": [] + }, + { + "id": "arkteos_discovery_inject", + "type": "inject", + "z": "arkteos_flow", + "name": "Send discovery (1x au démarrage)", + "props": [{ "p": "payload" }], + "repeat": "", + "crontab": "", + "once": true, + "onceDelay": 3, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 200, + "y": 360, + "wires": [["arkteos_discovery"]] + }, + { + "id": "arkteos_discovery", + "type": "function", + "z": "arkteos_flow", + "name": "MQTT Discovery", + "func": "const device = {\n identifiers: ['arkteos_zuran4'],\n name: 'PAC Arkteos Zuran 4',\n model: 'Zuran 4',\n manufacturer: 'Arkteos'\n};\n\nconst sensors = [\n {\n unique_id: 'arkteos_exterieur_temp',\n name: 'Température extérieure',\n state_topic: 'arkteos/frigo/exterieur_temp',\n unit_of_measurement: '°C',\n device_class: 'temperature',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_freq_comp_actuelle',\n name: 'Fréquence compresseur actuelle',\n state_topic: 'arkteos/frigo/freq_comp_actuelle',\n unit_of_measurement: 'Hz',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_dc_voltage',\n name: 'Voltage DC compresseur',\n state_topic: 'arkteos/frigo/dc_voltage',\n unit_of_measurement: 'V',\n device_class: 'voltage',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_puissance_inst_produite',\n name: 'Puissance instantanée produite',\n state_topic: 'arkteos/regulation/puissance_inst_produite',\n unit_of_measurement: 'kW',\n device_class: 'power',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_puissance_inst_consommee',\n name: 'Puissance instantanée consommée',\n state_topic: 'arkteos/regulation/puissance_inst_consommee',\n unit_of_measurement: 'kW',\n device_class: 'power',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_primaire_temp_eau_aller',\n name: 'Température eau primaire aller',\n state_topic: 'arkteos/regulation/primaire_temp_eau_aller',\n unit_of_measurement: '°C',\n device_class: 'temperature',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_primaire_temp_eau_retour',\n name: 'Température eau primaire retour',\n state_topic: 'arkteos/regulation/primaire_temp_eau_retour',\n unit_of_measurement: '°C',\n device_class: 'temperature',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_primaire_pression',\n name: 'Pression eau primaire',\n state_topic: 'arkteos/regulation/primaire_pression',\n unit_of_measurement: 'bar',\n device_class: 'pressure',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_zone1_temp_interieur',\n name: 'Température intérieure zone 1',\n state_topic: 'arkteos/regulation/zone1_temp_interieur',\n unit_of_measurement: '°C',\n device_class: 'temperature',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_zone1_consigne',\n name: 'Consigne température zone 1',\n state_topic: 'arkteos/regulation/zone1_consigne',\n unit_of_measurement: '°C',\n device_class: 'temperature',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_ecs_temp_eau_milieu',\n name: 'Température ballon ECS milieu',\n state_topic: 'arkteos/regulation/ecs_temp_eau_milieu',\n unit_of_measurement: '°C',\n device_class: 'temperature',\n state_class: 'measurement'\n },\n {\n unique_id: 'arkteos_ecs_temp_eau_bas',\n name: 'Température ballon ECS bas',\n state_topic: 'arkteos/regulation/ecs_temp_eau_bas',\n unit_of_measurement: '°C',\n device_class: 'temperature',\n state_class: 'measurement'\n }\n];\n\nconst msgs = [];\nfor (const s of sensors) {\n const config = Object.assign({}, s, { device });\n msgs.push({\n topic: `homeassistant/sensor/${s.unique_id}/config`,\n payload: JSON.stringify(config),\n qos: 0,\n retain: true\n });\n}\n\nreturn [msgs];\n", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 480, + "y": 360, + "wires": [["arkteos_debug_discovery", "arkteos_mqtt_out"]] + }, + { + "id": "arkteos_debug_discovery", + "type": "debug", + "z": "arkteos_flow", + "name": "Discovery MQTT", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 710, + "y": 420, + "wires": [] + } +]