Using PiKVM With HomeAssistant

Hello, all,

I’ve spent some time trying to figure it out, and got it working. I haven’t seen anyone else talk about getting HomeAssistant working with PiKVM, so figured I’d post here about it. I’m including the information I’ve got for my particular configuration - this isn’t as straightforward as it could be, as I am using several different pieces to attain the specific behavior that I was aiming for. My hope is that, while this exact scenario will likely not apply to many other people, the information here will give you an idea of how your configuration might need to be set up.

This document gives the information on how to get get and post information from/to PiKVM: HTTP API reference - PiKVM Handbook

Initially, I was planning on using the power LED status made available through https:///api/atx to determine the state of the computer. However, this would be unreliable when my computer is asleep due to the light flashing on-and-off, so I’ve opted for basing the status on how much power a smart plug my computer is connected to sees being pulled (I chose 30w as the threshold).

I also didn’t want to have it holding the power button to shut it down. I also usually have my Windows Power Settings set to put my computer to sleep when I push the power button, so I am using the HASS.Agent to handle gracefully shutting down my computer: GitHub - LAB02-Research/HASS.Agent: Windows-based client for Home Assistant. Provides notifications, quick actions, commands, sensors and more..

To summarize, these are the pieces I’ve got:

  1. A power adapter that measures how much power it’s pulling, to determine whether it’s on or off.
  2. A PiKVM connected to the power pins on the motherboard, to simulate pushing the power button to turn it on
  3. A piece of software running as a service that integrates with my home automation system to run the “shutdown” command when I want to power it off.
  4. To pull all these pieces together, and allow me to manage them verbally with Google Home, I am using an input_boolean helper.

If you want to avoid a smart plug, and don’t want to use the HASS.Agent, you can do these:
Smart plug replacement: Set up a script to pull the power LED state from https:///api/atx. I didn’t get that far into setting this up, so haven’t figured that out. This would be finicky if you were to put your computer to sleep, though, as the power light (at least on mine) flashes off and on.
HASS.Agent replacement: Have the action to shut your computer down be a short power-button press from the PiKVM, and set your Windows Power Options “When I press the power button” setting configured for “shut down.”

For authentication with the PiKVM, I opted for X-headers authentication method, which requires you put a username and password into the curl command. Session-based cookie authentication might be possible, but I have never been able to wrap my head around that kind of thing for automations. I was also unable to figure out how to insert my password into the middle of the command as a variable or a !secret call-type-thing (not sure what the term would be), but it didn’t appear possible. Instead, I put the whole command into the secrets.yaml file, and am just calling the whole command from the configuration.yaml. If you don’t care about having a password in your configuration.yaml, you could replace the “!secret pikvm-short_press” with the command in the secrets.yaml, and drop the secrets.yaml part.

To test the curl requests manually to make sure they will work, open up Command Prompt on Windows, and enter the following (replace “username” and “password” with a username/password from PiKVM, and “” with your PiKVM’s IP).

curl -k -H X-KVMD-User:username -H X-KVMD-Passwd:password https://<pikvm-ip>/api/info

Once you’ve confirmed that’s working, you can then put the commands into your configuration. I could not find a way to insert the password as a variable from the secrets.yaml file, so opted to put the whole command in the secrets.yaml file and just call it from configuration.yaml. If you don’t care about a password being in your configuration.yaml, you can just replace “!secret pikvm-short_press” with the command that I reference being in the secrets.yaml file.

Configuration.yaml:

# Pikvm-desktop
shell_command:
    desktop_pc_short_press: !secret pikvm-short_press

Secrets.yaml (replace “username” and “password” with a user account for your pikvm):

pikvm-short_press: "curl -X POST -k -H X-KVMD-User:username -H X-KVMD-Passwd:password https://<pikvm-ip>/api/atx/click?button=power"

The automation (screenshot first to visually show how it’s laid out):

So I don’t have a bunch of automations set up, I’ve got all 5 triggers and all 5 associated actions in one automation. I associate the actions back to the triggers by using the “If-Then” action type, and using the “If” as “Triggered By,” and enter in the Trigger ID of the trigger I want to associate it with.

The top two triggers/actions handle watching sensor.desktop_pc_power_power (smart plug) to see when it rises above or drops below 30w of power usage, then toggling switching input_boolean.computer helper to “on” or “off” as appropriate.

The third trigger/action handles checking the current power usage of the sensor.desktop_pc_power_power (smart plug) every 10 seconds, to automatically reset the Computer input_boolean healper (input_boolean.computer) to its current power state. This is because its state will otherwise only change when the power usage crosses the 30w threshold or I manually toggle it. So if I tell it to turn the computer on or off, and something prevents it from doing so, there is no way to know just by looking at the current status of the input_boolean.computer. This third trigger/action will sync the computers actual status over to it every 10 seconds.

The last two triggers/actions handle what happens when I manually toggle the input_boolean.computer (either by means of toggling the switch via the GUI, or telling my Google Home to turn it off/on). This is where it is configured to send the shutdown/startup commands.

Now the YAML (I entirely made this in the webGUI, so this type of configuration doesn’t require any YAML knowledge):

alias: Computer Power Status and Control
description: ""
trigger:
  - type: power
    platform: device
    device_id: 6986f6ddc9355c30d19ce4131e69ff42
    entity_id: sensor.desktop_pc_power_power
    domain: sensor
    id: status_on
    above: 30
    for:
      hours: 0
      minutes: 0
      seconds: 2
    alias: Power Monitor - Sense On
  - type: power
    platform: device
    device_id: 6986f6ddc9355c30d19ce4131e69ff42
    entity_id: sensor.desktop_pc_power_power
    domain: sensor
    id: status_off
    below: 30
    for:
      hours: 0
      minutes: 0
      seconds: 2
    alias: Power Monitor - Sense Off
  - platform: time_pattern
    seconds: "10"
    id: recurring_power_check
    alias: Recurring Power Check
  - platform: state
    entity_id:
      - input_boolean.computer
    to: "on"
    from: "off"
    id: manual_toggle_on
    alias: Manual Toggle On
  - platform: state
    entity_id:
      - input_boolean.computer
    to: "off"
    from: "on"
    id: manual_toggle_off
    alias: Manual Toggle Off
condition: []
action:
  - if:
      - condition: trigger
        id: status_on
    then:
      - service: input_boolean.turn_on
        data: {}
        target:
          entity_id: input_boolean.computer
    alias: Toggle Helper On
  - if:
      - condition: trigger
        id: status_off
    then:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.computer
    alias: Toggle Helper Off
  - if:
      - condition: trigger
        id: recurring_power_check
    then:
      - if:
          - type: is_power
            condition: device
            device_id: 6986f6ddc9355c30d19ce4131e69ff42
            entity_id: sensor.desktop_pc_power_power
            domain: sensor
            above: 30
        then:
          - service: input_boolean.turn_on
            data: {}
            target:
              entity_id: input_boolean.computer
        else:
          - service: input_boolean.turn_off
            data: {}
            target:
              entity_id: input_boolean.computer
    alias: Time Pattern Trigger Reconciliation
  - if:
      - condition: trigger
        id: manual_toggle_on
    then:
      - service: shell_command.desktop_pc_short_press
        data: {}
    alias: Manual Power On
  - if:
      - condition: trigger
        id: manual_toggle_off
    then:
      - service: button.press
        data: {}
        enabled: true
        target:
          entity_id: button.desktop_pc_agent_service_shutdown_immediately
    alias: Manual Power Off
mode: single

Hopefully someone finds this helpful!

5 Likes

Thank you soo much!! I wanted to do the same thing with my extra PiKVM.