Medição de Energia com Medidor TOMZN DTS238 + LocalTuya

Aqui em casa o meu inversor é da Goodwe e consegui acessar direto as informações de produção por ele mesmo.

Não sei te dizer…

Pode tentar perguntar para algum vendedor desse medidor que pode ter melhor essas informações.

Eu tentei colocá-lo na casa do meu pai mas lá não consegui porque a entrada da energia produzida já é dentro da casa e entendo que seria melhor colocar um medidor bidirecional mesmo.

Aqui em casa que coloquei os cabos da produção de energia injetando antes da medição do consumo de toda a casa funcionou sem problema.

A minha única preocupação é quanto a durabilidade desse medidor. O meu está em área externa em uma caixa para proteger da chuva mas queimou após 6 meses de uso. Eu ainda não comprei um novo para substituí-lo.

“Eu tentei colocá-lo na casa do meu pai mas lá não consegui porque a entrada da energia produzida já é dentro da casa e entendo que seria melhor colocar um medidor bidirecional mesmo.”

NA CASA DE SEU PAI OS CABOS GERAÇÃO FOTOVOLTAICA CHEGAM NO QUADRO DE DISTRIBUIÇÃO?

“Aqui em casa que coloquei os cabos da produção de energia injetando antes da medição do consumo de toda a casa funcionou sem problema.”

NA SUA CASA OS CABOS GERAÇÃO FOTOVOLTAICA CHEGAM ANTES DO QUADRO DE DISTRIBUIÇÃO, NA ÁREA EXTERNA DA CASA?

Estou pensando em comprar um medidor de energia e minha dúvida é onde instalar, pois entrada energia solar é na área externa casa. Você teria indicação de algum medidor?
Pesquisei na internet e encontrei o DTS238-7 bidirecional porem é trifásico e de acordo com fabricante não pode funcionar com apenas 2 fases.
Tem DTS238-4 não é bidirecional porem é bifásico.

Você que já tem experiência no tema, o medidor registra a energia GERADA pelo sistema fotovoltaico ou a energia CONSUMIDA pelas cargas conectadas, sendo que será instalado na entrada quadro distribuição?

grato

integração de um medidor elétrico trifásico DTS-238-7 (aplicativo WISEN, protocolo hekr) em um homeassistant por meio do complemento ESPhome.

migo, comprei um DTS 238-7 wifi IVAP e queria poder fazer exatametne como você fez…pode me dar uma luz? Obrigado

  • UVAP-Me passa como você conseguiu! Tenho um DTS 238-7 Ivap e queria fazer exatamente este monitoramento que você fez no HA

Eu estou usando a integração do HACS localtuya, está funcionando bem… Basta seguir o tutorial que tem lá mesmo no git que irá conectar sem problemas com o medidor.
A única restrição que achei foi que só consigo pegar a tensão e corrente de uma das fases, as outras duas vão para o limbo (até mesmo no próprio app da Tuya).
Agora o consumo ele vem certinho de forma agrupada nas três fases.

Eu tenho exatamente esse medidor tambem mas nao sei (e ninguem me explicou) como usar ele e necessito desesperadamente saber o consumo electrico da minha casa. Sugeriram usar ele por meio da Tuya local App mas nao tenho conseguido nem ligar ele por Wifi com a Tuya App. Ajuda? Obrigado Jose Martins

Olá!
Tenho o medidor DTS238-7 instalado a pouco mais de 2 anos , coletando dados via TuyaLocal , sem problemas.
A unica limitação que sempre me incomodou é o fato de trazer apenas o consumo total e não por fase.
Estou vendo de instalar/configurar o RS485 modbus wifi para integrar com o HA e ver se traz o consumo por fase.
Alguém já fez esta instalação / configuração?

Estou avaliando de instalar fotovoltaica também, então espero que ele funcione bem com este monitoramento.

Olá Pessoal,
Apenas compartilhando o que fiz aqui.

DST238-7 Ver:TY

Hoje tenho um DST238-7 Ver:TY , instalado em meu quadro principal , monitorando toda carga de energia da casa.

  • Conectado na nuvem da TUYA e coletando dados via integração TuyaLocal.
  • Na integração tuya , coleta apenas o consumo total das 3 fases , apesar de ele ter a informação por fase.
  • Salvo o histórico dos dados em um Influx , que usei para fazer levantamentos de horas de consumo e definir a compra da fotovoltaica que vou instalar.

PROBLEMAS com este modelo

  • Este modelo, oficialmente não é bi-direcional, para controlar com geração fotovoltaica, quando está injetando na rede.
    Descobri que existe a versão IVAP (acho que não existia quando comprei o meu).
    E que a diferença entre eles é o fato do IVAP ser oficialmente bidirecional (para geração fotovoltaica) e ter muito mais recursos de proteção.
  • A integração TUYA , não traz informação por fase, o que atrapalhou meu levantamento sobre a distribuição de carga aqui em casa (trifásico) e assim definição sobre a configuração da fotovoltaica (microinversores, 1 por fase , também para balanceamento)

RS485

Este modelo tem uma porta de comunicação RS485 , que ignorei quando instalei ele (não devia ter ignorado).
Com isso, é possivel coletar dados diretamente sem depender da nuvem tuya , não precisa nem parear o device com o app da tuya.
Comprei um modulo RS485-WIFI no aliexpress (Elfin EW11A mini) , conectei nele e com a ajuda da IA, criei um script python para fazer a coleta dos dados. Confesso que não foi fácil, devido à falta de documentação no site da TOMZN , mas para minha sorte achei a documentação dos comandos RS485 em outra variação do modelo que serviu perfeitamente.
Passei a coletar TODAS as informações exibida no display:

# ./modbus.dst238-7.ver-ty.py  modbus.conf
ADDR  | NOME                      | VALOR           | UNIDADE
-----------------------------------------------------------------
0     | Active Energy Total       | 14328.04        | kWh
4     | Reactive Energy Positive  | 60.14           | kvarh
8     | Reversing Energy          | 0.0             | kWh
10    | Forward Energy            | 14328.04        | kWh
17    | Frequency                 | 59.97           | Hz
21    | Comms Info                | Addr: 1, Baud: 9600 |
128   | Voltage Phase A           | 124.9           | V
129   | Voltage Phase B           | 124.0           | V
130   | Voltage Phase C           | 124.5           | V
131   | Current Phase A           | 1.66            | A
132   | Current Phase B           | 1.19            | A
133   | Current Phase C           | 0.95            | A
134   | Active Power Total        | 0.323           | kW
136   | Active Power Phase A      | 0.155           | kW
137   | Active Power Phase B      | 0.059           | kW
138   | Active Power Phase C      | 0.108           | kW
139   | Reactive Power Total      | -0.237          | kvar
141   | Reactive Power Phase A    | -0.104          | kvar
142   | Reactive Power Phase B    | -0.105          | kvar
143   | Reactive Power Phase C    | -0.027          | kvar
144   | Apparent Power Total      | 0.475           | kVA
146   | Apparent Power Phase A    | 0.207           | kVA
147   | Apparent Power Phase B    | 0.149           | kVA
148   | Apparent Power Phase C    | 0.118           | kVA
149   | Power Factor Total        | 0.678           | PF
150   | Power Factor Phase A      | 0.745           | PF
151   | Power Factor Phase B      | 0.396           | PF
152   | Power Factor Phase C      | 0.914           | PF

Pelas informações da documentação que encontrei, dá a entender que ele suporta o bi-direcional, pois tem registradores para isso. Mas não tenho como afirmar na prática e não terei no futuro, porque vou troca-lo pela versão IVAP.

Então ainda com a ajuda da IA, ajustei o script para já enviar os dados para o meu Home Assistant, via MQTT ou integração Modbus.

Na opção MQTT tem a vantagem de que ele cria o device , adiciona os sensores, tudo automático.
Porém o disparo de coleta é manual , ou você cria uma automação que roda o script ou cria uma chamada via crontab.
E a coleta é sempre 100% dos sensores, não é possivel separar qual sensor coletar (talvez ajustar o script para permitir receber como parametro esta informação).
No meu caso, como rodo meu HA em docker, tive que usar a opção de crontab do host para coletar a cada 20 segundos:

* *  *  *  *  { cd ~/bin ; for x in 1 2 3 ; do ./modbus.dst238-7.ver-ty.py --mqtt modbus.conf >/dev/null ; sleep 20 ; done ; }

Já a versão Modbus tem um ponto de vantagem e outras desvantagens:

  • Vantagem unica: possivel definir o intervalo de coleta por sensor
  • Desvantages
    • Não cria um device , todos os sensores aparecem dentro da integração Modbus
    • Faz a coleta item a item , o que deixa o processo muito lento, já que não é super rapido esta coleta. (coletar todos os itens em 1 comando leva ~2 segundos, item a item leva ~25seg).

Codigo

Segue abaixo a copia do script python e arquivo de configuração já com os registradores disponiveis para este modelo.

#!/usr/bin/python3
# Versão: 17.0
# Data: 2026-02-17
# Descrição: Leitor Modbus Tomzn DST238-7 
# Funcionalidades: 
#   - Leitura otimizada por Batch (blocos)
#   - Tratamento de tipos DWORD/INT32 e Signed/Unsigned
#   - Integração MQTT com Auto-Discovery do Home Assistant
#   - Geração de YAML para Cards (Lovelace)
#   - Geração de YAML para integração Modbus nativa

import socket
import struct
import time
import sys
import json
import argparse
import os

# Tenta importar paho-mqtt para funcionalidade opcional de MQTT
try:
    import paho.mqtt.client as mqtt
except ImportError:
    mqtt = None

# --- CONSTANTES GLOBAIS ---
SLAVE_ID = 1

def load_config(config_file):
    """Carrega o arquivo JSON de configuração."""
    if not os.path.exists(config_file):
        print(f"ERRO: Arquivo '{config_file}' não encontrado.")
        sys.exit(1)
    try:
        with open(config_file, 'r', encoding='utf-8') as f:
            return json.load(f)
    except Exception as e:
        print(f"ERRO JSON: {e}")
        sys.exit(1)

def calculate_crc(data):
    """Calcula o CRC16 (Modbus) para validação de pacotes."""
    crc = 0xFFFF
    for char in data:
        crc ^= char
        for _ in range(8):
            if (crc & 0x0001):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
    return struct.pack('<H', crc)

def read_batch(sock, start_addr, quantity):
    """
    Realiza a leitura de um bloco contínuo de registradores.
    Usa Modbus TCP encapsulando frames RTU (Modbus-TCP-to-RTU).
    """
    # Monta frame RTU: ID + Func(3) + Endereço + Qtd + CRC
    req = struct.pack('>BBHH', SLAVE_ID, 3, start_addr, quantity)
    req += calculate_crc(req)
    
    try:
        sock.send(req)
        # Resposta esperada: ID + Func + BytesCount + Dados + CRC
        response = sock.recv(1024)
        if len(response) < 5: 
            return None, f"Resposta Curta ({len(response)}b)"
        
        # Valida integridade dos dados recebidos via CRC
        if calculate_crc(response[:-2]) != response[-2:]: 
            return None, "Erro CRC"
            
        # Retorna apenas a carga útil (dados), removendo cabeçalho e CRC
        return response[3:-2], None
    except Exception as e:
        return None, str(e)

def parse_bytes_to_value(raw_chunk, reg_config):
    """
    Converte os bytes brutos lidos do medidor para valores humanos.
    Aplica escala, sinal e formatação baseada no 'type' definido no conf.
    """
    dtype = reg_config.get('type', 'WORD')
    scale = reg_config.get('scale', 1.0)
    hex_s = raw_chunk.hex().upper()
    
    try:
        if dtype == "HI_LO":
            # Tratamento especial para registrador 21 (0x15): High Byte = Address, Low Byte = Baudrate
            val_full = struct.unpack('>H', raw_chunk)[0]
            high = (val_full >> 8) & 0xFF
            low = val_full & 0xFF
            baud_map = {1: 9600, 2: 4800, 3: 2400, 4: 1200}
            baud_str = baud_map.get(low, f"Unknown({low})")
            val_fmt = f"Addr: {high}, Baud: {baud_str}"
            return hex_s, val_full, val_fmt

        # Definição de formatos para struct.unpack (Big Endian '>')
        fmt_map = { 
            "DWORD": ">I",  # Unsigned 32-bit (4 bytes)
            "INT32": ">i",  # Signed 32-bit (4 bytes)
            "WORD": ">H",   # Unsigned 16-bit (2 bytes)
            "INT16": ">h"   # Signed 16-bit (2 bytes)
        }
        fmt = fmt_map.get(dtype, ">H")
        
        val_int = struct.unpack(fmt, raw_chunk)[0]
        val_scaled = val_int * scale
        
        # Ajuste fino para float point issues
        if isinstance(val_scaled, float):
            val_scaled = round(val_scaled, 4)
            
        return hex_s, val_int, val_scaled
    except Exception as e:
        return hex_s, 0, 0

def get_mqtt_device_class(unit):
    """Helper para definir classes do Home Assistant baseadas na unidade."""
    if unit in ["kWh", "Wh", "MWh"]: return "energy", "total_increasing"
    elif unit in ["V"]: return "voltage", "measurement"
    elif unit in ["A"]: return "current", "measurement"
    elif unit in ["W", "kW", "VA", "kVA", "var", "kvar"]: return "power", "measurement"
    elif unit in ["Hz"]: return "frequency", "measurement"
    elif unit in ["PF"]: return "power_factor", "measurement"
    return None, "measurement"

def send_mqtt(results, full_conf):
    """Publica os dados coletados num broker MQTT com Auto-Discovery."""
    if not mqtt:
        print("ERRO: Biblioteca paho-mqtt não encontrada.")
        return

    m_conf = full_conf.get('mqtt', {})
    d_conf = full_conf.get('device', {})
    r_map = full_conf.get('registers', {})
    
    broker = m_conf.get('broker', 'localhost')
    port = int(m_conf.get('port', 1883))
    user = m_conf.get('username')
    passwd = m_conf.get('password')
    prefix = m_conf.get('topic_prefix', 'homeassistant')
    
    client = mqtt.Client()
    # Autenticação condicional: só usa se user E pass estiverem preenchidos
    if user and passwd:
        client.username_pw_set(user, passwd)
        
    try:
        client.connect(broker, port, 60)
    except Exception as e:
        print(f"Erro Conexão MQTT ({broker}:{port}): {e}")
        return

    dev_id = d_conf.get('unique_id', 'tomzn_meter')
    dev_name = d_conf.get('name', 'Tomzn Meter')
    
    # Payload do Dispositivo (para agrupar sensores)
    device_info = {
        "identifiers": [dev_id],
        "name": dev_name,
        "model": d_conf.get('model', 'DST238-7'),
        "manufacturer": d_conf.get('manufacturer', 'Tomzn')
    }

    payload_values = {}
    
    for addr, (hex_s, raw, val) in results.items():
        addr_s = str(addr)
        if addr_s not in r_map: continue
        reg = r_map[addr_s]
        
        if reg['type'] == 'HI_LO': continue

        safe_name = reg['name'].lower().replace(" ", "_").replace(".", "").replace("ç","c").replace("ã","a").replace("ê","e")
        unique_id = f"{dev_id}_{addr}"
        object_id = f"{safe_name}_{addr}"
        
        config_topic = f"{prefix}/sensor/{dev_id}/{object_id}/config"
        state_topic = f"{prefix}/sensor/{dev_id}/state"
        
        dc, sc = get_mqtt_device_class(reg['unit'])
        
        cfg_payload = {
            "name": f"{dev_name} {reg['name']}",
            "unique_id": unique_id,
            "state_topic": state_topic,
            "value_template": f"{{{{ value_json.{object_id} }}}}",
            "unit_of_measurement": reg['unit'],
            "device": device_info,
            "state_class": sc
        }
        if dc: cfg_payload["device_class"] = dc
        
        # Publica configuração (Retain)
        client.publish(config_topic, json.dumps(cfg_payload), retain=True)
        payload_values[object_id] = val

    # Publica valores (Estado)
    if payload_values:
        client.publish(f"{prefix}/sensor/{dev_id}/state", json.dumps(payload_values))
        print(f"MQTT: Enviados {len(payload_values)} sensores para {broker}")
    
    client.disconnect()

def generate_ha_card(full_conf):
    """Gera YAML para cartão 'Entities' do Dashboard do HA."""
    d_conf = full_conf.get('device', {})
    r_map = full_conf.get('registers', {})
    dev_id = d_conf.get('unique_id', 'tomzn_meter')
    
    print("\n# --- COPIE PARA SEU DASHBOARD (YAML) ---")
    print("type: entities")
    print(f"title: {d_conf.get('name', 'Medidor')}")
    print("entities:")
    
    sorted_addrs = sorted([int(k) for k in r_map.keys()])
    for addr in sorted_addrs:
        reg = r_map[str(addr)]
        if reg['type'] == 'HI_LO': continue
        safe_name = reg['name'].lower().replace(" ", "_").replace(".", "").replace("ç","c").replace("ã","a").replace("ê","e")
        print(f"  - entity: sensor.{dev_id}_{safe_name}_{addr}")
        print(f"    name: {reg['name']}")

def generate_modbus_integration_yaml(full_conf):
    """
    Gera configuração YAML para a integração 'modbus:' nativa do HA.
    Utiliza o 'scan_interval' definido por item no JSON.
    """
    ew11_conf = full_conf.get('ew11', {})
    d_conf = full_conf.get('device', {})
    r_map = full_conf.get('registers', {})
    
    # Valor padrão se não houver config específica
    default_scan = d_conf.get('scan_interval', 30)
    
    print("\n# --- COPIE PARA SEU CONFIGURATION.YAML (INTEGRAÇÃO MODBUS) ---")
    print("modbus:")
    print("  - name: tomzn_hub")
    print("    type: tcp")
    print(f"    host: {ew11_conf.get('ip', '192.168.1.163')}")
    print(f"    port: {ew11_conf.get('port', 8899)}")
    print("    sensors:")
    
    # Mapeamento de tipos internos para tipos do HA Modbus
    ha_type_map = {
        "DWORD": "uint32",
        "INT32": "int32",
        "WORD": "uint16",
        "INT16": "int16"
    }

    sorted_addrs = sorted([int(k) for k in r_map.keys()])
    for addr in sorted_addrs:
        reg = r_map[str(addr)]
        
        # Ignora HI_LO (Endereço 15) pois requer template complexo não suportado nativamente de forma simples
        if reg['type'] == 'HI_LO': 
            continue
            
        ha_type = ha_type_map.get(reg['type'], "uint16")
        # Usa scan_interval do item, ou o default do dispositivo se não existir
        item_scan = reg.get('scan_interval', default_scan)
        
        safe_name = reg['name'].lower().replace(" ", "_").replace(".", "").replace("ç","c").replace("ã","a").replace("ê","e")

        print(f"      - name: \"{reg['name']}\"")
        # Unique ID ajuda a editar o sensor via UI depois
        print(f"        unique_id: {d_conf.get('unique_id', 'tomzn')}_{safe_name}_{addr}")
        print(f"        address: {addr}")
        print(f"        slave: {SLAVE_ID}")
        print(f"        input_type: holding")
        print(f"        data_type: {ha_type}")
        print(f"        scale: {reg['scale']}")
        print(f"        unit_of_measurement: \"{reg['unit']}\"")
        print(f"        scan_interval: {item_scan}")
        
        # Define device_class e state_class para estatísticas de energia funcionarem
        dc, sc = get_mqtt_device_class(reg['unit']) 
        if dc:
            print(f"        device_class: {dc}")
        if sc == "total_increasing":
            print(f"        state_class: total_increasing")
        elif sc == "measurement":
             print(f"        state_class: measurement")

def main():
    parser = argparse.ArgumentParser(description="Leitor Tomzn DST238-7 v17.0")
    parser.add_argument('config_file', help='Arquivo modbus.conf')
    parser.add_argument('--mqtt', action='store_true', help='Envia leitura atual para MQTT')
    parser.add_argument('--gen-card', action='store_true', help='Gera YAML para card Lovelace')
    parser.add_argument('--gen-modbus', action='store_true', help='Gera YAML para integração Modbus nativa')
    args = parser.parse_args()

    full_conf = load_config(args.config_file)
    ew11_conf = full_conf.get('ew11', {})
    reg_map = full_conf.get('registers', {})

    # Se for apenas para gerar configurações, não conecta no medidor
    if args.gen_card:
        generate_ha_card(full_conf)
        return
        
    if args.gen_modbus:
        generate_modbus_integration_yaml(full_conf)
        return

    # Parâmetros de Conexão com o conversor EW11
    ip = ew11_conf.get('ip', '192.168.1.163')
    port = int(ew11_conf.get('port', 8899))

    # Estabelece Conexão TCP
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(3.0)
    try:
        sock.connect((ip, port))
    except Exception as e:
        print(f"ERRO: Não foi possível conectar em {ip}:{port} -> {e}")
        return

    target_addrs = sorted([int(k) for k in reg_map.keys()])
    results = {}
    
    # --- ALGORITMO DE LEITURA OTIMIZADA (BATCH) ---
    # Agrupa endereços próximos para reduzir número de requisições
    groups = []
    if target_addrs:
        current_group = [target_addrs[0]]
        for addr in target_addrs[1:]:
            last_addr = current_group[-1]
            last_reg = reg_map[str(last_addr)]
            
            # Determina tamanho do dado anterior (1 ou 2 words)
            last_size = 2 if last_reg['type'] in ['DWORD', 'INT32'] else 1
            expected_next = last_addr + last_size
            gap = addr - expected_next
            
            # Regras de agrupamento: gap pequeno (<10) e bloco total razoável (<60)
            curr_size = 2 if reg_map[str(addr)]['type'] in ['DWORD', 'INT32'] else 1
            block_len = (addr + curr_size) - current_group[0]
            
            if gap < 10 and block_len < 60:
                current_group.append(addr)
            else:
                groups.append(current_group)
                current_group = [addr]
        groups.append(current_group)

    # --- EXECUÇÃO DAS LEITURAS ---
    for grp in groups:
        start = grp[0]
        last = grp[-1]
        last_type = reg_map[str(last)]['type']
        last_size = 2 if last_type in ['DWORD', 'INT32'] else 1
        count = (last - start) + last_size
        
        raw_data, err = read_batch(sock, start, count)
        
        if not err and raw_data:
            for addr in grp:
                offset = (addr - start) * 2
                dtype = reg_map[str(addr)]['type']
                dsize = 4 if dtype in ['DWORD', 'INT32'] else 2
                
                # Garante que temos bytes suficientes no buffer para este registrador
                if offset + dsize <= len(raw_data):
                    chunk = raw_data[offset:offset+dsize]
                    results[addr] = parse_bytes_to_value(chunk, reg_map[str(addr)])
                else:
                    results[addr] = ("ERR", 0, "Buffer Incompleto")
        else:
            for addr in grp:
                results[addr] = ("ERR", 0, f"Falha Leitura: {err}")

    sock.close()

    # --- EXIBIÇÃO NO TERMINAL ---
    print(f"{'ADDR':<5} | {'NOME':<25} | {'VALOR':<15} | {'UNIDADE'}")
    print("-" * 65)
    for addr in target_addrs:
        if addr in results:
            hex_s, raw, val = results[addr]
            reg = reg_map[str(addr)]
            unit = reg.get('unit', '')
            print(f"{addr:<5} | {reg['name']:<25} | {str(val):<15} | {unit}")

    # Envio Opcional MQTT
    if args.mqtt:
        send_mqtt(results, full_conf)

if __name__ == "__main__":
    main()

Arquivo de configuração:

{
    "ew11": {
        "ip": "192.168.#.#,
        "port": 8899
    },
    "mqtt": {
        "broker": "192.168.#.#",
        "port": 1883,
        "username": "",
        "password": "",
        "topic_prefix": "homeassistant"
    },
    "device": {
        "name": "Disjuntor Geral",
        "unique_id": "dst2387_rs485",
        "model": "DST238-7 Ver:TY",
        "manufacturer": "Tomzn"
    },
    "registers": {
        "0": { "name": "Active Energy Total", "type": "DWORD", "scale": 0.01, "unit": "kWh", "sign": "Unsigned", "scan_interval": 60 },
        "4": { "name": "Reactive Energy Positive", "type": "DWORD", "scale": 0.01, "unit": "kvarh", "sign": "Unsigned", "scan_interval": 60 },
        "8": { "name": "Reversing Energy", "type": "DWORD", "scale": 0.01, "unit": "kWh", "sign": "Unsigned", "scan_interval": 60 },
        "10": { "name": "Forward Energy", "type": "DWORD", "scale": 0.01, "unit": "kWh", "sign": "Unsigned", "scan_interval": 60 },
        "17": { "name": "Frequency", "type": "WORD", "scale": 0.01, "unit": "Hz", "sign": "Unsigned", "scan_interval": 20 },
        "21": { "name": "Comms Info", "type": "HI_LO", "scale": 1, "unit": "", "sign": "Unsigned", "scan_interval": 300 },
        "128": { "name": "Voltage Phase A", "type": "WORD", "scale": 0.1, "unit": "V", "sign": "Unsigned", "scan_interval": 15 },
        "129": { "name": "Voltage Phase B", "type": "WORD", "scale": 0.1, "unit": "V", "sign": "Unsigned", "scan_interval": 15 },
        "130": { "name": "Voltage Phase C", "type": "WORD", "scale": 0.1, "unit": "V", "sign": "Unsigned", "scan_interval": 15 },
        "131": { "name": "Current Phase A", "type": "WORD", "scale": 0.01, "unit": "A", "sign": "Unsigned", "scan_interval": 10 },
        "132": { "name": "Current Phase B", "type": "WORD", "scale": 0.01, "unit": "A", "sign": "Unsigned", "scan_interval": 10 },
        "133": { "name": "Current Phase C", "type": "WORD", "scale": 0.01, "unit": "A", "sign": "Unsigned", "scan_interval": 10 },
        "134": { "name": "Active Power Total", "type": "INT32", "scale": 0.001, "unit": "kW", "sign": "Signed", "scan_interval": 10 },
        "136": { "name": "Active Power Phase A", "type": "INT16", "scale": 0.001, "unit": "kW", "sign": "Signed", "scan_interval": 10 },
        "137": { "name": "Active Power Phase B", "type": "INT16", "scale": 0.001, "unit": "kW", "sign": "Signed", "scan_interval": 10 },
        "138": { "name": "Active Power Phase C", "type": "INT16", "scale": 0.001, "unit": "kW", "sign": "Signed", "scan_interval": 10 },
        "139": { "name": "Reactive Power Total", "type": "INT32", "scale": 0.001, "unit": "kvar", "sign": "Signed", "scan_interval": 20 },
        "141": { "name": "Reactive Power Phase A", "type": "INT16", "scale": 0.001, "unit": "kvar", "sign": "Signed", "scan_interval": 20 },
        "142": { "name": "Reactive Power Phase B", "type": "INT16", "scale": 0.001, "unit": "kvar", "sign": "Signed", "scan_interval": 20 },
        "143": { "name": "Reactive Power Phase C", "type": "INT16", "scale": 0.001, "unit": "kvar", "sign": "Signed", "scan_interval": 20 },
        "144": { "name": "Apparent Power Total", "type": "DWORD", "scale": 0.001, "unit": "kVA", "sign": "Unsigned", "scan_interval": 20 },
        "146": { "name": "Apparent Power Phase A", "type": "WORD", "scale": 0.001, "unit": "kVA", "sign": "Unsigned", "scan_interval": 20 },
        "147": { "name": "Apparent Power Phase B", "type": "WORD", "scale": 0.001, "unit": "kVA", "sign": "Unsigned", "scan_interval": 20 },
        "148": { "name": "Apparent Power Phase C", "type": "WORD", "scale": 0.001, "unit": "kVA", "sign": "Unsigned", "scan_interval": 20 },
        "149": { "name": "Power Factor Total", "type": "WORD", "scale": 0.001, "unit": "PF", "sign": "Unsigned", "scan_interval": 30 },
        "150": { "name": "Power Factor Phase A", "type": "WORD", "scale": 0.001, "unit": "PF", "sign": "Unsigned", "scan_interval": 30 },
        "151": { "name": "Power Factor Phase B", "type": "WORD", "scale": 0.001, "unit": "PF", "sign": "Unsigned", "scan_interval": 30 },
        "152": { "name": "Power Factor Phase C", "type": "WORD", "scale": 0.001, "unit": "PF", "sign": "Unsigned", "scan_interval": 30 }
    }
}

Elfin EW11

No Elfin, a configuração serial dele :

  • precisa ser 9600,8,1,NONE ( se assim estiver no medidor).
  • Flow Control = none
  • Protocol = None

Sobre a versão IVAP

Eu já comprei a versão IVAP e estou testando ela conectada na tomada (com apenas 2 fases , 127v/127v).
Achei bem legal o sistema de proteção existente , algo inexistente na versão TY.
Porém esta versão não possui a porta RS485, o que limita o uso com o TuyaLocal .
Mas, funciona! Então acho valido a troca.

Custos

E para calcular os meus custos de energia : Preço do kwh e bandeira tarifaria - #40 de ceinmart