Dados do rodízio de água da Sanepar

Bom dia pessoal, estava em período de teste aqui e a princípio está funcionando beleza.
Para os Curitibanos como eu que sofrem com o rodízio, tem um método para pegar estes dados através de uma API escondida da SANEPAR e vou mostrar para vocês.

URL → Rodízio de Abastecimento em Curitiba e Região Metropolitana | Sanepar

Código Node-Red →

Lembre-se de alterar para a sua URL

[{"id":"68744aaa24cf3933","type":"inject","z":"bdb58adb.f65aa8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":1840,"wires":[["f755507dfeaabe7c"]]},{"id":"f755507dfeaabe7c","type":"http request","z":"bdb58adb.f65aa8","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://services1.arcgis.com/46Oage49MS2a3O6A/arcgis/rest/services/Mapa_Rodizio_Abastecimento_RMC_View/FeatureServer/2/query?f=json&where=CODOPE%3D%2700031%27&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=OBJECTID%2CRETOMADA%2CNORMALIZACAO%2CLOCALIDADE%2CPERIODO%2COBSERVACAO%2CINICIO%2CCODOPE","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":310,"y":1840,"wires":[["f2c510aa331d9994"]]},{"id":"78efef91fa2e6752","type":"debug","z":"bdb58adb.f65aa8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":630,"y":1840,"wires":[]},{"id":"f2c510aa331d9994","type":"function","z":"bdb58adb.f65aa8","name":"","func":"msg.lastRecord = msg.payload.features[msg.payload.features.length-1].attributes\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":1840,"wires":[["78efef91fa2e6752"]]}]

O Vídeo para vocês acompanharem:

Basicamente a ideia é buscar 1 das milhares de requisições que o site da SANEPAR realizar, e trazer os dados em JSON, tendo a URL basta jogar no Node-Red.

Dicas → Ao procurar pela requests, eu percebi que a que nos importa é a que tem o maior texto, procure a sua, caso não encontre poste que tentarei ajudar.

No meu apliquei algumas regras para pegar se estiver dentro do rodízio, pegar a data final, ou se estiver fora, pegar a data de início, mas ai vai da criatividade de vcs…

Resultado Final →

image

2 Likes

Noite!

Estou tentando fazer aqui.
Peguei o endereço como falado

Fiz o esquema no node

mas a resposta no payload é diferente da sua

Será que faltou algo?

Altere no nó “http request” para PARSED JSON OBJECT
image

o seu deve estar como string, então ele retorna tudo em um texto só.

Cara, tentei fazer por conta a parte da função ali, mas meus conhecimentos em programação não são tão bons ahhaha

Você consegue exportar esse flow, ajudaria bastante, até mesmo usar como modelo para outras coisas que estou pensando em monitorar.

Segue chará…tem que adaptar para as suas necessidades dai!

[{"id":"f7cbb37112db3fa0","type":"inject","z":"bdb58adb.f65aa8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1800","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":130,"y":1560,"wires":[["6a864afa106fc83d"]]},{"id":"6a864afa106fc83d","type":"http request","z":"bdb58adb.f65aa8","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://services1.arcgis.com/46Oage49MS2a3O6A/arcgis/rest/services/Mapa_Rodizio_Abastecimento_RMC_View/FeatureServer/2/query?f=json&where=CODOPE%3D%2700031%27&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=OBJECTID%2CRETOMADA%2CNORMALIZACAO%2CLOCALIDADE%2CPERIODO%2COBSERVACAO%2CINICIO%2CCODOPE","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":280,"y":1560,"wires":[["8e6869e73e8cd102"]]},{"id":"1d2e588ec29ffbc6","type":"comment","z":"bdb58adb.f65aa8","name":"JSON Rodízio","info":"","x":110,"y":1520,"wires":[]},{"id":"8e6869e73e8cd102","type":"function","z":"bdb58adb.f65aa8","name":"","func":"//Data Atual\ndNow = new Date(Date.now())\ndNow = dNow.setHours(dNow.getHours() - 3);\ndNow = new Date(dNow)\n\n\nlastRecord = msg.payload.features[msg.payload.features.length-1].attributes\n\nmsg.inicioRodizio = new Date ( lastRecord.INICIO )\nmsg.finalRodizio = new Date ( lastRecord.NORMALIZACAO )\n\n//Trat. Msgs. Rod\nmsg.inicioRodizio = new Date(msg.inicioRodizio.setHours(msg.inicioRodizio.getHours() - 3))\nmsg.finalRodizio = msg.finalRodizio.setHours(msg.finalRodizio.getHours() - 3);\n\nmsg.tempoParaProxRod = msg.inicioRodizio - dNow\n\n\nvar date;\n\n\nif (msg.tempoParaProxRod < 0) {\n    // msg.resultText = 'Rodízio acabando em ' + String(((msg.finalRodizio -  dNow) / 3600000).toFixed(0)) + ' hrs.'\n    msg.result = parseFloat(((msg.finalRodizio -  dNow) / 3600000).toFixed(0))\n    \n    msg.date = new Date(msg.finalRodizio);\n    msg.date = (\n        ('00' + msg.date.getDate()).slice(-2) + '/' + \n        ('00' + (msg.date.getMonth()+1)).slice(-2) + '/' + \n        msg.date.getFullYear() + ' ' + \n        ('00' + msg.date.getHours()).slice(-2) + ':' + \n        ('00' + msg.date.getMinutes()).slice(-2))\n    msg.dateStatus = 'Fim do rodízio: ' + String(msg.date)\n} else {\n    // msg.resultText = 'Rodízio começando em ' + String(((msg.inicioRodizio -  dNow) / 3600000).toFixed(0)) + ' hrs.'\n    msg.result = parseFloat(((msg.inicioRodizio -  dNow) / 3600000).toFixed(0))\n    \n    msg.date = new Date(msg.inicioRodizio);\n    msg.date = (\n        ('00' + msg.date.getDate()).slice(-2) + '/' + \n        ('00' + (msg.date.getMonth()+1)).slice(-2) + '/' + \n        msg.date.getFullYear() + ' ' + \n        ('00' + msg.date.getHours()).slice(-2) + ':' + \n        ('00' + msg.date.getMinutes()).slice(-2))\n    msg.dateStatus = 'Fim do rodízio: ' + String(msg.date)\n}\n\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":440,"y":1560,"wires":[["d869e4aa83eeb71a","8c1e26495ff97ea5"]]},{"id":"d869e4aa83eeb71a","type":"function","z":"bdb58adb.f65aa8","name":"next_rod","func":"msg.entity_id = 'sensor.sanepar_status_data'\n\nmsg.payload = {\n    data: {\n        state: msg.dateStatus,\n        attributes: {\n            friendly_name: 'Proximo Rodizio',\n        }\n    }\n};\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1440,"wires":[["3a54865ef72fed39"]]},{"id":"8c1e26495ff97ea5","type":"function","z":"bdb58adb.f65aa8","name":"hours_next_rod_number","func":"msg.entity_id = 'sensor.sanepar_status_rodizio'\n\nmsg.payload = {\n    data: {\n        state: msg.result,\n        attributes: {\n            friendly_name: 'Status Rodizio',\n            unit_of_measurement: 'hrs'\n            \n        }\n    }\n};\n\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":1640,"wires":[["3a54865ef72fed39"]]},{"id":"3a54865ef72fed39","type":"ha-api","z":"bdb58adb.f65aa8","name":"","server":"d854bbe5.321208","version":1,"debugenabled":false,"protocol":"http","method":"post","path":"/api/states/{{entity_id}}","data":"","dataType":"json","responseType":"json","outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"x":870,"y":1520,"wires":[[]]},{"id":"d854bbe5.321208","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30"}]
1 Like

Valeu!!

Agora já to conseguindo dar uma mexida aqui
image

Agora é só ir brincando!

Valeu mesmo!

1 Like

Como que faz esse card?

Lá no node-red, em um node de função, você atribui o valor para um “msg.entity_id”.
image

com isso é simples, só ir no HA e adicionar o card referente a entidade que você criou ali.

1 Like