Compare commits
3 Commits
4ee0424815
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 70e2114288 | |||
| 85ebf4fc69 | |||
| 0290a750e1 |
10
README.md
10
README.md
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Charge Current Limit: 31.4 A
|
Charge Current Limit: 31.4 A
|
||||||
|
|
||||||
### < 0º C
|
### <0º C
|
||||||
|
|
||||||
Charge Current Limit: 0 A
|
Charge Current Limit: 0 A
|
||||||
Discharge Current Limit: 31.4 A
|
Discharge Current Limit: 31.4 A
|
||||||
@@ -26,12 +26,12 @@ Discharge Current Limit: 62.8 A
|
|||||||
Charge Current Limit: 62.8 A
|
Charge Current Limit: 62.8 A
|
||||||
Discharge Current Limit: 62.8 A
|
Discharge Current Limit: 62.8 A
|
||||||
|
|
||||||
### 11-º C
|
### 11-15º C
|
||||||
|
|
||||||
Charge Current Limit: 62.8 A
|
Charge Current Limit: 62.8 A
|
||||||
Discharge Current Limit: 94.2 A
|
Discharge Current Limit: 94.2 A
|
||||||
|
|
||||||
### -º C
|
### >16º C
|
||||||
|
|
||||||
Charge Current Limit: 94.2 A
|
Charge Current Limit: 100 A
|
||||||
Discharge Current Limit: 94.2 A
|
Discharge Current Limit: 100 A
|
||||||
|
|||||||
@@ -1,47 +1,12 @@
|
|||||||
# aemet
|
# Aemet
|
||||||
|
Endpoint to get forecast summary to use with battery heater.
|
||||||
|
|
||||||
## 🧰 Usage
|
https://697361d50005d83da5ca.functions.app.fosil.eu/
|
||||||
|
|
||||||
### GET /ping
|
# Deployment
|
||||||
|
|
||||||
- Returns a "Pong" message.
|
Login:
|
||||||
|
appwrite login --endpoint "https://app.fosil.eu/v1"
|
||||||
|
|
||||||
**Response**
|
Deploy:
|
||||||
|
appwrite client --project-id="696bbb680032fc5192c9" && appwrite functions create-deployment --function-id=69736073000fadb92a9f --code="." --activate=true
|
||||||
Sample `200` Response:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Pong
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET, POST, PUT, PATCH, DELETE /
|
|
||||||
|
|
||||||
- Returns a "Learn More" JSON response.
|
|
||||||
|
|
||||||
**Response**
|
|
||||||
|
|
||||||
Sample `200` Response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"motto": "Build like a team of hundreds_",
|
|
||||||
"learn": "https://appwrite.io/docs",
|
|
||||||
"connect": "https://appwrite.io/discord",
|
|
||||||
"getInspired": "https://builtwith.appwrite.io"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚙️ Configuration
|
|
||||||
|
|
||||||
| Setting | Value |
|
|
||||||
| ----------------- | ------------- |
|
|
||||||
| Runtime | Bun (1.0) |
|
|
||||||
| Entrypoint | `src/main.ts` |
|
|
||||||
| Build Commands | `bun install` |
|
|
||||||
| Permissions | `any` |
|
|
||||||
| Timeout (Seconds) | 15 |
|
|
||||||
| Scopes | `users.read` |
|
|
||||||
|
|
||||||
## 🔒 Environment Variables
|
|
||||||
|
|
||||||
No environment variables required.
|
|
||||||
|
|||||||
@@ -10,9 +10,12 @@
|
|||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.1.16",
|
"@types/bun": "^1.3.6",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
},
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@@ -13,7 +13,11 @@
|
|||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.1.16",
|
"@types/bun": "^1.3.6",
|
||||||
"prettier": "^3.2.5"
|
"prettier": "^3.2.5"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,19 @@ export default async ({ req, res, log, error }: any) => {
|
|||||||
throw new Error(`Error! status: ${response.status}`);
|
throw new Error(`Error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const decoder = new TextDecoder('iso-8859-1'); // It should be iso-8859-15 but Bum v1.1 does not support it.
|
const decoder = new TextDecoder('windows-1252'); // It should be iso-8859-15 but Bum v1.1 does not support it.
|
||||||
let xml = decoder.decode(await response.arrayBuffer())
|
let xml = decoder.decode(await response.arrayBuffer())
|
||||||
|
|
||||||
const parser = new XMLParser();
|
const options = {
|
||||||
|
attributeNamePrefix: "",
|
||||||
|
ignoreAttributes: false
|
||||||
|
};
|
||||||
|
const parser = new XMLParser(options);
|
||||||
let json = parser.parse(xml);
|
let json = parser.parse(xml);
|
||||||
log(json.root.prediccion)
|
let currentDay = json.root.prediccion.dia[0]
|
||||||
return res.json({ sucess: true, data: json.root.prediccion })
|
return res.json({ sucess: true, data: currentDay })
|
||||||
|
} catch (err: any) {
|
||||||
} catch(err: any) {
|
|
||||||
error("Error fetching forecast: " + err.message);
|
error("Error fetching forecast: " + err.message);
|
||||||
return res.json({success: false, error: err.message})
|
return res.json({ success: false, error: err.message })
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
29
functions/aemet/tsconfig.json
Normal file
29
functions/aemet/tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Environment setup & latest features
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "Preserve",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowJs": true,
|
||||||
|
|
||||||
|
// Bundler mode
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
// Best practices
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
|
||||||
|
// Some stricter flags (disabled by default)
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noPropertyAccessFromIndexSignature": false
|
||||||
|
}
|
||||||
|
}
|
||||||
524
node-red_flow.json
Normal file
524
node-red_flow.json
Normal file
@@ -0,0 +1,524 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"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": 80,
|
||||||
|
"y": 200,
|
||||||
|
"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": 740,
|
||||||
|
"y": 40,
|
||||||
|
"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": 80,
|
||||||
|
"y": 260,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"7e04d0fa828e9868"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "de555a35fee6404c",
|
||||||
|
"type": "ui-switch",
|
||||||
|
"z": "cf255672ab90a22f",
|
||||||
|
"name": "heater_on",
|
||||||
|
"label": "Calefacción",
|
||||||
|
"group": "aa9cdf043b4ff6f3",
|
||||||
|
"order": 1,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"passthru": false,
|
||||||
|
"decouple": false,
|
||||||
|
"topic": "topic",
|
||||||
|
"topicType": "msg",
|
||||||
|
"style": "",
|
||||||
|
"className": "",
|
||||||
|
"layout": "row-spread",
|
||||||
|
"clickableArea": "none",
|
||||||
|
"onvalue": "true",
|
||||||
|
"onvalueType": "bool",
|
||||||
|
"onicon": "",
|
||||||
|
"oncolor": "",
|
||||||
|
"offvalue": "false",
|
||||||
|
"offvalueType": "bool",
|
||||||
|
"officon": "",
|
||||||
|
"offcolor": "",
|
||||||
|
"x": 940,
|
||||||
|
"y": 160,
|
||||||
|
"wires": [
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fb3c661bf8c01d98",
|
||||||
|
"type": "shelly-gen2",
|
||||||
|
"z": "cf255672ab90a22f",
|
||||||
|
"hostname": "172.24.24.2",
|
||||||
|
"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": 490,
|
||||||
|
"y": 520,
|
||||||
|
"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": 310,
|
||||||
|
"y": 160,
|
||||||
|
"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": 80,
|
||||||
|
"y": 140,
|
||||||
|
"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": 280,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"4f2f81e6c9c20a90",
|
||||||
|
"0f85c811db6b90cb"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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\")\nlet force_heater = context.get(\"force_heater\")\n\nlet log = \"\"\nfor (const key of context.keys()) {\n log += key + \"=\" + context.get(key) + \" \"\n}\n//node.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// Comprobar si se ha pedido explicitamente encender la calefacción.\nif (context.get(\"force_heater\")) {\n msg.payload = true\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// Encender el radiador si la batería está fría y hay suficiente SOC.\nif ((batt_temp < 5 && batt_soc > 50) || (batt_temp < 6 && batt_soc > 60) ||\n (batt_temp < 8 && batt_soc > 70) || (batt_temp < 12 && batt_soc > 80) ||\n (batt_temp < 16 && batt_soc > 90)) {\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": 550,
|
||||||
|
"y": 160,
|
||||||
|
"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": 970,
|
||||||
|
"y": 380,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"fb3c661bf8c01d98"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cd1a8c477cfe992a",
|
||||||
|
"type": "rbe",
|
||||||
|
"z": "cf255672ab90a22f",
|
||||||
|
"name": "filter equal",
|
||||||
|
"func": "rbe",
|
||||||
|
"gap": "",
|
||||||
|
"start": "",
|
||||||
|
"inout": "out",
|
||||||
|
"septopics": false,
|
||||||
|
"property": "payload",
|
||||||
|
"topi": "topic",
|
||||||
|
"x": 770,
|
||||||
|
"y": 160,
|
||||||
|
"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": 940,
|
||||||
|
"y": 100,
|
||||||
|
"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": 80,
|
||||||
|
"y": 80,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"7e04d0fa828e9868"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0f85c811db6b90cb",
|
||||||
|
"type": "switch",
|
||||||
|
"z": "cf255672ab90a22f",
|
||||||
|
"name": "",
|
||||||
|
"property": "topic",
|
||||||
|
"propertyType": "msg",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "box_temp",
|
||||||
|
"vt": "str"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"t": "eq",
|
||||||
|
"v": "room_temp",
|
||||||
|
"vt": "str"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checkall": "true",
|
||||||
|
"repair": false,
|
||||||
|
"outputs": 2,
|
||||||
|
"x": 530,
|
||||||
|
"y": 360,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"9593b9b734c4e4f9"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"62d7f8dd71fa7b38"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9593b9b734c4e4f9",
|
||||||
|
"type": "ui-text",
|
||||||
|
"z": "cf255672ab90a22f",
|
||||||
|
"group": "aa9cdf043b4ff6f3",
|
||||||
|
"order": 3,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"name": "box_temp",
|
||||||
|
"label": "Sarcófago",
|
||||||
|
"format": "{{msg.payload}}",
|
||||||
|
"layout": "row-spread",
|
||||||
|
"style": false,
|
||||||
|
"font": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"color": "#717171",
|
||||||
|
"wrapText": false,
|
||||||
|
"className": "",
|
||||||
|
"value": "payload",
|
||||||
|
"valueType": "msg",
|
||||||
|
"x": 680,
|
||||||
|
"y": 340,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "62d7f8dd71fa7b38",
|
||||||
|
"type": "ui-text",
|
||||||
|
"z": "cf255672ab90a22f",
|
||||||
|
"group": "aa9cdf043b4ff6f3",
|
||||||
|
"order": 4,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"name": "room_text",
|
||||||
|
"label": "Habitación",
|
||||||
|
"format": "{{msg.payload}}",
|
||||||
|
"layout": "row-spread",
|
||||||
|
"style": false,
|
||||||
|
"font": "",
|
||||||
|
"fontSize": 16,
|
||||||
|
"color": "#717171",
|
||||||
|
"wrapText": false,
|
||||||
|
"className": "",
|
||||||
|
"value": "payload",
|
||||||
|
"valueType": "msg",
|
||||||
|
"x": 680,
|
||||||
|
"y": 380,
|
||||||
|
"wires": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "91d7f7d3a52c6875",
|
||||||
|
"type": "ui-switch",
|
||||||
|
"z": "cf255672ab90a22f",
|
||||||
|
"name": "force_heater",
|
||||||
|
"label": "Forzar calefacción",
|
||||||
|
"group": "aa9cdf043b4ff6f3",
|
||||||
|
"order": 2,
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"passthru": false,
|
||||||
|
"decouple": false,
|
||||||
|
"topic": "force_heater",
|
||||||
|
"topicType": "str",
|
||||||
|
"style": "",
|
||||||
|
"className": "",
|
||||||
|
"layout": "row-spread",
|
||||||
|
"clickableArea": "switch",
|
||||||
|
"onvalue": "true",
|
||||||
|
"onvalueType": "bool",
|
||||||
|
"onicon": "",
|
||||||
|
"oncolor": "",
|
||||||
|
"offvalue": "false",
|
||||||
|
"offvalueType": "bool",
|
||||||
|
"officon": "",
|
||||||
|
"offcolor": "",
|
||||||
|
"x": 310,
|
||||||
|
"y": 100,
|
||||||
|
"wires": [
|
||||||
|
[
|
||||||
|
"4f2f81e6c9c20a90"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "aa9cdf043b4ff6f3",
|
||||||
|
"type": "ui-group",
|
||||||
|
"name": "Group 1",
|
||||||
|
"page": "545b3851d8568f59",
|
||||||
|
"width": "6",
|
||||||
|
"height": "1",
|
||||||
|
"order": 1,
|
||||||
|
"showTitle": false,
|
||||||
|
"className": "",
|
||||||
|
"visible": "true",
|
||||||
|
"disabled": "false",
|
||||||
|
"groupType": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "04263f2d054cc2a1",
|
||||||
|
"type": "shelly-gen2-server",
|
||||||
|
"port": "10001",
|
||||||
|
"hostname": "unimatrix"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "545b3851d8568f59",
|
||||||
|
"type": "ui-page",
|
||||||
|
"name": "Calefacción",
|
||||||
|
"ui": "cf2bb7479e560f99",
|
||||||
|
"path": "/heater",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user