원클릭으로
mock-device-development
Guide for developing and maintaining mock Marstek battery devices for local testing and devcontainer environments
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guide for developing and maintaining mock Marstek battery devices for local testing and devcontainer environments
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
How to create, update, and manage Changesets for release preparation in this repository
Guidance for using correct energy and power metrics in Home Assistant energy features
High-level Home Assistant integration best practices, quality scale cues, and testing/CI expectations for custom components
Patterns for Home Assistant config flows, discovery handlers, options flows, and reauth for custom components
Project-specific patterns for the Marstek integration (config flow, coordinator, scanner, entities, translations)
Practical test/CI playbook for Home Assistant custom components (config flow, coordinator, entities, diagnostics)
SOC 직업 분류 기준
| name | mock-device-development |
| description | Guide for developing and maintaining mock Marstek battery devices for local testing and devcontainer environments |
This skill covers creating, configuring, and maintaining mock Marstek devices for testing the Home Assistant integration without physical hardware.
Mock devices simulate real Marstek batteries (Venus A/D/E 3.0) using UDP on port 30000. They implement the same Open API protocol as real devices, enabling full integration testing.
tools/mock_device/
├── __init__.py # Package exports
├── __main__.py # CLI entry point (python -m mock_device)
├── const.py # Constants (modes, SOC limits, defaults)
├── device.py # MockMarstekDevice UDP server
├── handlers.py # API method response handlers
├── utils.py # Utility functions (get_local_ip)
├── mock_marstek.py # Backwards compatibility shim
├── Dockerfile # Container image
└── simulators/
├── __init__.py # Simulator exports
├── battery.py # BatterySimulator (main simulation logic)
├── household.py # HouseholdSimulator (power consumption)
└── wifi.py # WiFiSimulator (RSSI variations)
| File | Purpose |
|---|---|
simulators/battery.py | Core simulation: SOC, power, modes, temperature |
simulators/household.py | Household consumption patterns for Auto mode |
device.py | UDP server, request handling |
handlers.py | API method responses (DRY: one handler per method) |
const.py | All constants in one place |
.devcontainer/docker-compose.yml | Multi-device orchestration |
The devcontainer supports multiple mock devices:
# .devcontainer/docker-compose.yml
mock-marstek:
command: ["python", "-m", "mock_device", "--ip", "172.28.0.20"]
mock-marstek-2:
command: ["python", "-m", "mock_device", "--ip", "172.28.0.21", "--ble-mac", "009b08a5bb40", "--soc", "75"]
mock-marstek-3:
command: ["python", "-m", "mock_device", "--ip", "172.28.0.22", "--ble-mac", "009b08a5cc41", "--soc", "30"]
Add service to docker-compose.yml:
172.28.0.0/16 subnetRequired CLI flags:
--ip - Must match container's ipv4_address--ble-mac - Unique 12 hex chars (no colons)Central simulation coordinator in simulators/battery.py:
HouseholdSimulator and WiFiSimulator instancesGenerates realistic consumption in simulators/household.py:
Each API method has a dedicated handler in handlers.py:
def handle_es_get_status(request_id, src, state):
return {"id": request_id, "src": src, "result": {...}}
This keeps response logic separate from device/networking code.
python -m mock_device [OPTIONS]
--port PORT UDP port (default: 30000)
--ip IP Reported IP (must match container IP)
--device TYPE Device type (default: "VenusE 3.0")
--ble-mac MAC BLE MAC, 12 hex chars
--wifi-mac MAC WiFi MAC, 12 hex chars
--soc PERCENT Initial SOC 0-100 (default: 50)
--no-simulate Disable dynamic simulation
handlers.py:def handle_new_method(request_id: int, src: str, state: dict) -> dict:
return {"id": request_id, "src": src, "result": {...}}
device.py _build_response():elif method == "NewMethod.GetData":
return handle_new_method(request_id, src, state)
BatterySimulator.get_state().simulators/new_sim.pysimulators/__init__.py exportsBatterySimulator.__init__get_state() return dict# Run directly
cd tools && python -m mock_device --soc 30
# In devcontainer
docker logs marstek-mock-device -f
# Query device
python3 tools/query_device.py 172.28.0.20
Key constants in const.py:
| Constant | Value | Purpose |
|---|---|---|
SOC_MIN_DISCHARGE | 5 | Stop discharging below this |
SOC_RESERVE | 10 | Auto mode reserve |
SOC_TAPER_DISCHARGE | 10 | Start tapering discharge |
SOC_TAPER_CHARGE | 90 | Start tapering charge |
BATTERY_CAPACITY_WH | 5120 | Default capacity |
get_state() + handlerset_mode() in battery.py