Skip to content

Instantly share code, notes, and snippets.

@ov1d1u
Created January 26, 2026 10:56
Show Gist options
  • Select an option

  • Save ov1d1u/ffbbac5c5a2137c2aaba6357d3e72c4d to your computer and use it in GitHub Desktop.

Select an option

Save ov1d1u/ffbbac5c5a2137c2aaba6357d3e72c4d to your computer and use it in GitHub Desktop.
[
{
"id": "5c6c6fe6e65c4285",
"type": "inject",
"z": "9409b244d6890952",
"name": "Nowcasting alerts",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "300",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "<?xml version=\"1.0\"?> <avertizariNowcasting><avertizare tipMesaj=\"1\" numeTipMesaj=\"Avertizare nowcasting\" dataInceput=\"2025-06-11T17:20\" dataSfarsit=\"2025-06-11T18:00\" zona=\"Jude&#x21B;ul Neam&#x163;: Dolje&#x219;ti, Sagna, Oniceni, Bozieni, St&#x103;ni&#x21B;a, G&#xE2;din&#x21B;i, Boghicea, P&#xE2;nce&#x219;ti, Bira, Poienari;&lt;br&gt;Jude&#x21B;ul Ia&#x15F;i: &#x21A;ib&#x103;ne&#x219;ti, &#x21A;ibana, Voine&#x219;ti, Dag&#xE2;&#x21B;a, Mironeasa, Sine&#x219;ti, Mogo&#x219;e&#x219;ti, O&#x21B;eleni, Tansa, &#x218;cheia, Ipatele, M&#x103;d&#xE2;rjac, Dragu&#x219;eni;&lt;br&gt;Jude&#x21B;ul Vaslui: B&#x103;ce&#x219;ti, Dume&#x219;ti, Todire&#x219;ti, Negre&#x219;ti, Rafaila;&lt;br&gt;\" semnalare=\"Grindin&#x103; de dimensiuni medii, vijelie, viteza v&#xE2;ntului la rafal&#x103; de 70&#x2026;80 km/h, frecvente desc&#x103;rc&#x103;ri electrice, averse toren&#x21B;iale ce vor cumula 20...25 l/mp.\" culoare=\"1\" numeCuloare=\"portocaliu\" modificat=\"2025-06-11 17:10:01\" creat=\"2025-06-11 17:10:01\"/><avertizare tipMesaj=\"2\" numeTipMesaj=\"Atentionare nowcasting\" dataInceput=\"2025-06-11T17:20\" dataSfarsit=\"2025-06-11T18:30\" zona=\"Jude&#x21B;ul Bac&#x103;u: Lipova;&lt;br&gt;Jude&#x21B;ul Neam&#x163;: Roman, S&#x103;b&#x103;oani, T&#x103;m&#x103;&#x219;eni, Cordun, Horia, Dolje&#x219;ti, Gher&#x103;e&#x219;ti, Trife&#x219;ti, Ion Creang&#x103;, Sagna, Icu&#x219;e&#x219;ti, Bote&#x219;ti, Secuieni, Oniceni, Valea Ursului, Dulce&#x219;ti, Bozieni, St&#x103;ni&#x21B;a, Tupila&#x21B;i, G&#xE2;din&#x21B;i, Boghicea, V&#x103;leni, P&#xE2;nce&#x219;ti, Bira, Poienari;&lt;br&gt;Jude&#x21B;ul Ia&#x15F;i: Tome&#x219;ti, Holboca, Ciurea, R&#x103;duc&#x103;neni, &#x21A;ib&#x103;ne&#x219;ti, H&#x103;l&#x103;uce&#x219;ti, Miroslava, &#x21A;ibana, Voine&#x219;ti, Costuleni, Dag&#xE2;&#x21B;a, Ciorte&#x219;ti, Comarna, Mironeasa, Sine&#x219;ti, Mogo&#x219;e&#x219;ti, Schitu Duca, Butea, Pope&#x219;ti, Sc&#xE2;nteia, O&#x21B;eleni, Pris&#x103;cani, Mirce&#x219;ti, Rachi&#x21B;eni, Horle&#x219;ti, Tansa, Cozme&#x219;ti, B&#xE2;rnova, Grajduri, &#x218;cheia, Gorban, Dolhe&#x219;ti, Dobrov&#x103;&#x21B;, &#x21A;u&#x21B;ora, Mo&#x219;na, Ipatele, Groze&#x219;ti, M&#x103;d&#xE2;rjac, Dragu&#x219;eni;&lt;br&gt;Jude&#x21B;ul Vaslui: Vaslui, Hu&#x219;i, St&#x103;nile&#x219;ti, Duda-Epureni, Cod&#x103;e&#x219;ti, Dr&#xE2;nceni, Iv&#x103;ne&#x219;ti, V&#x103;leni, Z&#x103;podeni, Sole&#x219;ti, B&#x103;ce&#x219;ti, Dume&#x219;ti, Rebricea, Muntenii de Sus, Laza, Todire&#x219;ti, Punge&#x219;ti, T&#x103;cuta, &#x218;tefan cel Mare, Bune&#x219;ti-Avere&#x219;ti, O&#x219;e&#x219;ti, Pu&#x219;ca&#x219;i, Micle&#x219;ti, Negre&#x219;ti, Dele&#x219;ti, T&#x103;t&#x103;r&#x103;ni, D&#x103;ne&#x219;ti, G&#xE2;rceni, Bo&#x21B;e&#x219;ti, Cozme&#x219;ti, Tanacu, Vulture&#x219;ti, Fere&#x219;ti, Arsura, Rafaila, B&#x103;lteni;&lt;br&gt;\" semnalare=\"intensific&#x103;ri ale v&#xE2;ntului la rafal&#x103; de 50&#x2026;70 km/h, desc&#x103;rc&#x103;ri electrice, grindin&#x103;, averse.\" culoare=\"0\" numeCuloare=\"galben\" modificat=\"2025-06-11 17:06:01\" creat=\"2025-06-11 17:06:01\"/><avertizare tipMesaj=\"2\" numeTipMesaj=\"Atentionare nowcasting\" dataInceput=\"2025-06-11T16:40\" dataSfarsit=\"2025-06-11T18:00\" zona=\"Jude&#x21B;ul Prahova: M&#x103;neciu, Brebu, Sl&#x103;nic, Izvoarele, Drajna, Cera&#x219;u, Starchiojd, Pose&#x219;ti, Tei&#x219;ani, Bertea, Predeal-S&#x103;rari, &#x218;tefe&#x219;ti, B&#x103;tr&#xE2;ni, C&#x103;rbune&#x219;ti, Arice&#x219;tii Zeletin;&lt;br&gt;Zona de munte a jude&#x21B;ului Prahova, respectiv zona de munte a localit&#x103;&#x21B;ilor: Sinaia, Comarnic, Bu&#x219;teni, M&#x103;neciu, Valea Doftanei, Cera&#x219;u, Azuga, &#x218;otrile, Bertea, Sec&#x103;ria;&lt;br&gt;\" semnalare=\"Averse toren&#x21B;iale care vor acumula 20...25 l/mp, desc&#x103;rc&#x103;ri electrice, intensific&#x103;ri ale v&#xE2;ntului, grindin&#x103;.\" culoare=\"0\" numeCuloare=\"galben\" modificat=\"2025-06-11 16:32:01\" creat=\"2025-06-11 16:32:01\"/><avertizare tipMesaj=\"2\" numeTipMesaj=\"Atentionare nowcasting\" dataInceput=\"2025-06-11T16:35\" dataSfarsit=\"2025-06-11T17:30\" zona=\"Jude&#x21B;ul Boto&#x15F;ani: Ungureni, Hude&#x219;ti, Albe&#x219;ti, Tru&#x219;e&#x219;ti, &#x218;tef&#x103;ne&#x219;ti, Co&#x21B;u&#x219;ca, Suhar&#x103;u, Lunca, Hav&#xE2;rna, Vorniceni, R&#x103;d&#x103;u&#x21B;i-Prut, C&#x103;l&#x103;ra&#x219;i, Cristine&#x219;ti, Avr&#x103;meni, George Enescu, Gorb&#x103;ne&#x219;ti, Manoleasa, Hlipiceni, P&#x103;ltini&#x219;, Vl&#x103;sine&#x219;ti, Todireni, Mileanca, Suli&#x21B;a, D&#xE2;ngeni, Santa Mare, Un&#x21B;eni, &#x218;tiubieni, Darabani, Dr&#x103;gu&#x219;eni, Durne&#x219;ti, Dob&#xE2;rceni, Corl&#x103;teni, Mih&#x103;l&#x103;&#x219;eni, Bl&#xE2;nde&#x219;ti, Cord&#x103;reni, Vii&#x219;oara, H&#x103;ne&#x219;ti, S&#x103;veni, Ripiceni, Conce&#x219;ti, Rom&#xE2;ne&#x219;ti, Mitoc, Ad&#x103;&#x219;eni, R&#x103;u&#x219;eni;&lt;br&gt;\" semnalare=\"intensific&#x103;ri ale v&#xE2;ntului la rafal&#x103; de 50&#x2026;70 km/h, desc&#x103;rc&#x103;ri electrice, grindin&#x103;, averse.\" culoare=\"0\" numeCuloare=\"galben\" modificat=\"2025-06-11 16:22:01\" creat=\"2025-06-11 16:22:01\"/><avertizare tipMesaj=\"2\" numeTipMesaj=\"Atentionare nowcasting\" dataInceput=\"2025-06-11T16:50\" dataSfarsit=\"2025-06-11T17:30\" zona=\"Jude&#x21B;ul Boto&#x15F;ani: Pr&#x103;jeni;&lt;br&gt;Jude&#x21B;ul Suceava: For&#x103;&#x219;ti, Dr&#x103;gu&#x219;eni;&lt;br&gt;Jude&#x21B;ul Neam&#x163;: T&#xE2;rgu Neam&#x21B;, R&#x103;uce&#x219;ti, Petricani, &#x21A;ibucani, Urecheni, Timi&#x219;e&#x219;ti, Brusturi, P&#x103;str&#x103;veni, R&#x103;zboieni, Tupila&#x21B;i, Dr&#x103;g&#x103;ne&#x219;ti;&lt;br&gt;Jude&#x21B;ul Ia&#x15F;i: Ia&#x219;i, Pa&#x219;cani, T&#xE2;rgu Frumos, H&#xE2;rl&#x103;u, Holboca, Belce&#x219;ti, Deleni, Podu Iloaiei, Cotnari, Scobin&#x21B;i, Lespezi, H&#x103;l&#x103;uce&#x219;ti, T&#x103;t&#x103;ru&#x219;i, Miroslava, Le&#x21B;cani, Ruginoasa, Stolniceni-Pr&#x103;jescu, Valea Seac&#x103;, Popricani, &#x218;ipote, Erbiceni, Miroslove&#x219;ti, Mo&#x21B;ca, V&#xE2;n&#x103;tori, B&#x103;l&#x21B;a&#x21B;i, Cepleni&#x21B;a, Vl&#x103;deni, Dume&#x219;ti, Strunga, Ion Neculce, Sine&#x219;ti, Bivolari, Andrie&#x219;eni, Valea Lupului, Todire&#x219;ti, Focuri, Criste&#x219;ti, Mogo&#x219;e&#x219;ti-Siret, Sire&#x21B;el, Pope&#x219;ti, Lungani, Ungheni, Victoria, Br&#x103;e&#x219;ti, Probota, &#x21A;ig&#x103;n&#x103;&#x219;i, Rediu, Trife&#x219;ti, Gropni&#x21B;a, Plugari, Coarnele Caprei, Gol&#x103;ie&#x219;ti, Alexandru I. Cuza, Movileni, Bal&#x219;, Hele&#x219;teni, Aroneanu, H&#x103;rm&#x103;ne&#x219;ti, Rom&#xE2;ne&#x219;ti, Ciohor&#x103;ni, F&#xE2;nt&#xE2;nele, Coste&#x219;ti, Ro&#x219;cani, Cucuteni;&lt;br&gt;\" semnalare=\"intensific&#x103;ri ale v&#xE2;ntului la rafal&#x103; de 50&#x2026;70 km/h, desc&#x103;rc&#x103;ri electrice, grindin&#x103;, averse.\" culoare=\"0\" numeCuloare=\"galben\" modificat=\"2025-06-11 15:54:01\" creat=\"2025-06-11 15:54:01\"/></avertizariNowcasting>",
"payloadType": "str",
"x": 150,
"y": 1240,
"wires": [
[
"8e1b7439215e0fff"
]
]
},
{
"id": "8e1b7439215e0fff",
"type": "http request",
"z": "9409b244d6890952",
"name": "",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://www.meteoromania.ro/avertizari-nowcasting-xml.php",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 330,
"y": 1240,
"wires": [
[
"db3d4d9bcfc20132"
]
]
},
{
"id": "db3d4d9bcfc20132",
"type": "xml",
"z": "9409b244d6890952",
"name": "",
"property": "payload",
"attr": "",
"chr": "",
"x": 435,
"y": 1240,
"wires": [
[
"2fb9e559bfa430e0"
]
],
"l": false
},
{
"id": "cd7981b3abf14b75",
"type": "function",
"z": "9409b244d6890952",
"name": "for result in results",
"func": "var messages = [];\nvar seenHeadlines = new Set();\nmsg.results.forEach(alert => {\n var headline = alert;\n if (!seenHeadlines.has(headline)) {\n seenHeadlines.add(headline);\n messages.push({ alert: alert });\n }\n});\nreturn [messages];",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 695,
"y": 1240,
"wires": [
[
"a9a219cc16b743cc",
"da449ad7e5251f2d"
]
],
"l": false
},
{
"id": "70a4db441520b6a8",
"type": "function",
"z": "9409b244d6890952",
"name": "Set message",
"func": "function replaceRomanianDiacritics(str) {\n const diacriticMap = {\n 'Ă': 'A', 'Â': 'A', 'Ș': 'S', 'Ş': 'S', 'Ț': 'T', 'Ţ': 'T', 'Î': 'I',\n 'ă': 'a', 'â': 'a', 'ș': 's', 'ş': 's', 'ț': 't', 'ţ': 't', 'î': 'i'\n };\n\n return str.replace(/[ĂÂȘŞȚŢÎăâșşțţî]/g, function (match) {\n return diacriticMap[match] || match;\n });\n}\n\nlet startHour = \"\";\nlet endHour = \"\";\n\ntry {\n const startDate = new Date(msg.alert.dataInceput);\n if (isNaN(startDate.getTime())) {\n throw new Error('Invalid start date');\n }\n startHour = `${startDate.getHours()}:${startDate.getMinutes().toString().padStart(2, '0')}`;\n} catch (error) {\n console.error('Failed to parse start date:', error);\n}\n\ntry {\n const endDate = new Date(msg.alert.dataSfarsit);\n if (isNaN(endDate.getTime())) {\n throw new Error('Invalid end date');\n }\n endHour = `${endDate.getHours()}:${endDate.getMinutes().toString().padStart(2, '0')}`;\n} catch (error) {\n console.error('Failed to parse end date:', error);\n}\n\nlet headline = msg.headline.text;\nif (!headline.endsWith(\".\")) {\n headline = `${headline}.`;\n}\n\nconst title = `ALERTĂ NOWCASTING COD ${msg.alert.numeCuloare.toUpperCase()}`;\nconst timeRange = (startHour && endHour) ? `(${startHour}-${endHour})` : \"\";\nconst message = `${title} ${timeRange}: ${headline}`;\n\nif (title !== \"\" && message !== \"\") {\n msg.message = replaceRomanianDiacritics(message);\n return msg;\n}",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1050,
"y": 1240,
"wires": [
[
"7dbdcae0ab70ffff",
"4405ff414f12332d"
]
]
},
{
"id": "30f016f5d3e83676",
"type": "api-call-service",
"z": "9409b244d6890952",
"name": "GPT process",
"server": "b59d18a8.44b6f8",
"version": 7,
"debugenabled": false,
"action": "openai_conversation.generate_content",
"floorId": [],
"areaId": [],
"deviceId": [],
"entityId": [],
"labelId": [],
"data": "{\t \"config_entry\": \"4cd59172989f43f67ce95c9e48b75634\",\t \"prompt\": \"Rezumă, în cel mult 10 cuvinte, următorul text: \" & alert.semnalare \t}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [
{
"property": "headline",
"propertyType": "msg",
"value": "",
"valueType": "results"
}
],
"queue": "none",
"blockInputOverrides": true,
"domain": "openai_conversation",
"service": "generate_content",
"x": 890,
"y": 1240,
"wires": [
[
"70a4db441520b6a8"
]
]
},
{
"id": "4405ff414f12332d",
"type": "api-call-service",
"z": "9409b244d6890952",
"name": "Meshcore send",
"server": "b59d18a8.44b6f8",
"version": 7,
"debugenabled": false,
"action": "meshcore.send_channel_message",
"floorId": [],
"areaId": [],
"deviceId": [],
"entityId": [],
"labelId": [],
"data": "{\t \"channel_idx\": 0,\t \"message\": message\t}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"blockInputOverrides": true,
"domain": "meshcore",
"service": "send_channel_message",
"x": 1220,
"y": 1260,
"wires": [
[
"266815ee1485cf65"
]
]
},
{
"id": "266815ee1485cf65",
"type": "delay",
"z": "9409b244d6890952",
"name": "",
"pauseType": "delay",
"timeout": "15",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "minute",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"allowrate": false,
"outputs": 1,
"x": 1335,
"y": 1260,
"wires": [
[
"355ace024ed370c9"
]
],
"l": false
},
{
"id": "da449ad7e5251f2d",
"type": "delay",
"z": "9409b244d6890952",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "30",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 775,
"y": 1240,
"wires": [
[
"30f016f5d3e83676"
]
],
"l": false
},
{
"id": "2fb9e559bfa430e0",
"type": "function",
"z": "9409b244d6890952",
"name": "Get Iași warnings",
"func": "function replaceRomanianDiacritics(str) {\n const diacriticMap = {\n 'Ă': 'A', 'Â': 'A', 'Ș': 'S', 'Ş': 'S', 'Ț': 'T', 'Ţ': 'T', 'Î': 'I',\n 'ă': 'a', 'â': 'a', 'ș': 's', 'ş': 's', 'ț': 't', 'ţ': 't', 'î': 'i'\n };\n\n return str.replace(/[ĂÂȘŞȚŢÎăâșşțţî]/g, function (match) {\n return diacriticMap[match] || match;\n });\n}\n\nfunction extractWarnings(data, newerThan) {\n if (typeof data.avertizariNowcasting !== 'object') {\n return {};\n }\n const result = { lastUpdate: null, warnings: {} };\n const warnings = data.avertizariNowcasting.avertizare;\n\n let latestModification = null;\n\n const countyRegex = /Jude[țtțţ]ul (.*?)(?::\\s*(.*))?$/i;\n\n for (const warning of warnings) {\n const modificat = new Date(warning.$.modificat);\n\n if (modificat <= newerThan) {\n continue;\n }\n\n if (!latestModification || modificat > latestModification) {\n latestModification = modificat;\n }\n\n const zones = warning.$.zona.split(/<br>|;/);\n for (const zone of zones) {\n if (zone.trim().length === 0) continue;\n\n const parts = countyRegex.exec(zone);\n if (parts) {\n const county = replaceRomanianDiacritics(parts[1]).trim();\n const localities = (parts[2] ? parts[2].split(',').map(loc => replaceRomanianDiacritics(loc.trim())) : []);\n\n const warningDetails = {\n semnalare: warning.$.semnalare,\n dataInceput: warning.$.dataInceput,\n dataSfarsit: warning.$.dataSfarsit,\n numeCuloare: warning.$.numeCuloare,\n localitati: localities\n };\n\n if (!result.warnings[county]) {\n result.warnings[county] = [];\n }\n\n result.warnings[county].push(warningDetails);\n }\n }\n }\n\n if (latestModification) {\n result.lastUpdate = latestModification.toISOString();\n }\n\n return result;\n}\n\nmsg.results = [];\nvar startDate = new Date(0);\nvar startDateStr = flow.get(\"latestNowcastingAlert\", \"store\");\nif (startDateStr) {\n startDate = new Date(startDateStr);\n}\n\nvar nowcastingAlerts = extractWarnings(msg.payload, startDate);\nmsg.unfilteredNowcastingAlerts = nowcastingAlerts;\n\nif (nowcastingAlerts.lastUpdate != undefined && nowcastingAlerts.lastUpdate != null) {\n flow.set(\"latestNowcastingAlert\", nowcastingAlerts.lastUpdate, \"store\");\n if (nowcastingAlerts.warnings.hasOwnProperty(\"Iasi\")) {\n nowcastingAlerts.warnings[\"Iasi\"].forEach(function (alert) {\n // If alert.localitati is empty or includes \"Iasi\", add it to results\n if (alert.localitati.length === 0 || alert.localitati.includes(\"Iasi\")) {\n msg.results.push(alert);\n }\n });\n }\n}\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 570,
"y": 1240,
"wires": [
[
"cd7981b3abf14b75"
]
]
},
{
"id": "355ace024ed370c9",
"type": "api-call-service",
"z": "9409b244d6890952",
"name": "Meshcore send",
"server": "b59d18a8.44b6f8",
"version": 7,
"debugenabled": false,
"action": "meshcore.send_channel_message",
"floorId": [],
"areaId": [],
"deviceId": [],
"entityId": [],
"labelId": [],
"data": "{\t \"channel_idx\": 0,\t \"message\": \"Nota: aceasta functionalitate este in faza beta si pot aparea erori de raportare.\"\t}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"blockInputOverrides": true,
"domain": "meshcore",
"service": "send_channel_message",
"x": 1460,
"y": 1260,
"wires": [
[]
]
},
{
"id": "a9a219cc16b743cc",
"type": "switch",
"z": "9409b244d6890952",
"name": "Cod portocaliu sau roșu",
"property": "$uppercase(alert.numeCuloare)",
"propertyType": "jsonata",
"rules": [
{
"t": "regex",
"v": "PORTOCALIU|ROSU|ROȘU|ROŞU",
"vt": "str",
"case": false
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 765,
"y": 1320,
"wires": [
[
"252e88d111a94299"
]
],
"l": false
},
{
"id": "252e88d111a94299",
"type": "function",
"z": "9409b244d6890952",
"name": "Set message",
"func": "function capitalizeFirstLetter(string) {\n if (!string) return string;\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nlet startHour = \"\";\nlet endHour = \"\";\n\n// Start date\ntry {\n const startDate = new Date(msg.alert.dataInceput);\n if (isNaN(startDate.getTime())) {\n throw new Error('Invalid start date');\n }\n startHour = `${startDate.getHours()}:${startDate.getMinutes().toString().padStart(2, '0')}`;\n} catch (error) {\n console.error('Failed to parse start date:', error);\n startHour = \"ora de început necunoscută\"; // Set a default message if needed\n}\n\n// End date\ntry {\n const endDate = new Date(msg.alert.dataSfarsit);\n if (isNaN(endDate.getTime())) {\n throw new Error('Invalid end date');\n }\n endHour = `${endDate.getHours()}:${endDate.getMinutes().toString().padStart(2, '0')}`;\n} catch (error) {\n console.error('Failed to parse end date:', error);\n endHour = \"ora de sfârșit necunoscută\"; // Set a default message if needed\n}\n\nlet headline = msg.alert.semnalare;\nif (!headline.endsWith(\".\")) {\n headline = `${headline}.`;\n}\n\nconst title = `ALERTĂ NOWCASTING COD ${msg.alert.numeCuloare.toUpperCase()}`;\nconst timeRange = (startHour && endHour) ? `Valabil de la ${startHour} până la ${endHour}.` : \"\";\nconst message = `${capitalizeFirstLetter(headline)} ${timeRange}`;\n\nmsg.title = title;\nmsg.message = message;\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 825,
"y": 1320,
"wires": [
[
"5612181716d3b369",
"01b01e5f8e0b4e8a"
]
],
"l": false
},
{
"id": "5612181716d3b369",
"type": "api-call-service",
"z": "9409b244d6890952",
"name": "Send urgent notification",
"server": "b59d18a8.44b6f8",
"version": 7,
"debugenabled": false,
"action": "notify.mobile_apps",
"floorId": [],
"areaId": [],
"deviceId": [],
"entityId": [],
"labelId": [],
"data": "{\t \"title\": title,\t \"message\": message,\t \"data\":{\t \"ttl\":0,\t \"notification_icon\":\"mdi:weather-cloudy-alert\",\t \"priority\":\"high\",\t \"channel\":\"Urgențe\",\t \"actions\":[]\t }\t}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"blockInputOverrides": false,
"domain": "notify",
"service": "mobile_apps",
"x": 1010,
"y": 1320,
"wires": [
[]
]
},
{
"id": "01b01e5f8e0b4e8a",
"type": "api-call-service",
"z": "9409b244d6890952",
"name": "GPT process",
"server": "b59d18a8.44b6f8",
"version": 7,
"debugenabled": false,
"action": "openai_conversation.generate_content",
"floorId": [],
"areaId": [],
"deviceId": [],
"entityId": [],
"labelId": [],
"data": "{\t \"config_entry\": \"4cd59172989f43f67ce95c9e48b75634\",\t \"prompt\": \"Pregătește următorul text pentru a fi citit de o aplicatie text-to-speech. Extinde orice prescurtări și adaugă eventualele cuvinte lipsă de legătură:\\n\\nAtenție, a fost emisă o alertă imediată de vreme severă: \" & message\t}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [
{
"property": "headline",
"propertyType": "msg",
"value": "",
"valueType": "results"
}
],
"queue": "none",
"blockInputOverrides": true,
"domain": "openai_conversation",
"service": "generate_content",
"x": 990,
"y": 1380,
"wires": [
[
"38487570932f4d34"
]
]
},
{
"id": "38487570932f4d34",
"type": "api-call-service",
"z": "9409b244d6890952",
"name": "Announce",
"server": "b59d18a8.44b6f8",
"version": 7,
"debugenabled": false,
"action": "script.announce_emergency",
"floorId": [],
"areaId": [],
"deviceId": [],
"entityId": [],
"labelId": [],
"data": "{ \"message\": headline.text }",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"blockInputOverrides": false,
"domain": "script",
"service": "announce_emergency",
"x": 1160,
"y": 1380,
"wires": [
[]
]
},
{
"id": "b59d18a8.44b6f8",
"type": "server",
"name": "Home Assistant",
"version": 6,
"addon": true,
"rejectUnauthorizedCerts": true,
"ha_boolean": [
"y",
"yes",
"true",
"on",
"home",
"open"
],
"connectionDelay": true,
"cacheJson": true,
"heartbeat": false,
"heartbeatInterval": 30,
"areaSelector": "friendlyName",
"deviceSelector": "friendlyName",
"entitySelector": "friendlyName",
"statusSeparator": "at: ",
"statusYear": "hidden",
"statusMonth": "short",
"statusDay": "numeric",
"statusHourCycle": "h23",
"statusTimeFormat": "h:m",
"enableGlobalContextStore": true
},
{
"id": "18ddc65246da7573",
"type": "global-config",
"env": [],
"modules": {
"node-red-contrib-home-assistant-websocket": "0.80.3"
}
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment