Small Docker-friendly bridge for a Midea PortaSplit air conditioner.
It talks to the PortaSplit locally via msmart-ng and exposes the device to FHEM via:
- a native FHEM module (
MideaPortaSplit) - MQTT topics for
MQTT2_DEVICE - a small HTTP API for
HTTPMODor debugging
No Python packages are installed into the FHEM container. The FHEM module only talks to the bridge HTTP API.
Tested locally with a PortaSplit reachable at 10.20.0.49:
type: AIR_CONDITIONER
port: 6444
supported: true
Example readings seen via msmart-ng:
power: true
mode: COOL
target_temperature: 22.0
indoor_temperature: 21.5
outdoor_temperature: 30.0
fan_speed: AUTO
swing_mode: VERTICAL
real_time_power_usage: 152.9
total_energy_usage: 15.04
out_silent: false
cp .env.example .env
docker compose -f docker-compose.example.yml up --buildThe sample compose file uses network_mode: host, because the PortaSplit usually lives in an IoT VLAN and local routing/broadcast is easiest from the host network.
Build and run the bridge on the Docker host:
git clone https://github.com/MrStrategy/FHEM-MideaPortaSplit.git
cd FHEM-MideaPortaSplit
docker build -t fhem-midea-portasplit:0.3.1 -t fhem-midea-portasplit:latest .
cp .env.example .env
cp deploy/rpi/docker-compose.yml docker-compose.ymlEdit .env and set your PortaSplit IP:
MIDEA_HOST=10.20.0.49
HTTP_ENABLE=true
HTTP_PORT=8765
MQTT_ENABLE=false
Start the service:
docker compose up -d
curl http://127.0.0.1:8765/stateThen install the native FHEM module and define the device:
cp fhem/70_MideaPortaSplit.pm /path/to/fhem/FHEM/define midea.portasplit MideaPortaSplit http://10.0.0.80:8765
attr midea.portasplit room Klima
attr midea.portasplit devStateIcon .*:noIcon:noFhemwebLink
attr midea.portasplit webCmd target_temperature:mode:fan_speed:up_and_down:boost:eco
For an RPi at 10.0.0.80, a ready-to-use example is in:
deploy/rpi/fhem-module.cfg
HTTPMOD remains available as a fallback; see deploy/rpi/fhem-httpmod.cfg.
The native FHEM device offers readings like:
state
power
mode
target_temperature
indoor_temperature
outdoor_temperature
real_time_power_usage
total_energy_usage
fan_speed
swing_mode
out_silent
availability
boost / turbo
ion / purifier
led / display_on
sound / beep
smart_sleep / sleep
gear / rate_select
And set commands like:
set midea.portasplit off
set midea.portasplit power off
set midea.portasplit target_temperature 22
set midea.portasplit mode cool
set midea.portasplit fan_speed auto
set midea.portasplit up_and_down on
set midea.portasplit boost on
set midea.portasplit ion on
set midea.portasplit led on
set midea.portasplit sound on
set midea.portasplit gear level_3
set midea.portasplit out_silent on
set midea.portasplit update
The default state display is compact:
offline
off | 24.0°C indoor
cool | 26.0°C -> 22.0°C | Boost Silent | 194 W
The module defaults devStateIcon to text display and webCmd to
target_temperature:mode:fan_speed:up_and_down:boost:eco, so FHEMWEB does not
render it as a generic on/off lamp.
App-style set aliases are available beside the technical msmart-ng names:
| Midea app label | FHEM set alias | Technical reading/field |
|---|---|---|
| Mode | mode |
mode |
| Fan Speed | fan_speed |
fan_speed |
| Up and Down | `up_and_down on | off` |
| iECO / ECO | ieco, eco |
eco |
| Boost | boost |
turbo |
| Gear | gear |
rate_select |
| Smart Sleep | smart_sleep |
sleep |
| ION | ion |
purifier |
| LED | led |
display_on |
| Sound | sound |
beep |
| Freeze Protection | freeze_protection |
freeze_protection |
| Energy Monitor | readings only | real_time_power_usage, current_energy_usage, total_energy_usage |
Smart Guard, My Favorites, Active Clean and Temp. Range are visible in the
app but are not exposed as reliable local commands by the currently used
msmart-ng interface.
Required:
MIDEA_HOST=10.20.0.49
Useful options:
POLL_INTERVAL=30
QUERY_ENERGY=true
HTTP_ENABLE=true
HTTP_PORT=8765
MQTT_ENABLE=true
MQTT_HOST=127.0.0.1
MQTT_TOPIC_PREFIX=fhem/midea/portasplit
Optional direct auth:
MIDEA_ID=
MIDEA_TOKEN=
MIDEA_KEY=
Leave these empty unless you know what you are doing. Tokens and keys are credentials.
The bridge intentionally suppresses verbose msmart-ng logs unless LOG_LEVEL=DEBUG.
This also keeps expected offline periods quiet when the PortaSplit is unplugged. Midea V3
debug output may expose session keys or tokens.
Do not commit .env files with MIDEA_TOKEN, MIDEA_KEY, cloud account names, or passwords.
State:
fhem/midea/portasplit/availability online|offline
fhem/midea/portasplit/state JSON object
fhem/midea/portasplit/reading/... retained scalar readings
Commands:
fhem/midea/portasplit/set JSON object, e.g. {"power":"on","target_temperature":22}
fhem/midea/portasplit/set/power on|off
fhem/midea/portasplit/set/mode cool|heat|dry|fan_only|auto
Supported command fields:
power
target_temperature
mode
fan_speed
swing_mode
horizontal_swing_angle
vertical_swing_angle
cascade_mode
target_humidity
eco
ieco
turbo
boost
freeze_protection
sleep
smart_sleep
display_on
led
beep
sound
fahrenheit
follow_me
purifier
ion
out_silent
rate_select
gear
aux_mode
curl http://localhost:8765/health
curl http://localhost:8765/state
curl -X POST http://localhost:8765/set \
-H 'Content-Type: application/json' \
-d '{"target_temperature":22,"power":"on"}'For simple FHEM HTTPMOD set commands:
http://bridge-host:8765/set?power=on
http://bridge-host:8765/set?target_temperature=22
Preferred native module:
fhem/70_MideaPortaSplit.pm
deploy/rpi/fhem-module.cfg
The module includes FHEM commandref help with define, set, get, attribute, and reading descriptions.
Fallback examples are in:
fhem/mqtt2-example.cfg
fhem/httpmod-example.cfg
The native module is the preferred FHEM integration. HTTPMOD is useful for quick debugging, and MQTT2 is useful when you already run a broker.
python3 -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
pytest
ruff check .