[
  {
    "id": "2178e3d59dbc4d7c",
    "type": "tab",
    "label": "Zona 1 / Zone 1",
    "disabled": false,
    "info": "ETECH LAB: flusso di esempio per una zona. Example flow for one zone. Da provare su una copia prima dell’uso. Test on a copy before use."
  },
  {
    "id": "f72ef508a0ab41f7",
    "type": "comment",
    "z": "2178e3d59dbc4d7c",
    "name": "Zona 1: rinomina le entità con quelle del tuo impianto / Rename the entities to match your system",
    "info": "",
    "x": 330,
    "y": 40,
    "wires": []
  },
  {
    "id": "4bc0f0ab52284eba",
    "type": "server-state-changed",
    "z": "2178e3d59dbc4d7c",
    "name": "Sonda zona 1 / Zone 1 sensor",
    "server": "c3a461be23b542c2",
    "version": 4,
    "entityidfilter": "sensor.temperatura_zona1",
    "entityidfiltertype": "exact",
    "entityId": "sensor.temperatura_zona1",
    "entityIdType": "exact",
    "outputinitially": true,
    "state_type": "num",
    "outputOnlyOnStateChange": true,
    "outputs": 1,
    "x": 160,
    "y": 120,
    "wires": [
      [
        "b96fa5e1bcc44b93",
        "4623fe21d7504568",
        "4ff74c6f0ed14f60"
      ]
    ]
  },
  {
    "id": "ac9c4ad189fc42a4",
    "type": "inject",
    "z": "2178e3d59dbc4d7c",
    "name": "Comfort 6:00 e 18:00",
    "props": [
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "00 06,18 * * *",
    "once": false,
    "payload": "comfort",
    "payloadType": "str",
    "x": 160,
    "y": 220,
    "wires": [
      [
        "e555ea81d5644ac5"
      ]
    ]
  },
  {
    "id": "81b436a8583544bf",
    "type": "inject",
    "z": "2178e3d59dbc4d7c",
    "name": "Eco 9:00 e 23:00",
    "props": [
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "00 09,23 * * *",
    "once": false,
    "payload": "eco",
    "payloadType": "str",
    "x": 160,
    "y": 260,
    "wires": [
      [
        "e555ea81d5644ac5"
      ]
    ]
  },
  {
    "id": "1bf928d6b6d644af",
    "type": "server-state-changed",
    "z": "2178e3d59dbc4d7c",
    "name": "Regime / Mode (input_select)",
    "server": "c3a461be23b542c2",
    "version": 4,
    "entityidfilter": "input_select.regime_zona1",
    "entityidfiltertype": "exact",
    "entityId": "input_select.regime_zona1",
    "entityIdType": "exact",
    "outputinitially": true,
    "state_type": "str",
    "outputs": 1,
    "x": 170,
    "y": 320,
    "wires": [
      [
        "e555ea81d5644ac5"
      ]
    ]
  },
  {
    "id": "e555ea81d5644ac5",
    "type": "function",
    "z": "2178e3d59dbc4d7c",
    "name": "Setpoint attivo / Active set point",
    "func": "// Combina fascia oraria e regime. Combines time band and mode.\nconst SP = { comfort: 20.5, eco: 18.0 };\nif (msg.topic === 'input_select.regime_zona1' || msg.data) {\n    context.set('regime', String(msg.payload));   // Comfort, Eco, Automatico\n} else {\n    context.set('fascia', String(msg.payload));   // comfort / eco dal programma\n}\nconst regime = (context.get('regime') || 'Automatico').toLowerCase();\nconst fascia = context.get('fascia') || 'eco';\nlet sp = regime.startsWith('comfort') ? SP.comfort : regime.startsWith('eco') ? SP.eco : SP[fascia];\nflow.set('setpoint_zona1', sp);\nmsg.payload = sp;\nreturn msg;",
    "outputs": 1,
    "x": 450,
    "y": 260,
    "wires": [
      []
    ]
  },
  {
    "id": "b96fa5e1bcc44b93",
    "type": "function",
    "z": "2178e3d59dbc4d7c",
    "name": "Isteresi 0,3 °C / Hysteresis",
    "func": "// Ingresso: msg.payload = temperatura della zona in °C\nconst sp = flow.get('setpoint_zona1') ?? 20;\nconst ist = 0.3;\nlet stato = context.get('stato') ?? false;\nconst t = Number(msg.payload);\nif (isNaN(t)) return null;\nif (t <= sp - ist) stato = true;\nelse if (t >= sp + ist) stato = false;\ncontext.set('stato', stato);\nmsg.payload = stato;\nreturn msg;",
    "outputs": 1,
    "x": 450,
    "y": 120,
    "wires": [
      [
        "4375c5a692b848b3"
      ]
    ]
  },
  {
    "id": "4375c5a692b848b3",
    "type": "api-call-service",
    "z": "2178e3d59dbc4d7c",
    "name": "Testina zona 1 / Zone 1 actuator",
    "server": "c3a461be23b542c2",
    "version": 5,
    "domain": "switch",
    "service": "turn_{{#payload}}on{{/payload}}{{^payload}}off{{/payload}}",
    "action": "switch.turn_{{#payload}}on{{/payload}}{{^payload}}off{{/payload}}",
    "entityId": [
      "switch.testina_zona1"
    ],
    "data": "",
    "dataType": "jsonata",
    "mergeContext": "",
    "x": 730,
    "y": 120,
    "wires": [
      []
    ]
  },
  {
    "id": "4623fe21d7504568",
    "type": "change",
    "z": "2178e3d59dbc4d7c",
    "name": "Verso Grafana (InfluxDB) / To Grafana",
    "rules": [
      {
        "t": "set",
        "p": "payload",
        "pt": "msg",
        "to": "{\"temperatura\": payload, \"setpoint\": $flowContext('setpoint_zona1')}",
        "tot": "jsonata"
      }
    ],
    "x": 740,
    "y": 180,
    "wires": [
      []
    ]
  },
  {
    "id": "4ff74c6f0ed14f60",
    "type": "function",
    "z": "2178e3d59dbc4d7c",
    "name": "Avviso dopo 3 ore / Alert after 3 h",
    "func": "// Se la zona chiede calore da più di 3 ore senza arrivare al setpoint, manda un avviso.\nconst sp = flow.get('setpoint_zona1') ?? 20;\nconst t = Number(msg.payload);\nif (isNaN(t)) return null;\nconst now = Date.now();\nlet since = context.get('since');\nif (t < sp - 0.3) { if (!since) { since = now; context.set('since', since); } }\nelse { context.set('since', null); context.set('sent', false); return null; }\nif (now - since > 3 * 3600 * 1000 && !context.get('sent')) {\n    context.set('sent', true);\n    msg.payload = { title: 'Zona 1', message: 'La zona 1 non arriva in temperatura da 3 ore' };\n    return msg;\n}\nreturn null;",
    "outputs": 1,
    "x": 460,
    "y": 180,
    "wires": [
      [
        "d7955f248432416a"
      ]
    ]
  },
  {
    "id": "d7955f248432416a",
    "type": "api-call-service",
    "z": "2178e3d59dbc4d7c",
    "name": "Notifica / Notify",
    "server": "c3a461be23b542c2",
    "version": 5,
    "domain": "notify",
    "service": "notify",
    "action": "notify.notify",
    "data": "{\"title\": payload.title, \"message\": payload.message}",
    "dataType": "jsonata",
    "x": 720,
    "y": 240,
    "wires": [
      []
    ]
  },
  {
    "id": "c3a461be23b542c2",
    "type": "server",
    "name": "Home Assistant",
    "addon": true
  }
]