Ajuda com calculo em Node-Red e chartjs-card

Boas,

Sobre a apresentação de valores nos gráficos chartjs-card, alguém me consegue ajudar a inserir o calculo que tenho em baixo em yaml, no function node?

Tenho este template a funcionar:

### Custo €€€ Mes
      custo_energia_mes_casa:
        friendly_name: "Fatura Energia Mensal"
        icon_template: "mdi:currency-eur"
        value_template: >
          {{ ( states('sensor.energy_shelly_em_casa_monthly_total')|float(0) * 0.1927 + states('sensor.monthly_energy_cicle_days_shelly_em_casa')|float(0) * 0.1459 ) | round(2) }}
        unit_of_measurement: "€"

E gostava de inserir estes calculos acimo no function node:

let month;
let year;
let cur_date = new Date();

msg.topic = `
SELECT
  CONCAT(
  	'[',
  	GROUP_CONCAT(DAY(\`date\`)),
  	']'
  ) AS days,
  ROUND(SUM(\`consumo_energia_diario\`), 3) AS total,
  FORMAT(round(((sum(\`consumo_energia_diario\`) * 0.1927 )), 2), 2) AS 'total_eur',
  CONCAT(
  	'["',
  	GROUP_CONCAT(IF(\`consumo_energia_diario\` >= 10, 'red', IF(\`consumo_energia_diario\` >= 5, 'orange', 'green')) SEPARATOR '","'),
  	'"]'
  ) AS colors,
  CONCAT(
  	'[',
  	GROUP_CONCAT(DAY(\`date\`) SEPARATOR ','),
  	']'
  ) AS labels,
  CONCAT(
  	'[',
  	GROUP_CONCAT(ROUND(consumo_energia_diario, 2) SEPARATOR ','),
  	']'
  ) AS data,
  'info in attributes' AS attributes
FROM \`consumo_casa\`
`;

if (msg.payload == "Últimos 30 dias") {
    msg.topic += "WHERE `date` BETWEEN CURRENT_DATE - INTERVAL 30 DAY AND CURRENT_DATE;";
    msg.label = msg.payload.toLowerCase();
} else {
    switch (msg.payload) {
        case "Janeiro":
            month = 1;
            break;
        case "Fevereiro":
            month = 2;
            break;
        case "Março":
            month = 3;
            break;
        case "Abril":
            month = 4;
            break;
        case "Maio":
            month = 5;
            break;
        case "Junho":
            month = 6;
            break;
        case "Julho":
            month = 7;
            break;
        case "Agosto":
            month = 8;
            break;
        case "Setembro":
            month = 9;
            break;
        case "Outubro":
            month = 10;
            break;
        case "Novembro":
            month = 11;
            break;
        case "Dezembro":
            month = 12;
            break;
    }
    
    year = (cur_date.getMonth()+1 > month ? cur_date.getFullYear() : cur_date.getFullYear()-1 );
    msg.label = msg.payload + " " + year;
    msg.topic += "WHERE MONTH(`date`) = "+month+" AND YEAR(`date`) = "+year+";";
}


return msg;

Tentei até mesmo inserir do mesmo modo, mas não funciona e não sei como fazer.

Obrigado

Coloca o código dentro de um template node e vê se funciona.

image

Assim?
Acho que estou a fazer algo de errado…

Só com essa imagem não dá para perceber o que possa estar mal. Coloca aqui o código completo do template node e também o erro que tens no debug. Tudo devidamente formatado…

Claro :man_facepalming:

Este é o flow que estou a experimentar, e me dá erro. Mas no entanto tenho outro flow que utiliza a mesma Database do mysql node, mas isso não deve implicar?

[{"id":"1dd4c1a8.2698ce","type":"template","z":"9e778893.1e95e8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"let month;\nlet year;\nlet cur_date = new Date();\n\nmsg.topic = `\nSELECT\n  CONCAT(\n  \t'[',\n  \tGROUP_CONCAT(DAY(\\`date\\`)),\n  \t']'\n  ) AS days,\n  ROUND(SUM(\\`consumo_energia_diario\\`), 3) AS total,\n  FORMAT(round(((sum(\\`consumo_energia_diario\\`) * 0.1927 )), 2), 2) AS 'total_eur',\n  CONCAT(\n  \t'[\"',\n  \tGROUP_CONCAT(IF(\\`consumo_energia_diario\\` >= 10, 'red', IF(\\`consumo_energia_diario\\` >= 5, 'orange', 'green')) SEPARATOR '\",\"'),\n  \t'\"]'\n  ) AS colors,\n  CONCAT(\n  \t'[',\n  \tGROUP_CONCAT(DAY(\\`date\\`) SEPARATOR ','),\n  \t']'\n  ) AS labels,\n  CONCAT(\n  \t'[',\n  \tGROUP_CONCAT(ROUND(consumo_energia_diario, 2) SEPARATOR ','),\n  \t']'\n  ) AS data,\n  'info in attributes' AS attributes\nFROM \\`consumo_casa\\`\n`;\n\nif (msg.payload == \"Últimos 30 dias\") {\n    msg.topic += \"WHERE `date` BETWEEN CURRENT_DATE - INTERVAL 30 DAY AND CURRENT_DATE;\";\n    msg.label = msg.payload.toLowerCase();\n} else {\n    switch (msg.payload) {\n        case \"Janeiro\":\n            month = 1;\n            break;\n        case \"Fevereiro\":\n            month = 2;\n            break;\n        case \"Março\":\n            month = 3;\n            break;\n        case \"Abril\":\n            month = 4;\n            break;\n        case \"Maio\":\n            month = 5;\n            break;\n        case \"Junho\":\n            month = 6;\n            break;\n        case \"Julho\":\n            month = 7;\n            break;\n        case \"Agosto\":\n            month = 8;\n            break;\n        case \"Setembro\":\n            month = 9;\n            break;\n        case \"Outubro\":\n            month = 10;\n            break;\n        case \"Novembro\":\n            month = 11;\n            break;\n        case \"Dezembro\":\n            month = 12;\n            break;\n    }\n    \n    year = (cur_date.getMonth()+1 > month ? cur_date.getFullYear() : cur_date.getFullYear()-1 );\n    msg.label = msg.payload + \" \" + year;\n    msg.topic += \"WHERE MONTH(`date`) = \"+month+\" AND YEAR(`date`) = \"+year+\";\";\n}\n\n\nreturn msg;","output":"str","x":380,"y":620,"wires":[["a3ff06ce.cab2a8"]]},{"id":"f4728210.6b656","type":"ha-entity","z":"9e778893.1e95e8","name":"PZEM2a","server":"","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"pzem_energy_db_2a"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"payload[0].attributes","stateType":"msg","attributes":[{"property":"days","value":"payload[0].days","valueType":"msg"},{"property":"total","value":"payload[0].total","valueType":"msg"},{"property":"colors","value":"payload[0].colors","valueType":"msg"},{"property":"labels","value":"payload[0].labels","valueType":"msg"},{"property":"data","value":"payload[0].data","valueType":"msg"},{"property":"label","value":"label","valueType":"msg"},{"property":"total_eur","value":"payload[0].total_eur","valueType":"msg"}],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":1040,"y":620,"wires":[[]]},{"id":"fabc91b.0000a7","type":"poll-state","z":"9e778893.1e95e8","name":"trigger select","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"60","updateIntervalUnits":"seconds","outputinitially":true,"outputonchanged":true,"entity_id":"input_select.energy_daily_graph_select_2a","state_type":"str","halt_if":"Últimos 30 dias","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"x":120,"y":620,"wires":[["f56c5945.df7538","1dd4c1a8.2698ce"],["1dd4c1a8.2698ce"]]},{"id":"582dcb48.91cd74","type":"comment","z":"9e778893.1e95e8","name":"PZEM2a","info":"","x":110,"y":560,"wires":[]},{"id":"f56c5945.df7538","type":"stoptimer","z":"9e778893.1e95e8","duration":"30","units":"Minute","payloadtype":"num","payloadval":"0","name":"","x":400,"y":680,"wires":[["31a4653a.999eda"],[]]},{"id":"31a4653a.999eda","type":"api-call-service","z":"9e778893.1e95e8","name":"PZEM 2a set \"Últimos 30 dias\"","server":"","version":1,"debugenabled":false,"service_domain":"input_select","service":"select_option","entityId":"input_select.energy_daily_graph_select_2a","data":"{\"option\":\"Últimos 30 dias\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":670,"y":680,"wires":[[]]},{"id":"a3ff06ce.cab2a8","type":"mysql","z":"9e778893.1e95e8","mydb":"cd87069d.cf4cb8","name":"","x":630,"y":620,"wires":[["f4728210.6b656","9ae8fec2.2003c"]]},{"id":"cd87069d.cf4cb8","type":"MySQLdatabase","name":"Consumos Energeticos","host":"core-mariadb","port":"3306","db":"custom_data","tz":"","charset":""}]

E o erro é este:

"Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'input_select.energy_daily_graph_select_2a' at line 1"

Este erro refere-se ao node “mysql node” mas deve ser por o template não estar correto…

Sim, é por isso mesmo. Não estou a perceber o que estás a tentar fazer com o flow e surgem-me algumas questões.

  • Porque estás a usar um poll state node e não um events state node?
  • Porque é que estás a ligar a duas saídas do poll state node ao Template node?

Pelo que vejo do erro tem a ver com o conteúdo do payload que tem o nome do input select que usaste, e que vem do poll state node. Mete um debug e vê o que está a passar no payload, poderá ser um problema de formatação do texto.

Este flow apanhei-o do tutorial “base de dados leve”, creio. E de fato funciona, conforme estava.
Mas como queria alterar a formula de calculo, não sei como fazer.

Como fazias para isto funcionar?

19/04/2022, 22:30:13node: 3e50d515.07232a
input_select.energy_daily_graph_select_2a : msg.payload : string[1950]
"let month;↵let year;↵let cur_date = new Date();↵↵msg.topic = `↵SELECT↵  CONCAT(↵  →'[',↵  →GROUP_CONCAT(DAY(\`date\`)),↵  →']'↵  ) AS days,↵  ROUND(SUM(\`consumo_energia_diario\`), 3) AS total,↵  FORMAT(round(((sum(\`consumo_energia_diario\`) * 0.1927 )), 2), 2) AS 'total_eur',↵  CONCAT(↵  →'["',↵  →GROUP_CONCAT(IF(\`consumo_energia_diario\` >= 10, 'red', IF(\`consumo_energia_diario\` >= 5, 'orange', 'green')) SEPARATOR '","'),↵  →'"]'↵  ) AS colors,↵  CONCAT(↵  →'[',↵  →GROUP_CONCAT(DAY(\`date\`) SEPARATOR ','),↵  →']'↵  ) AS labels,↵  CONCAT(↵  →'[',↵  →GROUP_CONCAT(ROUND(consumo_energia_diario, 2) SEPARATOR ','),↵  →']'↵  ) AS data,↵  'info in attributes' AS attributes↵FROM \`consumo_casa\`↵`;↵↵if (msg.payload == "Últimos 30 dias") {↵    msg.topic += "WHERE `date` BETWEEN CURRENT_DATE - INTERVAL 30 DAY AND CURRENT_DATE;";↵    msg.label = msg.payload.toLowerCase();↵} else {↵    switch (msg.payload) {↵        case "Janeiro":↵            month = 1;↵            break;↵        case "Feve..."
19/04/2022, 22:30:13node: 9ae8fec2.2003c
SELECT CONCAT( '[', GROUP_CONCAT(DAY(`date`)), ']' ) AS days, ROUND(SUM(`consumo_energia_diario`), 3) AS total, FORMAT(round(((sum(`consumo_energia_diario`) * 0.1927 )), 2), 2) AS 'total_eur', CONCAT( '["', GROUP_CONCAT(IF(`consumo_energia_diario` >= 10, 'red', IF(`consumo_energia_diario` >= 5, 'orange', 'green')) SEPARATOR '","'), '"]' ) AS colors, CONCAT( '[', GROUP_CONCAT(DAY(`date`) SEPARATOR ','), ']' ) AS labels, CONCAT( '[', GROUP_CONCAT(ROUND(consumo_energia_diario, 2) SEPARATOR ','), ']' ) AS data, 'info in attributes' AS attributes FROM `consumo_casa` WHERE MONTH(`date`) = 3 AND YEAR(`date`) = 2022; : msg.payload : array[1]
[ object ]
19/04/2022, 22:30:13node: a3ff06ce.cab2a8
msg : error
"Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'input_select.energy_daily_graph_select_2a' at line 1"
19/04/2022, 22:31:08node: 9ae8fec2.2003c
SELECT CONCAT( '[', GROUP_CONCAT(DAY(`date`)), ']' ) AS days, ROUND(SUM(`consumo_energia_diario`), 3) AS total, FORMAT(round(((sum(`consumo_energia_diario`) * 0.1927 )), 2), 2) AS 'total_eur', CONCAT( '["', GROUP_CONCAT(IF(`consumo_energia_diario` >= 10, 'red', IF(`consumo_energia_diario` >= 5, 'orange', 'green')) SEPARATOR '","'), '"]' ) AS colors, CONCAT( '[', GROUP_CONCAT(DAY(`date`) SEPARATOR ','), ']' ) AS labels, CONCAT( '[', GROUP_CONCAT(ROUND(consumo_energia_diario, 2) SEPARATOR ','), ']' ) AS data, 'info in attributes' AS attributes FROM `consumo_casa` WHERE MONTH(`date`) = 3 AND YEAR(`date`) = 2022; : msg.payload : array[1]
[ object ]
19/04/2022, 22:31:09node: 3e50d515.07232a
input_select.energy_daily_graph_select_2a : msg.payload : string[1950]
"let month;↵let year;↵let cur_date = new Date();↵↵msg.topic = `↵SELECT↵  CONCAT(↵  →'[',↵  →GROUP_CONCAT(DAY(\`date\`)),↵  →']'↵  ) AS days,↵  ROUND(SUM(\`consumo_energia_diario\`), 3) AS total,↵  FORMAT(round(((sum(\`consumo_energia_diario\`) * 0.1927 )), 2), 2) AS 'total_eur',↵  CONCAT(↵  →'["',↵  →GROUP_CONCAT(IF(\`consumo_energia_diario\` >= 10, 'red', IF(\`consumo_energia_diario\` >= 5, 'orange', 'green')) SEPARATOR '","'),↵  →'"]'↵  ) AS colors,↵  CONCAT(↵  →'[',↵  →GROUP_CONCAT(DAY(\`date\`) SEPARATOR ','),↵  →']'↵  ) AS labels,↵  CONCAT(↵  →'[',↵  →GROUP_CONCAT(ROUND(consumo_energia_diario, 2) SEPARATOR ','),↵  →']'↵  ) AS data,↵  'info in attributes' AS attributes↵FROM \`consumo_casa\`↵`;↵↵if (msg.payload == "Últimos 30 dias") {↵    msg.topic += "WHERE `date` BETWEEN CURRENT_DATE - INTERVAL 30 DAY AND CURRENT_DATE;";↵    msg.label = msg.payload.toLowerCase();↵} else {↵    switch (msg.payload) {↵        case "Janeiro":↵            month = 1;↵            break;↵        case "Feve..."
19/04/2022, 22:31:10node: a3ff06ce.cab2a8
msg : error
"Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'input_select.energy_daily_graph_select_2a' at line 1"

SQL não é o meu forte. Se explicares exactamente o que pretende pode ser quem alguém mais entendido possa ajudar.

O que pretendo é mesmo o que está no inicio do topico, ou seja, o template que tenho a funcionar em yaml “sensor.custo_energia_mes_casa”, queria fazer o mesmo neste flow no node-red.
Porque quero ter a apresentação do grafico selétivel por meses:
image

O problema é que a formula de calculo do sensor template não funciona no function node. Pelo menos eu nao consigo fazer na mesma formatação.

image

Instala um cliente mysql (pode ser o Heidi Sql), adiciona a connection para o tua base de dados e copia a tua query para lá a ver do que se queixa…

Depois até podes remover a parte do statement que está a dar erro para teres a certeza que a query corre sem erros. Então aí é que adicionas o que pretendes e vais validando senão dá erro …

Testo as minhas queries desta forma antes de colocar no NR.

1 Curtiu

Eu tenho o flow e o query a funcionar.
Consigo alterar no input_select e apresenta-me tudo certinho, de acordo com a formula de calculo que lá tenho.
Gostava era de inserir um estado de um sensor HA na formula do query:

FORMAT(round(((sum(\`consumo_energia_diario\`) * 0.1927 * 0.1459), 2), 2) AS 'total_eur',

Algo tipo assim:

FORMAT(round(((sum(\`consumo_energia_diario\`) * 0.1927 + states('sensor.monthly_energy_cicle_days_shelly_em_casa') * 0.1459 , 2), 2) AS 'total_eur',

Só que isto não funciona, não sei como fazer para o function node poder ir buscar este sensor do HA…


Copyright © 2017-2021. Todos os direitos reservados
CPHA.pt - info@cpha.pt


FAQ | Termos de Serviço/Regras | Política de Privacidade