Fala Pessoal,
Compartilhando com vocês um projetinho que monitora as Linhas de Metrô e Trem de São Paulo/SP baseado no Rastreamento Correios [Node-Red] do queridissimo @kelvinrafaeli.
Ahaaaa José, mas eu não uso metrô e CPTM de SP!!! Tranquilo, espero que sirva de inspiração para te ajudar em alguma outra necessidade.
Node Red
Código Node-Red:
[{"id":"a9677bd61d822a0b","type":"group","z":"ae486ad7c144f9df","name":"Metrô SP","style":{"stroke":"#a4a4a4","fill":"#e1e1e1","label":true,"color":"#000000"},"nodes":["1d45cb0596f828cb","795606b7d45dde2a","3b95ce65a0a271ac","d74b89b621ccbf65","1cadc20bd1bdc102","159ac8b655c8c06a","d37a60a3885b8973","9ece87c268947457"],"x":34,"y":259,"w":832,"h":142},{"id":"1d45cb0596f828cb","type":"inject","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"Digitar Chave token e IP","props":[{"p":"payload"}],"repeat":"1800","crontab":"","once":true,"onceDelay":"2","topic":"","payload":"","payloadType":"date","x":95,"y":300,"wires":[["795606b7d45dde2a"]],"l":false},{"id":"795606b7d45dde2a","type":"change","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"Token e IP HASS","rules":[{"t":"set","p":"token","pt":"flow","to":"SEU_TOKEN_AQUI","tot":"str"},{"t":"set","p":"ip","pt":"flow","to":"192.168.15.83:8123","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":300,"wires":[[]]},{"id":"3b95ce65a0a271ac","type":"switch","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"","property":"from","propertyType":"msg","rules":[{"t":"eq","v":"to","vt":"msg"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":790,"y":360,"wires":[[],["d74b89b621ccbf65"]]},{"id":"d74b89b621ccbf65","type":"http request","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"Site","method":"GET","ret":"txt","paytoqs":"body","url":"http://apps.cptm.sp.gov.br:8080/AppMobileService/api/LinhasMetropolitanas","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":270,"y":360,"wires":[["1cadc20bd1bdc102"]]},{"id":"1cadc20bd1bdc102","type":"json","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"","property":"payload","action":"","pretty":false,"x":390,"y":360,"wires":[["159ac8b655c8c06a"]]},{"id":"159ac8b655c8c06a","type":"function","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"Cria Sensor","func":"msg.from = msg.from + 1;\n\nmsg.entity_id = 'sensor.transporte_' + msg.from;\n\n// Verificar se payload é um array e se o índice from é válido\nif (!Array.isArray(msg.payload) || msg.from >= msg.payload.length) {\n // Encerra o fluxo se a condição não for atendida\n return null;\n}\n\nvar dados = msg.payload[msg.from];\n\nif (!dados) {\n return null; // Garante que não tenta acessar propriedades de um objeto indefinido\n}\n\nvar status = dados.Status || \"Desconhecido\";\nvar descricao = dados.Descricao || \"Sem Detalhamento\";\nvar linha_id = dados.LinhaId || \"N/A\";\nvar nome = (dados.Nome || \"Sem Nome\").charAt(0).toUpperCase() + (dados.Nome || \"\").slice(1).toLowerCase();\nvar tipo = dados.Tipo || \"N/A\";\n\nvar data_geracao = new Date(dados.DataGeracao || Date.now());\nvar data_formatada = data_geracao.toLocaleString('pt-BR');\n\nmsg.payload = {\n data: {\n state: status,\n attributes: {\n nome: nome,\n status: status,\n descricao: descricao,\n linha_id: linha_id,\n tipo: tipo,\n data_geracao: data_formatada,\n texto_sensor: `- Status: ${status}\\n- Descrição:\\n ${descricao}\\n- Atualização: ${data_formatada}`,\n friendly_name: `Linha ${linha_id} ${nome}`,\n }\n }\n};\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":360,"wires":[["9ece87c268947457"]]},{"id":"d37a60a3885b8973","type":"inject","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"","props":[{"p":"from","v":"-1","vt":"num"},{"p":"to","v":"13","vt":"num"}],"repeat":"120","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":130,"y":360,"wires":[["d74b89b621ccbf65"]]},{"id":"9ece87c268947457","type":"ha-api","z":"ae486ad7c144f9df","g":"a9677bd61d822a0b","name":"","server":"2b35d450378a9ff7","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":670,"y":360,"wires":[["3b95ce65a0a271ac"]]},{"id":"2b35d450378a9ff7","type":"server","name":"Home Assistant","version":5,"addon":false,"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":": ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"default","statusTimeFormat":"h:m","enableGlobalContextStore":false}]
Lovelace
Código Lovelace
- type: vertical-stack
cards:
- type: custom:button-card
layout: icon_name
name: Situação Linhas Metrô/CPTM SP
icon: mdi:train
styles:
grid:
- grid-template-areas: '"n i"'
- grid-template-columns: 1fr 20%
icon:
- align-self: end
- color: var(--text-primary-color)
- height: 35px
card:
- padding: 4px
- height: 40px
- background: '#001487'
name:
- color: var(--text-primary-color)
- justify-self: start
- padding-left: 10%
- font-weight: 400
- font-size: 18px
- type: custom:auto-entities
card:
type: grid
columns: 1
square: false
card_param: cards
show_empty: false
filter:
include:
- entity_id: sensor.transporte_*
options:
type: custom:mushroom-template-card
entity: this.entity_id
primary: '{{ state_attr(''this.entity_id'', ''friendly_name'') }}'
secondary: '{{ state_attr(''this.entity_id'', ''texto_sensor'') }}'
icon: |-
{% if
states['this.entity_id'].state == "Informação indisponível" %} mdi:close-box {% elif
states['this.entity_id'].state == "Operação Normal" %} mdi:check-circle {% elif
states['this.entity_id'].state == "Operação Parcial" %} mdi:alert-rhombus-outline {% elif
states['this.entity_id'].state == "Operação com Impacto Pontual" %} mdi:alert-circle {% elif
states['this.entity_id'].state == "Circulação de Trens" %} mdi:alert-circle {% elif
states['this.entity_id'].state == "Velocidade Reduzida" %} mdi:speedometer-slow {% elif
states['this.entity_id'].state == "Atividade Programada" %} mdi:calendar-clock {% elif
states['this.entity_id'].state == "Operação Encerrada" %} mdi:close-circle {% elif
states['this.entity_id'].state == "Operações Encerradas" %} mdi:close-circle {% endif %}
icon_color: |-
{% if
states['this.entity_id'].state == "Informação indisponível" %} red {% elif
states['this.entity_id'].state == "Operação Normal" %} green {% elif
states['this.entity_id'].state == "Operação Parcial" %} red {% elif
states['this.entity_id'].state == "Operação com Impacto Pontual" %} yellow {% elif
states['this.entity_id'].state == "Circulação de Trens" %} '#e1762b' {% elif
states['this.entity_id'].state == "Velocidade Reduzida" %} '#e2d96e' {% elif
states['this.entity_id'].state == "Atividade Programada" %} yellow {% elif
states['this.entity_id'].state == "Operação Encerrada" %} '#d0cace' {% elif
states['this.entity_id'].state == "Operações Encerradas" %} '#d0cace' {% endif %}
multiline_secondary: true
tap_action:
action: more-info
order_by:
last_changed: asc
sort:
count: 15