Load Shedding Over Local Network Messaging Lnm And Ev Load Balancing

37c430cc-174d-4344-a4f0-b7d003f781ed.png

At 18:30 the oven, the water heater and the car charger all start within ten minutes, and the main fuse trips. With Local Network Messaging (LNM) in Shelly firmware 2.0, a Shelly Pro 3EM publishes every new house-load reading once to all listeners on the local network, and each Shelly Pro CB drops its own circuit by priority. A TopAC EV charger turns its current down at the same time, so the essentials stay on and the car keeps charging.

Overview

On a 3 x 25 A connection the main fuse doesn't care which appliance pushed it over. Once it trips, everything is off, including the fridge and the router. This guide keeps the total under the limit with two mechanisms that read the same Shelly Pro 3EM at the main incomer.

LNM in one paragraph. Local Network Messaging lets Shelly devices talk to each other directly over UDP multicast on your local network. One device publishes (TX) the status of selected components to a group address such as 239.255.0.1:3333. Every device that listens (RX) on the same address in the same network segment receives each update, without the cloud and without knowing the sender's IP address. Here the Pro 3EM publishes its em:0 power reading, and each Pro CB listens.

Part A, load shedding over LNM. Each Prio 2 and Prio 3 Pro CB runs a ready-made script that reads the total active power from the LNM messages. The Prio 3 breaker switches off above 2 kW, the Prio 2 breaker above 3 kW. Prio 1 is never touched. Each breaker decides on its own, so adding a circuit means setting up one more breaker, with nothing to change on the meter. Part A runs entirely on the local network, with no cloud and no polling.

Part B, dynamic load balancing. The TopAC portable EV charger EVE01-11R reads the same Pro 3EM through its built-in Auto balance function. It adjusts its charging current between 6 A and 16 A so the total stays under the current limit you set, with a 2 A reserve kept in hand.

Important scope note: load shedding is a comfort layer on top of protection, not a replacement for it. The Pro CB still trips by itself on overcurrent and short circuit. A Pro CB can be switched on remotely only if it was switched off remotely: after a real trip, after a manual off with the lever, or with the front safety switch locked, the script leaves it off. The Pro CB is rated for less than 1 remote toggle per minute, so the script keeps every breaker off for at least 5 minutes and on for at least 1 minute. The 2 kW and 3 kW values are examples; size yours from your main fuse rating. If LNM messages stop arriving, the breakers keep their current state and the main fuse is the only protection left. The LNM API is currently published as a preview and may change between firmware releases, so check the LNM documentation after updates.

Prerequisites

  • Shelly Pro 3EM in its default three-phase profile (the profile that reports em:0), with its current clamps on L1, L2 and L3 at the main incomer (after the utility meter), so it measures the whole house.

  • Shelly Pro CB, one per Prio 2 and Prio 3 circuit: Pro 1CB to Pro 4CB, depending on the number of poles and whether the neutral must be switched, with a rated current that matches the cable. The Prio 1 circuit can sit on a Pro CB too, for monitoring and trip notifications; it gets no script.

  • Firmware 2.0.1 or newer on the Pro 3EM and on every Pro CB that takes part. LNM arrived in 2.0.0, and 2.0.1 adds a Pro CB fix that prevents unexpected automatic reclosure.

  • TopAC portable EV charger EVE01-11R on its own CEE 16 A three-phase socket, protected by a 3-pole 20 A type B or C breaker, as the charger's documentation specifies. Its built-in leakage protection is rated Type A (30 mA AC) + 6 mA DC; add the upstream residual-current protection your local wiring rules require.

  • All devices in the same network segment, with client (AP) isolation off. If your switches use IGMP snooping, the network needs an IGMP querier, or multicast won't be delivered.

  • Shelly Smart Control app, plus each device's local web interface for the scripts.

  • Installation of Shelly Pro 3EM must be performed by a qualified electrician (Shelly Pro 3EM user and safety guide).

  • Installation of Shelly Pro CB must be performed by a qualified electrician (Shelly Pro CBs user and safety guide).

Steps

Part A: Load shedding over LNM with Shelly Pro CB

  1. Sort the circuits into three priorities. Prio 1: what must never go off, such as the fridge, lighting, network and heating controls. Prio 2: large loads that can pause for a few minutes. Prio 3: loads that can wait longest, such as a water heater or a towel rail.

  2. On the Prio 2 and Prio 3 Pro CBs, check that the front safety switch is unlocked. When it is locked, the breaker ignores every remote command, including its own script.

  3. Write down what each Prio 2 and Prio 3 circuit draws when it is running: switch its load on and read the change in the Pro 3EM total. You need this number in step 6.

  4. Pick one group address for the whole installation, for example 239.255.0.1:3333. Use the 239.255.x.y range and a port between 1024 and 65535. Every device in this setup uses exactly the same address and port.

  5. Set up the Pro 3EM as the publisher. In its local web interface, open Scripts, create a script named lnm-publisher, paste Script 1 from the block below, set ADDR to your group address and press Start. It creates the LNM instance, publishes only em:0 and then stops itself. The console prints LNM TX on lnm:200 ready. You run it once; the setting stays after a reboot.

Script 1: lnm-publisher (Shelly Pro 3EM, run once)
JavaScript
// LNM publisher setup for a Shelly Pro 3EM (firmware 2.0.1 or newer). // Run once: creates the LNM instance, publishes em:0 to the group, then stops itself. let ADDR = "239.255.0.1:3333"; // group address, the same on every device let LNM_ID = 200; // instance id this script looks for first function done(msg) { print(msg); Shelly.call("Script.Stop", { id: Shelly.getCurrentScriptId() }); } function enableTx(id) { Shelly.call("LNM.SetConfig", { id: id, config: { tx: { enable: true, components: ["em:0"] } } }, function (r, err, msg) { done(err === 0 ? "LNM TX on lnm:" + id + " ready" : "LNM.SetConfig failed: " + msg); }); } Shelly.call("LNM.GetConfig", { id: LNM_ID }, function (cfg, err) { if (err === 0) { if (cfg.addr !== ADDR) { done("lnm:" + LNM_ID + " already uses " + cfg.addr + ", expected " + ADDR); return; } enableTx(LNM_ID); return; } Shelly.call("LNM.Create", { config: { addr: ADDR } }, function (r, err2, msg2) { if (err2 !== 0) { done("LNM.Create failed: " + msg2); return; } enableTx(r.id); }); }); 
  1. Set up each Prio 2 and Prio 3 Pro CB as a listener. Open Scripts, create a script named lnm-load-shedding, paste Script 2 from the block below and set the values in CFG from the table. Set restore_w to shed_w minus the load from step 3, minus a margin of at least 10% of shed_w. Save, press Start, and switch on Run on startup. The script joins the LNM group by itself and remembers across reboots that it switched the breaker off. The console prints Listening on lnm:200.

Value in CFG

Prio 3 breaker

Prio 2 breaker

Why the two differ

shed_w

2000 W

3000 W

Prio 3 goes first

over_s

10 s

30 s

On a sudden jump, Prio 3 sheds first and Prio 2 only if the load is still too high

restore_w

Example: 400 W (1.5 kW heater)

Example: 1000 W

From step 3: shed_w minus circuit load minus margin

under_s

120 s

60 s

Prio 2 returns first, Prio 3 after it

min_off_s

360 s

300 s

Keeps both from returning at the same moment

min_on_s

60 s

60 s

Pro CB limit: under 1 remote toggle per minute

Script 2: lnm-load-shedding (each Prio 2 and Prio 3 Shelly Pro CB)
JavaScript
// LNM load shedding for a Shelly Pro CB (firmware 2.0.1 or newer). // Joins the LNM group, listens to the Pro 3EM's em:0 status and switches this breaker by priority. let CFG = { addr: "239.255.0.1:3333", // LNM group address, the same as on the Pro 3EM meter_id: "", // optional: Pro 3EM Device ID; "" accepts any sender in the group shed_w: 2000, // switch off when total active power (W) stays above this... over_s: 10, // ...for this many seconds restore_w: 400, // switch back on when total active power (W) stays below this... under_s: 120, // ...for this many seconds min_off_s: 360, // stay off at least this many seconds min_on_s: 60 // stay on at least this many seconds (Pro CB: under 1 remote toggle/min) }; let LNM_ID = 200; let KVS_KEY = "lnm_shed"; // remembers across reboots that THIS script switched the breaker off let shedByUs = false; // true only while this script holds the breaker off let busy = false; // a CB.Set call is in progress let offAt = 0, onAt = 0, lastTry = -60, lastMsg = 0; let overSince = -1, underSince = -1; function up() { return Shelly.getComponentStatus("sys").uptime; } function save(v) { Shelly.call("KVS.Set", { key: KVS_KEY, value: v ? "1" : "0" }); } function switchCb(on) { busy = true; lastTry = up(); Shelly.call("CB.Set", { id: 0, output: on }, function (r, err, msg) { busy = false; if (err !== 0) { print("CB.Set", on ? "on" : "off", "failed:", msg); return; } shedByUs = !on; save(shedByUs); if (on) { onAt = up(); print("Restored"); } else { offAt = up(); print("Shed"); } }); } Shelly.addEventHandler(function (ev) { if (ev.name !== "lnm" || !ev.info || ev.info.event !== "rx" || busy) return; if (CFG.meter_id !== "" && ev.info.device !== CFG.meter_id) return; let st = ev.info.status; if (!st || !st["em:0"]) return; // message without the meter reading let p = st["em:0"].total_act_power; // W, all three phases together let now = up(); if (now - lastMsg > 30) { overSince = -1; underSince = -1; } // gap in messages: restart timers lastMsg = now; let on = Shelly.getComponentStatus("cb", 0).output; if (on) { if (shedByUs) { shedByUs = false; save(false); onAt = now; } // switched on by someone else if (p > CFG.shed_w) { if (overSince < 0) overSince = now; if (now - overSince >= CFG.over_s && now - onAt >= CFG.min_on_s) { overSince = -1; switchCb(false); } } else { overSince = -1; } } else if (shedByUs) { if (p < CFG.restore_w) { if (underSince < 0) underSince = now; if (now - underSince >= CFG.under_s && now - offAt >= CFG.min_off_s && now - lastTry >= 60) { underSince = -1; switchCb(true); } } else { underSince = -1; } } // Breaker off but not by this script (tripped, lever, safety switch): leave it alone. }); function enableRx(id) { Shelly.call("LNM.SetConfig", { id: id, config: { rx: { enable: true } } }, function (r, err, msg) { print(err === 0 ? "Listening on lnm:" + id + " " + CFG.addr : "LNM.SetConfig failed: " + msg); }); } function setupLnm() { Shelly.call("LNM.GetConfig", { id: LNM_ID }, function (cfg, err) { if (err === 0) { if (cfg.addr !== CFG.addr) { print("lnm:" + LNM_ID + " uses " + cfg.addr + ", expected " + CFG.addr); return; } enableRx(LNM_ID); return; } Shelly.call("LNM.Create", { config: { addr: CFG.addr } }, function (r, err2, msg2) { if (err2 !== 0) { print("LNM.Create failed:", msg2); return; } enableRx(r.id); }); }); } // Start: restore the shed state after a reboot (the off time counts again from now), then join the group. Shelly.call("KVS.Get", { key: KVS_KEY }, function (r, err) { if (err === 0 && r && r.value === "1") { shedByUs = true; offAt = up(); print("Shed state restored after restart"); } setupLnm(); }); 
  1. Check that the messages arrive. On a Pro CB, open http:///rpc/LNM.GetStatus?id=200 in a browser on the same network. stats.rx_msgs should keep rising while the Pro 3EM reading changes. If it stays at 0, see Troubleshooting.

  2. Test it. Switch on a known load that takes the total above 2 kW. After about 10 seconds the Prio 3 lever drops, its mechanical state indicator turns green and its script console prints Shed. Switch the load off. Prio 3 returns once it has been off for at least 6 minutes and the total has stayed below its restore_w for 2 minutes.

Part B: Dynamic load balancing with the TopAC EV charger

  1. Add the charger to Shelly Smart Control and update the firmware on both the charger and the Pro 3EM.

  2. In the charger's settings, enable Auto balance, select the Pro 3EM as the energy meter and set the Total current limit. "Total" means house plus car together. Enter your main fuse rating per phase, for example 25 A on a 3 x 25 A supply, not 75 A. The charger keeps 2 A below this value as a safety reserve.

  3. Leave Auto balance in its default mode when the Pro 3EM clamps sit at the main incomer. In this mode the charger is part of the measured system, and it subtracts its own measured current from the Pro 3EM reading so the car isn't counted twice.

  4. Check the configuration over the local API: open http:///rpc/Service.GetConfig?id=0. Under auto_balance you should see enable: true, em_ip set to the Pro 3EM address, max_current set to your limit and exclude_self_current: true (the subtraction from step 3).

  5. Test it. Start charging at 16 A, then switch on the oven and a kettle. The charging current shown in the app drops, and ramps back up once they switch off.

a180c9a3-d9ac-4ce7-b2cb-11e0a2fcbe71.png

Troubleshooting

  • rx_msgs stays at 0 on a Pro CB → check that the address and port match exactly on all devices, that they are in one network segment, that client (AP) isolation is off, and that an IGMP querier is present if IGMP snooping is on.

  • A Prio circuit switches off and on again and again → its restore_w is too close to shed_w; lower it by at least that circuit's own load. If it stays off instead, check whether it tripped, was switched off with the lever, or has its safety switch locked, and reset it by hand.

  • Charging current ignores the house load → check em_ip in Service.GetConfig, that the Pro 3EM answers on that IP, and the firmware on both devices.

0c8b4145-8f62-4e4b-84b5-66abbb40ca84.png

Tips

  • Using both parts on one supply: at its 6 A minimum, a three-phase car draws about 4.1 kW (3 x 6 A x 230 V). That is above both example limits, so every charging session would shed Prio 2 and Prio 3, and they stay off for as long as the car fills the remaining headroom. Size the shed limits from the main fuse instead (3 x 25 A at 230 V is about 17 kW), and keep restore_w above what the house draws while the car charges at its limit.

  • The script compares total power across all three phases, while the main fuse protects each phase separately. If one heavy load sits on a single phase, compare that phase's power (a_act_power, b_act_power or c_act_power in em:0) instead of total_act_power.

  • Every remote switch-off counts as an electrical cycle, and the Pro CB is rated for more than 6,000. Watch total_cycles in CB.GetStatus. If a circuit sheds many times a day, raise min_off_s or the shed limit.

  • If another Shelly device also publishes em:0 in the same group, fill in meter_id with the Pro 3EM's Device ID (Settings, Device information in the app) so each breaker listens only to the right meter.

  • To add another shed circuit later, set up only the new breaker with Script 2 and its own values. The Pro 3EM and the other breakers stay as they are.

Devices Used

  • Shelly Pro 3EM

  • Shelly Pro CB (Pro 1CB to Pro 4CB)

  • TopAC portable EV charger EVE01-11R (Powered by Shelly)

Documentation & References

  • Shelly Pro CBs — remote switch-on rules, safety switch, the under-1-per-minute toggle limit and 6,000-cycle rating; useful for min_off_s, min_on_s and Troubleshooting.

  • TopAC portable EV charger EVE01-11R — Auto balance modes, Total current limit with 2 A reserve, 6–16 A range and supply requirements; useful for Part B.

  • LNM Components — LNM configuration fields, the rx event Script 2 listens to and the LNM.GetStatus counters; useful for Part A, steps 5–7.

Why It's Worth It

The meter publishes each reading once, and every breaker acts on it locally, with no cloud, no polling and no breaker IP addresses to maintain. The fridge and the lights stay on, and the car charges at whatever current the house can spare instead of tripping the main fuse.

5d79e219-32b0-4b5e-b7bd-6ee652be3eb4.png

Conclusion

The Pro 3EM now publishes the house load over LNM, and each priority breaker acts on it by itself with a ready-made script. Low-priority circuits drop in a fixed order and come back when there is room, and the car charges at whatever current is left.

YAML
--- vertical: home-energy-management concept: lnm-load-shedding-ev-load-balancing complexity: advanced devices: [Shelly Pro 3EM, Shelly Pro CB, TopAC portable EV charger EVE01-11R] ---