diff --git a/README.md b/README.md index 5dccedc..c37388f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Charge Current Limit: 31.4 A -### < 0º C +### <0º C Charge Current Limit: 0 A Discharge Current Limit: 31.4 A @@ -26,12 +26,12 @@ Discharge Current Limit: 62.8 A Charge Current Limit: 62.8 A Discharge Current Limit: 62.8 A -### 11-º C +### 11-15º C Charge Current Limit: 62.8 A Discharge Current Limit: 94.2 A -### -º C +### >16º C -Charge Current Limit: 94.2 A -Discharge Current Limit: 94.2 A +Charge Current Limit: 100 A +Discharge Current Limit: 100 A diff --git a/node-red_flow.json b/node-red_flow.json new file mode 100644 index 0000000..debea1d --- /dev/null +++ b/node-red_flow.json @@ -0,0 +1,408 @@ +[ + { + "id": "cf255672ab90a22f", + "type": "tab", + "label": "Battery heater", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "edd7c4cce6eb5861", + "type": "victron-input-battery", + "z": "cf255672ab90a22f", + "service": "com.victronenergy.battery/512", + "path": "/Dc/0/Temperature", + "serviceObj": { + "service": "com.victronenergy.battery/512", + "name": "Cegasa battery" + }, + "pathObj": { + "path": "/Dc/0/Temperature", + "type": "float", + "name": "Battery temperature (°C)" + }, + "name": "batt_temp", + "onlyChanges": true, + "roundValues": "0", + "x": 380, + "y": 380, + "wires": [ + [ + "7e04d0fa828e9868" + ] + ] + }, + { + "id": "e4786f6532b0e8d0", + "type": "debug", + "z": "cf255672ab90a22f", + "name": "debug 1", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1040, + "y": 220, + "wires": [] + }, + { + "id": "43f946d4d47ba3ec", + "type": "victron-input-solarcharger", + "z": "cf255672ab90a22f", + "service": "com.victronenergy.solarcharger/273", + "path": "/Yield/Power", + "serviceObj": { + "service": "com.victronenergy.solarcharger/273", + "name": "SmartSolar MPPT VE.Can 250/100 rev2" + }, + "pathObj": { + "path": "/Yield/Power", + "type": "float", + "name": "PV Power (W)" + }, + "name": "pv_power", + "onlyChanges": true, + "roundValues": "0", + "x": 380, + "y": 440, + "wires": [ + [ + "7e04d0fa828e9868" + ] + ] + }, + { + "id": "de555a35fee6404c", + "type": "ui-switch", + "z": "cf255672ab90a22f", + "name": "heater_switch", + "label": "Calefacción", + "group": "aa9cdf043b4ff6f3", + "order": 0, + "width": 0, + "height": 0, + "passthru": false, + "decouple": false, + "topic": "topic", + "topicType": "msg", + "style": "", + "className": "", + "layout": "row-left-swapped", + "clickableArea": "switch", + "onvalue": "true", + "onvalueType": "bool", + "onicon": "", + "oncolor": "", + "offvalue": "false", + "offvalueType": "bool", + "officon": "", + "offcolor": "", + "x": 1220, + "y": 360, + "wires": [ + [] + ] + }, + { + "id": "fb3c661bf8c01d98", + "type": "shelly-gen2", + "z": "cf255672ab90a22f", + "hostname": "10.0.1.11", + "description": "shelly", + "mode": "callback", + "verbose": false, + "server": "04263f2d054cc2a1", + "outputmode": "event", + "uploadretryinterval": "5000", + "pollinginterval": 5000, + "pollstatus": false, + "getstatusoncommand": false, + "devicetype": "SNSW-001X16EU", + "devicetypemustmatchexactly": false, + "captureblutooth": false, + "outputs": 1, + "x": 810, + "y": 660, + "wires": [ + [ + "bd1f36a1d9afba8d" + ] + ] + }, + { + "id": "7e04d0fa828e9868", + "type": "delay", + "z": "cf255672ab90a22f", + "name": "", + "pauseType": "timed", + "timeout": "5", + "timeoutUnits": "seconds", + "rate": "1", + "nbRateUnits": "5", + "rateUnits": "second", + "randomFirst": "1", + "randomLast": "5", + "randomUnits": "seconds", + "drop": true, + "allowrate": false, + "outputs": 1, + "x": 610, + "y": 340, + "wires": [ + [ + "4f2f81e6c9c20a90" + ] + ] + }, + { + "id": "8c3a3af1c81eaec6", + "type": "victron-input-battery", + "z": "cf255672ab90a22f", + "service": "com.victronenergy.battery/512", + "path": "/Dc/0/Power", + "serviceObj": { + "service": "com.victronenergy.battery/512", + "name": "Cegasa battery" + }, + "pathObj": { + "path": "/Dc/0/Power", + "type": "float", + "name": "Battery power (W)" + }, + "name": "batt_power", + "onlyChanges": true, + "roundValues": "0", + "x": 380, + "y": 320, + "wires": [ + [ + "7e04d0fa828e9868" + ] + ] + }, + { + "id": "bd1f36a1d9afba8d", + "type": "function", + "z": "cf255672ab90a22f", + "name": "set_shelly_message", + "func": "let name = msg.payload.name\nlet component = msg.payload.component\n\nif (name == \"temperature\"){\n msg.topic = component == \"temperature:100\" ? \"box_temp\" : \"room_temp\"\n msg.payload = msg.payload.info.tC\n}\nelse if (name == \"switch\"){\n msg.topic = \"relay\"\n msg.payload = msg.payload.info.state\n}\nelse {\n node.warn(\"Error parsing Shelly message\")\n node.warn(msg)\n return null\n}\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 700, + "y": 500, + "wires": [ + [ + "4f2f81e6c9c20a90" + ] + ] + }, + { + "id": "4f2f81e6c9c20a90", + "type": "function", + "z": "cf255672ab90a22f", + "name": "heater_switch_manager", + "func": "context.set(msg.topic, msg.payload)\n\nlet batt_temp = context.get(\"batt_temp\")\nlet batt_power = context.get(\"batt_power\")\nlet batt_soc = context.get(\"batt_soc\")\nlet box_temp = context.get(\"box_temp\")\nlet room_temp = context.get(\"room_temp\")\nlet pv_power = context.get(\"pv_power\")\nlet relay = context.get(\"relay\")\n\nlet log = \"\"\nfor (const key of context.keys()) {\n log += key + \"=\" + context.get(key) + \" \"\n}\nnode.warn(log)\n\n// Si estamos iniciando y faltan datos apagar el radiador.\nif (batt_temp == undefined || batt_power == undefined || box_temp == undefined\n || room_temp == undefined || pv_power == undefined) {\n node.warn(\"INITIALIZING\")\n msg.payload = false\n return msg;\n}\n\n// Si la temperatura ambiente o de la batería es alta apagar el radiador.\nif (batt_temp > 20 || room_temp > 20) {\n msg.payload = false\n return msg;\n}\n\n// Si la temperatura del sarcofago es baja desmarcar que se ha llegado al límite.\nif (box_temp < 15) {\n context.set(\"box_temp_upper_limit_reached\", false)\n}\n// Si la temperatura del sarcofago es alta marcar que se ha llegado al límite.\nelse if (box_temp > 25) {\n context.set(\"box_temp_upper_limit_reached\", true)\n}\n\n// Si se ha llegado al límite superior de temperatura del sarcófago apagar el\n// radiador, hay que esperar a cruzar el límite inferior.\nif (context.get(\"box_temp_upper_limit_reached\")) {\n msg.payload = false\n return msg;\n}\n\n// Encender el radiador si la potencia de carga es alta teniendo en cuenta el SOC.\nif ((pv_power > 700 && batt_soc > 50) || (pv_power > 300 && batt_soc > 70) ||\n (pv_power > 200 && batt_soc > 90)) {\n msg.payload = true\n return msg;\n}\n\n// Encender el radiador si la potencia de carga está limitada por la temperatura\n// de la batería.\nif ((pv_power > 1200 && batt_temp < 8) || (pv_power > 2500 && batt_temp < 16)) {\n msg.payload = true\n return msg;\n}\n\n// La batería debe estar por encima de 5º, a menos que el SOC sea menor que 50%.\nif (batt_temp < 5 && batt_soc > 50) {\n msg.payload = true\n return msg;\n}\n\n// En el resto de casos apagamos el radiador.\nmsg.payload = false\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 850, + "y": 340, + "wires": [ + [ + "cd1a8c477cfe992a", + "e4786f6532b0e8d0" + ] + ] + }, + { + "id": "5a77160b6a27db82", + "type": "function", + "z": "cf255672ab90a22f", + "name": "switch_relay", + "func": "let on = msg.payload\n\nmsg.payload = {\n method: \"Switch.Set\",\n parameters : {\n id : 0,\n on : on\n }\n};\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1170, + "y": 460, + "wires": [ + [ + "fb3c661bf8c01d98" + ] + ] + }, + { + "id": "cd1a8c477cfe992a", + "type": "rbe", + "z": "cf255672ab90a22f", + "name": "", + "func": "rbe", + "gap": "", + "start": "", + "inout": "out", + "septopics": false, + "property": "payload", + "topi": "topic", + "x": 1050, + "y": 340, + "wires": [ + [ + "de555a35fee6404c", + "5a77160b6a27db82", + "2e458f61d504ee9b" + ] + ] + }, + { + "id": "2e458f61d504ee9b", + "type": "debug", + "z": "cf255672ab90a22f", + "name": "debug 2", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 1220, + "y": 300, + "wires": [] + }, + { + "id": "2c23d4c1a6fbb2c0", + "type": "victron-input-battery", + "z": "cf255672ab90a22f", + "service": "com.victronenergy.battery/512", + "path": "/Soc", + "serviceObj": { + "service": "com.victronenergy.battery/512", + "name": "Cegasa battery" + }, + "pathObj": { + "path": "/Soc", + "type": "float", + "name": "State of charge (%)" + }, + "name": "batt_soc", + "onlyChanges": true, + "roundValues": "0", + "x": 380, + "y": 260, + "wires": [ + [ + "7e04d0fa828e9868" + ] + ] + }, + { + "id": "aa9cdf043b4ff6f3", + "type": "ui-group", + "name": "Group 1", + "page": "545b3851d8568f59", + "width": "6", + "height": "1", + "order": 1, + "showTitle": true, + "className": "", + "visible": "true", + "disabled": "false", + "groupType": "default" + }, + { + "id": "04263f2d054cc2a1", + "type": "shelly-gen2-server", + "port": "10001", + "hostname": "unimatrix" + }, + { + "id": "545b3851d8568f59", + "type": "ui-page", + "name": "Page 1", + "ui": "cf2bb7479e560f99", + "path": "/page1", + "icon": "home", + "layout": "grid", + "theme": "43a2d84f031e3dc7", + "breakpoints": [ + { + "name": "Default", + "px": 0, + "cols": 3 + }, + { + "name": "Tablet", + "px": 576, + "cols": 6 + }, + { + "name": "Small Desktop", + "px": 768, + "cols": 9 + }, + { + "name": "Desktop", + "px": 1024, + "cols": 12 + } + ], + "order": 1, + "className": "", + "visible": "true", + "disabled": "false" + }, + { + "id": "cf2bb7479e560f99", + "type": "ui-base", + "name": "My Dashboard", + "path": "/dashboard", + "appIcon": "", + "includeClientData": true, + "acceptsClientConfig": [ + "ui-notification", + "ui-control" + ], + "showPathInSidebar": false, + "headerContent": "page", + "navigationStyle": "default", + "titleBarStyle": "default", + "showReconnectNotification": true, + "notificationDisplayTime": 1, + "showDisconnectNotification": true, + "allowInstall": false + }, + { + "id": "43a2d84f031e3dc7", + "type": "ui-theme", + "name": "Default Theme", + "colors": { + "surface": "#ffffff", + "primary": "#0094CE", + "bgPage": "#eeeeee", + "groupBg": "#ffffff", + "groupOutline": "#cccccc" + }, + "sizes": { + "density": "default", + "pagePadding": "12px", + "groupGap": "12px", + "groupBorderRadius": "4px", + "widgetGap": "12px" + } + } +] \ No newline at end of file