Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant
Toda vez que recebo a conta de eletricidade e água, fico surpresa - será que minha família consome tudo isso? Sim, temos aquecimento no banheiro e um boiler, mas eles não ficam funcionando o tempo todo. Também tentamos economizar água (embora adorar um banho relaxante seja uma de nossas preferências). Há alguns anos, eu já instalei medidores de água e de eletricidade no sistema de casa inteligente, mas por aí ficou. Só agora consegui analisar o consumo, e é sobre isso que fala este artigo.

Recentemente, migrei para o Home Assistant como meu sistema de casa inteligente. Uma das razões foi justamente a possibilidade de coletar muitos dados e gerar gráficos de forma conveniente.

As informações descritas neste artigo não são novas, todos esses métodos já foram abordados de várias maneiras na internet. Porém, cada artigo geralmente foca apenas em uma abordagem ou aspecto. Tive que comparar todas essas abordagens e escolher a mais adequada. O artigo ainda não oferece informações abrangentes sobre coleta de dados, mas é uma espécie de resumo do que eu fiz. Então, críticas construtivas e sugestões de aprimoramento são bem-vindas.

Formulação do problema

Portanto, o objetivo deste exercício é obter gráficos bonitos de consumo de água e eletricidade:

  • Por hora por 2 dias
  • Diário por 2 semanas
  • (opcional) semanal e mensal

Aqui, encontramos algumas dificuldades:

  • Os componentes gráficos padrão são geralmente bastante limitados. Na melhor das hipóteses, é possível criar um gráfico linear usando pontos.

    Se você procurar bem, encontrará componentes de terceiros que ampliam as capacidades dos gráficos padrão. Para o home assistant, há um componente mini-graph-card, mas ele também é um pouco limitado:

    • É difícil definir os parâmetros de gráficos de barras em períodos longos (a largura da barra é definida em frações de hora, então intervalos maiores que uma hora são definidos com números fracionários)
    • Não é possível adicionar diferentes entidades em um único gráfico (por exemplo, temperatura e umidade, ou misturar um gráfico de barras com uma linha)
  • Além de que o home assistant por padrão utiliza o banco de dados SQLite mais primitivo (e eu, com minhas habilidades limitadas, não consegui instalar o MySQL ou Postgres), os dados não são armazenados da forma mais otimizada. Por exemplo, a cada alteração de qualquer parâmetro numérico, mesmo que seja o menor, uma enorme json com cerca de um kilobyte é gravada no banco.
    {"entity_id": "sensor.water_cold_hourly", "old_state": {"entity_id": "sensor.water_cold_hourly", "state": "3", "attributes": {"source": "sensor.water_meter_cold", "status": "collecting", "last_period": "29", "last_reset": "2020-02-23T21:00:00.022246+02:00", "meter_period": "hourly", "unit_of_measurement": "l", "friendly_name": "water_cold_hourly", "icon": "mdi:counter"}, "last_changed": "2020-02-23T19:05:06.897604+00:00", "last_updated": "2020-02-23T19:05:06.897604+00:00", "context": {"id": "aafc8ca305ba4e49ad4c97f0eddd8893", "parent_id": null, "user_id": null}}, "new_state": {"entity_id": "sensor.water_cold_hourly", "state": "4", "attributes": {"source": "sensor.water_meter_cold", "status": "collecting", "last_period": "29", "last_reset": "2020-02-23T21:00:00.022246+02:00", "meter_period": "hourly", "unit_of_measurement": "l", "friendly_name": "water_cold_hourly", "icon": "mdi:counter"}, "last_changed": "2020-02-23T19:11:11.251545+00:00", "last_updated": "2020-02-23T19:11:11.251545+00:00", "context": {"id": "0de64b8af6f14bb9a419dcf3b200ef56", "parent_id": null, "user_id": null}}}

    Tenho muitos sensores (sensores de temperatura em cada cômodo, contadores de água e eletricidade), e alguns deles geram uma quantidade considerável de dados. Por exemplo, apenas o contador de eletricidade SDM220 gera cerca de uma dezena de valores a cada 10-15 segundos, e gostaria de instalar cerca de 8 desses contadores. Além disso, existem muitos parâmetros que são calculados com base em outros sensores. Assim, todos esses valores podem facilmente inflar o banco em 100-200 Mb diariamente. Após uma semana, o sistema terá dificuldades para funcionar, e depois de um mês, o cartão de memória do Raspberry Pi (em uma instalação típica do home assistant) pode falhar, e a ideia de armazenar dados por um ano torna-se inviável.

  • Se você tiver sorte, seu contador pode registrar o consumo por conta própria. Você pode consultar o contador a qualquer momento e perguntar qual o valor acumulado de consumo. Normalmente, todos os contadores de eletricidade que possuem uma interface digital (RS232/RS485/Modbus/Zigbee) oferecem essa possibilidade.

    Pior ainda se o dispositivo puder apenas medir um determinado parâmetro instantâneo (como potência instantânea ou corrente), ou simplesmente gerar pulsos a cada X watt-horas ou litros. Nesse caso, é necessário pensar em como e com o que integrar isso e onde armazenar o valor. Há o risco de perder um relatório por algum motivo, e a precisão do sistema como um todo levanta questões. Claro, tudo isso pode ser delegado a um sistema de casa inteligente como o home assistant, mas o ponto sobre o número de registros na base de dados não foi esquecido, e não é possível consultar os sensores com frequência maior que uma vez por segundo (limitação da arquitetura do home assistant).

Abordagem 1

Primeiro, vamos ver o que o home assistant oferece de forma nativa. A medição do consumo durante um período é uma funcionalidade bastante requisitada. Sem dúvida, isso foi implementado há muito tempo na forma de um componente especializado — utility_meter.

A essência do componente é que ele cria internamente uma variável current_accumulated_value e a redefine ao final de um determinado período (hora/semanal/mensal). O componente monitora a variável de entrada (valor de algum sensor) e assina as mudanças de valor — você simplesmente recebe o resultado pronto. Essa coisa é descrita em apenas algumas linhas no arquivo de configuração.

utility_meter:
  water_cold_hour_um:
    source: sensor.water_meter_cold
    cycle: hourly
  water_cold_day_um:
    source: sensor.water_meter_cold
    cycle: daily

Aqui, sensor.water_meter_cold representa o valor atual do medidor em litros, que estou recebendo diretamente do dispositivo via mqtt. A estrutura cria 2 novos sensores water_cold_hour_um e water_cold_day_um, que acumulam as leituras horárias e diárias, zerando-as ao final do período. Aqui está o gráfico do acumulador horário por meio dia.

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

O código para os gráficos horários e diários no lovelace-UI parece assim:

      - type: history-graph
        title: 'Consumo de água horário usando variáveis'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Consumo de água diário usando variáveis'
        hours_to_show: 360
        entities:
          - sensor.water_day

Na verdade, neste algoritmo reside o problema dessa abordagem. Como mencionei anteriormente, para cada valor de entrada (o valor atual do medidor a cada litro seguinte) é gerado 1KB de registro na base. Cada medidor de utilidade também gera um novo valor, que também é adicionado à base. Se eu quiser coletar medições horárias / diárias / semanais / mensais, e ainda adicionar vários sistemas de água, além de um monte de medidores de eletricidade — isso gerará uma quantidade enorme de dados. Na verdade, não são muitos dados, mas como o home assistant escreve uma porção de informações desnecessárias na base, o tamanho da base aumentará rapidamente. Tenho medo de até estimar o tamanho da base para gráficos semanais e mensais.

Além disso, o medidor de utilidade por si só não resolve o problema proposto. O gráfico dos valores fornecidos pelo medidor de utilidade é uma função que cresce monotonamente, que é zerada a cada hora. Precisamos de um gráfico de consumo compreensível para o usuário, mostrando quantos litros foram consumidos durante o período. O componente padrão history-graph não faz isso, mas podemos contar com um componente externo chamado mini-graph-card.

Este é o código do cartão para o lovelace-UI:

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_hour_um
        group_by: hour
        hours_to_show: 48
        name: "Consumo de água horário agregado pelo medidor de utilidade"
        points_per_hour: 1
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Além das configurações padrão, como o nome do sensor, o tipo de gráfico, a cor (não gostei do laranja padrão), é importante ressaltar 3 configurações:

  • group_by:hour — o gráfico será gerado com o alinhamento das barras no início da hora
  • points_per_hour: 1 — uma barra para cada hora
  • E o mais importante, aggregate_func: max — pega o valor máximo dentro de cada hora. É esse parâmetro que transforma o gráfico serrilhado em barras.

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Não preste atenção a uma série de barras à esquerda — esse é o comportamento padrão do componente quando não há dados. E realmente não havia dado — eu só liguei a coleta de dados pelo medidor de utilidade há apenas algumas horas, apenas para este artigo (minha abordagem atual explicarei um pouco mais abaixo).

Nesta imagem, eu queria mostrar que às vezes a exibição dos dados realmente funciona, e as colunas refletem os valores corretos. Porém, nem todos eles. A coluna destacada para o intervalo das 11h às 12h da manhã, por algum motivo, exibe 19 litros, enquanto que no gráfico dentado logo acima, para o mesmo período e do mesmo sensor, vemos um consumo de 62 litros. Ou é um bug ou é erro humano. E ainda não entendi por que os dados à direita foram de alguma forma corrompidos — o consumo ali estava normal, como também é visível no gráfico dentado.

Em suma, não consegui alcançar a credibilidade com essa abordagem — o gráfico quase sempre mostra alguma coisa absurda.

Código semelhante para o sensor diário.

      - aggregate_func: max
        entities:
          - color: var(--primary-color)
            entity: sensor.water_cold_day_um
        group_by: interval
        hours_to_show: 360
        name: "Consumo diário de água agregado pelo medidor de utilidade"
        points_per_hour: 0.0416666666
        show:
          graph: bar
        type: 'custom:mini-graph-card'

Note que o parâmetro group_by está definido como interval, e o parâmetro points_per_hour controla tudo. E isso traz à tona outro problema deste componente — points_per_hour funciona bem em gráficos de uma hora ou menos, mas horrivelmente em intervalos maiores. Portanto, para obter uma única coluna por dia, foi necessário inserir o valor 1/24=0.04166666. Já nem falo sobre gráficos semanais e mensais.

Abordagem 2

Enquanto ainda estava aprendendo sobre o Home Assistant, me deparei com este vídeo:

Por que no hosting comum a administração do PrestaShop é lenta, e no seu não é?

Um amigo coleta dados de consumo de vários tipos de tomadas da Xiaomi. A tarefa dele é um pouco mais simples — apenas exibir o valor do consumo de hoje, ontem e do mês. Nenhum gráfico é necessário.

Vamos deixar de lado as discussões sobre a integração manual dos valores instantâneos de potência — já escrevi sobre a 'precisão' dessa abordagem acima. Não está claro por que ele não usou os valores acumulados de consumo, que já estão sendo coletados pela mesma tomada. Na minha opinião, a integração dentro do dispositivo funcionará melhor.

Do vídeo, vamos pegar a ideia de contar manualmente o consumo durante um período. O homem só considera os valores de hoje e ontem, mas vamos além e tentaremos desenhar um gráfico. A essência do método proposto, no meu caso, é a seguinte.

Vamos criar uma variável chamada valor_no_início_da_hora, onde registraremos os dados atuais do contador.
No final da hora (ou no início da próxima), contabilizaremos a diferença entre a leitura atual e a armazenada no início da hora. Esta diferença será o consumo no horário atual — vamos salvar o valor no sensor, e no futuro construiremos um gráfico a partir desse valor.
Também é necessário "zerar" a variável valor_no_início_da_hora, armazenando o valor atual do contador.

Tudo isso pode ser feito por meio dos próprios recursos do home assistant.

O código precisará ser um pouco maior do que na abordagem anterior. Primeiro, vamos definir essas "variáveis". Por padrão, não temos uma entidade "variável", mas podemos usar os serviços do broker mqtt. Vamos enviar valores para lá com o sinalizador retain=true — isso preservará o valor dentro do broker, e poderá ser recuperado a qualquer momento, mesmo após a reinicialização do home assistant. Eu criei contadores horais e diários.

- platform: mqtt
  state_topic: "test/water/hour"
  name: water_hour
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/hour_begin"
  name: water_hour_begin
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/day"
  name: water_day
  unit_of_measurement: l

- platform: mqtt
  state_topic: "test/water/day_begin"
  name: water_day_begin
  unit_of_measurement: l

Toda a mágica ocorre na automação, que é acionada a cada hora e a cada noite, respectivamente.

- id: water_new_hour
  alias: water_new_hour
  initial_state: true
  trigger:
    - platform: time_pattern
      minutes: 0
  action:
    - service: mqtt.publish
      data:
        topic: "test/water/hour"
        payload_template: >
          {{ (states.sensor.water_meter_cold.state|int) - (states.sensor.water_hour_begin.state|int) }}
        retain: true
    - service: mqtt.publish
      data:
        topic: "test/water/hour_begin"
        payload_template: >
          {{ states.sensor.water_meter_cold.state }}
        retain: true

- id: water_new_day
  alias: water_new_day
  initial_state: true
  trigger:
    - platform: time
      at: "00:00:00"
  action:
    - service: mqtt.publish
      data:
        topic: "test/water/day"
        payload_template: >
          {{ (states.sensor.water_meter_cold.state|int) - (states.sensor.water_day_begin.state|int) }}
        retain: true
    - service: mqtt.publish
      data:
        topic: "test/water/day_begin"
        payload_template: >
          {{ states.sensor.water_meter_cold.state }}
        retain: true

Ambas as automações realizam 2 ações:

  • Calculam o valor do intervalo como a diferença entre o valor inicial e o final
  • Atualizam o valor base para o próximo intervalo

A construção de gráficos, neste caso, é resolvida com um history-graph comum:

      - type: history-graph
        title: 'Consumo de água horário usando variáveis'
        hours_to_show: 48
        entities:
          - sensor.water_hour

      - type: history-graph
        title: 'Consumo de água diário usando variáveis'
        hours_to_show: 360
        entities:
          - sensor.water_day

Assim que se apresenta:

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Basicamente, isso é tudo o que é necessário. A vantagem desse método é que os dados são gerados uma vez por intervalo. Ou seja, no total haverá 24 registros por dia para o gráfico horário.

Infelizmente, isso não resolve o problema geral da base de dados em crescimento. Se eu quiser um gráfico de consumo mensal, terei que armazenar dados por pelo menos um ano. E como o home assistant oferece apenas uma configuração de duração de armazenamento para toda a base, isso significa que TODOS os dados do sistema precisarão ser armazenados por um ano inteiro. Por exemplo, em um ano eu consumo 200 metros cúbicos de água, o que resulta em 200.000 registros na base. E se considerarmos outros sensores, esse número se torna realmente desproporcional.

Abordagem 3

Felizmente, pessoas inteligentes já resolveram esse problema criando o banco de dados InfluxDB. Esse banco é otimizado especificamente para armazenar dados baseados em tempo e é ideal para manter os valores de diferentes sensores. O sistema também oferece uma linguagem de consulta semelhante ao SQL, que permite extrair valores da base e, em seguida, agregá-los de várias formas. Finalmente, diferentes dados podem ser armazenados por períodos distintos. Por exemplo, leituras que mudam frequentemente, como temperatura ou umidade, podem ser armazenadas por apenas algumas semanas, enquanto os dados diários de consumo de água podem ser mantidos por um ano inteiro.

Além do InfluxDB, pessoas inteligentes também inventaram o Grafana — um sistema para criar gráficos a partir dos dados do InfluxDB. O Grafana consegue gerar diferentes tipos de gráficos, personalizá-los detalhadamente e, o mais importante, esses gráficos podem ser “inseridos” na interface lovelace do home assistant.

Inspirar-se aqui e aqui. Os artigos detalham o processo de instalação e conexão do InfluxDB e Grafana ao home assistant. Eu, por minha vez, vou me concentrar na resolução da minha tarefa específica.

Portanto, em primeiro lugar, vamos começar a armazenar os valores do contador no InfluxDB. Um trecho da configuração do home assistant (neste exemplo, vou lidar não apenas com água fria, mas também com água quente):

influxdb:
  host: localhost
  max_retries: 3
  default_measurement: state
  database: homeassistant
  include:
    entities:
      - sensor.water_meter_hot
      - sensor.water_meter_cold

Vamos desativar o armazenamento dos mesmos dados na base interna do home assistant, para não inchá-la desnecessariamente:

recorder:
  purge_keep_days: 10
  purge_interval: 1
  exclude:
    entities:
      - sensor.water_meter_hot
      - sensor.water_meter_cold

Agora, vamos para o console do InfluxDB e configuraremos nosso banco de dados. Em particular, precisamos definir por quanto tempo certos dados serão armazenados. Isso é gerenciado pela chamada retention policy — isso é semelhante a bancos de dados dentro do banco de dados principal, onde cada banco interno tem suas próprias configurações. Por padrão, todos os dados são armazenados na retention policy chamada autogen, e esses dados serão mantidos por uma semana. Eu gostaria que os dados horários fossem armazenados por um mês, os semanais por um ano, e os mensais nunca fossem excluídos. Vamos criar as retention policies correspondentes.

CREATE RETENTION POLICY "month" ON "homeassistant" DURATION 30d REPLICATION 1
CREATE RETENTION POLICY "year" ON "homeassistant" DURATION 52w REPLICATION 1
CREATE RETENTION POLICY "infinite" ON "homeassistant" DURATION INF REPLICATION 1

Agora, a verdadeira jogada — a agregação de dados através de uma continuous query. Este é um mecanismo que executa automaticamente uma consulta em intervalos de tempo definidos, agrega os dados com base nessa consulta, e armazena o resultado em um novo valor. Vamos analisar por meio de um exemplo (eu estou escrevendo em coluna para facilitar a leitura, mas na prática eu precisei inserir esse comando em uma única linha).

CREATE CONTINUOUS QUERY cq_water_hourly ON homeassistant 
BEGIN 
  SELECT max(value) AS value 
  INTO homeassistant.month.water_meter_hour 
  FROM homeassistant.autogen.l 
  GROUP BY time(1h), entity_id fill(previous) 
END

Este comando:

  • Cria uma continuous query chamada cq_water_cold_hourly no banco homeassistant.
  • A consulta será executada a cada hora (time(1h)).
  • A consulta irá extrair todos os dados da measurement homeassistant.autogen.l (litros), incluindo as leituras de água fria e quente.
  • Os dados agregados serão agrupados por entity_id, o que nos dará valores separados para água fria e quente.
  • Como o medidor de litros é uma sequência monótona crescente, em cada hora precisaremos pegar o valor máximo, portanto, a agregação será realizada pela função max(value).
  • O novo valor será gravado em homeassistant.month.water_meter_hour, onde month é o nome da retention policy com prazo de armazenamento de um mês. Além disso, os dados de água fria e quente serão dispersos em registros separados com os respectivos entity_id e valor no campo value.

Durante a noite ou quando não há ninguém em casa, o consumo de água é zero, portanto, não há novos registros em homeassistant.autogen.l. Para evitar lacunas nos valores em consultas normais, pode-se usar fill(previous). Isso fará com que o InfluxDB use o valor da hora anterior.

Infelizmente, a consulta contínua tem uma particularidade: o truque fill(previous) não funciona e os registros simplesmente não são criados. Além disso, é um problema que está sendo discutido há vários anos. Vamos lidar com esse problema mais tarde, e o fill(previous) na consulta contínua pode ficar — ele não atrapalha.

Vamos verificar o que conseguimos (é claro que precisamos esperar algumas horinhas):

> select * from homeassistant.month.water_meter_hour group by entity_id
...
name: water_meter_hour
tags: entity_id=water_meter_cold
time                 value
----                 -----
...
2020-03-08T01:00:00Z 370511
2020-03-08T02:00:00Z 370513
2020-03-08T05:00:00Z 370527
2020-03-08T06:00:00Z 370605
2020-03-08T07:00:00Z 370635
2020-03-08T08:00:00Z 370699
2020-03-08T09:00:00Z 370761
2020-03-08T10:00:00Z 370767
2020-03-08T11:00:00Z 370810
2020-03-08T12:00:00Z 370818
2020-03-08T13:00:00Z 370827
2020-03-08T14:00:00Z 370849
2020-03-08T15:00:00Z 370921

Note que os valores na base de dados são armazenados em UTC, portanto, nesta lista eles diferem em 3 horas — os valores das 7 da manhã no resultado do InfluxDB correspondem aos valores das 10 da manhã nos gráficos acima. Também observe que entre 2 e 5 da manhã, não há registros — essa é a particularidade da consulta contínua.

Como pode ver, o valor agregado também é uma sequência monótona crescente, apenas os registros aparecem com menos frequência — uma vez por hora. Mas isso não é um problema — podemos escrever mais uma consulta que obterá os dados corretos para o gráfico.

SELECT difference(max(value)) 
FROM homeassistant.month.water_meter_hour 
WHERE entity_id='water_meter_cold' and time >= now() -24h 
GROUP BY time(1h), entity_id 
fill(previous)

Vou explicar:

  • Da base homeassistant.month.water_meter_hour, vamos puxar os dados para entity_id='water_meter_cold' das últimas 24 horas (time >= now() -24h).
  • Como mencionei, na sequência homeassistant.month.water_meter_hour podem faltar alguns registros. Vamos gerar esses dados novamente, executando a consulta com GROUP BY time(1h). Desta vez, o fill(previous) funcionará como deveria, gerando os dados faltantes (a função pegará o valor anterior)
  • O mais importante nesta consulta é a função difference, que calculará a diferença entre as marcas horárias. Ela não funciona sozinha e requer uma função de agregação. Vamos usar max() que foi utilizada anteriormente.

O resultado da execução é assim

name: water_meter_hour
tags: entity_id=water_meter_cold
time                 difference
----                 ----------
...
2020-03-08T02:00:00Z 2
2020-03-08T03:00:00Z 0
2020-03-08T04:00:00Z 0
2020-03-08T05:00:00Z 14
2020-03-08T06:00:00Z 78
2020-03-08T07:00:00Z 30
2020-03-08T08:00:00Z 64
2020-03-08T09:00:00Z 62
2020-03-08T10:00:00Z 6
2020-03-08T11:00:00Z 43
2020-03-08T12:00:00Z 8
2020-03-08T13:00:00Z 9
2020-03-08T14:00:00Z 22
2020-03-08T15:00:00Z 72

Das 2 às 5 da manhã (UTC), não houve consumo. No entanto, a consulta retornará o mesmo valor de consumo graças ao fill(previous), e a função difference subtrairá esse valor de si mesma, resultando em 0, que é exatamente o que se requer.

Agora, falta o mais simples — construir o gráfico. Para isso, abriremos o Grafana, abriremos um painel existente (ou criaremos um novo), e criaremos um novo painel. As configurações dos gráficos serão as seguintes.

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Vou exibir os dados de água fria e quente em um mesmo gráfico. A consulta é exatamente como descrevi acima.

As opções de exibição são definidas assim. Para mim, será um gráfico de linhas (lines), que será exibido em degraus (stairs). Vou explicar o parâmetro Stack um pouco mais abaixo. Existem ainda outros parâmetros de exibição, mas eles não são tão interessantes.

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Para adicionar o gráfico obtido ao home assistant, é necessário:

  • sair do modo de edição do gráfico. Por algum motivo, as configurações de compartilhamento de gráficos corretas são oferecidas apenas na página do painel.
  • Clique no triângulo ao lado do nome do gráfico e, no menu, selecione compartilhar.
  • Na janela que se abre, vá para a aba embed.
  • Desmarque a opção current time range — o intervalo de tempo será definido através da URL.
  • Escolha o tema necessário. No meu caso, é o tema claro.
  • Copie a URL resultante para o cartão de configurações do lovelace-UI.

      - type: iframe
        id: graf_water_hourly
        url: "http://192.168.10.200:3000/d-solo/rZARemQWk/water?orgId=1&panelId=2&from=now-2d&to=now&theme=light"

Observe que o intervalo de tempo (últimos 2 dias) é definido exatamente aqui, e não nas configurações do painel.

O gráfico se apresenta assim. Não usei água quente nos últimos 2 dias, portanto, apenas o gráfico da água fria é desenhado.

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Assim, ainda não decidi qual gráfico eu gosto mais, se o de linha em degraus ou os de barras reais. Portanto, apenas apresentarei um exemplo do gráfico diário de consumo, desta vez apenas com barras. As consultas são construídas de maneira semelhante às descritas acima. As opções de exibição são as seguintes:

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Este gráfico se apresenta assim:

Casa inteligente: Construindo gráficos de consumo de água e eletricidade no Home Assistant

Aqui está o que diz respeito ao parâmetro Stack. Neste gráfico, a barra de água fria é desenhada sobre a barra de água quente. A altura total corresponde ao consumo total de água fria e quente durante o período.

Todos os gráficos mostrados são dinâmicos. Você pode passar o mouse sobre um ponto de interesse e ver os detalhes e o valor em um ponto específico.

Infelizmente, não conseguimos evitar um pequeno problema. No gráfico de barras (diferente do gráfico de linhas-segmentadas), o meio da barra não está no meio do dia, mas sim à meia-noite. Ou seja, a metade esquerda da barra é desenhada no dia anterior. Assim, os gráficos de sábado e domingo estão um pouco à esquerda da zona azulada. Até agora, não consegui pensar em uma solução para isso.

Outro problema é a incapacidade de trabalhar corretamente com intervalos mensais. A questão é que a duração da hora/dia/semana é fixa, mas a duração do mês é diferente a cada vez. O InfluxDB só consegue trabalhar com intervalos iguais. Até agora, consegui definir um intervalo fixo de 30 dias. Sim, o gráfico vai diluir um pouco ao longo do ano e as barras não corresponderão perfeitamente aos meses. Mas como estou apenas interessado nisso como um indicador, estou bem com isso.

Vejo pelo menos duas soluções:

  • Abrir mão dos gráficos mensais e limitar-me aos semanais. 52 barras semanais por ano ficam bem melhores.
  • Calcular o consumo mensal como método nº 2 e usar o Grafana apenas para gráficos bonitos. Assim, teremos uma solução bastante precisa. É possível até sobrepor os gráficos do ano passado para comparação — o Grafana faz isso.

Conclusão

Não sei por que, mas eu gosto desse tipo de gráficos. Eles mostram que a vida está pulsando e tudo muda. Ontem havia muito, hoje pouco, amanhã será de outra forma. Resta trabalhar com os familiares sobre o tema do consumo. Mas mesmo com os atuais hábitos, um número grande e confuso na fatura já se transforma em uma imagem bastante clara do consumo.

Apesar de quase 20 anos de carreira como programador, eu praticamente não tinha experiência com bancos de dados. Portanto, a instalação de um banco de dados externo parecia algo muito complexo e confuso. Tudo mudou o artigo mencionado acima — descobri que a integração da ferramenta adequada pode ser feita em alguns cliques, e com uma ferramenta especializada, a tarefa de construir gráficos se torna um pouco mais fácil.

No título, mencionei o consumo de eletricidade. Infelizmente, no momento não posso apresentar nenhum gráfico. Um medidor SDM120 queimou, e o outro está com falha ao ser acessado via Modbus. No entanto, isso não afeta o tema deste artigo — os gráficos serão construídos da mesma forma que para a água.

Neste artigo, compartilhei as abordagens que testei pessoalmente. Com certeza existem outras formas de organizar a coleta e visualização de dados que eu não conheço. Compartilhe isso nos comentários, ficarei muito interessado. Agradeço por críticas construtivas e novas ideias. Espero que o material apresentado também ajude alguém.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster