Skip to content

esp32-wifi-bridge

Use esp32-s3-poe-eth to connect to Tesla Powerwall AP and proxy requests to ethernet

Lihan__

Published August 30, 2026

Original author: cwagzOriginal source (new tab)

esp32-wifi-bridge

Project description

ESP32-S3 WiFi-Ethernet SSL Bridge โ€” A W5500 TLS Passthrough Bridge That Pulls an Isolated Powerwall AP onto Your Home LAN

#W5500 #MACRAW #ESP32S3 #ESP-IDF #TLS-Passthrough #PoE #TeslaPowerwall #HomeEnergy #OTA #NetworkBridge

๐Ÿ“š Context: A live home-energy deployment (built and operated by a Tesla Powerwall owner in their own house) Verification status: Photos of the hardware installed on PoE next to an actual Powerwall, screenshots of the running dashboard, 130+ commits of iterative refinement, and a full GitHub Actions firmware-release and OTA pipeline are all public. This is not a hobby demo โ€” it is equipment that runs every day.


01 โ€” What is this project?

Forked from https://github.com/mccahan/esp32-wifi-bridge

but not a copy. The original stopped at v1.0.4 in February 2026; this repository picked it up six months later and added 46 commits and some 2,700 lines to reach v1.4.2. Authentication, Ethernet static IP with DNS defense, log and temperature monitoring, and a self-hosted OTA pipeline were all added here.

๐Ÿ”ท Background โ€” the Powerwall and its local API

The Tesla Powerwall is a residential energy storage system (ESS). It banks electricity generated by solar during the day, or cheap off-peak grid power, and discharges it at night or during an outage. Alongside the battery sits a separate controller called the Backup Gateway โ€” the brain that meters grid, solar, and household load in real time and orchestrates battery charge and discharge.

What Powerwall owners want is the second-by-second telemetry this gateway holds. How many watts solar is producing right now, what the battery state of charge is, whether the house is importing from or exporting to the grid โ€” owners pull this into Home Assistant or Grafana to build their own dashboards and automations. Tesla's official app routes through the cloud, so refresh intervals are slow and call limits apply; serious users query the gateway's local API directly.

๐Ÿ”ท The problem โ€” the local API is stranded on an island

The obstacle is the access path. The Backup Gateway permanently broadcasts its own Wi-Fi AP for installation and servicing, and the TEDAPI endpoint that serves the extended dataset is only reachable at 192.168.91.1, an address inside that AP. But this AP is a completely isolated island โ€” no internet, no link to the home LAN.

The gateway chassis does have an Ethernet port, but that is the gateway's own uplink to Tesla's servers; it does not expose 192.168.91.1 to the home LAN. In other words, the only way to reach this data is to associate with that AP over Wi-Fi.

Every existing workaround was awkward.

  • Park a laptop or Raspberry Pi on the Powerwall AP โ†’ that machine vanishes from the home network the moment it connects. Dual NICs or elaborate routing rules are required.
  • Bridge in a Wi-Fi router in repeater mode โ†’ an entire piece of dedicated hardware is wasted, and the Powerwall now sees foreign traffic.
  • Use the cloud API โ†’ high latency, dies with the internet connection, and is hostage to Tesla policy changes.

๐Ÿ”ท The solution โ€” a single bridge board

This project settles all of it with one PoE board that fits in your palm.

๐Ÿ”ท The solution โ€” a single bridge board

Firmware running on a Waveshare ESP32-S3-POE-ETH board attaches simultaneously to the home LAN over W5500 Ethernet on one side and to the Powerwall AP as a Wi-Fi STA on the other. TLS traffic arriving at :443 on the Ethernet IP is pushed through to the Powerwall byte-for-byte, without decryption.

The end result: from any PC in the house, typing https://powerwall.local/ simply opens the Powerwall local API. The user never has to be aware they are talking to an isolated AP at all.

๐Ÿ”ท In one line

Powerwall's real-time data can only be retrieved over Wi-Fi. This bridge moves that Wi-Fi data onto Ethernet, so it can be picked up over a LAN cable from anywhere in the house.


02 โ€” System architecture

02 โ€” System architecture

03 โ€” Why TLS "passthrough"?

Passthrough means the intermediate device hands encrypted traffic straight through byte-for-byte, without ever opening it. The bridge is not a participant in the TLS session โ€” it is plumbing. The opposite concept, termination, has the intermediate device decrypt the TLS session and establish a new one, effectively becoming a sanctioned man-in-the-middle (MITM).

๐Ÿ”ท The design decision not to decrypt

The commit history preserves a telling trail. The author initially tried to implement TLS termination with mbedTLS, and nearly twenty commits went into embedding certificates and wrestling with esp_tls configuration. Then, finally: Revert to transparent TCP proxy to fix memory exhaustion crashes โ€” rolled back because of memory exhaustion crashes.

Terminating TLS on an ESP32-S3 costs tens of kilobytes of heap per session, and just a few overlapping connections drain it. Worse, the moment you terminate, the device becomes a MITM and creates one more point where Powerwall credentials exist in plaintext.

The final choice is unambiguous: relay ciphertext as ciphertext. The client and the Powerwall negotiate end-to-end TLS, and the bridge simply moves bytes between them. The security surface shrinks, and memory cost collapses to two 4KB buffers per session.

๐Ÿ”ท TTL=64 โ€” persuading the Powerwall rather than deceiving it

 
c
int ttl = TTL_VALUE;   // 64
setsockopt(powerwall_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));

From the Powerwall's vantage point, this traffic must look like it originated locally rather than having crossed a hop. These two lines, explicitly pinning TTL to 64, are what make the Powerwall accept a proxied request as a legitimate local client. Nothing about the protocol is forged โ€” this is an honest way of preserving locality at the IP layer.


04 โ€” Why WIZnet W5500? โญ

๐Ÿ”ท The ESP32-S3 has no built-in Ethernet MAC

This is the project's actual starting point. The original ESP32 integrates an EMAC, but the ESP32-S3 has no Ethernet MAC at all. Wired Ethernet on the S3 therefore requires an external controller over SPI โ€” which makes the W5500 not a choice but a precondition.

That is the same reason Waveshare put a W5500 on the ESP32-S3-POE-ETH board, and WIZnet's recently announced ESP32-W5500 Dev-kit / EOD-W55 SoM consolidates exactly this pairing (ESP32-S3 + W5500) into a single module. This project is best read as field evidence of why that pairing is needed in the first place.

๐Ÿ”ท Operating mode: MACRAW (esp_eth backend)

The project initializes the W5500 through the standard ESP-IDF drivers esp_eth_mac_new_w5500() / esp_eth_phy_new_w5500(). Internally this API family opens Socket 0 of the W5500 in MACRAW mode to exchange raw Ethernet frames. The W5500 here is therefore not a hardware TCP/IP offload engine (TOE) but a full 10/100 Ethernet MAC + PHY, with TCP/IP handled by the ESP32-S3's LwIP.

Why MACRAW rather than TOE โ€” this is the most consequential technical judgment in the project.

  • Standard BSD sockets were required. The proxy watches two sockets at once with select() while running a bidirectional relay, and uses the IP_TTL / TCP_NODELAY / SO_RCVTIMEO socket options directly. That code is only possible on top of LwIP.
  • Wi-Fi and Ethernet had to be alive simultaneously. Both interfaces must exist as esp_netif instances for a single socket API to address either side.
  • TLS passthrough gains nothing from offload. Since the device only shuttles ciphertext bytes, delegating checksums and reassembly to the chip buys little.
  • HTTPS OTA, mDNS, and NTP all had to work. Every one of those needs the full feature set of the software stack.

Among the W5500's four socket modes (TCP TOE / UDP / IPRAW / MACRAW), MACRAW is precisely the answer to these requirements, making this project a textbook case of "why you would run a W5500 in MACRAW."

๐Ÿ”ท Advantages over alternative solutions

CriterionW5500 (MACRAW)ENC28J60LAN8720 and other RMII PHYs
ESP32-S3 supportโœ… Official IDF esp_eth driverThird-party, many caveatsโŒ No EMAC on the S3
Speed10/100 Mbps10 Mbps only10/100
InterfaceSPI 4-wire + INTSPIRMII 9-wire + 25MHz clock
Driver maturityBuilt into ESP-IDF, interrupt-driven RXFrequent instability reportsUnusable on the S3
PoE board ecosystemWaveshare, WIZnet SoM, and moreRareโ€”

The decisive factor is that a single line, CONFIG_ETH_SPI_ETHERNET_W5500=y, enables official IDF support. This project began on the Arduino framework and migrated wholesale to ESP-IDF in the commit Migrate from Arduino to ESP-IDF framework with native W5500 support โ€” the stated reason being exactly that native W5500 support. The IDF standard driver ended a stretch of struggling with library compatibility.

05 โ€” Key components

๐ŸŒ WIZnet W5500 โ€” MACRAW mode (esp_eth MAC + PHY)

SPI3_HOST at 20MHz, MISO 12 / MOSI 11 / SCLK 13 / CS 14 / INT 10. The ESP-IDF esp_eth driver delivers raw Ethernet frames to LwIP via Socket 0 in MACRAW. Both DHCP and static IP are supported, with configuration persisted in NVS.

๐Ÿ”Œ Waveshare ESP32-S3-POE-ETH

802.3af PoE. A single Ethernet cable carries both power and data, which reduces the wiring next to the Powerwall to the absolute minimum. USB power also works.

๐Ÿ”€ TLS passthrough proxy (src/proxy.c, 567 lines)

  • Up to 4 concurrent clients, with 4KB ร— 2 buffers per client allocated from a static pool (no dynamic allocation โ†’ no heap fragmentation)
  • A select() loop on a 100ms timeout watches both directions; sessions close after 60 seconds of inactivity
  • TTFB / TTLB measurement plus a ring buffer of request logs

๐Ÿ“Š Dashboard (src/main.c, 3,389 lines)

24-hour Wi-Fi RSSI chart, Powerwall reachability, CPU and die temperature, heap, uptime, proxy statistics, log download (last 200 lines), and local/remote OTA. Authentication stores a salt plus SHA-256 in NVS behind an HTML login with a 7-day session cookie (HttpOnly; SameSite=Lax, and Secure when behind the HTTPS proxy).

๐Ÿ”„ OTA pipeline (src/remote_ota.c)

Pushing a v* tag makes GitHub Actions publish firmware.bin and version.json to GitHub Pages, and the device checks for and installs them itself. Initial flashing over USB from a browser (Chrome/Edge/Opera) is also supported. The partition table is 24KB nvs plus two 1.75MB OTA slots.

One buried detail deserves attention โ€” the instant the device associates with the Powerwall AP, Tesla's DHCP overwrites LwIP's DNS server with 192.168.91.1, leaving GitHub Pages unresolvable. The project snapshots the Ethernet DNS and restores it at OTA time (remote_ota_apply_eth_dns()). This is a trap that only surfaces on dual-interface devices, and the kind of bug you only learn about by living through it.


06 โ€” Application scenarios

01. Home energy monitoring automation

Home Assistant, Node-RED, or InfluxDB can poll the Powerwall local API directly with no cloud round trip. Latency falls to tens of milliseconds, and the setup keeps working when the internet is down.

02. Gateway for isolated industrial equipment

Substitute something else for the Powerwall and the same pattern becomes an industrial one. Inverters, PLCs, instruments, and medical devices that expose nothing but their own AP โ€” a bridge that makes them reachable from the corporate LAN without touching the vendor network. Because management ports bind only to the Ethernet side, the attack surface on the vendor equipment does not grow.

03. Template for field-installed protocol bridges

Single-cable PoE power, a web dashboard, OTA, a watchdog, and a factory-reset button. Those five are, in practice, the common requirements of every field-installed embedded device. This repository is a reference implementation of that skeleton, ready to be reused as-is.

04. Teaching material for dual-network development

Keeping Wi-Fi and Ethernet alive at the same time detonates default-route, DNS-ownership, and socket bind-address problems all at once. This project has a commit-by-commit record of stepping on those traps and fixing them, making it an unusually good text for studying dual esp_netif under ESP-IDF.


Conclusion

The problem of sacrificing a laptop to one isolated Wi-Fi AP is closed out by a single palm-sized PoE board carrying a W5500.

  • โœ… Fills the Ethernet MAC the ESP32-S3 lacks with W5500 MACRAW, and implements full LwIP socket programming on top of it
  • โœ… Passthrough rather than decryption of TLS, minimizing security surface and memory footprint at once (including the documented rollback after memory crashes with the termination approach)
  • โœ… TTL=64 socket option makes the Powerwall read the traffic as local
  • โœ… Binds management ports to the Ethernet IP only, categorically preventing exposure on the vendor network
  • โœ… Single-cable PoE power collapses field wiring to one run
  • โœ… Operations-grade dashboard with 24-hour RSSI history, die temperature, and proxy statistics
  • โœ… GitHub Actions โ†’ Pages โ†’ device OTA fully automated, plus browser-based flashing
  • โœ… Redundant unattended-recovery paths: watchdog auto-reboot, DHCP fallback, and 15-second BOOT factory reset
  • โœ… Defends against Tesla DHCP's DNS hijack via snapshot and restore โ€” hard-won dual-interface know-how

Q&A

Q. Isn't it a waste not to use the W5500 as a TOE (hardware TCP/IP)? A. For this workload, MACRAW is correct. The proxy requires select() multiplexing, the IP_TTL / TCP_NODELAY / SO_RCVTIMEO socket options, and coexistence with a Wi-Fi interface โ€” all of it standard socket semantics. Under TOE the chip owns the socket, which makes those semantics hard to use directly. Conversely, for a workload like a simple Modbus TCP gateway where MCU resources must be conserved, TOE would have been the right answer. Same chip, different mode, different correct answer โ€” that is the W5500's strength.

Q. Why the W5500 instead of an ENC28J60? A. The ENC28J60 is 10Mbps-only and its ESP-IDF driver maturity does not match the W5500's. The W5500 gets official IDF support from the single line CONFIG_ETH_SPI_ETHERNET_W5500=y, and ships 10/100 full-duplex with INT-based RX as standard. This project itself struggled with Arduino library compatibility and then migrated its entire framework specifically because of IDF's native W5500 support.

Q. Why bother wiring the interrupt pin (GPIO10)? A. Polling keeps SPI transactions running continuously, wasting CPU and bus bandwidth while increasing latency. Using the W5500's INT pin wakes SPI only when a frame has arrived. That said, this project hit an ordering dependency โ€” gpio_install_isr_service() must be called before esp_eth_driver_install() registers the INT GPIO handler โ€” and fixed it in a dedicated commit. It is a trap you are likely to meet in practice with the W5500 + ESP-IDF combination.

Q. Could this design move to the W6300? A. Yes, with clear benefits. The W6300 supports QSPI, which substantially raises bandwidth over SPI, and adds IPv6. WIZnet's wsm_driver component abstracts the W5500 and W6300 behind an identical API, so changing the board selection automatically configures the pin map and chip type. For a workload like TLS passthrough where raw bandwidth translates directly into response time, the QSPI gain would be felt immediately.

Original Link: https://github.com/cwagz/esp32-wifi-bridge Upstream: https://github.com/mccahan/esp32-wifi-bridge



[ํ•œ๊ธ€ ๋ฒ„์ „]

ESP32-S3 WiFi-Ethernet SSL Bridge โ€” ๊ฒฉ๋ฆฌ๋œ Powerwall AP๋ฅผ ์šฐ๋ฆฌ ์ง‘ LAN์œผ๋กœ ๋Œ์–ด์˜ค๋Š” W5500 TLS ํŒจ์Šค์Šค๋ฃจ ๋ธŒ๋ฆฌ์ง€

#W5500 #MACRAW #ESP32S3 #ESP-IDF #TLS-Passthrough #PoE #TeslaPowerwall #HomeEnergy #OTA #NetworkBridge

๐Ÿ“š ์ปจํ…์ŠคํŠธ: ํ™ˆ ์—๋„ˆ์ง€ ์‹œ์Šคํ…œ ์‹ค์‚ฌ์šฉ ํ”„๋กœ์ ํŠธ (Tesla Powerwall ์†Œ์œ ์ž๊ฐ€ ์ž๊ธฐ ์ง‘์— ์„ค์น˜ยท์šด์˜ ์ค‘) ๊ฒ€์ฆ ์ƒํƒœ: ์‹ค์ œ Powerwall ์˜†์— PoE๋กœ ์„ค์น˜๋œ ํ•˜๋“œ์›จ์–ด ์‚ฌ์ง„, ์‹ค ์šด์˜ ๋Œ€์‹œ๋ณด๋“œ ์Šคํฌ๋ฆฐ์ƒท, 130์—ฌ ๊ฐœ ์ปค๋ฐ‹์˜ ๋ฐ˜๋ณต ๊ฐœ์„  ์ด๋ ฅ, GitHub Actions ๊ธฐ๋ฐ˜ ํŽŒ์›จ์–ด ๋ฆด๋ฆฌ์ŠคยทOTA ํŒŒ์ดํ”„๋ผ์ธ๊นŒ์ง€ ๋ชจ๋‘ ๊ณต๊ฐœ๋˜์–ด ์žˆ์Œ. ์ทจ๋ฏธ ์ˆ˜์ค€์˜ ๋ฐ๋ชจ๊ฐ€ ์•„๋‹ˆ๋ผ ๋งค์ผ ๋Œ๊ณ  ์žˆ๋Š” ์žฅ๋น„์ž…๋‹ˆ๋‹ค.


01 โ€” ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋ฌด์—‡์ธ๊ฐ€?

https://github.com/mccahan/esp32-wifi-bridge ์—์„œ ํฌํฌํ–ˆ์ง€๋งŒ ๋‹จ์ˆœ ๋ณต์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

 ์›๋ณธ์€ 2026๋…„ 2์›” v1.0.4์—์„œ ๋ฉˆ์ท„๊ณ , ์ด ์ €์žฅ์†Œ๋Š” 6๊ฐœ์›” ๋’ค ์ด์–ด๋ฐ›์•„ 46๊ฐœ ์ปค๋ฐ‹, 2,700์—ฌ ์ค„์„ ๋”ํ•ด v1.4.2๊นŒ์ง€ ์™„์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ณด์•ˆ ์ธ์ฆ, ์ด๋”๋„ท ์ •์  IP์™€ DNS ๋ฐฉ์–ด, ๋กœ๊ทธยท์˜จ๋„ ๋ชจ๋‹ˆํ„ฐ๋ง, ์ž์ฒด OTA ํŒŒ์ดํ”„๋ผ์ธ์ด ๋ชจ๋‘ ์—ฌ๊ธฐ์„œ ์ถ”๊ฐ€๋์Šต๋‹ˆ๋‹ค.

๐Ÿ”ท ๋ฐฐ๊ฒฝ โ€” Powerwall๊ณผ ๋กœ์ปฌ API

Tesla Powerwall์€ ๊ฐ€์ •์šฉ ์—๋„ˆ์ง€ ์ €์žฅ ์‹œ์Šคํ…œ(ESS)์ž…๋‹ˆ๋‹ค. ๋‚ฎ์— ํƒœ์–‘๊ด‘์œผ๋กœ ๋งŒ๋“  ์ „๊ธฐ๋‚˜ ์‹ฌ์•ผ ์ €๋ ดํ•œ ์ „๋ ฅ์„ ๋ฐฐํ„ฐ๋ฆฌ์— ์ €์žฅํ–ˆ๋‹ค๊ฐ€, ๋ฐค์ด๋‚˜ ์ •์ „ ์‹œ์— ๊บผ๋‚ด ์”๋‹ˆ๋‹ค. ๋ฐฐํ„ฐ๋ฆฌ ์˜†์—๋Š” Backup Gateway๋ผ๋Š” ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ๋”ฐ๋กœ ๋ถ™๋Š”๋ฐ, ์ด ์žฅ์น˜๊ฐ€ ๊ณ„ํ†ตยทํƒœ์–‘๊ด‘ยท๊ฐ€์ • ๋ถ€ํ•˜์˜ ์ „๋ ฅ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ณ„์ธกํ•˜๊ณ  ๋ฐฐํ„ฐ๋ฆฌ ์ถฉ๋ฐฉ์ „์„ ์ง€ํœ˜ํ•˜๋Š” ๋‘๋‡Œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

Powerwall ์†Œ์œ ์ž๋“ค์ด ์›ํ•˜๋Š” ๊ฑด ์ด ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ๋“ค๊ณ  ์žˆ๋Š” ์ดˆ ๋‹จ์œ„ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ ํƒœ์–‘๊ด‘์ด ๋ช‡ W๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ๋Š”์ง€, ๋ฐฐํ„ฐ๋ฆฌ ์ž”๋Ÿ‰์ด ๋ช‡ %์ธ์ง€, ๊ณ„ํ†ต์—์„œ ์‚ฌ๊ณ  ์žˆ๋Š”์ง€ ํŒ”๊ณ  ์žˆ๋Š”์ง€ โ€” ์ด๊ฑธ Home Assistant๋‚˜ Grafana๋กœ ๋Œ์–ด์™€ ์ง์ ‘ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  ์ž๋™ํ™”๋ฅผ ๊ฒ๋‹ˆ๋‹ค. Tesla ๊ณต์‹ ์•ฑ์€ ํด๋ผ์šฐ๋“œ๋ฅผ ๊ฑฐ์น˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐฑ์‹  ์ฃผ๊ธฐ๊ฐ€ ๋А๋ฆฌ๊ณ  ํ˜ธ์ถœ ์ œํ•œ๋„ ์žˆ์–ด์„œ, ์ง„์ง€ํ•œ ์‚ฌ์šฉ์ž๋“ค์€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ ๋กœ์ปฌ API๋ฅผ ์ง์ ‘ ์ฐŒ๋ฆ…๋‹ˆ๋‹ค.

๐Ÿ”ท ๋ฌธ์ œ โ€” ์ž์ฒด Wi-Fi AP๋งŒ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

์—ฌ๊ธฐ์„œ ๊ฑธ๋ฆฌ๋Š” ๊ฒŒ ์ ‘๊ทผ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. Backup Gateway๋Š” ์„ค์น˜ยท์ ๊ฒ€์šฉ์œผ๋กœ ์ž์ฒด Wi-Fi AP๋ฅผ ์ƒ์‹œ ๋„์šฐ๊ณ  ์žˆ๊ณ , ํ™•์žฅ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” TEDAPI ์—”๋“œํฌ์ธํŠธ๋Š” ๊ทธ AP ์•ˆ์ชฝ ์ฃผ์†Œ์ธ 192.168.91.1์—๋งŒ ์—ด๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด AP๋Š” ์ธํ„ฐ๋„ท๋„ ์—†๊ณ  ์ง‘ LAN๊ณผ๋„ ์ด์–ด์ง€์ง€ ์•Š๋Š” ์™„์ „ํžˆ ๊ฒฉ๋ฆฌ๋œ ์„ฌ์ž…๋‹ˆ๋‹ค.

๊ฒŒ์ดํŠธ์›จ์ด ๋ณธ์ฒด์— ์ด๋”๋„ท ํฌํŠธ๊ฐ€ ์žˆ๊ธด ํ•˜์ง€๋งŒ, ๊ทธ๊ฑด ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ Tesla ์„œ๋ฒ„๋กœ ๋‚˜๊ฐ€๋Š” ์ž๊ธฐ ์—…๋งํฌ์ผ ๋ฟ 192.168.91.1์„ ์ง‘ LAN์— ๋…ธ์ถœ์‹œ์ผœ ์ฃผ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋ ค๋ฉด Wi-Fi๋กœ ๊ทธ AP์— ๋ถ™๋Š” ๊ฒƒ ์™ธ์— ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ธฐ์กด์— ์“ฐ๋˜ ๋ฐฉ๋ฒ•๋“ค์€ ํ•˜๋‚˜๊ฐ™์ด ๋ถˆํŽธํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋…ธํŠธ๋ถ/๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด๋ฅผ Powerwall AP์— ๋ถ™์—ฌ๋‘”๋‹ค โ†’ ๊ทธ ์žฅ๋น„๋Š” ๊ทธ ์ˆœ๊ฐ„๋ถ€ํ„ฐ ์ง‘ ๋„คํŠธ์›Œํฌ์—์„œ ์‚ฌ๋ผ์ง. ์ด์ค‘ NIC๋‚˜ ๋ณต์žกํ•œ ๋ผ์šฐํŒ… ์„ค์ •์ด ํ•„์š”.
  • Wi-Fi ๋ผ์šฐํ„ฐ๋ฅผ ๋ฆฌํ”ผํ„ฐ ๋ชจ๋“œ๋กœ ๋ฌผ๋ฆฐ๋‹ค โ†’ ์ „์šฉ ํ•˜๋“œ์›จ์–ด ํ•˜๋‚˜๋ฅผ ํ†ต์งธ๋กœ ๋‚ญ๋น„ํ•˜๊ณ , Powerwall์ด ์™ธ๋ถ€ ํŠธ๋ž˜ํ”ฝ์„ ์ธ์ง€ํ•จ.
  • ํด๋ผ์šฐ๋“œ API๋ฅผ ์“ด๋‹ค โ†’ ์ง€์—ฐ์ด ํฌ๊ณ , ์ธํ„ฐ๋„ท์ด ๋Š๊ธฐ๋ฉด ๊ฐ™์ด ๋Š๊ธฐ๊ณ , Tesla ์ •์ฑ… ๋ณ€๊ฒฝ์— ์ข…์†๋จ.

๐Ÿ”ท ํ•ด๋ฒ• โ€” ๋ธŒ๋ฆฌ์ง€ ํ•œ ์žฅ

์ด ํ”„๋กœ์ ํŠธ๋Š” ์ด๊ฑธ ์†๋ฐ”๋‹ฅ๋งŒ ํ•œ PoE ๋ณด๋“œ ํ•œ ์žฅ์œผ๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”ท ํ•ด๋ฒ• โ€” ๋ธŒ๋ฆฌ์ง€ ํ•œ ์žฅ

Waveshare ESP32-S3-POE-ETH ๋ณด๋“œ์— ์˜ฌ๋ผ๊ฐ„ ํŽŒ์›จ์–ด๊ฐ€ ํ•œ์ชฝ์œผ๋กœ๋Š” W5500 ์ด๋”๋„ท์œผ๋กœ ์ง‘ LAN์—, ๋‹ค๋ฅธ ์ชฝ์œผ๋กœ๋Š” Wi-Fi STA๋กœ Powerwall AP์— ๋™์‹œ์— ๋ถ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋”๋„ท IP์˜ :443์œผ๋กœ ๋“ค์–ด์˜จ TLS ํŠธ๋ž˜ํ”ฝ์„ ๋ณตํ˜ธํ™”ํ•˜์ง€ ์•Š๊ณ  ๋ฐ”์ดํŠธ ๊ทธ๋Œ€๋กœ Powerwall๋กœ ํ˜๋ ค๋ณด๋ƒ…๋‹ˆ๋‹ค.

์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค. ์ง‘ ์•ˆ ์•„๋ฌด PC์—์„œ๋‚˜ https://powerwall.local/์„ ์น˜๋ฉด Powerwall ๋กœ์ปฌ API๊ฐ€ ๊ทธ๋ƒฅ ์—ด๋ฆฝ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ž๊ธฐ๊ฐ€ ๊ฒฉ๋ฆฌ๋œ AP์™€ ํ†ต์‹ ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค ์ž์ฒด๋ฅผ ์ธ์‹ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๐Ÿ”ท ํ•œ๋งˆ๋””๋กœ

Powerwall์˜ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋Š” Wi-Fi๋กœ๋งŒ ๊บผ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ธŒ๋ฆฌ์ง€๊ฐ€ ๊ทธ Wi-Fi ๋ฐ์ดํ„ฐ๋ฅผ ์ด๋”๋„ท์œผ๋กœ ์˜ฎ๊ฒจ, ์ง‘ ์•ˆ ์–ด๋””์„œ๋“  ๋žœ์„ ์œผ๋กœ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.


02 โ€” ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

 

02 โ€” ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

03 โ€” ์™œ TLS "ํŒจ์Šค์Šค๋ฃจ"์ธ๊ฐ€?

**ํŒจ์Šค์Šค๋ฃจ(passthrough)**๋ž€ ์ค‘๊ฐ„ ์žฅ๋น„๊ฐ€ ์•”ํ˜ธํ™”๋œ ํŠธ๋ž˜ํ”ฝ์„ ํ’€์–ด๋ณด์ง€ ์•Š๊ณ  ๋ฐ”์ดํŠธ ๊ทธ๋Œ€๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ฆฌ์ง€๋Š” TLS ์„ธ์…˜์˜ ์ฐธ์—ฌ์ž๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฐฐ๊ด€์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€ ๊ฐœ๋…์ธ **์ข…๋‹จ(termination)**์€ ์ค‘๊ฐ„ ์žฅ๋น„๊ฐ€ TLS๋ฅผ ์ง์ ‘ ํ’€๊ณ  ๋‹ค์‹œ ๋งบ๋Š” ๋ฐฉ์‹์œผ๋กœ, ์‚ฌ์‹ค์ƒ ํ•ฉ๋ฒ•์ ์ธ ์ค‘๊ฐ„์ž(MITM)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”ท ๋ณตํ˜ธํ™”ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์„ค๊ณ„ ๊ฒฐ๋‹จ

์ด ํ”„๋กœ์ ํŠธ์˜ ์ปค๋ฐ‹ ํžˆ์Šคํ† ๋ฆฌ์—๋Š” ํฅ๋ฏธ๋กœ์šด ํ”์ ์ด ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ดˆ๊ธฐ์—๋Š” mbedTLS๋กœ TLS ์ข…๋‹จ(termination) ์„ ๊ตฌํ˜„ํ•˜๋ ค ํ–ˆ๊ณ , ์ธ์ฆ์„œ๋ฅผ ์ž„๋ฒ ๋”ฉํ•˜๊ณ  esp_tls ์„ค์ •๊ณผ ์”จ๋ฆ„ํ•œ ์ปค๋ฐ‹์ด 20๊ฐœ ๊ฐ€๊นŒ์ด ์ด์–ด์ง‘๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ตญ Revert to transparent TCP proxy to fix memory exhaustion crashes โ€” ๋ฉ”๋ชจ๋ฆฌ ๊ณ ๊ฐˆ ํฌ๋ž˜์‹œ ๋•Œ๋ฌธ์— ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.

ESP32-S3์—์„œ TLS๋ฅผ ์ข…๋‹จํ•˜๋ ค๋ฉด ์„ธ์…˜๋งˆ๋‹ค ์ˆ˜์‹ญ KB์˜ ํž™์ด ํ•„์š”ํ•˜๊ณ , ๋™์‹œ ์ ‘์†์ด ๋ช‡ ๊ฐœ๋งŒ ๊ฒน์ณ๋„ heap์ด ๋ฐ”๋‹ฅ๋‚ฉ๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์ข…๋‹จํ•˜๋Š” ์ˆœ๊ฐ„ ์ด ์žฅ๋น„๋Š” ์ค‘๊ฐ„์ž(MITM) ๊ฐ€ ๋˜์–ด, Powerwall ์ž๊ฒฉ์ฆ๋ช…์ด ํ‰๋ฌธ์œผ๋กœ ์ง€๋‚˜๊ฐ€๋Š” ์ง€์ ์ด ํ•˜๋‚˜ ๋” ์ƒ๊น๋‹ˆ๋‹ค.

์ตœ์ข… ์„ ํƒ์€ ๋ช…์พŒํ•ฉ๋‹ˆ๋‹ค. ์•”ํ˜ธ๋ฌธ์€ ์•”ํ˜ธ๋ฌธ์ธ ์ฑ„๋กœ relayํ•œ๋‹ค. ํด๋ผ์ด์–ธํŠธ์™€ Powerwall์ด end-to-end TLS๋ฅผ ๋งบ๊ณ , ๋ธŒ๋ฆฌ์ง€๋Š” ๊ทธ ์‚ฌ์ด์—์„œ ๋ฐ”์ดํŠธ๋งŒ ์˜ฎ๊น๋‹ˆ๋‹ค. ๋ณด์•ˆ ํ‘œ๋ฉด์ด ์ค„๊ณ , ๋ฉ”๋ชจ๋ฆฌ๋Š” ์„ธ์…˜๋‹น 4KB ๋ฒ„ํผ ๋‘ ๊ฐœ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

๐Ÿ”ท TTL=64 โ€” Powerwall์„ ์†์ด์ง€ ์•Š๊ณ  ์„ค๋“ํ•˜๊ธฐ

 
c
int ttl = TTL_VALUE;   // 64
setsockopt(powerwall_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));

Powerwall ์ชฝ์—์„œ ๋ดค์„ ๋•Œ ์ด ํŠธ๋ž˜ํ”ฝ์€ ํ™‰์„ ํ•˜๋‚˜ ๊ฑด๋„ˆ์˜จ ๊ฒŒ ์•„๋‹ˆ๋ผ ๋กœ์ปฌ์—์„œ ์˜จ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. TTL์„ ๋ช…์‹œ์ ์œผ๋กœ 64๋กœ ์„ธํŒ…ํ•˜๋Š” ์ด ๋‘ ์ค„์ด, ํ”„๋ก์‹œ๋ฅผ ํ†ต๊ณผํ•œ ์š”์ฒญ์„ Powerwall์ด "์ •์ƒ์ ์ธ ๋กœ์ปฌ ํด๋ผ์ด์–ธํŠธ"๋กœ ๋ฐ›์•„๋“ค์ด๊ฒŒ ๋งŒ๋“œ๋Š” ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ํ”„๋กœํ† ์ฝœ์„ ์œ„์กฐํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, IP ๊ณ„์ธต์—์„œ ๋กœ์ปฌ์„ฑ์„ ์œ ์ง€ํ•ด ์ฃผ๋Š” ์ •์งํ•œ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.


04 โ€” ์™œ WIZnet W5500์ธ๊ฐ€? โญ

๐Ÿ”ท ESP32-S3์—๋Š” ๋‚ด์žฅ ์ด๋”๋„ท MAC์ด ์—†๋‹ค

์ด ํ”„๋กœ์ ํŠธ์˜ ์ถœ๋ฐœ์  ์ž์ฒด๊ฐ€ ์—ฌ๊ธฐ์ž…๋‹ˆ๋‹ค. ESP32(์˜ค๋ฆฌ์ง€๋„)์—๋Š” EMAC์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์ง€๋งŒ, ESP32-S3์—๋Š” ์ด๋”๋„ท MAC์ด ์•„์˜ˆ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰ S3์—์„œ ์œ ์„  ์ด๋”๋„ท์„ ์“ฐ๋ ค๋ฉด SPI๋กœ ๋ถ™๋Š” ์™ธ์žฅ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ•„์ˆ˜์ด๊ณ , ์—ฌ๊ธฐ์„œ W5500์ด ์„ ํƒ์ง€๊ฐ€ ์•„๋‹ˆ๋ผ ์ „์ œ ์กฐ๊ฑด์ด ๋ฉ๋‹ˆ๋‹ค.

Waveshare๊ฐ€ ESP32-S3-POE-ETH ๋ณด๋“œ๋ฅผ ๋งŒ๋“ค ๋•Œ W5500์„ ์–น์€ ๊ฒƒ๋„ ๊ฐ™์€ ์ด์œ ์ด๋ฉฐ, WIZnet์ด ์ตœ๊ทผ ๋ฐœํ‘œํ•œ ESP32-W5500 Dev-kit / EOD-W55 SoM ์—ญ์‹œ ์ •ํ™•ํžˆ ์ด ์กฐํ•ฉ(ESP32-S3 + W5500)์„ ํ•˜๋‚˜์˜ ๋ชจ๋“ˆ๋กœ ์ •๋ฆฌํ•œ ์ œํ’ˆ์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ๊ทธ ์กฐํ•ฉ์ด ์‹ค์ œ ํ˜„์žฅ์—์„œ ์™œ ํ•„์š”ํ•œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์‹ค์ฆ ์‚ฌ๋ก€์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.

๐Ÿ”ท ์‚ฌ์šฉ ๋ชจ๋“œ: MACRAW (esp_eth ๋ฐฑ์—”๋“œ)

์ด ํ”„๋กœ์ ํŠธ๋Š” ESP-IDF ํ‘œ์ค€ ๋“œ๋ผ์ด๋ฒ„์ธ esp_eth_mac_new_w5500() / esp_eth_phy_new_w5500()์œผ๋กœ W5500์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณ„์—ด API๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ W5500์˜ Socket 0์„ MACRAW ๋ชจ๋“œ๋กœ ์—ด์–ด ์ƒ ์ด๋”๋„ท ํ”„๋ ˆ์ž„์„ ์ฃผ๊ณ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ฆ‰ ์—ฌ๊ธฐ์„œ W5500์€ ํ•˜๋“œ์›จ์–ด TCP/IP ์˜คํ”„๋กœ๋“œ ์—”์ง„(TOE)์ด ์•„๋‹ˆ๋ผ ์™„์ „ํ•œ 10/100 ์ด๋”๋„ท MAC + PHY๋กœ ๋™์ž‘ํ•˜๊ณ , TCP/IP ์ฒ˜๋ฆฌ๋Š” ESP32-S3์˜ LwIP๊ฐ€ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

์™œ TOE๊ฐ€ ์•„๋‹ˆ๋ผ MACRAW์—ฌ์•ผ ํ–ˆ๋Š”๊ฐ€ โ€” ์ด๊ฒŒ ์ด ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ธฐ์ˆ ์  ํŒ๋‹จ์ž…๋‹ˆ๋‹ค.

  • ํ‘œ์ค€ BSD ์†Œ์ผ“์ด ํ•„์š”ํ–ˆ๋‹ค. ํ”„๋ก์‹œ๋Š” select()๋กœ ๋‘ ์†Œ์ผ“์„ ๋™์‹œ์— ๊ฐ์‹œํ•˜๋ฉฐ ์–‘๋ฐฉํ–ฅ relay๋ฅผ ๋Œ๋ฆฌ๊ณ , IP_TTL / TCP_NODELAY / SO_RCVTIMEO ์†Œ์ผ“ ์˜ต์…˜์„ ๊ทธ๋Œ€๋กœ ์”๋‹ˆ๋‹ค. LwIP ์œ„์—์„œ๋งŒ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
  • Wi-Fi์™€ ์ด๋”๋„ท์ด ๋™์‹œ์— ์‚ด์•„ ์žˆ์–ด์•ผ ํ–ˆ๋‹ค. ๋‘ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋ชจ๋‘ esp_netif๋กœ ์กด์žฌํ•ด์•ผ ํ•˜๋‚˜์˜ ์†Œ์ผ“ API๋กœ ์–‘์ชฝ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • TLS ํŒจ์Šค์Šค๋ฃจ๋Š” ์˜คํ”„๋กœ๋“œ์˜ ์ด์ ์ด ์—†๋‹ค. ์–ด์ฐจํ”ผ ์•”ํ˜ธ๋ฌธ ๋ฐ”์ดํŠธ๋ฅผ ์˜ฎ๊ธธ ๋ฟ์ด๋ผ ์ฒดํฌ์„ฌยท์žฌ์กฐ๋ฆฝ์„ ์นฉ์— ๋งก๊ธธ ์‹ค์ต์ด ํฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • HTTPS OTA / mDNS / NTP๋ฅผ ๋‹ค ์จ์•ผ ํ–ˆ๋‹ค. ์ „๋ถ€ ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ์˜ ํ’€ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ์˜์—ญ์ž…๋‹ˆ๋‹ค.

W5500์˜ 4๊ฐ€์ง€ ์†Œ์ผ“ ๋ชจ๋“œ(TCP TOE / UDP / IPRAW / MACRAW) ์ค‘ MACRAW๊ฐ€ ์ •ํ™•ํžˆ ์ด ์š”๊ตฌ์‚ฌํ•ญ์˜ ๋‹ต์ด๋ฉฐ, ์ด ํ”„๋กœ์ ํŠธ๋Š” "W5500์„ ์™œ MACRAW๋กœ ์“ฐ๋Š”๊ฐ€"์˜ ๊ต๊ณผ์„œ์ ์ธ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

๐Ÿ”ท ๋Œ€์ฒด ์†”๋ฃจ์…˜ ๋Œ€๋น„ ์šฐ์œ„

ํ•ญ๋ชฉW5500 (MACRAW)ENC28J60LAN8720 ๋“ฑ RMII PHY
ESP32-S3 ์ง€์›โœ… IDF ๊ณต์‹ esp_eth ๋“œ๋ผ์ด๋ฒ„์„œ๋“œํŒŒํ‹ฐ/์ œ์•ฝ ๋งŽ์ŒโŒ S3์— EMAC ์—†์Œ
์†๋„10/100 Mbps10 Mbps only10/100
์ธํ„ฐํŽ˜์ด์ŠคSPI 4ํ•€ + INTSPIRMII 9ํ•€ + 25MHz ํด๋Ÿญ
๋“œ๋ผ์ด๋ฒ„ ์„ฑ์ˆ™๋„ESP-IDF ๋‚ด์žฅ, ์ธํ„ฐ๋ŸฝํŠธ ๊ตฌ๋™ RX๋ถˆ์•ˆ์ • ์‚ฌ๋ก€ ๋‹ค์ˆ˜S3 ์‚ฌ์šฉ ๋ถˆ๊ฐ€
PoE ๋ณด๋“œ ์ƒํƒœ๊ณ„Waveshare, WIZnet SoM ๋“ฑ ๋‹ค์ˆ˜๋“œ๋ฌพโ€”

ํŠนํžˆ CONFIG_ETH_SPI_ETHERNET_W5500=y ํ•œ ์ค„๋กœ IDF์—์„œ ์ •์‹ ์ง€์›๋œ๋‹ค๋Š” ์ ์ด ๊ฒฐ์ •์ ์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ์ดˆ๊ธฐ์— Arduino ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์‹œ์ž‘ํ–ˆ๋‹ค๊ฐ€ Migrate from Arduino to ESP-IDF framework with native W5500 support ์ปค๋ฐ‹์—์„œ ESP-IDF๋กœ ์ „๋ฉด ์ด์ „ํ–ˆ๋Š”๋ฐ, ๊ทธ ์‚ฌ์œ ๊ฐ€ ๋ฐ”๋กœ "W5500 ๋„ค์ดํ‹ฐ๋ธŒ ์ง€์›" ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋กœ ํ—ค๋งค๋˜ ์‹œ๊ธฐ๋ฅผ IDF ํ‘œ์ค€ ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๋๋‚ด์ค€ ์…ˆ์ž…๋‹ˆ๋‹ค.

05 โ€” ํ•ต์‹ฌ ๊ตฌ์„ฑ ์š”์†Œ

๐ŸŒ WIZnet W5500 โ€” MACRAW ๋ชจ๋“œ (esp_eth MAC + PHY)

SPI3_HOST, 20MHz, MISO 12 / MOSI 11 / SCLK 13 / CS 14 / INT 10. ESP-IDF์˜ esp_eth ๋“œ๋ผ์ด๋ฒ„๋กœ Socket 0 MACRAW๋ฅผ ํ†ตํ•ด ์ƒ ์ด๋”๋„ท ํ”„๋ ˆ์ž„์„ LwIP์— ์ „๋‹ฌ. DHCP / ์ •์  IP ๋ชจ๋‘ ์ง€์›ํ•˜๋ฉฐ ์„ค์ •์€ NVS์— ์ €์žฅ.

๐Ÿ”Œ Waveshare ESP32-S3-POE-ETH

802.3af PoE ์ง€์›. ์ด๋”๋„ท ์ผ€์ด๋ธ” ํ•œ ๊ฐ€๋‹ฅ์œผ๋กœ ์ „์›๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ๋ฐ›์œผ๋ฏ€๋กœ Powerwall ์˜† ๋ฐฐ์„ ์ด ๊ทน๋‹จ์ ์œผ๋กœ ๋‹จ์ˆœํ•ด์ง‘๋‹ˆ๋‹ค. USB ์ „์›๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

๐Ÿ”€ TLS ํŒจ์Šค์Šค๋ฃจ ํ”„๋ก์‹œ (src/proxy.c, 567์ค„)

  • ์ตœ๋Œ€ 4๊ฐœ ๋™์‹œ ํด๋ผ์ด์–ธํŠธ, ํด๋ผ์ด์–ธํŠธ๋‹น 4KB ร— 2 ๋ฒ„ํผ๋ฅผ ์ •์  ํ’€์—์„œ ํ• ๋‹น (๋™์  ํ• ๋‹น ์—†์Œ โ†’ ํž™ ํŒŒํŽธํ™” ๋ฐฉ์ง€)
  • select() 100ms ํƒ€์ž„์•„์›ƒ ๋ฃจํ”„๋กœ ์–‘๋ฐฉํ–ฅ ๊ฐ์‹œ, 60์ดˆ ๋ฌดํ™œ๋™ ์‹œ ์„ธ์…˜ ์ข…๋ฃŒ
  • TTFB / TTLB ์ธก์ • ๋ฐ ์š”์ฒญ ๋กœ๊ทธ ๋ง ๋ฒ„ํผ

๐Ÿ“Š ๋Œ€์‹œ๋ณด๋“œ (src/main.c, 3,389์ค„)

Wi-Fi RSSI 24์‹œ๊ฐ„ ์ฐจํŠธ, Powerwall ๋„๋‹ฌ์„ฑ, CPUยท๋‹ค์ด ์˜จ๋„ยทํž™ยท์—…ํƒ€์ž„, ํ”„๋ก์‹œ ํ†ต๊ณ„, ๋กœ๊ทธ ๋‹ค์šด๋กœ๋“œ(์ตœ๊ทผ 200์ค„), ๋กœ์ปฌ/์›๊ฒฉ OTA. ์ธ์ฆ์€ salt + SHA-256์„ NVS์— ์ €์žฅํ•˜๊ณ  HTML ๋กœ๊ทธ์ธ + 7์ผ ์„ธ์…˜ ์ฟ ํ‚ค(HttpOnly; SameSite=Lax, HTTPS ํ”„๋ก์‹œ ๋’ค์—์„œ๋Š” Secure).

๐Ÿ”„ OTA ํŒŒ์ดํ”„๋ผ์ธ (src/remote_ota.c)

v* ํƒœ๊ทธ๋ฅผ ํ‘ธ์‹œํ•˜๋ฉด GitHub Actions๊ฐ€ firmware.bin๊ณผ version.json์„ GitHub Pages์— ๋ฐœํ–‰ํ•˜๊ณ , ์žฅ๋น„๊ฐ€ ์ด๋ฅผ ์ง์ ‘ ํ™•์ธยท์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €(Chrome/Edge/Opera)์—์„œ USB๋กœ ์ดˆ๊ธฐ ํ”Œ๋ž˜์‹ฑ๋„ ๊ฐ€๋Šฅ. ํŒŒํ‹ฐ์…˜์€ nvs 24KB + 1.75MB OTA ์Šฌ๋กฏ 2๊ฐœ.

์—ฌ๊ธฐ์— ์ˆจ์€ ๋””ํ…Œ์ผ ํ•˜๋‚˜ โ€” Powerwall AP์— ๋ถ™๋Š” ์ˆœ๊ฐ„ Tesla์˜ DHCP๊ฐ€ LwIP์˜ DNS ์„œ๋ฒ„๋ฅผ 192.168.91.1๋กœ ๋ฎ์–ด์”๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด GitHub Pages๋ฅผ ํ•ด์„ํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜์ฃ . ์ด ํ”„๋กœ์ ํŠธ๋Š” ์ด๋”๋„ท DNS๋ฅผ ์Šค๋ƒ…์ƒทํ•ด ๋‘์—ˆ๋‹ค๊ฐ€ OTA ์‹œ์ ์— ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค(remote_ota_apply_eth_dns()). ๋“€์–ผ ์ธํ„ฐํŽ˜์ด์Šค ์žฅ๋น„์—์„œ๋งŒ ๋‚˜ํƒ€๋‚˜๋Š” ํ•จ์ •์ด๊ณ , ์‹ค์ œ๋กœ ๊ฒช์–ด๋ด์•ผ ์•Œ ์ˆ˜ ์žˆ๋Š” ์ข…๋ฅ˜์˜ ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค.


06 โ€” ์‘์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค

01. ํ™ˆ ์—๋„ˆ์ง€ ๋ชจ๋‹ˆํ„ฐ๋ง ์ž๋™ํ™”

Home Assistant, Node-RED, InfluxDB์—์„œ Powerwall ๋กœ์ปฌ API๋ฅผ ํด๋ผ์šฐ๋“œ ๊ฒฝ์œ  ์—†์ด ์ง์ ‘ ํด๋ง. ์ง€์—ฐ์ด ์ˆ˜์‹ญ ms ์ˆ˜์ค€์œผ๋กœ ๋–จ์–ด์ง€๊ณ , ์ธํ„ฐ๋„ท์ด ๋Š๊ฒจ๋„ ๊ณ„์† ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

02. ๊ฒฉ๋ฆฌ๋œ ์‚ฐ์—… ์žฅ๋น„ ๊ฒŒ์ดํŠธ์›จ์ด

Powerwall์„ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋ฐ”๊ฟ” ์ฝ์œผ๋ฉด ๊ทธ๋Œ€๋กœ ์‚ฐ์—…์šฉ ํŒจํ„ด์ด ๋ฉ๋‹ˆ๋‹ค. ์ž์ฒด AP๋งŒ ๋„์šฐ๋Š” ์ธ๋ฒ„ํ„ฐ, PLC, ๊ณ„์ธก๊ธฐ, ์˜๋ฃŒ ์žฅ๋น„ โ€” ๋ฒค๋” ๋„คํŠธ์›Œํฌ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ์‚ฌ๋‚ด LAN์—์„œ ์ ‘๊ทผํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ธŒ๋ฆฌ์ง€. ๊ด€๋ฆฌ ํฌํŠธ๊ฐ€ ์ด๋”๋„ท ์ธก์—๋งŒ bind๋˜๋Š” ์„ค๊ณ„๋ผ ๋ฒค๋” ์žฅ๋น„ ์ชฝ ๊ณต๊ฒฉ ํ‘œ๋ฉด์ด ๋Š˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

03. ํ˜„์žฅ ์„ค์น˜ํ˜• ํ”„๋กœํ† ์ฝœ ๋ธŒ๋ฆฌ์ง€ ํ…œํ”Œ๋ฆฟ

PoE ๋‹จ์„  ๊ธ‰์ „ + ์›น ๋Œ€์‹œ๋ณด๋“œ + OTA + ์›Œ์น˜๋… + ๊ณต์žฅ์ดˆ๊ธฐํ™” ๋ฒ„ํŠผ. ์ด ๋‹ค์„ฏ ๊ฐ€์ง€๋Š” ์‚ฌ์‹ค ๋ชจ๋“  ํ˜„์žฅ ์„ค์น˜ํ˜• ์ž„๋ฒ ๋””๋“œ ์žฅ๋น„์˜ ๊ณตํ†ต ์š”๊ตฌ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ์ด ์ €์žฅ์†Œ๋Š” ๊ทธ ๊ณจ๊ฒฉ์„ ๊ทธ๋Œ€๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฐธ์กฐ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.

04. ์ด์ค‘ ๋„คํŠธ์›Œํฌ ๊ฐœ๋ฐœ ํ•™์Šต ์ž๋ฃŒ

Wi-Fi์™€ ์ด๋”๋„ท์„ ๋™์‹œ์— ์‚ด๋ ค๋‘๋ฉด ๊ธฐ๋ณธ ๋ผ์šฐํŠธ, DNS ์†Œ์œ ๊ถŒ, ์†Œ์ผ“ bind ์ฃผ์†Œ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ํ•œ๊บผ๋ฒˆ์— ํ„ฐ์ง‘๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ๊ทธ ํ•จ์ •๋“ค์„ ์‹ค์ œ๋กœ ๋ฐŸ๊ณ  ๊ณ ์นœ ๊ธฐ๋ก์ด ์ปค๋ฐ‹ ๋‹จ์œ„๋กœ ๋‚จ์•„ ์žˆ์–ด, ESP-IDF ๋“€์–ผ netif๋ฅผ ๊ณต๋ถ€ํ•˜๊ธฐ์— ๋Œ€๋‹จํžˆ ์ข‹์€ ๊ต์žฌ์ž…๋‹ˆ๋‹ค.


Conclusion

๊ฒฉ๋ฆฌ๋œ Wi-Fi AP ํ•˜๋‚˜ ๋•Œ๋ฌธ์— ๋…ธํŠธ๋ถ์„ ํฌ์ƒํ•˜๋˜ ๋ฌธ์ œ๋ฅผ, W5500์„ ์–น์€ ์†๋ฐ”๋‹ฅ๋งŒ ํ•œ PoE ๋ณด๋“œ ํ•œ ์žฅ์ด ๋๋ƒ…๋‹ˆ๋‹ค.

  • โœ… ESP32-S3์— ์—†๋Š” ์ด๋”๋„ท MAC์„ W5500 MACRAW๋กœ ์ฑ„์šฐ๊ณ , ๊ทธ ์œ„์—์„œ ์™„์ „ํ•œ LwIP ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ตฌํ˜„
  • โœ… TLS๋ฅผ ๋ณตํ˜ธํ™”ํ•˜์ง€ ์•Š๋Š” ํŒจ์Šค์Šค๋ฃจ ์„ค๊ณ„๋กœ ๋ณด์•ˆ ํ‘œ๋ฉด๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ๋™์‹œ์— ์ตœ์†Œํ™” (์ข…๋‹จ ๋ฐฉ์‹์—์„œ ๋ฉ”๋ชจ๋ฆฌ ํฌ๋ž˜์‹œ๋ฅผ ๊ฒช๊ณ  ๋˜๋Œ๋ฆฐ ์‹ค์ฆ ๊ธฐ๋ก ํฌํ•จ)
  • โœ… TTL=64 ์†Œ์ผ“ ์˜ต์…˜์œผ๋กœ Powerwall์ด ํŠธ๋ž˜ํ”ฝ์„ ๋กœ์ปฌ๋กœ ์ธ์‹
  • โœ… ๊ด€๋ฆฌ ํฌํŠธ๋ฅผ ์ด๋”๋„ท IP์—๋งŒ bindํ•ด ๋ฒค๋” ๋„คํŠธ์›Œํฌ ์ธก ๋…ธ์ถœ์„ ์›์ฒœ ์ฐจ๋‹จ
  • โœ… PoE ๋‹จ์„  ๊ธ‰์ „์œผ๋กœ ํ˜„์žฅ ๋ฐฐ์„ ์„ ํ•œ ๊ฐ€๋‹ฅ์œผ๋กœ ์ถ•์†Œ
  • โœ… 24์‹œ๊ฐ„ RSSI ํžˆ์Šคํ† ๋ฆฌ, ๋‹ค์ด ์˜จ๋„, ํ”„๋ก์‹œ ํ†ต๊ณ„๊นŒ์ง€ ๊ฐ–์ถ˜ ์šด์˜๊ธ‰ ๋Œ€์‹œ๋ณด๋“œ
  • โœ… GitHub Actions โ†’ Pages โ†’ ์žฅ๋น„ OTA ์ „ ๊ณผ์ • ์ž๋™ํ™” + ๋ธŒ๋ผ์šฐ์ € ํ”Œ๋ž˜์‹ฑ
  • โœ… ์›Œ์น˜๋… ์ž๋™ ์žฌ๋ถ€ํŒ…, DHCP ํด๋ฐฑ, BOOT 15์ดˆ ๊ณต์žฅ์ดˆ๊ธฐํ™” ๋“ฑ ๋ฌด์ธ ์šด์˜ ๋ณต๊ตฌ ๊ฒฝ๋กœ ๋‹ค์ค‘ํ™”
  • โœ… Tesla DHCP์˜ DNS ํƒˆ์ทจ๋ฅผ ์Šค๋ƒ…์ƒทยท๋ณต์›์œผ๋กœ ๋ฐฉ์–ด โ€” ๋“€์–ผ ์ธํ„ฐํŽ˜์ด์Šค ์‹ค์ „ ๋…ธํ•˜์šฐ

Q&A

Q. W5500์„ TOE(ํ•˜๋“œ์›จ์–ด TCP/IP)๋กœ ์•ˆ ์“ด ๊ฒŒ ์•„๊น์ง€ ์•Š๋‚˜์š”? A. ์ด ์›Œํฌ๋กœ๋“œ์—์„œ๋Š” MACRAW๊ฐ€ ๋งž์Šต๋‹ˆ๋‹ค. ํ”„๋ก์‹œ๊ฐ€ select() ๋‹ค์ค‘ํ™”, IP_TTL / TCP_NODELAY / SO_RCVTIMEO ์†Œ์ผ“ ์˜ต์…˜, ๊ทธ๋ฆฌ๊ณ  Wi-Fi ์ธํ„ฐํŽ˜์ด์Šค์™€์˜ ๊ณต์กด์„ ์ „๋ถ€ ์š”๊ตฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. TOE๋Š” ์นฉ์ด ์†Œ์ผ“์„ ์†Œ์œ ํ•˜๋Š” ๊ตฌ์กฐ๋ผ ์ด๋Ÿฐ ํ‘œ์ค€ ์†Œ์ผ“ ์‹œ๋งจํ‹ฑ์„ ๊ทธ๋Œ€๋กœ ์“ฐ๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ MCU ์ž์›์„ ์•„๊ปด์•ผ ํ•˜๋Š” ๋‹จ์ˆœ Modbus TCP ๊ฒŒ์ดํŠธ์›จ์ด ๊ฐ™์€ ์›Œํฌ๋กœ๋“œ์˜€๋‹ค๋ฉด TOE๊ฐ€ ์ •๋‹ต์ด์—ˆ์„ ๊ฒ๋‹ˆ๋‹ค. ๊ฐ™์€ ์นฉ, ๋‹ค๋ฅธ ๋ชจ๋“œ, ๋‹ค๋ฅธ ์ •๋‹ต์ด๋ผ๋Š” ์ ์ด W5500์˜ ๊ฐ•์ ์ž…๋‹ˆ๋‹ค.

Q. ์™œ ENC28J60์ด ์•„๋‹ˆ๋ผ W5500์ธ๊ฐ€์š”? A. ENC28J60์€ 10Mbps ์ „์šฉ์ด๊ณ  ESP-IDF์—์„œ์˜ ๋“œ๋ผ์ด๋ฒ„ ์„ฑ์ˆ™๋„๊ฐ€ W5500์— ๋ชป ๋ฏธ์นฉ๋‹ˆ๋‹ค. W5500์€ CONFIG_ETH_SPI_ETHERNET_W5500=y ํ•œ ์ค„๋กœ IDF ๊ณต์‹ ์ง€์›์„ ๋ฐ›๊ณ , 10/100 full-duplex์— INT ๊ธฐ๋ฐ˜ RX๊นŒ์ง€ ํ‘œ์ค€์œผ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ด ํ”„๋กœ์ ํŠธ๋„ Arduino ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋กœ ํ—ค๋งค๋‹ค๊ฐ€ IDF์˜ W5500 ๋„ค์ดํ‹ฐ๋ธŒ ์ง€์›์„ ์ด์œ ๋กœ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ต์งธ๋กœ ๊ฐˆ์•„ํƒ”์Šต๋‹ˆ๋‹ค.

Q. ์™œ ์ธํ„ฐ๋ŸฝํŠธ ํ•€(GPIO10)๊นŒ์ง€ ์—ฐ๊ฒฐํ–ˆ๋‚˜์š”? A. ํด๋ง ๋ฐฉ์‹์ด๋ฉด SPI ํŠธ๋žœ์žญ์…˜์ด ๊ณ„์† ๋Œ์•„ CPU์™€ ๋ฒ„์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๊ณ  ์ง€์—ฐ๋„ ์ปค์ง‘๋‹ˆ๋‹ค. W5500์˜ INT ํ•€์„ ์“ฐ๋ฉด ์ˆ˜์‹  ํ”„๋ ˆ์ž„์ด ์žˆ์„ ๋•Œ๋งŒ SPI๊ฐ€ ๊นจ์–ด๋‚ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด ํ”„๋กœ์ ํŠธ๋Š” esp_eth_driver_install()์ด INT GPIO ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•˜๊ธฐ ์ „์— gpio_install_isr_service()๊ฐ€ ๋จผ์ € ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ์ˆœ์„œ ์˜์กด์„ฑ์— ๊ฑธ๋ ค ๋ณ„๋„ ์ปค๋ฐ‹์œผ๋กœ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. W5500 + ESP-IDF ์กฐํ•ฉ์—์„œ ์‹ค์ œ๋กœ ๋งŒ๋‚˜๊ธฐ ์‰ฌ์šด ํ•จ์ •์ž…๋‹ˆ๋‹ค.

Q. ์ด ๊ตฌ์กฐ๋ฅผ W6300์œผ๋กœ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ๋‚˜์š”? A. ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ด์ ๋„ ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. W6300์€ QSPI๋ฅผ ์ง€์›ํ•ด SPI ๋Œ€๋น„ ๋Œ€์—ญํญ์ด ํฌ๊ฒŒ ์˜ฌ๋ผ๊ฐ€๊ณ  IPv6๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. WIZnet์˜ wsm_driver ์ปดํฌ๋„ŒํŠธ๊ฐ€ W5500/W6300์„ ๋™์ผ API๋กœ ์ถ”์ƒํ™”ํ•˜๊ณ  ์žˆ์–ด, ๋ณด๋“œ ์„ ํƒ๋งŒ ๋ฐ”๊พธ๋ฉด ํ•€๋งต๊ณผ ์นฉ ํƒ€์ž…์ด ์ž๋™ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. TLS ํŒจ์Šค์Šค๋ฃจ์ฒ˜๋Ÿผ ์ˆœ์ˆ˜ ๋Œ€์—ญํญ์ด ๊ณง ์‘๋‹ต ์†๋„์ธ ์›Œํฌ๋กœ๋“œ์—์„œ๋Š” QSPI์˜ ์ด๋“์ด ๊ทธ๋Œ€๋กœ ์ฒด๊ฐ๋  ์˜์—ญ์ž…๋‹ˆ๋‹ค.

Original Link: https://github.com/cwagz/esp32-wifi-bridge Upstream: https://github.com/mccahan/esp32-wifi-bridge

Comments

Comments