Intelligent electrical load management for Home Assistant.
Load Manager is an AppDaemon application built to monitor household power demand, disconnect configured loads when consumption remains above safe thresholds, and restore them when sufficient power becomes available again.
| Field | Current state |
|---|---|
| Maturity | π‘ Active Development |
| Used in my homelab | β Yes |
| Recommended for production | β No |
| Setup difficulty | π΄ Advanced |
| Documentation | π‘ In progress |
| Current code version | 2.2 |
Note
Advanced setup: Load Manager requires a working AppDaemon and MQTT environment, manual YAML configuration, and careful testing of device priorities and power thresholds.
Warning
Load Manager can automatically turn configured devices off and on. It is not a replacement for certified electrical protections, circuit breakers or load-control hardware. Test every device carefully and never use it to control safety-critical equipment.
Load Manager was created for a real homelab requirement: preventing avoidable power-limit trips while keeping useful loads available whenever possible.
Instead of reacting to every short spike, it combines instantaneous power, a moving average, configurable timers and device priorities. Photovoltaic export is also handled correctly: negative readings remain visible for monitoring but are normalized to zero for load-control decisions.
The configured power sensor is evaluated every few seconds. Load Manager assigns the current demand to one of three energy zones:
| Zone | Default threshold | Signal used | Behaviour |
|---|---|---|---|
| π’ Green | Below 110% | Moving average | Keeps loads active and attempts safe restoration. |
| π‘ Yellow | 110%β133% | Moving average | Starts a persistence timer before disconnecting a load. |
| π΄ Red | Above 133% | Instant normalized power | Uses a short anti-spike timer, then disconnects a load quickly. |
With a 3000 W contract, the default thresholds are:
Green < 3300 W
Yellow 3300β3990 W
Red > 3990 W
A fixed 50 W hysteresis prevents rapid switching around zone boundaries.
- β‘ Three-zone load-control logic.
- π Moving-average filtering for transient changes.
- π΄ Faster response to critical instantaneous peaks.
- βοΈ Correct handling of negative photovoltaic readings.
- π Priority-based load disconnection.
- π LIFO restoration with exponential pause and final delay.
- π‘οΈ Support for
switch,climateandinput_booleanentities. - πΎ Persistent climate-mode restoration through
climate_states.json. - π± Configurable Home Assistant notifications.
- π‘ MQTT Discovery entities for monitoring and control.
- π§Ύ An MQTT event history containing the latest five actions.
- βοΈ YAML configuration without editing the Python modules.
LoadManager
βββ PowerMonitor Reads real, normalized and average power
βββ StateManager Selects the energy zone and manages timers
βββ DeviceManager Controls Home Assistant entities
βββ SwitchOffLogic Selects the next load by priority
βββ RestoreLogic Validates and schedules safe restoration
βββ NotificationManager Sends Home Assistant notifications
βββ EventLogger Publishes recent events through MQTT
The modules use relative Python imports and must be installed together inside one AppDaemon application directory.
- Home Assistant.
- AppDaemon 4.x, installed as an add-on or standalone.
- An MQTT broker reachable from AppDaemon.
- The MQTT integration enabled in Home Assistant.
- A Home Assistant sensor reporting current household power in watts.
Create the following structure inside the AppDaemon apps directory:
/config/apps/
βββ load_manager/
βββ __init__.py
βββ load_manager.py
βββ power_monitor.py
βββ state_manager.py
βββ switch_off_logic.py
βββ restore_logic.py
βββ device_manager.py
βββ notification_manager.py
βββ event_logger.py
βββ load_manager_config.yaml
Copy all Python modules from this repository into that directory. The __init__.py file is required because the application uses relative imports.
Add the application to apps.yaml:
load_manager:
module: load_manager.load_manager
class: LoadManagerLoad Manager expects an MQTT plugin using the appdaemon namespace. Adapt this example to your environment:
appdaemon:
plugins:
HASS:
type: hass
token: !env_var SUPERVISOR_TOKEN
MQTT:
type: mqtt
namespace: appdaemon
client_host: 192.0.2.10
client_port: 1883
client_user: "mqtt-user"
client_password: "change-me"
client_id: "appdaemon-load-manager"
subscribe_topics:
- "appdaemon/gestione_energia/#"Important
Never commit real MQTT credentials, Home Assistant tokens or private entity details to a public repository.
This file is intentionally excluded by .gitignore because every installation has different entities and may contain private infrastructure details.
power_sensor: "sensor.house_power"
contracted_power: 3000
timer_red_seconds: 10
timer_yellow_seconds: 100
delay_between_switchoff: 5
delay_restore_minutes: 1
exponential_pause_base: 5
loop_interval_seconds: 5
notification_service: "notify.notify"
devices:
- name: "Water heater"
entity_type: "switch"
switch: "switch.water_heater"
power_sensor: "sensor.water_heater_power"
estimated_power: 1300
priority: 10
- name: "Heat pump"
entity_type: "climate"
climate: "climate.heat_pump"
power_sensor: null
estimated_power:
heat: 950
cool: 1200
dry: 400
priority: 5Higher priority values are disconnected first: priority 10 is shed before priority 1.
Restart AppDaemon and inspect its logs. After approximately five seconds, MQTT Discovery should create the Load Manager entities in Home Assistant.
Start with non-critical test devices and conservative thresholds. Confirm both disconnection and restoration behaviour before adding more loads.
| Parameter | Default | Purpose |
|---|---|---|
power_sensor |
Required | Home Assistant power sensor entity ID. |
contracted_power |
Required | Contracted power in watts. |
timer_red_seconds |
10 |
Persistence time for the red zone. |
timer_yellow_seconds |
Required | Persistence time for the yellow zone. |
delay_between_switchoff |
5 |
Minimum seconds between two disconnections. |
delay_restore_minutes |
1 |
Final delay after restoration conditions become valid. |
exponential_pause_base |
5 |
Base seconds for repeated-disconnection backoff. |
loop_interval_seconds |
5 |
Main evaluation interval. |
notification_service |
notify.notify |
Home Assistant notification service. |
devices |
[] |
Devices managed by the application. |
Supported entity_type values are switch, climate and input_boolean.
MQTT Discovery groups the following entities under the Gestione Energia device:
| Entity | Purpose |
|---|---|
switch.gestione_energia_automazione_carichi |
Enables or disables automatic load management. |
sensor.gestione_energia_stato_carico |
Reports the current zone and power state. |
sensor.gestione_energia_potenza_media_mobile |
Reports normalized moving-average power. |
sensor.gestione_energia_potenza_reale |
Reports the original reading, including photovoltaic export. |
sensor.gestione_energia_registro_eventi |
Shows the latest five disconnection and restoration events. |
State topic: appdaemon/gestione_energia/state
Command topic: appdaemon/gestione_energia/cmd/switch
The internal MQTT identifiers remain in Italian for compatibility with existing installations.
- There is currently no automated test suite or published compatibility matrix.
- The 110% and 133% thresholds and the
50 Whysteresis are defined in code rather than YAML. - If the main power sensor becomes unavailable, the monitor keeps using its last valid reading instead of entering a dedicated fail-safe state.
- The list of loads disconnected by the application is stored in memory and is lost when AppDaemon restarts.
- Climate modes are persisted, but event history and restoration tracking reset on restart.
- MQTT device names, entity identifiers and topics currently use the original Italian naming.
These limitations are the main reason the project is not currently recommended for production use.
MQTT entities do not appear in Home Assistant
Confirm that the MQTT integration is active, the broker is reachable from AppDaemon and the appdaemon namespace is configured. Discovery messages are published approximately five seconds after initialization.
AppDaemon cannot import load_manager.load_manager
Verify the directory name, the apps.yaml module path and the presence of __init__.py.
Power remains at zero or does not update
Verify power_sensor and confirm that the Home Assistant entity returns a numeric value instead of unknown or unavailable.
A climate entity restores the wrong mode
Confirm that AppDaemon can write climate_states.json inside the application directory.
Released under the MIT License.
