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
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 https://github.com/mvp/uhubctl).
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 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: https://account.smartthings.com/login.
Note that the ip_address of 0.0.0.0 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 127.0.0.1, 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.
- type: SmartThingDevice name: nuc1 # token and id redacted api_token: YOUR_SMART_THINGS_API_TOKEN device_id: YOUR_SMART_THING_DEVICE_ID off: main switch off on: main switch on query: switch
Web GUI Control
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: | sendcr/cls/pwd-field-text/PASSWORD_GOES_HERE click/link/POE logout: | click/cls/src-views-header-nav-icon-button click/cls/icon-logout click/id/modal_footer_button_primary
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)
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: | click/n/isShowPot3 click/n/editPot3 click/cls/poePortPwrTxt click/link/Enable click/n/submitPotedit off: | click/n/isShowPot3 click/n/editPot3 click/cls/poePortPwrTxt click/link/Disable click/n/submitPotedit query: | delay/5 get/cls/portPwr 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: https://github.com/gilesknap/maaspower/blob/main/utils/webuitest.py 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 https://github.com/gilesknap/maaspower/issues. Also post any working configurations too (you can do a PR to the docs or report in issues).