Mastering MikroTik Integration: Automating Network Policies & PoE with Home Assistant

Represent Mastering MikroTik Integration: Automating Network Policies & PoE with Home Assistant article
3m read

Intro

Your smart home isn't truly smart until its network infrastructure actively participates in your automations. MikroTik routers offer powerful control via their RouterOS API, allowing you to integrate deep network management directly into Home Assistant. This guide focuses on practical, actionable steps to automate Power over Ethernet (PoE) ports and dynamic firewall rules, turning your network into a responsive extension of your smart home.

Step-by-Step Setup: PoE Control

1. Prepare Your MikroTik Router for API Access

First, enable the API-SSL service and create a dedicated, restricted user for Home Assistant.

  1. Enable API-SSL Service: In WinBox or WebFig, go to IP > Services and ensure api-ssl is enabled (default port: 8729).
  2. Create API User: Go to System > Users. Add a new user (e.g., ha_api_user) with a strong password. Create a new group (e.g., ha_api_group) with read, write, policy, test permissions. Restrict Allowed From to your Home Assistant's IP.
/user group add name=ha_api_group policy=read,write,policy,test
/user add name=ha_api_user group=ha_api_group password="YOUR_SECURE_PASSWORD" address="YOUR_HOME_ASSISTANT_IP"

2. Configure Home Assistant `shell_command` for PoE Toggle

We'll use a small Python script executed via Home Assistant's shell_command to interact with MikroTik's API. Install the routeros_api library in your Home Assistant environment (e.g., pip install routeros_api if using a container/venv, or via a custom add-on). Create config/scripts/mikrotik_poe_toggle.py:

import routeros_api, sys

HOST = sys.argv[3]; USER = sys.argv[4]; PASS = sys.argv[5]; PORT = 8729
action = sys.argv[1]; port = sys.argv[2]

try:
    api = routeros_api.RouterOsApi(HOST, username=USER, password=PASS, port=PORT, use_ssl=True)
    interfaces = api.get_resource('/interface/ethernet')
    target_iface = next((iface for iface in interfaces.get() if iface.get('name') == port), None)
    if target_iface:
        interfaces.set(id=target_iface['.id'], 'poe-out'='auto' if action == 'enable' else 'off')
        print(f"PoE on {port} {action}d.")
    else: print(f"Error: Interface {port} not found.")
    api.disconnect()
except Exception as e: print(f"MikroTik API Error: {e}"); sys.exit(1)

Then, configure your configuration.yaml to call this script, passing secrets securely:

# configuration.yaml
shell_command:
  mikrotik_poe_ether2_on: "python3 /config/scripts/mikrotik_poe_toggle.py enable ether2 {{ secrets.mikrotik_host }} {{ secrets.mikrotik_username }} {{ secrets.mikrotik_password }}"
  mikrotik_poe_ether2_off: "python3 /config/scripts/mikrotik_poe_toggle.py disable ether2 {{ secrets.mikrotik_host }} {{ secrets.mikrotik_username }} {{ secrets.mikrotik_password }}"

# secrets.yaml
mikrotik_host: "192.168.1.1"
mikrotik_username: "ha_api_user"
mikrotik_password: "YOUR_SECURE_PASSWORD"

3. Create Sensors to Monitor PoE State

Use a command_line sensor to retrieve the PoE status:

# config/scripts/mikrotik_get_poe_status.py
import routeros_api, sys, json

HOST = sys.argv[2]; USER = sys.argv[3]; PASS = sys.argv[4]; PORT = 8729
port = sys.argv[1]

try:
    api = routeros_api.RouterOsApi(HOST, username=USER, password=PASS, port=PORT, use_ssl=True)
    interfaces = api.get_resource('/interface/ethernet')
    target_iface = next((iface for iface in interfaces.get() if iface.get('name') == port), None)
    if target_iface: print(json.dumps({"poe_status": target_iface.get('poe-out', 'off')}))
    else: print(json.dumps({"error": f"Interface {port} not found."})); sys.exit(1)
    api.disconnect()
except Exception as e: print(json.dumps({"error": f"MikroTik API Error: {e}"})); sys.exit(1)
# configuration.yaml
sensor:
  - platform: command_line
    name: "MikroTik Ether2 PoE Status"
    command: "python3 /config/scripts/mikrotik_get_poe_status.py ether2 {{ secrets.mikrotik_host }} {{ secrets.mikrotik_username }} {{ secrets.mikrotik_password }}"
    scan_interval: 30
    value_template: "{{ value_json.poe_status }}"

Troubleshooting Common Issues

  • API Connection/Auth: Check MikroTik firewall (port 8729 from HA IP), API service enabled, user credentials, and permissions.
  • `routeros_api` Not Found: Install library in HA's Python environment (e.g., pip install routeros_api).
  • Script Errors: Check HA logs for script output; ensure scripts are executable (chmod +x).

Advanced Config: Dynamic Guest Wi-Fi

Extend this by controlling a guest Wi-Fi interface. Create config/scripts/mikrotik_wifi_toggle.py:

import routeros_api, sys

HOST = sys.argv[3]; USER = sys.argv[4]; PASS = sys.argv[5]; PORT = 8729
action = sys.argv[1]; iface_name = sys.argv[2]

try:
    api = routeros_api.RouterOsApi(HOST, username=USER, password=PASS, port=PORT, use_ssl=True)
    wireless_ifaces = api.get_resource('/interface/wireless')
    target_iface = next((w for w in wireless_ifaces.get() if w.get('name') == iface_name), None)
    if target_iface:
        wireless_ifaces.set(id=target_iface['.id'], disabled='no' if action == 'enable' else 'yes')
        print(f"Guest Wi-Fi {iface_name} {action}d.")
    else: print(f"Error: Wireless interface {iface_name} not found.")
    api.disconnect()
except Exception as e: print(f"MikroTik API Error: {e}"); sys.exit(1)

In configuration.yaml:

input_boolean:
  guest_wifi_active:
    name: Guest Wi-Fi Network
    initial: off
    icon: mdi:wifi

shell_command:
  mikrotik_guest_wifi_toggle_on: "python3 /config/scripts/mikrotik_wifi_toggle.py enable wlan2 {{ secrets.mikrotik_host }} {{ secrets.mikrotik_username }} {{ secrets.mikrotik_password }}"
  mikrotik_guest_wifi_toggle_off: "python3 /config/scripts/mikrotik_wifi_toggle.py disable wlan2 {{ secrets.mikrotik_host }} {{ secrets.mikrotik_username }} {{ secrets.mikrotik_password }}"

automation:
  - alias: 'Toggle Guest Wi-Fi via MikroTik'
    trigger: { platform: state, entity_id: input_boolean.guest_wifi_active }
    action:
      - service: "shell_command.mikrotik_guest_wifi_toggle_{{ states('input_boolean.guest_wifi_active') }}"

Real-World Example: Privacy-Aware Camera Power

Combine these. If a motion sensor detects movement in a private area (e.g., binary_sensor.living_room_motion) while residents are home (binary_sensor.home_occupancy), automatically disable the camera's PoE. Re-enable when away or no motion for a period.

automation:
  - alias: "Living Room Camera Privacy - Disable PoE"
    trigger: { platform: state, entity_id: binary_sensor.living_room_motion, to: 'on' }
    condition: { condition: state, entity_id: binary_sensor.home_occupancy, state: 'on' }
    action: { service: shell_command.mikrotik_poe_ether2_off }

  - alias: "Living Room Camera Re-enable PoE"
    trigger: { platform: state, entity_id: binary_sensor.home_occupancy, to: 'off' }
    action: { service: shell_command.mikrotik_poe_ether2_on }

Best Practices & Wrap-up

Prioritize security: use a dedicated API user with minimal permissions, restrict by IP, and always use API-SSL. Centralize sensitive credentials using Home Assistant Secrets. Document your MikroTik configs and HA automations. By integrating your network, you gain granular control, enhancing your smart home's security, privacy, and responsiveness.

Avatar picture of NGC 224
Written by:

NGC 224

Author bio: DIY Smart Home Creator

There are no comments yet
loading...