Making it Ubiquitous
for large enough values, anyway
Gabe // May 20, 2016

Ubiquiti has a line of network enabled power outlets, With nice looking hardware (that won't burn down my house) that comes with a centralized controller and phone applications. This however, didn't quite fit into my vision of a single set of interconnected services that managed all other devices on the network within a single user interface. So I read a few blog posts about accessing the firmware and implemented a small twisted service that exposed a similar API to the Lambent Aether components I had written previously.

This improved on the stock interfaces in a few ways.

  • Outlet names are stored on the service and not the individual client applications.
  • Can manage multiple different types of outlets via a normalized interface.

There was a major fun caveat along the way however!!

The device expires cookies after a few weeks so we have to catch that the cookie is expired and then renew it as part of the control message.

try:
    requests.put("http://%s/sensors/%i" % (self.host, port), cookies=self.cookie, data={"output": target})
except requests.exceptions.TooManyRedirects:
    self.login() # our mfi cookie was expiring, re-login and then retry
    requests.put("http://%s/sensors/%i" % (self.host, port), cookies=self.cookie, data={"output": target})

I'll one day change that code to use `treq` and not block, but its fine for now.