Supported Types of Device Control


This project has been tested against 3 power control devices. These specific examples have their own documentation pages as follows:

Command Line Control


TP Link Tapo Smart Plug

The simplest form of control is to execute a command line utility. Clearly the command tool needs to be installed on the machine running the webhook server, the server account needs permission to run it and the tool must be able to contact the device from the server.

A common example for RPI power is a switchable USB hub. Most of these can be controlled by the uhubctl command line tool. (see

Using uhubctl implies that the hub in question is plugged into a USB port on the webhook server.

example yaml:

- type: CommandLine
    name: pi2
    on: uhubctl -a 1 -p 2
    off: uhubctl -a 0 -p 2
    query: uhubctl -p 2
    query_on_regex: .*power$
    query_off_regex: .*off$

SmartThings Control


TP Link Tapo Smart Plug

SmartThings are IoT devices which are controlled using a SmartThing api token and SmartThing device ID. Once you have set up a SmartThing and tested it via the associated App you will be able to discover your device ID via the App. You can get your api token by logging in here:

Note that the ip_address of tells the server to listen on all interfaces on the machine on which it is running. Instead one could supply the IP of a single NIC or for best security use, meaning that only processes on the same machine will have access (in this cases you would run the webhook server on the maas rack server).

SmartThing commands for switch devices will usually take the exact same form as in the above example. Command line devices will just take a command line to execute in the shell.

In all cases the response from the query command is passed through a regex search and will return ‘on’ if the the response matches query_on_regex and ‘off’ it matches query_off_regex. Note that the defaults for these regex are ‘on’ and ‘off’ which is what SmartThing devices will return in the switch status field by default. This is why the nuc1 example is not required to specify query_on_regex, query_off_regex.

Note that the query response which goes to MAAS is converted to MAAS default values and hence no configuration of regex in MAAS itself are required.

example yaml:

- type: SmartThingDevice
    name: nuc1
    # token and id redacted
    off: main switch off
    on: main switch on
    query: switch

Web GUI Control


Netgear GS803EP PoE 8 port switch

For those power control devices that are configured by a web UI only, I provide a Web Scraping device type. This uses the python selenium library to click buttons and send text to forms on any Web UI. Defining the correct sequence should allow you to login to any Web GUI and control it.

Per Control Device Configuration

For this device type there are two types of entry. First is the global entry where you configure how to connect/disconnect to/from each device. (i.e. if you had 2 PoE switches you would have 2 of these)

example WebGui yaml:

- type: WebGui
    name: GS308EP
    connect_url: http://GS308EP_IP_ADDRESS
    timeout: 10
    driver: /home/giles/work/maaspower/utils/chromedriver
    login: |
    logout: |

You will need the chromedriver for selenium for this to work. Download from here (pick one that matches your Chrome version):

The configuration ‘driver:’ needs to point at the downloaded file. ‘timeout:’ should be the max time taken for any transitions in the click sequences you specify.

‘login:’ and ‘logout’: specify the sequence of clicks to perform these two tasks.

The configuration strings are ‘/’ separated fields as follows:



clicks on the specified HTML Element


sends text to a specified HTML Element


sends text plus carriage return to a specified HTML Element


gets the text from a specified HTML Element


pauses for n seconds (floating point supported)

Field Identifiers

The second and third parts of the / separated strings identify the HTML Element to target:


finds the fields whose name is ‘value’


finds the fields whose class is ‘value’


find the fields with link contents specified by a partial match on ‘value’


find the fields whose id is ‘value’

NOTE: in all cases if more than one field is matched you can index it like this:


Where n is the 0 based index into the list of fields.

NOTE: in all cases the code will wait for the specified field to be seen if it cannot immediately be seen. ‘timeout’ specifies the maximum wait time before an error.

When the web scraper detects an error it will execute the logout script (ignoring errors) followed by the login script and try again. This has been shown to successfully recover on the GS308EP when it has timed out due to inactivity and gone back to the login screen.

Per Control Device Configuration

For each computer that you want to power control you will need an additional entry like the following example. On, Off and Query use the same syntax as described above.

Note that the name has the entry above’s name followed by a computer name separated by ‘-’ this is important as it associates this entry with the correct Web Device. Only one instance of the selenium driver is loaded per web device and can control any number of target PCs.

The _regex parameters are regular expressions which will try to match the text returned from the final get in the query sequence. If there is a match it will return on or off to MAAS, or an error if there is none.

example WebDevice yaml:

- type: WebDevice
    name: GS308EP-pi5
    on: |
    off: |
    query: |
    query_on_regex: Enable
    query_off_regex: Disable

Working with another Web GUI

This has been tested with the Netgear GS3008EP. I have tried to make a generic DSL that allows for most possible sequences of Web Element interactions, but YMMV.

To experiment with the approach and develop your own command sequences for this device type see the python script here: You can launch this script interactively with iPython and experiment with your device to get the right sequence of commands to turn devices on/off and query their state. See the comments in the file for details.

If you are brave enough to create your own config for a new device, please report any problems here Also post any working configurations too (you can do a PR to the docs or report in issues).