Files
Idalecio Schvartz Sobrinho df2c999d9b Add files via upload
2026-05-30 18:44:44 -03:00

141 lines
4.0 KiB
Python

#!/usr/bin/env python3
import os
import sys
import time
import asyncio
from datetime import datetime, date, timedelta
from decimal import Decimal
import xml.etree.ElementTree as ET
import aiohttp
import goodwe
from dotenv import load_dotenv
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
load_dotenv()
print("=" * 60)
print("GoodWe Influx Exporter")
print("=" * 60)
INVERTER_IP = os.getenv('INVERTER_IP')
POLLING_INTERVAL = int(os.getenv('POLLING_INTERVAL', '30'))
PV_POWER = float(os.getenv('PV_POWER', '5670'))
SCRAPE_SPOT_PRICE = os.getenv('SCRAPE_SPOT_PRICE', 'False').lower() == 'true'
INFLUXDB_URL = os.getenv('INFLUXDB_URL')
INFLUXDB_TOKEN = os.getenv('INFLUXDB_TOKEN')
INFLUXDB_ORG = os.getenv('INFLUXDB_ORG')
INFLUXDB_BUCKET = os.getenv('INFLUXDB_BUCKET')
if not INVERTER_IP:
print("ERRO: INVERTER_IP não configurado no .env")
sys.exit(1)
if not all([INFLUXDB_URL, INFLUXDB_TOKEN, INFLUXDB_ORG, INFLUXDB_BUCKET]):
print("ERRO: Configurações do InfluxDB faltando no .env")
sys.exit(1)
print(f"Inversor: {INVERTER_IP}")
print(f"Intervalo: {POLLING_INTERVAL}s")
print(f"InfluxDB: {INFLUXDB_URL}")
print("=" * 60)
influx_client = InfluxDBClient(url=INFLUXDB_URL, token=INFLUXDB_TOKEN, org=INFLUXDB_ORG)
write_api = influx_client.write_api(write_options=SYNCHRONOUS)
current_port = 8899
def write_to_influx(measurement, fields, tags=None):
try:
point = Point(measurement)
if tags:
for key, value in tags.items():
point = point.tag(key, value)
for key, value in fields.items():
if isinstance(value, (int, float)):
point = point.field(key, float(value))
write_api.write(bucket=INFLUXDB_BUCKET, record=point)
except Exception as e:
print(f"Erro ao escrever no InfluxDB: {e}")
async def connect_inverter():
#conecta ao inversor alternando entre portas 8899 e 48899
global current_port
ports = [8899, 48899]
for attempt in range(len(ports)):
try:
print(f"Tentando conectar na porta {current_port}...")
inverter = await goodwe.connect(INVERTER_IP, timeout=5, retries=1,port=current_port, family="DT")
print(f"✓ Conectado na porta {current_port}")
return inverter
except Exception as e:
print(f"✗ Falha na porta {current_port}: {e}")
current_port = 48899 if current_port == 8899 else 8899
print(f"Tentando novamente na porta {current_port}...")
return await goodwe.connect(INVERTER_IP, timeout=5, retries=1, family="DT")
async def collect_and_send():
inverter = await connect_inverter()
runtime_data = await inverter.read_runtime_data()
# prepara dados
fields = {}
for sensor in inverter.sensors():
if sensor.id_ in runtime_data:
value = runtime_data[sensor.id_]
if isinstance(value, (int, float)):
fields[sensor.id_] = float(value)
fields['pv_total_power'] = PV_POWER
write_to_influx(
"inverter_data",
fields,
{
"inverter_ip": INVERTER_IP,
"model": runtime_data.get("model_name", "unknown")
}
)
print(f"[{datetime.now().strftime('%H:%M:%S')}] Enviado {len(fields)} métricas | "
f"Potência: {fields.get('ppv', 0):.0f}W | "
f"Energia hoje: {fields.get('e_day', 0):.2f}kWh ")
async def main_loop():
print("\nIniciando coleta de dados...\n")
while True:
try:
await collect_and_send()
except Exception as e:
print(f"✗ Erro: {e}")
await asyncio.sleep(POLLING_INTERVAL)
if __name__ == "__main__":
try:
asyncio.run(main_loop())
except KeyboardInterrupt:
print("\n\nInterrompido pelo usuário")
influx_client.close()
sys.exit(0)
except Exception as e:
print(f"\n\nErro fatal: {e}")
influx_client.close()
sys.exit(1)