Back to all posts

2026-03-30

home automation part 4

electronics · network · diary

poor mans presence sensor

Today i tackled the classic automation use-case to turn on and off stuff depending on the state of some presence sensors. This in my experience is what makes up the majority of the ROI of a automation system. Granted for now it’s just the workbench, a light and some screens, so it does not cut down on wasted energy that much, the real magic is when we factor in HVAC and window sensors, but i’m very much not there yet. On that note let me quickly write down what i did today: - Made esphome work on the cheap esp32-c3 devboards (unrelated) - I extracted my IRK code from my phone - I integrated my phone as a private BLE device - Using Bermuda i can now know the distance between the server (in my room) and my phone - Made a helper template switch for manual operation of the system - Interacting with my 3d printer to avoid removing power while printing - Using node-RED i can then implement the logic for sensing and actuation

ESPHome

You can read this ESPHome part 1 to check out what was wrong

IRK

I was able to use ESPHome and a specific irk extraction firmware to get the irk code of my phone, specifically used Derek Seaman irk-capture firmware, very nice, worked nicely first try, well done mr. Seaman.

private BLE device

Using that IRK i am just able to integrate it as a private BLE device on stock hass

Bermuda

This is where it gets interesting. Using HACS i am able to install Bermuda that instantly gets the private BLE device and have a fast refresh distance entity for my phone

manual override

Just a basic switch template: Pasted image 20260330233747.png This is basically acts as a global variable between node-RED and home assistant

3d printer

The 3d printer setup actually is quite convoluted, and it also does introduce a circular usage dependency. That’s the reason we are going to look at node-RED in here: Pasted image 20260330234517.png (Yes i know i am using GET) This just set global variables based on the 3d printer state, where i defined macros to actually use these endpoint using gcode shell commands and curl:

[gcode_shell_command _notify_printing]
command: curl -s "http://192.168.1.22:1880/printer/printing"
timeout: 10.
verbose: False

[gcode_shell_command _notify_done]
command: curl -s "http://192.168.1.22:1880/printer/done"
timeout: 10.
verbose: False

[gcode_shell_command _poweroff_via_nodered]
command: curl -s "http://192.168.1.22:1880/printer/off"
timeout: 10.
verbose: False

[gcode_macro _AUTO_POWEROFF]
description: Stores whether printer should power off after print
variable_enabled: 0
gcode:
    RESPOND MSG="Auto poweroff is {'ON' if printer['gcode_macro _AUTO_POWEROFF'].enabled|int == 1 else 'OFF'}"

[gcode_macro _AUTO_POWEROFF_ON]
description: Enable auto poweroff at end of print
gcode:
    SET_GCODE_VARIABLE MACRO=_AUTO_POWEROFF VARIABLE=enabled VALUE=1
    RESPOND MSG="Auto poweroff enabled"

[gcode_macro _AUTO_POWEROFF_OFF]
description: Disable auto poweroff at end of print
gcode:
    SET_GCODE_VARIABLE MACRO=_AUTO_POWEROFF VARIABLE=enabled VALUE=0
    RESPOND MSG="Auto poweroff disabled"
I call these comands on the standard print end and start macros
[gcode_macro START_PRINT]
gcode:
  {% set BED = params.VALUE|default(60)|float %}
  RUN_SHELL_COMMAND CMD=_notify_printing
  M190 S{BED}

  G90 ; use absolute coordinates
  M83 ; extruder relative mode
  G4 S30 ; allow partial nozzle warmup
  {% if printer.toolhead.homed_axes != "xyz" %}
    G28
  {% endif %}
  BED_MESH_CALIBRATE
  SMART_PARK

[gcode_macro END_PRINT]
gcode:
    # Turn off bed, extruder, and fan
    M140 S0
    M104 S0
    M106 S0
    # Move nozzle away from print while retracting
    G91
    G1 X-2 Y-2 E-3 F3000
    # Raise nozzle by 10mm
    G1 Z10 F3000
    G90
    G1 Y200
    RUN_SHELL_COMMAND CMD=_notify_done
    {% if printer["gcode_macro _AUTO_POWEROFF"].enabled|int == 1 %}
      RESPOND MSG="Auto poweroff is enabled, shutting down soon"
      RUN_SHELL_COMMAND CMD=_poweroff_via_nodered
    {% else %}
      RESPOND MSG="Auto poweroff is disabled"
    {% endif %}
Here is where thing get weird, the “turn off when done printing” logic sits on the printer firmware, since that’s the best place to determine when a print is done, but the presence logic sits on node-RED, so the printer notifies the state to it, hence the circular dependency (i’m ok with this since it just reflects on the added feature and not on both systems functionalities).

Node-RED logic

Pasted image 20260330235503.png This is the flow that handles presence, let’s go over it from left to right, i have a inject node that triggers every 1.5 sec. Then i extract the state of the Bermuda entry and feed it to this function block:

// output 1 = inside -> ON
// output 2 = outside -> OFF
// output 3 = lost after previously inside -> manual override ON

let raw = msg.payload;
let distance = Number(raw);
let isNumeric = Number.isFinite(distance);

let currentMode;
if (isNumeric) {
    currentMode = distance < 5 ? "inside" : "outside";
} else {
    currentMode = "lost";
}

let previousMode = flow.get("bleMode") || null;

// always update stored mode
flow.set("bleMode", currentMode);

// do nothing if mode did not change
if (currentMode === previousMode) {
    return null;
}

// decide action only on transitions
if (currentMode === "inside") {
    return [msg, null, null];
}

if (currentMode === "outside") {
    return [null, msg, null];
}

// currentMode === "lost"
if (previousMode === "inside") {
    return [null, null, msg];
}

// lost after outside/lost -> normal off or nothing
return [null, msg, null];

This just check if the previous state was inside the range and the current state is disconnected it false it goes into a fault state (because it means my phone died inside the room) and sets the system to manual, other wise it changes the states of the devices according to their logic: - The screens and light just turn off - The printer is a bit more convoluted - If it is not printing it turns off - If it is printing it calls the macro that then will call back to node red once it is done printing to turn itself off

the end

This works for me quite nicely and the only edge case i have not covered is if my phone runs out of battery while outside the range of the ble adapter of the server, in that case when i come home i have no way (beside using another device) to turn everything back on. Ofc i can unpower the relay box since everything is NC i will get power back to the printer and my PC, and also my main light is unsmart so it will always work :3. I am thinking to make a override physical switch to set everything into manual mode and then turn on everything for good measure using ESPHome.

That is it for today, thank you for the read and if you have any questions remember that you can mail me at fippolo@r4inbow.ddns.net , have a nice day :)