Cara, pode compartilhar mais info de como q vc construiu os valores dos sensores? Só pra entender tbm, vc está fazendo OCR com quais dados?
Ola Vinicius ,
Desculpe a demora para responder , eu configurei o site para enviar email de notificação , mas não veio nada.
Vi por acaso a sua questão agora.
Bom , abaixo escrevi na sequencia que achei mais logica .
O que foi mais dificil de descobrir para aplicar foi a regra do PIS/COFINS e ICMS , é um calculo “maldito” .
Achei ele de forma clara no site outra distribuidora.
Buscar dados da WEB
A unica exceção foi o ICMS , que desde sempre é 18% em SP , então não me dei ao trabalho de buscar de alguma fonte oficial.
Este é o primeiro script que coleta tarifas e bandeira.
# by Cesar Martins - 2025-01-09
#
#
# https://dadosabertos.aneel.gov.br/dataset/tarifas-distribuidoras-energia-eletrica
#
# BUSCA PERSONALIZADA COM OS FILTROS
# https://dadosabertos.aneel.gov.br/dataset/tarifas-distribuidoras-energia-eletrica/resource/fcf2906c-7c32-4b9b-a637-054e7a5234f4?filters=SigAgente%3ACPFL-PIRATINING%7CDscSubGrupo%3AB1%7CDscSubClasse%3AResidencial%7CDscClasse%3AResidencial%7CDscModalidadeTarifaria%3AConvencional%7CDscBaseTarifaria%3ATarifa%20de%20Aplica%C3%A7%C3%A3o%7CDscDetalhe%3AN%C3%A3o%20se%20aplica
#
_baixar_dados(){
# busca dados
Resource=fcf2906c-7c32-4b9b-a637-054e7a5234f4
SigAgente=CPFL-PIRATINING
SubGrupo=B1
Classe=Residencial
SubClasse=Residencial
ModalidadeT=Convencional
BaseT='Tarifa de Aplicação'
Detalhe='%aplica%' #nao se aplica
curl --silent -G "https://dadosabertos.aneel.gov.br/api/3/action/datastore_search_sql" --data-urlencode 'sql=SELECT
_id
--,DatGeracaoConjuntoDados
--,DscREH
,a."SigAgente"
,a."NumCNPJDistribuidora"
,a."DatInicioVigencia"
,a."DatFimVigencia"
,a."DscBaseTarifaria"
,a."DscSubGrupo"
,a."DscModalidadeTarifaria"
,a."DscClasse"
,a."DscSubClasse"
,a."DscDetalhe"
,a."NomPostoTarifario"
,a."DscUnidadeTerciaria"
,a."SigAgenteAcessante"
,a."VlrTUSD"
,a."VlrTE"
FROM "'"$Resource"'" as a
WHERE a."SigAgente" = '\'"$SigAgente"\''
AND a."DscSubGrupo" = '\'"$SubGrupo"\''
AND a."DscClasse" = '\'"$Classe"\''
AND a."DscSubClasse" = '\'"$SubClasse"\''
and a."DscModalidadeTarifaria" = '\'"$ModalidadeT"\''
and a."DscBaseTarifaria" = '\'"$BaseT"\''
and a."DscDetalhe" like '\'"$Detalhe"\''
order by "DatInicioVigencia" desc
' > cpfl_tarifas.out
[ $? -ne 0 ] && exit 1
#
# Converte output em csv , comando gerado por IA.
cat cpfl_tarifas.out | jq '.result.records' | jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > cpfl_tarifas.csv
# BANDEIRA TARIFARIA
# https://dadosabertos.aneel.gov.br/dataset/bandeiras-tarifarias
# https://dadosabertos.aneel.gov.br/dataset/bandeiras-tarifarias/resource/0591b8f6-fe54-437b-b72b-1aa2efd46e42
Resource=0591b8f6-fe54-437b-b72b-1aa2efd46e42
curl --silent -G "https://dadosabertos.aneel.gov.br/api/3/action/datastore_search_sql" --data-urlencode 'sql=SELECT "DatCompetencia", "NomBandeiraAcionada", "VlrAdicionalBandeira"
FROM "'"$Resource"'"
ORDER BY "DatCompetencia" DESC
' > bandeira.out
cat bandeira.out | jq '.result.records' | jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > bandeira.csv
}
_show_valores() {
vFiltro=$1
# busca abaixo, traz os valores dentro da vigencia, vigencias futuras nao sao exibidas...
vD=$(date +%Y-%m-%d)
vOut=$(
# valores do TE e TUSD
awk '{gsub(/","?/,";") ; gsub(/"/,"") ; print }' cpfl_tarifas.csv | tail -n +2 | \
awk -v D="$vD" -F";" 'D >= $2 { print ; exit ;}' | \
awk -F';' '{printf "vVigenciaIni=%s\nvVigenciaFim=%s\nvTE=%s\nvTUSD=%s\n",$2,$1,$14,$15}'
# Informacoes da bandeira
awk '{gsub(/","?/,";") ; gsub(/"/,"") ; print }' bandeira.csv | \
awk -v D="$vD" -F";" '$1 <= D { print ; exit ;}' | \
awk -F';' '{
gsub(/^,/,"0,",$3)
printf "vInicioBand=%s\nvBandeira=%s\nvValorBandeira=%s\n",$1,$2,$3}'
)
{
if [ "$vFiltro" != "-" ]; then
echo "$vOut" | awk -v IGNORECASE=1 -v F=$vFiltro -F= '$1 ~ F { print $2}'
else
echo "$vOut"
fi
} | tr "," "."
}
cd $(dirname $0)
while getopts :bs: vOpcao
do
case $vOpcao in
b) _baixar_dados ;;
s) _show_valores $OPTARG ;;
esac
done
Exemplo de como usar:
# bash cpfl.tarifas.sh -b
# bash cpfl.tarifas.sh -s -
vVigenciaIni=2026-01-01
vVigenciaFim=2026-10-22
vTE=344.05
vTUSD=395.64
vInicioBand=2026-02-01
vBandeira=Verde
vValorBandeira=0.00
# bash cpfl.tarifas.sh -s vTE
344.05
Para o PIS e COFINS
Este é outro script para PIS e COFINS , pois eles “andam juntos” nas divulgações.
Tem algumas tratativas de SSH ai porque como eu rodo meu HA em docker , a nova versão (ultima versão) não era mais possível rodar diretamente dentro do docker por causa do comando tesseract de OCR .
Então fiz ajustes para ele executar “remotamente” no host linux local via ssh.
#
# https://www.cpfl.com.br/piratininga/pis-cofins
#
# em out/2025 a cpfl mudou o site , o que antes era uma tabela passou a ser uma imagem que vem com javascript
# foi necessario refazer todo o script, fazer OCR da imagem...
# como utiliza comandos novos, nao da mais para executar direto no container.
# Entao troquei o esquema para fazer um ssh para o host
#
cd $(dirname $0)
set -euo pipefail
# -e exit quando qq comando falhar
# -u falha se acessar variaveis nao inicializadas
# -o pipefail falha se qualquer comando em um cmd1 | cmd2 | cmd3 falhar..
# CUIDADO: no ambiente docker , este parametro falha o script com erro 141 no "| head -n1" .
# porque o head -n1 fecha o pipe enquanto recebe dados .
# no caso contornei no awk com NR==1
shopt -s nocasematch
# para uso do [[ ]]
vTmp=tmp.$(basename $0 .sh).$$
touch $vTmp # apenas para evitar codigo de exit errado no trap
trap "rm ${vTmp}* 2>/dev/null ; exit " 0 1 2
## versao 2 , funcionou ate set/2025 ai eles mudaram o site , onde a tabela passou a ser uma imagem.
_baixar_dados2() {
# Extrai imagens e OCR das tabelas PIS e COFINS da CPFL Piratininga.
#
# 2025-10-19
# Este script foi criado pelo ChatGPT
# Porem readaptei o script original para funcionar aqui dentro...
# https://chatgpt.com/share/68f54090-27d0-8001-95dc-77d7a339fd01
BASE_URL="https://www.cpfl.com.br"
PAGE_PATH="/piratininga/pis-cofins"
TMPDIR=.
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"
vTmpPage=$vTmp.page.html
vTmpLinks=$vTmp.links.txt
echo "🔍 Baixando HTML da página..."
curl -sSL -A "$UA" "${BASE_URL}${PAGE_PATH}" -o "$vTmpPage"
echo "🔎 Procurando imagens de tarifas (PIS/COFINS)..."
grep -Eoi '<img[^>]+src="[^"]+"' "$vTmpPage" \
| sed -E 's/.*src="([^"]+)".*/\1/' \
| grep -Ei 'pis|cofins' \
| sed -E "s#^/#${BASE_URL}/#" \
| sed -E "s#//#/#g" \
| sort -u > "$vTmpLinks"
if [ ! -s "$vTmpLinks" ]; then
echo "❌ Nenhuma imagem encontrada com nomes contendo 'PIS' ou 'COFINS'."
exit 1
fi
echo "🖼️ Imagens encontradas:"
cat "$vTmpLinks"
echo
for LINK in $(cat "$vTmpLinks"); do
NAME=$(basename "$LINK" | sed 's/%20/_/g')
OUTIMG="$NAME"
OUTTXT="${OUTIMG%.png}.txt"
[[ $NAME =~ pis ]] && OUTTXT=pis.txt
[[ $NAME =~ cofins ]] && OUTTXT=cofins.txt
echo "⬇️ Baixando $NAME..."
curl -sSL -A "$UA" -o "$OUTIMG" "$LINK"
if command -v convert >/dev/null 2>&1; then
echo "🧹 Limpando imagem antes do OCR (convert)..."
convert "$OUTIMG" -colorspace Gray -contrast-stretch 1%x1% "$OUTIMG"
fi
echo "🔤 Rodando OCR (tesseract)..."
# tesseract "$OUTIMG" "${OUTTXT%.txt}" -l por --psm 6 --oem 1 --dpi 300 -c preserve_interword_spaces=1 >/dev/null # 2>&1
tesseract "$OUTIMG" "${OUTTXT%.txt}" -l por --psm 6 >/dev/null 2>&1
echo "📝 Texto salvo em: $OUTTXT"
echo
done
echo "✅ Extração concluída."
}
_corrige_tab(){
grep -aiEh -A10 "$1" pis.txt cofins.txt | awk '
function _converte(s){ split(s,d,"/"); printf "%s-%s-%s ",d[3],d[2],d[1] } ;
$1 ~ "../../...." {
printf "%s %s %s\n" , _converte($1),_converte($2),$3
}
'
}
_pega_valor(){
awk -v d=$1 ' d >= $1 && d <= $2 { print $3} '
}
##########################
## feito para funcionar com a versao 1
_show_valores2(){
vFiltro=$1
d=$(date +%Y-%m-%d)
vPIS=$(_corrige_tab "Tarifa(_| *)PIS" | _pega_valor $d)
vCOFINS=$(_corrige_tab "Tarifa(_| *)COFINS" | _pega_valor $d)
# se valor do periodo nao existe, usa o ultimp disponivel...
[ -z "$vPIS" ] && vPIS=$(_corrige_tab "Tarifa(_| *)PIS"| awk 'NR==1 {print $3}' )
# se valor do periodo nao existe, usa o ultimp disponivel...
[ -z "$vCOFINS" ] && vCOFINS=$(_corrige_tab "Tarifa(_| *)COFINS"| awk 'NR==1 {print $3}' )
vOut=$(
echo "vPIS="$vPIS
echo "vCOFINS="$vCOFINS
)
{
if [ "$vFiltro" != "-" ]; then
echo "$vOut" | awk -v IGNORECASE=1 -v F=$vFiltro -F= '$1 ~ F { print $2}'
else
echo "$vOut"
fi
} | tr "," "." | tr -d "%"
}
#-# ##########################
#-# ## versao 1 , funcionou ate set/2025 ai eles mudaram o site , onde a tabela passou a ser uma imagem.
#-# _baixar_dados() {
#-# curl -s https://www.cpfl.com.br/piratininga/pis-cofins > pis_cofins.html
#-# [ $? -ne 0 ] && exit 1
#-# html2text -ascii pis_cofins.html > pis_cofins.txt
#-# }
#-#
#-# ##########################
#-# ## feito para funcionar com a versao 1
#-# _show_valores1(){
#-# vFiltro=$1
#-# d=$(date +%Y-%m-%d)
#-# vPIS=$(_corrige_tab "Tarifa_PIS" | _pega_valor $d)
#-# vCOFINS=$(_corrige_tab "Tarifa_COFINS" | _pega_valor $d)
#-#
#-# # se valor do periodo nao existe, usa o ultimp disponivel...
#-# [ -z "$vPIS" ] && vPIS=$(_corrige_tab "Tarifa_PIS"| head -n1 | awk '{print $3}' )
#-# # se valor do periodo nao existe, usa o ultimp disponivel...
#-# [ -z "$vCOFINS" ] && vCOFINS=$(_corrige_tab "Tarifa_COFINS"| head -n1 | awk '{print $3}' )
#-# vOut=$(
#-# echo "vPIS="$vPIS
#-# echo "vCOFINS="$vCOFINS
#-# )
#-# {
#-# if [ "$vFiltro" != "-" ]; then
#-# echo "$vOut" | awk -v IGNORECASE=1 -v F=$vFiltro -F= '$1 ~ F { print $2}'
#-# else
#-# echo "$vOut"
#-# fi
#-# } | tr "," "." | tr -d "%"
#-# }
#
# Modo remoto!
# ssh-keygen -t rsa -b 4096 -f docker_ssh_key -N ""
# cat docker_ssh_key.pub >> ~/.ssh/authorized_keys
#
if [[ $1 == -r ]]; then
shift
vCmd="~/ha.git/cpfl.tarifas/$( basename $0 ) $@ "
chmod 400 $(dirname $0)/docker_ssh_key
ssh -i $(dirname $0)/docker_ssh_key -o StrictHostKeyChecking=no root@box "$vCmd"
exit
fi
while getopts :bs: vOpcao
do
case $vOpcao in
b) _baixar_dados2 ;;
s) _show_valores2 $OPTARG ;;
esac
done
Ler dados
Utilizo a integração command_line para executar o script shell e capturar os dados de cada coleta.
##### CPFL - atualizacao online dos valores de tarifa
- sensor:
name: CPFL Tarifa Vigencia Inicio
unique_id: cpfl_tarifa_vigencia_inicio
command: 'bash /config/root.bin/ha/cpfl.tarifas/cpfl.tarifas.sh -s VigenciaIni '
scan_interval: 86400
- sensor:
name: CPFL Tarifa Vigencia Fim
unique_id: cpfl_tarifa_vigencia_fim
command: 'bash /config/root.bin/ha/cpfl.tarifas/cpfl.tarifas.sh -s Vigenciafim '
scan_interval: 86400
- sensor:
name: CPFL Tarifa Valor TE
unique_id: cpfl_tarifa_valor_te
command: 'bash /config/root.bin/ha/cpfl.tarifas/cpfl.tarifas.sh -s TE '
device_class: monetary
unit_of_measurement: "R$"
scan_interval: 3600
- sensor:
name: CPFL Tarifa Valor USD
unique_id: cpfl_tarifa_valor_usd
command: 'bash /config/root.bin/ha/cpfl.tarifas/cpfl.tarifas.sh -s USD '
device_class: monetary
unit_of_measurement: "R$"
scan_interval: 3600
- sensor:
name: CPFL Bandeira atual
unique_id: cpfl_bandeira_atual
command: 'bash /config/root.bin/ha/cpfl.tarifas/cpfl.tarifas.sh -s vBandeira '
scan_interval: 3600
- sensor:
name: CPFL Bandeira atual Inicio
unique_id: cpfl_bandeira_atual_inicio
command: 'bash /config/root.bin/ha/cpfl.tarifas/cpfl.tarifas.sh -s vInicioBand '
scan_interval: 3600
- sensor:
name: CPFL Bandeira atual Valor
unique_id: cpfl_bandeira_atual_valor
command: 'bash /config/root.bin/ha/cpfl.tarifas/cpfl.tarifas.sh -s ValorBand '
device_class: monetary
unit_of_measurement: "R$"
scan_interval: 3600
- sensor:
name: "CPFL % PIS"
unique_id: cpfl_pis
command: 'bash /config/root.bin/ha/cpfl.tarifas/pis.cofins.sh -s PIS '
device_class: monetary
unit_of_measurement: "%"
scan_interval: 3600
- sensor:
name: "CPFL % COFINS"
unique_id: cpfl_cofins
command: 'bash /config/root.bin/ha/cpfl.tarifas/pis.cofins.sh -s COFINS '
device_class: monetary
unit_of_measurement: "%"
scan_interval: 3600
# ICMS , nao pesquisei onde buscar, mas basicamente eh sempre 18%...
- sensor:
name: "CPFL % ICMS"
unique_id: cpfl_icms
command: 'echo 18'
device_class: monetary
unit_of_measurement: "%"
scan_interval: 3600
Carrego eles através de crontab
Antes tudo ficava em automação dentro do HA.
Com a mudança do site da CPFL tive que readaptar.
Então 1o faço o download dos dados as 3h da manhã, via crontab no host linux :
0 3 * * * { cd ~/ha/root.bin/ha/cpfl.tarifas ; bash pis.cofins.sh -b ; bash cpfl.tarifas.sh -b ; }
E os sensores já tem o parametro scan_interval que se atualizam automaticamente, não preciso configurar mais nada.
Calculos
Como template, criei os sensores abaixo para somar corretamente os tributos.
- sensor:
- name: Custo Energia CPFL
unique_id: custo_energia_cpfl
unit_of_measurement: "R$/kWh"
state: >
{{ (
( states("sensor.cpfl_tarifa_valor_te")|float(0)
+ states("sensor.cpfl_tarifa_valor_usd")|float(0) ) / 1000
) | round(4)
}}
- sensor:
- name: Custo Energia CPFL com tributos
unique_id: custo_energia_cpfl_com_tributos
unit_of_measurement: "R$/kWh"
# Sobre bandeiras...
# https://atosoficiais.com.br/aneel/resolucao-homologatoria-n-3306-2024-estabelece-as-faixas-de-acionamento-e-os-adicionais-das-bandeiras-tarifarias-de-que-trata-o-submodulo-6-8-do-proret-com-vigencia-a-partir-de-abril-de-2024
#
# Regra para calculo do tributo (fonte: https://energes.com.br/entendendo-a-fatura-de-energia-3/ )
# (tarifa) / ((1-ICMS%)*(1-(PIS%+COFINS%)))
state: >
{{ (
(
(states("sensor.custo_energia_cpfl")|float(0))
/ ( (1-( (states('sensor.cpfl_icms')|float)/100) )
* (1-( ( states('sensor.cpfl_pis')|float + states('sensor.cpfl_cofins')|float ) /100) )
)
)
+ ((states('sensor.cpfl_bandeira_atual_valor')|float) / 1000)
) |round(4)
}}
Então, também, como template , faço o calculo de custos.
Neste caso, eu tenho outros sensores acumuladores de potencia (Watts) que vem do meu device de monitor de consumo de energia da minha casa (Medição de Energia com Medidor TOMZN DTS238 + LocalTuya - #30 de ceinmart) .
Usando as integrações “Riemann sum” para acumular corretamente o consumo e utility_meter para quebrar isso em dias / semanas / mes , então eu tenho os consumos e os custos em tempo real.
Não só para a energia da casa , mas também para cada dispositivo que eu instalei uma tomada inteligente como geladeria, tv, pressurizadores, ar-condicionado (neste caso o aparelho já fornece o consumo), maquina de lavar roupa, maquina de lavar louça…
Valores totalizadores por dia , semana e mês.
(no caso, mês , eu considero o dia 24 de cada mês , pq é o dia que a CPFL sempre passa para fazer a leitura aqui em casa) .
energia_consumo_casa_diario:
source: sensor.energia_consumida_acumulada_casa
name: Energia consumo casa diario
unique_id: 88f4a2ce-99e6-11ee-ae3d-56135b517a8f
cron: "0 00 * * *"
energia_consumo_casa_semanal:
source: sensor.energia_consumida_acumulada_casa
name: Energia consumo casa semanal
unique_id: a1a1e570-99e6-11ee-bbb8-56135b517a8f
cron: "0 00 * * MON"
energia_consumo_casa_mensal_cpfl:
source: sensor.energia_consumida_acumulada_casa
name: Energia consumo casa mensal CPFL
unique_id: b30f386c-99e6-11ee-8f56-56135b517a8f
cron: "0 00 24 * *"
Calculo do consumo W x custo em R$
- sensor:
- name: Energia consumo - casa - diario - cpfl custo
unit_of_measurement: "R$"
state: >
{% set consumo = states('sensor.energia_consumo_casa_diario') | float %}
{% set tarifa = states('sensor.custo_energia_cpfl_com_tributos') | float %}
{% set valor = ( consumo * tarifa ) | round(2) %}
{{ valor }}
Aqui , vai perceber que estou “duplicando” parte da logica do painel Energy nativo do HA.
Quando implementei isso, ele era limitado, tinha menos recursos e visualizações limitadas.
Por isso fiz o meu controle eo meu proprio dashboard de controle de energia.
Bom, talvez não tenha compartilhado aqui 100% do codigo, mas o grosso acho que dá para entender e dar uma iniciativa para construir o seu .
Eu diria que para simplificar, não precisaria do sensor “Riemann sum” (porque normalmente os dispositivos já vem com os acumuladores), eu usei porque muitos dos sensores que eu tinha não possuiam o totalizadores de potencia, hoje já possuem (recurso adicionado pelo TuyaLocal , salvo engano).
O utility_meter, considero necessário para conseguir ter o controle nos periodos de interesse.
Não sei se tem outra forma, mais simplificada, de fazer tudo isso que fiz.
Na época foi como conseguir dar de solução.
Bom dia pessoal!!
Para quem teve problema na inicialização do addon após a atualização do core para a versão 2026.3.0, já está disponível o hotfix 1.0.3.
Eu havia atualizado, mas acabei não reparando que a extensão não subiu.
Agradecimentos ao @Felps por enviar o PR com a correção.
Bom dia pessoal!!
Sempre são grandes emoções com a API da ANEEL quando o final do mês se aproxima. Quem teve problema na inicialização do addon ontem, já está disponível o hotfix 1.0.4.
Agradecimentos ao @Felps por enviar o PR com mais uma correção.
Bom dia pessoal!
Só para alertar a todos os usuários da integração. A fonte de dados das bandeiras tarifárias não está retornando dados desde o início da semana. Já abri um protocolo com eles para verificarem. Com este último fix, a integração não quebrará, mas pegará um valor default. Assim que tiver um posicionamento, aviso por aqui.
Abraço! o/
Bom dia pessoal!
Disponibilizei a versão 1.1.0-beta.1 do addon com uma refatoração em alguns pontos, incluindo esta parte da aquisição da bandeira tarifária. Enquanto a ANEEL não responde sobre a API, notei que o arquivo CSV está completo, então adicionei o pré-carregamento do CSV ao subir a extensão e assim já mantém atualizado a bandeira tarifária atual. O fallback acabou ficando todo no banco de dados agora.
Já estou trabalhando para os próximos releases a exibição separada dos componentes tarifários. Estou estudando como farei a parte dos impostos e dos créditos de retorno para quem utiliza energia solar.
Se tiverem mais sugestões ou quiserem trocar mais idéias, é só chamar!
Abraço e boa páscoa!
Ola @vodikus ,
É , eu tive esse problema com o acesso da API da ANEEL e também resolvi baixando o CSV, o complicado é que alguns CSVs são enormes para ficar baixando com frequencia.
Gostaria de abandonar meus scripts e usar sua extensão, mas ai precisamos de mais dados.
No caso , eu estou fazendo cálculos também para a minha Fotovoltaica.
Quais tarifas sua extensão consegue disponibilizar hoje?
O chato é saber encontrar os dados, por exemplo, taxa do fio b de 2026 está no arquivo de 2025… porque eles colocam pela data de quando sai a Lei e não pela vigencia.
As informações que precisaria :
Que é possivel pegar no site da ANEEL
No meu caso para CPFL PIRATININGA
- Valor do TE
- Valor do TUSD
- Bandeira
- Custo da bandeira
- Taxa do fio B
Este, eu fiz um teste e implementei acessando a API direto no meu HA. Com o receio da API falhar novamente… preciso avaliar como manter o valor caso a API falhe (provavelmente terei que criar um sensor de template)
Vou compartilhar no final da msg como peguei.
Esse é o maior desaifo.
As informações abaixo, que eu saiba são federais, estaduais cada distribuidora trabalhar com um valor. É uma zona.
Teria que tentar achar um lugar com estas informações centralizadas, eu não achei…
O site da CPFL está uma m***a , era html , virou imagem, agora voltou para tabela html… descobri hoje que eu estou usando as % antigas pq meu script não encontra e ai esta mantendo valores antigos..
- % PIS
- % COFINS
- % ICMS
PIS e COFINS , são federais, mas cada distribuidora calcula o seu, da CPFL fica nessa pagina : PIS-Cofins - CPFL Piratininga | CPFL
ICMS : a explicação fica nessa pagina , Tributos Municipais, Estaduais e Federais | CPFL , mas basicamente é : consumo até 90kwh = isento, consumo até 200 kwh = 12% , acima de 200kwh = 18%
Torcendo para que o IVA/CBS facilite isso…
Eu acredito que você teria que fazer funções especificas para cada distribuidora , de onde buscar a informação e cada vez que eles mexem na pagina, teria o retrabalho de fazer a extração novamente.
E com todos estes dados, trazer os valores para facilitar o calculo com os medidores de potencia e painel de energia.
- TE+TUSD
- TE+TUSD + aplicação dos impostos
- Fio B com desconto de % referente ao Ano
- Fio B com desconto de % referente ao Ano + aplicação dos impostos
REST - Taxa Fio B
rest:
- resource: "https://dadosabertos.aneel.gov.br/api/3/action/datastore_search"
scan_interval: 21600 # 6 horas...
timeout: 30
params:
# ID exclusivo do arquivo CSV de componentes tarifárias de 2025
resource_id: "a4060165-3a0c-404f-926c-83901088b67c"
# Filtros em formato JSON para extrair exatamente a linha desejada
# Aqui usamos a acentuação correta que validamos no cURL
filters: '{"SigNomeAgente": "CPFL-PIRATINING", "DscComponenteTarifario": "TUSD_FioB", "DscBaseTarifaria": "Tarifa de Aplicação", "DscSubGrupoTarifario": "B3", "DscModalidadeTarifaria": "Convencional"}'
sensor:
- name: "Tarifa Fio B CPFL Piratininga"
unique_id: "tarifa_fio_b_cpfl_api"
unit_of_measurement: "R$/kWh"
device_class: monetary
# Agora o HA vai ver que a API retornou 4 itens (length > 0) e habilitará o sensor
value_template: >
{% if value_json is defined and value_json.success and (value_json.result.records | length > 0) %}
{# Pega o campo VlrComponenteTarifario do registro (o primeiro dos 4 retornado) #}
{# Usamos o 'first' para pegar o primeiro registro da lista com segurança #}
{% set registro = value_json.result.records | first %}
{% set valor_bruto = registro.VlrComponenteTarifario %}
{# Troca a vírgula brasileira por ponto e converte para decimal #}
{% set valor_decimal = valor_bruto | replace(',', '.') | float(0) %}
{# Divide por 1000 para converter de MWh para kWh #}
{{ (valor_decimal / 1000) | round(4) }}
{% else %}
{# Retorna 0 em caso de erro para não quebrar a validação monetária #}
0
{% endif %}
# Teste manual do acesso rest via curl
# # $ curl -X POST "https://dadosabertos.aneel.gov.br/api/3/action/datastore_search" -H "Content-Type: application/json" -d '{
# # "resource_id": "a4060165-3a0c-404f-926c-83901088b67c",
# # "filters": {
# # "SigNomeAgente": "CPFL-PIRATINING",
# # "DscComponenteTarifario": "TUSD_FioB",
# # "DscBaseTarifaria": "Tarifa de Aplicação",
# # "DscSubGrupoTarifario": "B3",
# # "DscModalidadeTarifaria": "Convencional"
# # }
# # }' | jq
Opa, boa tarde @ceinmart!
Atualmente a extensão busca tarifa de qualquer operadora. Estou começando uma nova versão para separar em entidades os valores do TE e TUSD, calcular a taxa do fio B. A parte dos tributos realmente temos o problema de não ter a informação centralizada, porém a Receita Federal disponibilizou o IVA/CBS via API, tenho que ver como faz exatamente para acessar, pq não é aberto. Até isso entrar oficialmente, a opção seria realmente fazer por operadora e ir criando as interfaces para tentar extrair conforme a necessidade.
Eu entro de férias na quarta-feira, dai terei um pouco mais de tempo para seguir com essa nova versão.
Acabo de instalar sua integração. Parabéns! Também estou interessado nos valores de TE e TUSD.
@vodikus , boa noite!
A algumas semanas atras, criei uma extensão para coleta de API da FOXESS , aparelho de micro-inversor , para a fotovoltaia que instalei.
Juro, não escrevi uma unica linha de codigo, apenas um documento super detalhado e usei o codex/chatgpt para criar a extensão , ficou melhor que as extensões oficiais existentes no H.A. hoje.
Pra isso eu fiz uma assinatura “temporaria” do codex , aquelas assinaturas que não paga o primeiro mês.
Depois que te mandei a msg sobre os itens de coleta, pensei aqui , vou tentar aproveitar essa assinatura e ver o que consigo criar para resolver esse das tarifas.
Olha , ainda tem falhas, mas acho que avancei muito.
Coleta TE, TUSD, bandeira, Fio B , nas APIs da ANEEL (com tratativa de fallback caso a API falhe) , busca nos sites das concessionárias as informações sobre os impostos (PIS/COFINS/ICMS) , calcula valores para quem tem micro-geração/fotovoltaica (auto-consumo, valor de conta com a geração , saldo de credito, custo com Fio B).
Inclui também um calculo para tarifa branca, mas esse as regras são muito variaveis, não sei se vai rolar … a ideia é a pessoa saber se vale apena ou não migrar para tarifa branca.
Criei tudo isso no mesmo esquema , fazendo um documento bem estruturado com links , fontes e explicações.
As falhas que ocorreram no desenvolvimento , boa parte foram por falta de informação que eu não coloquei (por falha, ou esquecimento).
Então, pq estou te contando tudo isso?
Eu não sou desenvolvedor Python. Tenho conhecimento e experiencia com desenvolvimento, mas não com Python.
Não consigo revisar e validar esse codigo.
Minha intenção , seria tentar deixar esta extensão funcional e ver se você quer assumir a continuidade do desenvolvimento dela.
Não sei se codigo gerado por IA é algo facil de trabalhar…
Se este codigo não for facil de trabalhar e não tiver interesse em dar continuidade , fique a vontade para extrair as partes que lhe interessa para agregar na sua extensão.
bom dia @ceinmart !
Essas ferramentas são muito boas realmente. Eu uso bastante para diversas funções, validação de código e tal. As vezes fazem umas cabeçadas, mas se fizer sob supervisão, dá pra tirar um caldo hahaha
Vou analisar o código, ver como tá a estrutura e vemos como fazer um frankstein de tudo.
Em tempo, sobre a API da RF para pegar o IVA, só é liberado para CNPJ. Por mais que eu consiga o acesso e implemente isso na extensão futuramente, quem não tiver o acesso liberado lá vai acabar tendo essa funcionalidade prejudicada. Mas vou deixar isso guardado na gaveta para pensar mais pra frente!
Na segunda já estou de volta a minha cidade e consigo analisar e testar o código.
Obrigado!
Olha , muitos ajustes, mas acho que finalmente consegui dar uma boa laptada…
O fallback para o csv foi a maior dor de cabeça .
Não sei porque esses caras do site dadosabertos não disponibilizam o csv compactado , iria reduzir muito a transferencia.
Como a pagina estava com intermitencia , consegui testar bem o contorno pelo csv.
Os demais campos, me parecem corretos.
Os calculos também.
Porém , testei apenas para CPFL- PIRATININGA , ainda não testei para as outras duas concessionarias que ja tem suporte.
Essa é a coleta que iniciei a pouco , depois de alguns ajustes.
No atributos inclui varias informações para ajudar em diagnostico e entendimento dos valores :
Bom dia @ceinmart .
Dei uma olhada no código do seu repo e junto com o que já tinha aqui, comecei a montar a release 2.0.0 da extensão. Aproveitei para pegar um template modelo de extensões do HACS e coloquei na estrutura sugerida deles. Por enquanto está com a tag develop no repo, pois ainda estou testando em meu ambiente e provavelmente terá mais alterações.
Se quiser dar uma olhada, segue o link:
Show!
Dei uma olhada rapida nos seus prints, deu uma melhorada boa.
Eu vi que vc não fez o fork.
Eu apliquei mais algumas correções na parte de fallback para quando a API falha e na restauração dos dados quando a API falha , depois que te mandei a msg.. a ultima versão é a 0.1.9 .
Se não tiver pego esta , pega no diff as melhorias.
diaaa
ao tentar add o custom esta dando erro e no log aparece
Log details (ERROR)
This error originated from a custom integration.
Logger: custom_components.tarifas_energia_brasil.api
Source: custom_components/tarifas_energia_brasil/api.py:214
Integration: Tarifas de Energia Brasil ([documentation](https://github.com/vodikus/ha_tarifas_energia_brasil), [issues](https://github.com/vodikus/ha_tarifas_energia_brasil/issues))
First occurred: 23 de junho de 2026 às 13:01:44 (4 occurrences)
Last logged: 11:05:38
Erro ao acessar a API da ANEEL: 400, message='BAD REQUEST', url='https://dadosabertos.aneel.gov.br/api/3/action/datastore_search_sql?sql=SELECT+%22SigAgente%22+from+%22fcf2906c-7c32-4b9b-a637-054e7a5234f4%22+group+by+%22SigAgente%22'
Boa tarde!
Vou avaliar, mas pelo que olhei por alto, houve alguma mudança nas chamadas. Em breve já solto uma fix.
Boa tarde amigos! Espero que estejam todos bem!
Liberei um novo release (1.2.0) resolvendo o atual problema de consumo da API da ANEEL, que pelo que vi, mudou uma ação que usava para consultar as tarifas.
Fiz uma alteração um pouco mais robusta, mas necessária, visto que já não é a primeira vez que os “iluminados” lá alteram coisas e quebra o addon haha
A alteração consiste na adição de uma API que disponibilizei na Cloudflare, onde sempre libera a última atualização disponível no CSV. Eu tenho um serviço monitorando a atualização lá e que dispara essa atualização de base quando houver alteração.
O addon vai buscar a informação sempre que estiver próximo do fim da data de vigência da tarifa.
Caso tenham algum problema, me avisem. Tentarei resolver o mais rápido possível.
Um abraço a todos!
seria possivel um sensor já com o desconto do “FIO B” assim poderiamos calcular o valor economizado em casa conta, se comprarado ao valor cheio do KW!
Boa tarde @Oraculo .
Estou trabalhando na v2 do addon já com essa feature e outras. Como fiz a migração no final de semana para essa nova API, preciso refatorar também na v2. Além disso, estou planejando jogar a parte dos tributos para lá também.
Em breve libero um pre-release da v2.
Abraço!




