Introdução
Neste tutorial vou mostrar a minha implementação para enviar um email todos os meses com os dados referentes ao mês passado do consumo energético. Indica também o custo da fatura e faz as contas para mostrar o custo de cada equipamento nesse mês.
É uma forma de nos mantermos informados.
Requerimento ![]()
Este tutorial usa um tópico meu, que habilita guardarmos os dados na base de dados durante muito tempo, ele guarda um valor por dia, neste caso guardamos o valor total do dia por aparelho e o total, algo como isto:
| data | total | forno | frigorifico |
|---|---|---|---|
| 15-04-2020 | 20.4 | 2.4 | 1 |
| 16-04-2020 | 18.2 | 0 | 0.89 |
| 17-04-2020 | 21 | 0.1 | 0.57 |
| 18-04-2020 | 19.8 | 0 | 0.9 |
Código
Sensor para a recolha dos dados da base de dados
Os dados são guardados nos atributos, porque pelos meus testes o state tem um limite menor de caractéres do que o attributes.
No db_url alterem o user, password e table para o vosso caso
No SELECT, pelo menos 3 dados são precisos (Day, month e year), o resto são as vossas colunas na tabela. Notem que eu tenho uma coluna chamada total_eur_increment, essa coluna é onde tenho o valor da fatura, na verdade esse campo só é preciso na última linha, serve para fazer os cálculos dos gastos em €
Alterem também o energy_kwh pelo nome da vossa tabela
RECOMENDAÇÃO: Aconselho a excluirem este sensor do recorder para não ocupar espaço na base de dados do Home Assistant, na verdade só vão precisar do valor atual, isto é totalmente opcional.
ATENÇÃO: Se a vossa query SQL tiver muitos campos, pode acontecer ao SQL não passar a informação toda devido ao max_allowed_packet (não tenho a certeza se é mesmo isto, mas acho que sim), neste caso, têm duas opções, ou diminuem os campos ou então têm de alterar a variável na base de dados.
sensor:
- platform: sql
db_url: mysql://user:password@core-mariadb/table
queries:
- name: energy_last_month_report
query: >
SELECT
CONCAT
(
'[',
GROUP_CONCAT(json_content SEPARATOR ','),
']'
) AS json,
'info in attributes' AS 'attributes'
FROM
(
SELECT JSON_OBJECT(
"day", DAY(`date`),
"month", MONTH(`date`),
"year", YEAR(`date`),
"total", ROUND(IFNULL(`total`, 0), 2),
"total_eur_increment", ROUND(IFNULL(`total_eur_increment`, 0), 2),
"placa", ROUND(IFNULL(`placa`, 0), 2),
"oven", ROUND(IFNULL(`oven`, 0), 2),
"microwave", ROUND(IFNULL(`microwave`, 0), 2),
"fridge", ROUND(IFNULL(`fridge`, 0), 2),
"washing_machine", ROUND(IFNULL(`washing_machine`, 0), 2),
"drying_machine", ROUND(IFNULL(`drying_machine`, 0), 2),
"dishwasher", ROUND(IFNULL(`dishwasher`, 0), 2),
"hot_water_tank", ROUND(IFNULL(`hot_water_tank`, 0), 2),
"ender3", ROUND(IFNULL(`ender3`, 0), 2),
"pc_ricardo", ROUND(IFNULL(`pc_ricardo`, 0), 2)
) AS json_content
FROM `energy_kwh`
WHERE YEAR(`date`) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(`date`) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
ORDER BY DAY(`date`)
) AS json;
column: "attributes"
Configuração do notify para envio de email
Neste passo, usem as configurações que sejam corretas para o vosso email.
notify:
- platform: smtp
name: email
sender: noreply@cpha.pt
sender_name: Home Assistant
recipient: ricreis394@cpha.pt
server: smtp.cpha.pt
port: 587
username: noreply@cpha.pt
password: teste123
Sensor que altera todos os meses
Este sensor vai servir de trigger na automação, podem utilizar outro caso tenham.
sensor:
- platform: time_date
display_options:
- "date"
- platform: template
sensors:
month:
entity_id: sensor.date
value_template: >
{{ ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"][now().month-1] }}
Automação
A automação vai atualizar os dados do sensor SQL (alterem para o nome do vosso sensor), para que na passagem de mês ele altere os valores para os corretos e envia imediatamente os dados por email.
Na parte do html têm de alterar pelos vossos nomes das colunas.
Resumidamente o html está composto da seguinte forma:
- Preenche o cabeçalho da tabela com os nomes, está dentro da tag
<thead> - Dentro da
<tbody>ele percorre todos os dias e mostra os valores - No
<tfoot>tem duas linhas que é o Total em kWh e o Total em €
Ou seja, nestes três sítios têm que alterar os nomes. Neste caso pode ter células a mais ou a menos dependendo do vosse setup, adaptem!
automation:
- alias: energy_last_month_report_email
initial_state: true
trigger:
- platform: state
entity_id: sensor.month
action:
- service: homeassistant.update_entity
data:
entity_id: sensor.energy_last_month_report
- service: notify.email
data_template:
title: Relatório Mensal - Consumo energético
message: " "
data:
html: >
{% set json = (states.sensor.energy_last_month_report.attributes.json|from_json) %}
{% set month_number = json[0]["month"] | int %}
{% set year = json[0]["year"] | int %}
{% set month = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"][month_number-1] %}
{% set total_eur = json[-1]["total_eur_increment"] %}
{% macro get_total(attribute) %}
{{ json | sum(attribute=attribute) | round(2) }}
{% endmacro %}
{% macro cell(value) %}
{% if value == 0.00 %}
{% set value = value | int %}
{% endif %}
<td>{{ value }}</td>
{% endmacro %}
{% macro get_total_eur(attribute) %}
{{ ((float(get_total(attribute)) * float(total_eur)) / float(get_total("total"))) | round(2) }} €
{% endmacro %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style type="text/css">
body {
font-family: Arial, Helvetica, sans-serif;
}
table {
border-collapse: collapse;
border-radius: 3px;
overflow: hidden;
background: #fff;
}
table th, table td {
padding: 0.4em;
text-align: center;
}
table thead tr {
background: #03a9f4;
color: #fff;
}
table tbody tr.odd {
background-color: #fff;
color: #222;
}
table tbody tr.even {
background-color: #e9e9e9;
color: #222;
}
table tfoot tr {
background: #919191;
color: #fff;
}
</style>
</head>
<body>
<h1>Home Assistant</h1>
<h2>Consumo energético</h2>
<p>Relatório mensal de {{month}} de {{year}}</p>
<p>Total: {{ get_total("total") }} kWh</p>
<p>Valor aproximado da fatura: <b>{{ total_eur }} €</b></p>
<table>
<thead>
<tr>
<th>Dia</th>
<th>Total</th>
<th>Placa</th>
<th>Micro-ondas</th>
<th>Forno</th>
<th>Frigorífico</th>
<th>Máquina de lavar roupa</th>
<th>Máquina de secar roupa</th>
<th>Máquina de lavar loiça</th>
<th>Ender3</th>
<th>PC Ricardo</th>
</tr>
</thead>
<tbody>
{% for day in json %}
<tr class="{{loop.cycle('odd', 'even')}}">
{{ cell(day["day"]) }}
{{ cell(day["total"]) }}
{{ cell(day["placa"]) }}
{{ cell(day["microwave"]) }}
{{ cell(day["oven"]) }}
{{ cell(day["fridge"]) }}
{{ cell(day["washing_machine"]) }}
{{ cell(day["drying_machine"]) }}
{{ cell(day["dishwasher"]) }}
{{ cell(day["ender3"]) }}
{{ cell(day["pc_ricardo"]) }}
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td><b>Total (kWh)</b></td>
<td>{{ get_total("total") }}</td>
<td>{{ get_total("placa") }}</td>
<td>{{ get_total("microwave") }}</td>
<td>{{ get_total("oven") }}</td>
<td>{{ get_total("fridge") }}</td>
<td>{{ get_total("washing_machine") }}</td>
<td>{{ get_total("drying_machine") }}</td>
<td>{{ get_total("dishwasher") }}</td>
<td>{{ get_total("ender3") }}</td>
<td>{{ get_total("pc_ricardo") }}</td>
</tr
<tr>
<td><b>Total (€)</b></td>
<td>{{ total_eur }} €</td>
<td>{{ get_total_eur("placa") }}</td>
<td>{{ get_total_eur("microwave") }}</td>
<td>{{ get_total_eur("oven") }}</td>
<td>{{ get_total_eur("fridge") }}</td>
<td>{{ get_total_eur("washing_machine") }}</td>
<td>{{ get_total_eur("drying_machine") }}</td>
<td>{{ get_total_eur("dishwasher") }}</td>
<td>{{ get_total_eur("ender3") }}</td>
<td>{{ get_total_eur("pc_ricardo") }}</td>
</tr>
</tfoot>
</table>
<p>Relatório gerado automaticamente por computador.</p>
<p>Criado por Ricardo Reis</p>
</body>
</html>
