Erro em cálculo de custos


(Francisco Silva) #1

Boas!

Vinha pedir ajuda aos mais entendidos.
Tenho uns erros no log devido às formulas usadas no cálculo do custo:

2019-07-11 15:34:27 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.casa_today_cost fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 220, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 375, in async_device_update
    await self.async_update()
  File "/usr/src/homeassistant/homeassistant/components/template/sensor.py", line 191, in async_update
    self._state = self._template.async_render()
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 191, in async_render
    return self._compiled.render(kwargs).strip()
  File "/usr/local/lib/python3.7/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
TypeError: can't multiply sequence by non-int of type 'float'
2019-07-11 15:34:27 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.casa_yesterday_cost fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 220, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 375, in async_device_update
    await self.async_update()
  File "/usr/src/homeassistant/homeassistant/components/template/sensor.py", line 191, in async_update
    self._state = self._template.async_render()
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 191, in async_render
    return self._compiled.render(kwargs).strip()
  File "/usr/local/lib/python3.7/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
TypeError: can't multiply sequence by non-int of type 'float'
2019-07-11 15:34:27 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.casa_anual_cost fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 220, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 375, in async_device_update
    await self.async_update()
  File "/usr/src/homeassistant/homeassistant/components/template/sensor.py", line 191, in async_update
    self._state = self._template.async_render()
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 191, in async_render
    return self._compiled.render(kwargs).strip()
  File "/usr/local/lib/python3.7/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
TypeError: can't multiply sequence by non-int of type 'float'

O código é o seguinte:

  - platform: template
    sensors:
    
      casa_today_cost:
        friendly_name: Custo de hoje
        entity_id: sensor.casa_energy_today
        unit_of_measurement: "€"
        value_template: "{{ float((float(states.sensor.casa_energy_today.state) * 0.1513 + 0.3715 + 0.094) * 1.23 ) | round(2) }}"

      casa_yesterday_cost:
        friendly_name: Custo de ontem
        entity_id: sensor.casa_energy_yesterday
        unit_of_measurement: "€"

        value_template: "{{ float((float(states.sensor.casa_energy_yesterday.state) * 0.1513 + 0.3715 + 0.094) * 1.23 ) | round(2) }}"

      casa_mensal_cost:
        friendly_name: Custo mensal
        entity_id: sensor.energia_casa_mensal
        unit_of_measurement: "€"
        value_template: "{{ ((float(states.sensor.energia_casa_mensal.state) * 0.1513 + now().day * 0.3715 + 2.85) * 1.23 ) | round(2) }}"

      casa_anual_cost:
        friendly_name: Custo anual
        entity_id: sensor.energia_casa_anual
        unit_of_measurement: "€"
        value_template: "{{ (float(states.sensor.energia_casa_anual.state) * 0.1513 + float(states.sensor.dias_apos_inicio_2019.state) * 0.3715 * 1.23  + float(states.sensor.dias_apos_inicio_2019.state) * 0.0937 * 1.06)  | round(2) }}"

Antes que perguntem por que não juntar os valores todos em vez de os ter em separado, serve apenas para caso haja alguma alteração seja mais fácil fazê-lo pois como até pode ser daqui a uma ano, posso já nem me lembrar disto…

Sei que tem a ver com o tipo de dados (float vs int) mas como ainda pesco pouco disto não tenho tido muita sorte a resolver isto…

sensor.dias_apos_inicio_2019.state:

  - platform: template
    sensors:
      dias_apos_inicio_2019:
        value_template: '{{ ((as_timestamp(now()) - (states.input_datetime.inicio_ano_2019.attributes.timestamp)) | int /60/1440) | round(0) }}'
        unit_of_measurement: 'Days'
        entity_id: input_datetime.inicio_ano_2019,sensor.time

Desde já obrigado…


(Jorge Assunção) #2

E já experimentaste usar a opção Templates do Dev Tools :templates: para validar a formula?


(Francisco Silva) #3

Esqueci-me de referir que com as formulas dão o resultado no entanto aparecem os erros no log…

Sobre a tua pergunta, estás a referir-te a isto?


(Jorge Assunção) #4

Sim, era isso mesmo. Penso que o problema aí é teres um float a mais e não usarem as prioridades nas contas (multiplicações e divisões primeiro, adições e subtrações depois).

Mais logo já faço um teste para veres como fica.


(Francisco Silva) #5

Acho que já estou aperceber qual é o problema…

Alterei o código para isto:

value_template: "{{ ((float(states.sensor.casa_energy_today.state) * 0.1513 + 0.3715 + 0.094) * 1.23 ) | round(2) }}"

O problema parece ser porque no arranque os valores do sensor “sensor.casa_energy_today” é “unknown” pelo que só quando actualiza para o valor é que aparece o valor de custo…

Na página de ajuda do Template sensor do Home assistant aparece isto:

Considerations

STARTUP

If you are using the state of a platform that takes extra time to load, the Template Sensor may get an unknown state during startup. To avoid this (and the resulting error messages in your log file), you can use is_state() function in your template. For example, you would replace {{ is_state('switch.source', 'on') }} with this equivalent that returns true / false and never gives an unknown result:

{{ is_state('switch.source', 'on') }}

A questão agora é como fazer o que aqui diz ou então dar a volta a isto e colocar tipo um delay…


(Jorge Assunção) #6

Isso que está na página do template sensor só funciona para valores binários (on/off, true/false, etc).

No template não podes usar wait nem delay.

A única solução é esperar um pouco até os valores aparecerem.


(Francisco Silva) #7

era o que pensava, mas assim os erros no log mantêm-se… :frowning_face:
Se criar um bínary sensor que fique on após por exemplo 1 minuto a seguir ao arranque do HA não dará para dar a volta a isto?


(Jorge Assunção) #8

Só aparecem até teres valores. Os valores vêm de onde?


(Francisco Silva) #9
  - platform: mqtt
    name: "Casa energy today"
    state_topic: "tele/bhpzem/SENSOR"
    value_template: "{{ value_json.ENERGY.Today | round(1) }}"
    unit_of_measurement: "kWh"
    icon: mdi:power-socket-eu

  - platform: mqtt
    name: "Casa energy yesterday"
    state_topic: "tele/bhpzem/SENSOR"
    value_template: "{{ value_json.ENERGY.Yesterday | round(1) }}"
    unit_of_measurement: "kWh"
    icon: mdi:power-socket-eu

(Jorge Assunção) #10

Ahhh… MQTT…

Então isso é muito fácil de resolver. Basta adicionar retain: true em cada sensor. O que o retain faz e memorizar o último valor recebido e mantém-o até receber novo valor.


(Francisco Silva) #11

simples… lol

Nem tal coisa me passou pela cabeça…


(Jorge Assunção) #12

Testa e diz se resolve o problema.


(Francisco Silva) #13

Não resolve porque ao colocar o retain dá erro:

Configuração inválidaVERIFICAR A CONFIGURAÇÃO

Invalid config for [sensor.mqtt]: [retain] is an invalid option for [sensor.mqtt]. Check: sensor.mqtt->retain. (See ?, line ?). Please check the docs at https://home-assistant.io/components/sensor.mqtt/ Invalid config for [sensor.mqtt]: [retain] is an invalid option for [sensor.mqtt]. Check: sensor.mqtt->retain. (See ?, line ?). Please check the docs at https://home-assistant.io/components/sensor.mqtt/


(Jorge Assunção) #14

Mostra como ficou o código.


(Francisco Silva) #15
  - platform: mqtt
    name: "Casa energy today"
    state_topic: "tele/bhpzem/SENSOR"
    value_template: "{{ value_json.ENERGY.Today | round(1) }}"
    unit_of_measurement: "kWh"
    icon: mdi:power-socket-eu
    retain: true

Seria assim, certo?


(Jorge Assunção) #16

Sim mas aparentemente foi descontinuadao o retain.

Experimenta usar o force_update.


(Francisco Silva) #17

não funciona, demora sempre um pouco a dar o valores…
Paciência, parece que vou ter de viver com esses erros no log…