ワンクリックで
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 ページを確認してインストールできます。
SOC 職業分類に基づく
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)
| 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