Skip to content

Huawei-Modbus-TLS-Server

Huawei EMMA dials out over TLS as the TCP client, so a normal Modbus server cannot answer it. A W5500 gives that reverse link its own isolated LAN.

irina

Published August 06, 2026

Original author: valexi7Original source (new tab)

Huawei-Modbus-TLS-Server

Components

Hardware components

WIZnet parts

Project description

COMPONENTS 

ComponentQtyRole in this project
WIZnet W5500 (product page)x 1SPI Ethernet controller on the EMMA-facing side. It holds the fixed IP on the solar-installation LAN and terminates EMMA's inbound TCP session on port 16100.
LilyGO T-ETH-Elite (ESP32-S3 + W5500 / ETH1)x 1Dual-network connector appliance. Wi-Fi faces Home Assistant, W5500 faces EMMA.
Huawei EMMA-A01 / A02 (with SUN2000 / LUNA / SmartGuard / SDongle / SCharger)x 1The energy-management unit that opens the reverse TLS connection.
Home Assistant host (any)x 1Owns the entities; talks to the connector over the authenticated API on port 8088.

๐Ÿ“Œ Huawei-Modbus-TLS-Server๋Š” ๋ฌด์—‡์ธ๊ฐ€?

Huawei-Modbus-TLS-Server๋Š” valexi7์ด ๊ณต๊ฐœํ•œ Huawei EMMA์šฉ Home Assistant ๊ด€๋ฆฌ ํ†ตํ•ฉ์ด์ž ๋ฆฌ๋ฒ„์Šค Modbus/TLS ์ปค๋„ฅํ„ฐ์ž…๋‹ˆ๋‹ค. EMMA, SUN2000/LUNA, SmartGuard ํ† ํด๋กœ์ง€, SmartLogger, SDongle, SCharger์˜ ๋ฐ์ดํ„ฐ์™€ ์ œ์–ด๋ฅผ Home Assistant ์žฅ์น˜๋กœ ๋…ธ์ถœํ•˜๋ฉฐ, FusionSolar ํด๋ผ์šฐ๋“œ ์˜์กด ์—†์ด ๋กœ์ปฌ ๋„คํŠธ์›Œํฌ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๋‹ต๋ณ€: EMMA๋Š” Modbus ํด๋ผ์ด์–ธํŠธ์˜ ์ ‘์†์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. EMMA๊ฐ€ TCP ํด๋ผ์ด์–ธํŠธ๋กœ์„œ TLS ์†Œ์ผ“์„ ๋จผ์ € ์—ด๊ณ , ๊ทธ ์œ„์—์„œ Modbus ์Šฌ๋ ˆ์ด๋ธŒ๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ๊ทธ ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฝํ•œ ๋’ค Modbus ๋งˆ์Šคํ„ฐ๊ฐ€ ๋˜๋Š” ๋ฐ˜๋Œ€ํŽธ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.

์™œ ์ผ๋ฐ˜ Modbus TCP ์„œ๋ฒ„๋กœ๋Š” ์•ˆ ๋˜๋‚˜?

ํ‘œ์ค€ Modbus TCP์—์„œ๋Š” ์†Œ์ผ“์„ ์—ฌ๋Š” ์ชฝ์ด ๊ณง ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ชฝ์ž…๋‹ˆ๋‹ค. EMMA๋Š” ์ด ์—ญํ• ์„ ์ ˆ๋ฐ˜๋งŒ ๋’ค์ง‘์Šต๋‹ˆ๋‹ค.

  • EMMA๊ฐ€ TCP ํด๋ผ์ด์–ธํŠธ์ž…๋‹ˆ๋‹ค. ์„ค์ •๋œ "ํƒ€์‚ฌ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ" ์ฃผ์†Œ์˜ 16100 ํฌํŠธ๋กœ TLS ์ ‘์†์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
  • EMMA๊ฐ€ Modbus ์Šฌ๋ ˆ์ด๋ธŒ์ž…๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋˜๋ฉด ํด๋ง์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
  • ํ‘œ์ค€ Modbus ํŠธ๋ž˜ํ”ฝ ์ „์— Huawei ์‚ฌ์„ค 0x41 ์‹œ์ž‘ ํ”„๋ ˆ์ž„์„ ๋จผ์ € ๋ณด๋ƒ…๋‹ˆ๋‹ค.
์™œ ์ผ๋ฐ˜ Modbus TCP ์„œ๋ฒ„๋กœ๋Š” ์•ˆ ๋˜๋‚˜?

๊ทธ๋ฆผ 1 โ€” ํ‘œ์ค€ Modbus TCP์—์„œ๋Š” ์†Œ์ผ“์„ ์—ฐ ์ชฝ์ด ๊ณง ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ชฝ์ž…๋‹ˆ๋‹ค. EMMA์—์„œ๋Š” ์†Œ์ผ“ ๋ฐฉํ–ฅ๊ณผ ํ”„๋กœํ† ์ฝœ ์—ญํ• ์ด ์„œ๋กœ ๋ฐ˜๋Œ€๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ, ๊ทธ ์•ž์— ์‚ฌ์„ค 0x41 ํ”„๋ ˆ์ž„์ด ๋จผ์ € ์˜ต๋‹ˆ๋‹ค.

์ผ๋ฐ˜ Modbus TCP ์„œ๋ฒ„๋Š” ์†Œ์ผ“์„ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ์š”์ฒญ์ด ์˜ค๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆด ๋ฟ, "์—ฐ๊ฒฐ์„ ์ˆ˜๋ฝํ•œ ๋’ค ๊ทธ ์—ฐ๊ฒฐ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š”" ๊ฒฝ๋กœ๊ฐ€ ์—†๊ณ  0x41 ํ•ธ๋“œ์…ฐ์ดํฌ๋„ ํ•ด์„ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. .

์ปค๋„ฅํ„ฐ๋Š” ๋ฌด์—‡์„ ํ•˜๋‚˜?

  • ๊ณ ์ •๋œ huawei-solar 3.0.6์—์„œ ์ƒ์„ฑํ•œ ๋ ˆ์ง€์Šคํ„ฐ ์ •์˜ 740๊ฐœ โ€” ์Šค์นผ๋ผ, enum, boolean, ํƒ€์ž„์Šคํƒฌํ”„, ๋น„ํŠธํ•„๋“œ, ๋ฌธ์ž์—ด, ๊ตฌ์กฐํ™”๋œ ๊ธฐ๊ฐ„ ๋””์ฝ”๋”ฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ํŽ˜์ด์ง€ ๋‹จ์œ„ ํ† ํด๋กœ์ง€ ํƒ์ƒ‰๊ณผ EMMA / ์ธ๋ฒ„ํ„ฐยทLUNA / ์ถฉ์ „๊ธฐ / SDongle / SmartLogger ์—ญํ• ๋ณ„ ๋ผ์šฐํŒ….
  • 3๋‹จ๊ณ„ ํด๋ง โ€” ์‹ค์‹œ๊ฐ„ ํ…”๋ ˆ๋ฉ”ํŠธ๋ฆฌ 30์ดˆ, ์—๋„ˆ์ง€ยท์„ค์ • 5๋ถ„, ์ •์  ์ง„๋‹จ 30๋ถ„. ์ธ์ ‘ ์ฃผ์†Œ๋ฅผ ๋ณ‘ํ•ฉํ•˜๋˜ ํ•œ ์š”์ฒญ๋‹น 125 ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ๋„˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ตฌ๋… ๊ธฐ๋ฐ˜ ํด๋ง. ์นดํƒˆ๋กœ๊ทธ ๋Œ€๋ถ€๋ถ„์€ ๋น„ํ™œ์„ฑ ์ƒํƒœ๋กœ ์ƒ์„ฑ๋˜๋ฉฐ, Home Assistant์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ด๋‹น ๋ ˆ์ง€์Šคํ„ฐ ํด๋ง์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋ณด๋Š” ๊ฐ’๋งŒ ๋ฒ„์Šค์— ํ๋ฆ…๋‹ˆ๋‹ค.
  • ์•ˆ์ „ํ•œ ์“ฐ๊ธฐ โ€” ๋ฒ”์œ„ ์ œํ•œ ์ˆซ์ž, enum, boolean, datetime, Huawei TOU ์Šค์ผ€์ค„์„ ๊ฒ€์ฆํ•˜๊ณ  ์ฝ๊ธฐ ํ™•์ธ ํ›„ ์„ฑ๊ณต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ปค๋„ฅํ„ฐ๋Š” ๋ฌด์—‡์„ ํ•˜๋‚˜? 

๊ทธ๋ฆผ 2 โ€” ๋ ˆ์ง€์Šคํ„ฐ ์นดํƒˆ๋กœ๊ทธ๋Š” ๋น„ํ™œ์„ฑ ์ƒํƒœ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์—”ํ‹ฐํ‹ฐ๋ฅผ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ด๋‹น ๋ ˆ์ง€์Šคํ„ฐ๊ฐ€ ์ปค๋„ฅํ„ฐ ๊ตฌ๋…์— ๋“ค์–ด๊ฐ€๋ฉฐ, 3๋‹จ๊ณ„ ํด๋ง์€ ์‹ค์ œ๋กœ ๋ณด๊ณ  ์žˆ๋Š” ๊ฐ’๋งŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์„ธ ๊ฐ€์ง€ ๋Ÿฐํƒ€์ž„(Home Assistant ๋‚ด์žฅ / Linux ๋…๋ฆฝ Python / LilyGO T-ETH-Elite ๊ธฐ๋ฐ˜ ESPHome)์ด ๊ฐ™์€ ํ†ตํ•ฉ, ๊ฐ™์€ ์—”ํ‹ฐํ‹ฐ ์นดํƒˆ๋กœ๊ทธ, ๊ฐ™์€ /api/v1 ๊ณ„์•ฝ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„์„ ๋ฐ”๊ฟ”๋„ ์—”ํ‹ฐํ‹ฐยท๋Œ€์‹œ๋ณด๋“œยท์ž๋™ํ™”ยท์žฅ์น˜ ID๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

W5500์€ ์–ด๋””์— ๋“ค์–ด๊ฐ€๋‚˜?

 
Home Assistant LAN <-- Wi-Fi --> ESP32-S3 <-- W5500 / ETH1 --> EMMA LAN
       API / OTA                   :8088        TLS/Modbus :16100
W5500์€ ์–ด๋””์— ๋“ค์–ด๊ฐ€๋‚˜?

๊ทธ๋ฆผ 3 โ€” Wi-Fi๋Š” ESPHome APIยทOTAยท์ปค๋„ฅํ„ฐ API(8088)๋ฅผ, W5500์€ ์„ค๋น„ LAN์˜ ๊ณ ์ • ์ฃผ์†Œ์—์„œ EMMA์˜ ๋ฆฌ๋ฒ„์Šค TLS ์„ธ์…˜(16100)๋งŒ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ์‚ฌ์ด์—๋Š” ํฌ์›Œ๋”ฉ์ด ์—†์Šต๋‹ˆ๋‹ค.

๋‘ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์˜๋„์ ์œผ๋กœ ์„œ๋กœ ๋‹ค๋ฅธ ๋„คํŠธ์›Œํฌ๋ฅผ ๋ฐ”๋ผ๋ณด๋ฉฐ, ์ด ์žฅ์น˜๋Š” ๋ผ์šฐํ„ฐ๋‚˜ ๋ธŒ๋ฆฌ์ง€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

  • Wi-Fi ์ธก์€ ESPHome ๋„ค์ดํ‹ฐ๋ธŒ API, OTA, ๋กœ๊ทธ, ๊ทธ๋ฆฌ๊ณ  ํ† ํฐ ์ธ์ฆ ์ปค๋„ฅํ„ฐ API(8088)๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. Home Assistant๊ฐ€ ์ด์ชฝ๊ณผ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.
  • W5500 ์ธก์€ ํƒœ์–‘๊ด‘ ์„ค๋น„ LAN์—์„œ ๊ณ ์ • IP(emma_eth_ip)๋ฅผ ๊ฐ–๊ณ , EMMA์˜ ๋ฆฌ๋ฒ„์Šค TLS ์—ฐ๊ฒฐ(16100)๋งŒ ์ˆ˜๋ฝํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ถ„๋ฆฌ๊ฐ€ ์„ค๊ณ„์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ์„ค์น˜์‚ฌ๊ฐ€ ๊ตฌ์„ฑํ•œ EMMA ๋„คํŠธ์›Œํฌ๋Š” ํ™ˆ LAN์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ณ , Modbus/TLS ์ œ์–ด ์ข…๋‹จ์ ์€ OTAยท๋กœ๊น…๊ณผ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. W5500์€ EMMA ์ธก ์†Œ์ผ“๊ณผ ๋งํฌ ๊ณ„์ธต์„ ํ•˜๋“œ์›จ์–ด๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , ESP32-S3๋Š” TLS ์„ธ์…˜, 0x41 ํ•ด์„, ๋ ˆ์ง€์Šคํ„ฐ ์นดํƒˆ๋กœ๊ทธ, ํด๋ง ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

ethernet:
  type: W5500
  # ... ๋ณด๋“œ๋ณ„ SPI ํ•€ ...
  manual_ip:
    static_ip: 192.168.88.20
    gateway: 192.168.88.1

์ธ์ฆ์„œ๋Š” python tools/generate_esphome_tls.py --server-name 192.168.88.20์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ , EMMA์—๋Š” ca-cert.pem๋งŒ ์‹ ๋ขฐ CA๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ธ์ฆ์„œ SAN์€ EMMA์— ์„ค์ •ํ•œ W5500 IP ๋˜๋Š” DNS ์ด๋ฆ„๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ํ•  ๋งŒํ•œ ํ•˜๋“œ์›จ์–ด ๋””ํ…Œ์ผ ํ•˜๋‚˜: T-ETH-Elite ๋นŒ๋“œ๋Š” GPIO38 ์‹œ์Šคํ…œ LED๊ฐ€ ๋‹จ์ƒ‰ ์ด์ง„ LED์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ‰์ด ์•„๋‹ˆ๋ผ ์ ๋ฉธ ๊ธธ์ด๋กœ ์ƒํƒœ๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์งง๊ฒŒ=Modbus RX, ์ค‘๊ฐ„=Modbus TX, ๋‘ ๋ฒˆ=API RX, ๊ธธ๊ฒŒ=API TX. LED ํ•˜๋‚˜๋กœ ์–‘์ชฝ ๋„คํŠธ์›Œํฌ์˜ ํŠธ๋ž˜ํ”ฝ ํŒจํ„ด์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

WIZnet์˜ ์—ญํ• : W5500์€ ์—๋„ˆ์ง€ ๊ด€๋ฆฌ LAN์œผ๋กœ ํ–ฅํ•˜๋Š” ๊ฒฉ๋ฆฌ๋œ ์œ ์„  ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ๊ณ ์ • ์ฃผ์†Œ๋กœ EMMA์˜ ์•„์›ƒ๋ฐ”์šด๋“œ TCP ์„ธ์…˜(16100)์„ ์ข…๋‹จํ•˜๊ณ , TLSยทModbus ๋งˆ์Šคํ„ฐ๋งยทHome Assistant ์—”ํ‹ฐํ‹ฐ ๋กœ์ง์€ ESP32-S3๊ฐ€ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ด ํ”„๋กœ์ ํŠธ๊ฐ€ ์œ ์„  IoT ์„ค๊ณ„์— ์ฃผ๋Š” ์‹œ์‚ฌ์ 

๋Œ€๋ถ€๋ถ„์˜ W5500 + ESP32 ํ”„๋กœ์ ํŠธ๋Š” Ethernet์„ "๋” ์•ˆ์ •์ ์ธ ๋„คํŠธ์›Œํฌ"๋กœ ์”๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” Ethernet์„ "๋‘ ๋ฒˆ์งธ ๋„คํŠธ์›Œํฌ"๋กœ ์”๋‹ˆ๋‹ค. ๋ฒค๋”๊ฐ€ ํ†ต์ œํ•˜๋Š” ์„ค๋น„ LAN๊ณผ ์‚ฌ์šฉ์ž์˜ ํ™ˆ LAN ์‚ฌ์ด์— ์˜๋„์ ์ธ ๋ถ„๋ฆฌ๋ฅผ ๋‘๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต์˜ ๋‹จ์ผ ํ†ต๋กœ๋งŒ ๋‚จ๊ธฐ๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

์ด ํŒจํ„ด์€ ํƒœ์–‘๊ด‘์„ ๋„˜์–ด ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. ๊ฑด๋ฌผ ์ œ์–ด๊ธฐ, ๊ณ„๋Ÿ‰๊ธฐ, EV ์ถฉ์ „๊ธฐ, HVAC ๊ฒŒ์ดํŠธ์›จ์ด์ฒ˜๋Ÿผ ๋ฒค๋” ํ”„๋กœํ† ์ฝœ๋กœ ์‚ฌ์šฉ์ž ๋ง์— ์•„์›ƒ๋ฐ”์šด๋“œ ์ ‘์†ํ•˜๋Š” ์žฅ๋น„์—๋Š” ๋ชจ๋‘ ๊ฐ™์€ ํ˜•ํƒœ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ฒค๋” ์„ธ๊ทธ๋จผํŠธ๋ฅผ ํ–ฅํ•œ ์ €์ „๋ ฅ SPI Ethernet ์ธํ„ฐํŽ˜์ด์Šค, ์šด์˜์ž๋ฅผ ํ–ฅํ•œ ๋ณ„๋„ ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์‚ฌ์ด์˜ ํฌ์›Œ๋”ฉ ์—†์Œ.

์œ ์ง€๋ณด์ˆ˜ ๊ตฌ์กฐ๋„ ์ฐธ๊ณ ํ•  ๋งŒํ•ฉ๋‹ˆ๋‹ค. ๋ ˆ์ง€์Šคํ„ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐยทํฌํŠธยท์ฃผ๊ธฐยทํ•œ๊ณ„๊ฐ’์€ Python์— ๋‘๊ณ , python tools/generate_esphome_catalog.py๊ฐ€ ESP32 ํ—ค๋” ํ…Œ์ด๋ธ”๊ณผ JSON ๊ณ„์•ฝ์„ ์ƒ์„ฑํ•˜๋ฉฐ, CI๋Š” ์ƒ์„ฑ ํŒŒ์ผ์ด ๋‚ก์œผ๋ฉด ๋นŒ๋“œ๋ฅผ ์‹คํŒจ์‹œํ‚ต๋‹ˆ๋‹ค. ESP32 ํŽŒ์›จ์–ด ๋นŒ๋“œ์—๋Š” Python๋„ huawei-solar๋„ ํ•„์š” ์—†์ง€๋งŒ, ์„ธ ๋Ÿฐํƒ€์ž„ ๋ชจ๋‘ ํ•˜๋‚˜์˜ ์›๋ณธ์—์„œ ํ•จ๊ป˜ ๋ฐ”๋€๋‹ˆ๋‹ค.

๊ด€๋ จ Maker ๊ธ€

ํƒœ์–‘๊ด‘ ์ธ๋ฒ„ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ W5500 ์œ ์„ ์œผ๋กœ Home Assistant์— ๋„ฃ๋Š” Maker ๊ธ€์ด ๋‘ ํŽธ ๋” ์žˆ์Šต๋‹ˆ๋‹ค. ์ „์†ก ๋ฐฉ์‹์ด ๊ฐ๊ฐ ๋‹ฌ๋ผ, ๋ณธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋‚˜๋ž€ํžˆ ๋†“์œผ๋ฉด ๋ฆฌ๋ฒ„์Šค TLS ๋งํฌ๊ฐ€ ๋ฌด์—‡์„ ์–ป๋Š”์ง€ ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.

 ๋ณธ ํ”„๋กœ์ ํŠธOpenDTU-OnBatteryAhoyDTU
๋Œ€์ƒ ์žฅ๋น„Huawei EMMA / SUN2000 / LUNAOpenDTU Fusion ๊ฒฝ์œ  HoymilesHoymiles ๋งˆ์ดํฌ๋กœ์ธ๋ฒ„ํ„ฐ
์žฅ๋น„์™€์˜ ์—ฐ๊ฒฐModbus over TLS, :16100๋ณด๋“œ ๋ ˆ๋ฒจ ์—ฐ๊ฒฐ ํ›„ Ethernet์„œ๋ธŒ๊ธฐ๊ฐ€ RF
์—ฐ๊ฒฐ์„ ์—ฌ๋Š” ์ชฝEMMA๊ฐ€ ๋จผ์ € ์ ‘์†, ์ปค๋„ฅํ„ฐ๊ฐ€ ์ˆ˜๋ฝ ํ›„ ํด๋ง์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์™ธ๋ถ€๋กœ ์ ‘์†์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ RF๋กœ ํด๋ง
W5500์˜ ์—ญํ• ๊ฒฝ๊ณ„ โ€” ๊ฒฉ๋ฆฌ๋œ ์„ค๋น„ LAN์—์„œ ๋ฆฌ๋ฒ„์Šค ์„ธ์…˜ ์ข…๋‹จMQTT ๋ธŒ๋กœ์ปค๋กœ ๊ฐ€๋Š” ์œ ์„  ์—…๋งํฌ์„ ํƒ ์‚ฌํ•ญ, ์‚ฌ์šฉ์ž ์ •์˜ ETH ํŽŒ์›จ์–ด
Home Assistant ์—ฐ๋™์ „์šฉ HACS ํ†ตํ•ฉ, ์—”ํ‹ฐํ‹ฐ 740๊ฐœMQTT ๋ธŒ๋กœ์ปค โ†’ Home AssistantMQTT / JSON

๋‚˜๋จธ์ง€ ๋‘ ํ”„๋กœ์ ํŠธ๋Š” ์ด๋”๋„ท์„ ํ•˜๋‚˜์˜ ํ‰๋ฉด LAN ์œ„ ์—…๋งํฌ๋กœ ์”๋‹ˆ๋‹ค. ๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ์ด๋ฅผ ๋„คํŠธ์›Œํฌ ๊ฒฝ๊ณ„๋กœ ์“ฐ๋ฉฐ, ์ด ์ง€์ ์ด ์ฐธ๊ณ ํ•  ๋งŒํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

โ“ FAQ

huawei_solar HACS ํ†ตํ•ฉ๊ณผ ๊ฐ™์€ ๊ฑด๊ฐ€์š”? ์•„๋‹™๋‹ˆ๋‹ค. huawei_solar๋Š” Modbus TCP ์ข…๋‹จ์ ์œผ๋กœ ์ ‘์†ํ•ด ๋‚˜๊ฐ€๊ณ , ์ด ํ”„๋กœ์ ํŠธ๋Š” EMMA๊ฐ€ ๊ฑธ์–ด์˜ค๋Š” ๋ฆฌ๋ฒ„์Šค TLS ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฝํ•œ ๋’ค ํด๋งํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉํ–ฅ์ด ๋ฐ˜๋Œ€์ž…๋‹ˆ๋‹ค.

0x41 ํ”„๋ ˆ์ž„์ด ๋ฌด์—‡์ธ๊ฐ€์š”? EMMA๊ฐ€ ํ‘œ์ค€ Modbus ํŠธ๋ž˜ํ”ฝ์— ์•ž์„œ ๋ณด๋‚ด๋Š” Huawei ์‚ฌ์„ค ์‹œ์ž‘ ํ”„๋ ˆ์ž„์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜ Modbus ์„œ๋ฒ„๋Š” ์ด๋ฅผ ํ•ด์„ํ•˜์ง€ ๋ชปํ•ด ํ•ธ๋“œ์…ฐ์ดํฌ ๋‹จ๊ณ„์—์„œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

W5500์ด TLS๋‚˜ Modbus ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋‚˜์š”? ์•„๋‹™๋‹ˆ๋‹ค. W5500์€ EMMA LAN์—์„œ์˜ ํ•˜๋“œ์›จ์–ด TCP/IP ๊ฒฝ๋กœ์™€ ๊ณ ์ • ์ฃผ์†Œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. TLS, 0x41 ํ•ด์„, ๋ ˆ์ง€์Šคํ„ฐ ๋””์ฝ”๋”ฉ, ํด๋ง์€ ๋ชจ๋‘ ESP32-S3์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

ESP32๊ฐ€ ๋‘ ๋„คํŠธ์›Œํฌ๋ฅผ ๋ธŒ๋ฆฌ์ง€ํ•˜๋‚˜์š”? ์•„๋‹™๋‹ˆ๋‹ค. ํฌ์›Œ๋”ฉ ์—†๋Š” ๋“€์–ผ ํ™ˆ ์žฅ์น˜์ž…๋‹ˆ๋‹ค. Wi-Fi๋Š” ESPHome APIยทOTAยท์ปค๋„ฅํ„ฐ API(8088), W5500์€ EMMA์˜ TLS ์—ฐ๊ฒฐ(16100)๋งŒ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

๊ผญ ESP32๊ฐ€ ํ•„์š”ํ•œ๊ฐ€์š”? ์•„๋‹™๋‹ˆ๋‹ค. ์ปค๋„ฅํ„ฐ๋Š” Home Assistant ๋‚ด์žฅ ๋˜๋Š” Linux ๋…๋ฆฝ Python์œผ๋กœ๋„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ESPHome/W5500 ๋Ÿฐํƒ€์ž„์€ ๋„คํŠธ์›Œํฌ ๊ฒฉ๋ฆฌ์™€ ๋‚ฎ์€ ๋Œ€๊ธฐ ์ „๋ ฅ์„ ์–ป๊ณ  ์‹ถ์„ ๋•Œ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์šฐ๋“œ๋ฅผ ๊ฑฐ์น˜๋‚˜์š”? ์•„๋‹™๋‹ˆ๋‹ค. ๋กœ์ปฌ ์ „์šฉ ๋™์ž‘์ด๋ฉฐ, ๋‘ ํฌํŠธ ๋ชจ๋‘ ์ธํ„ฐ๋„ท์œผ๋กœ ํฌ์›Œ๋”ฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.



PROJECT DESCRIPTION

๐Ÿ“Œ What Is Huawei-Modbus-TLS-Server?

Huawei-Modbus-TLS-Server by valexi7 is a Home Assistant management integration plus a reverse Modbus/TLS connector for Huawei EMMA. It exposes EMMA, SUN2000/LUNA, SmartGuard topology, SmartLogger, SDongle and SCharger data and controls as Home Assistant devices, entirely on the local network with no FusionSolar cloud dependency.

It is not a generic Modbus gateway and not a fork of the existing huawei_solar integration. It solves one specific transport problem, and then builds a full entity catalog on top of it.

Direct answer: EMMA does not sit and wait for a Modbus client. EMMA opens an outbound TLS socket as the TCP client, and then answers as the Modbus slave. This project is the counterpart that accepts that connection and becomes the Modbus master.

Why Can't a Normal Modbus TCP Server Talk to EMMA?

In a textbook Modbus TCP deployment the roles line up neatly: the client opens the socket and the client sends the request. EMMA inverts half of that.

  • EMMA is the TCP client โ€” it dials out to a configured "third-party management system" address on port 16100, over TLS.
  • EMMA is the Modbus slave โ€” once the socket is up, it waits to be polled.
  • EMMA opens with a Huawei private 0x41 startup frame before any standard Modbus traffic.

Why Can't a Normal Modbus TCP Server Talk to EMMA? 

Fig. 1 โ€” In standard Modbus TCP the side that opens the socket also sends the requests. With EMMA the socket direction and the protocol role point opposite ways, and a private 0x41 frame precedes everything.

A stock Modbus TCP server binds a socket and expects requests to arrive. It has no path for "accept a connection, then start issuing requests down it," and it will not parse the 0x41 handshake. That mismatch is the reason this repository exists.

What Does the Connector Actually Do?

Once the reverse link is established, the connector behaves like a well-mannered Modbus master:

  • 740 generated register definitions, derived from a pinned huawei-solar 3.0.6, covering scalar, enum, boolean, timestamp, bitfield, string, and structured-period decoding.
  • Paged topology discovery, with device-role routing across EMMA, inverter/LUNA, charger, SDongle and SmartLogger.
  • Three polling tiers โ€” fast (30 s) for live telemetry, medium (5 min) for energy and configuration, slow (30 min) for static diagnostics โ€” with adjacent addresses coalesced into single requests that never exceed 125 registers.
  • Subscription-driven polling. Most of the catalog is created disabled. Enabling an entity in Home Assistant is what starts polling that register, and disabling it stops the traffic. The bus only carries what someone is actually looking at.
  • Safe writes โ€” bounded numbers, enums, booleans, datetimes and Huawei TOU schedules, each validated and read back before success is reported.

What Does the Connector Actually Do? 

Fig. 2 โ€” The register catalog is created disabled. Enabling an entity is what puts its register into the connector's subscription, and the three polling tiers only ever carry what someone is actually looking at.

Three interchangeable runtimes share the same integration, the same entity catalog and the same /api/v1 connector contract: embedded inside Home Assistant, standalone Python on Linux, or ESPHome on a LilyGO T-ETH-Elite. Switching runtime changes the transport only โ€” entities, dashboards, automations and device IDs survive the move.

Where Does W5500 Fit?

Where Does W5500 Fit? 

Fig. 3 โ€” Wi-Fi carries the ESPHome API, OTA and the connector API on port 8088. W5500 holds a fixed address on the installation LAN and accepts only EMMA's reverse TLS session on port 16100. Nothing is forwarded between the two.

The ESPHome runtime is the one built around WIZnet silicon, and it uses the W5500 for something more interesting than "Wi-Fi is unreliable here."

 
Home Assistant LAN <-- Wi-Fi --> ESP32-S3 <-- W5500 / ETH1 --> EMMA LAN
       API / OTA                   :8088        TLS/Modbus :16100

The two interfaces face two different networks on purpose, and the device is explicitly not a router or a bridge between them:

  • Wi-Fi side carries the ESPHome native API, OTA, logs, and the token-authenticated connector API on port 8088. This is the side Home Assistant talks to.
  • W5500 side holds a fixed IP (emma_eth_ip) on the solar-installation LAN and accepts exactly one thing: EMMA's reverse TLS connection on port 16100.

That separation is the whole design argument. The installer-configured EMMA network never becomes reachable from the home LAN, and the Modbus/TLS control endpoint never rides on the same interface as OTA and logging. W5500's hardware TCP/IP offload handles the socket and link layer on the EMMA side, while the ESP32-S3 runs the TLS session, the 0x41 parsing, the register catalog and the polling scheduler.

Configuration is ordinary ESPHome:

 
# The EMMA-facing interface on LilyGO T-ETH-Elite
ethernet:
  type: W5500
  # ... SPI pins per board ...
  manual_ip:
    static_ip: 192.168.88.20
    gateway: 192.168.88.1

Certificates are generated from a repo checkout with python tools/generate_esphome_tls.py --server-name 192.168.88.20, and only ca-cert.pem is imported into EMMA's trusted-CA settings. The certificate SAN must match the exact W5500 IP or DNS name configured in EMMA โ€” a detail that trips up most first attempts.

One small hardware touch worth copying: the T-ETH-Elite build drives the GPIO38 system LED by pulse timing rather than colour, because it is a single binary LED โ€” short pulse for Modbus RX, medium for Modbus TX, double for API RX, long for API TX. You can read the traffic pattern of both networks off one LED.

WIZnet's role: W5500 is the isolated wired path to the energy-management LAN. It terminates EMMA's outbound TCP session on port 16100 with a fixed address, while the ESP32-S3 handles TLS, Modbus mastering, and the Home Assistant entity logic.

Why This Project Matters for Wired IoT Design

Most W5500 + ESP32 projects use Ethernet as a better network. This one uses Ethernet as a second network โ€” a deliberate air gap between a vendor-controlled installation LAN and the user's home LAN, with a single audited application-layer crossing point.

That pattern generalises well beyond solar. Any time a piece of installed infrastructure dials outbound into your network on a vendor protocol โ€” building controllers, meters, EV chargers, HVAC gateways โ€” the same shape applies: a low-power SPI Ethernet interface facing the vendor segment, a separate management interface facing the operator, and no forwarding between them.

There is also a maintenance lesson in the repository layout. Register metadata, ports, intervals and limits live in Python; python tools/generate_esphome_catalog.py then emits the ESP32 header tables and a JSON contract, and CI fails the build if the generated files are stale. The ESP32 firmware needs neither Python nor the huawei-solar package to build, yet all three runtimes change from one source of truth. If you maintain firmware and a server-side integration together, that is a pattern worth stealing.

Related Maker Reading

Two other Maker posts pull solar-inverter data into Home Assistant over W5500, each with a different transport. Placing this project beside them shows what the reverse TLS link actually buys:

 This projectOpenDTU-OnBatteryAhoyDTU
Target deviceHuawei EMMA / SUN2000 / LUNAHoymiles via OpenDTU FusionHoymiles microinverters
Link to the deviceModbus over TLS, :16100Board-level link, then EthernetSub-GHz RF
Who opens itEMMA dials out; the connector accepts, then pollsController connects outwardController polls over RF
W5500's roleBoundary โ€” terminates the reverse session on an isolated installation LANWired uplink to the MQTT brokerOptional, as a user-built ETH firmware variant
Home Assistant pathNative HACS integration, 740 entitiesMQTT broker โ†’ Home AssistantMQTT / JSON

The two neighbours treat Ethernet as a faster uplink on one flat LAN. This project treats it as a network boundary, which is the part worth copying.

โ“ FAQ

Is this the same as the huawei_solar HACS integration? No. huawei_solar connects out to a Modbus TCP endpoint. This project accepts EMMA's inbound reverse TLS connection and then polls it, which is the opposite direction.

What is the 0x41 frame? A Huawei private startup frame that EMMA sends before standard Modbus traffic. Generic Modbus servers do not parse it, so the connection fails at the handshake.

Does the W5500 run the TLS or the Modbus logic? No. W5500 provides the hardware TCP/IP path and the fixed address on the EMMA LAN. TLS, the 0x41 parsing, register decoding and polling all run on the ESP32-S3.

Is the ESP32 bridging the two networks? No. It is a dual-homed appliance with no forwarding. Wi-Fi carries the ESPHome API, OTA and the connector API on 8088; W5500 accepts only EMMA's TLS connection on 16100.

Do I need the ESP32 at all? No โ€” the connector also runs embedded in Home Assistant or as standalone Python on Linux. The ESPHome/W5500 runtime is the one that buys you network isolation and low idle power.

Does any of this touch Huawei's cloud? No. It is local-only operation, and neither port should ever be forwarded to the internet.

 

 

Comments

Similar projects you might like

Comments