From eBower Wiki
Jump to: navigation, search
(Bugs and To-Do List)
(Bugs and To-Do List)
Line 98: Line 98:
  
 
* Refreshing the main page prompts for a submission of form data (the Google+ ID token). I should use a forwarding page for this and rely on PHP session data, but I'm not familiar enough with PHP sessions to tell if they're secure enough. This will also fix an issue with token expiration forcing a login to refresh it periodically.
 
* Refreshing the main page prompts for a submission of form data (the Google+ ID token). I should use a forwarding page for this and rely on PHP session data, but I'm not familiar enough with PHP sessions to tell if they're secure enough. This will also fix an issue with token expiration forcing a login to refresh it periodically.
* Changing the fan speed will cause an error the next time the light level is read. Clicking refresh will clear the error.
 
 
* I display dimmer information but I don't allow setting anything other than on/off.
 
* I display dimmer information but I don't allow setting anything other than on/off.
 
* On Android devices some light icons appear off-center.
 
* On Android devices some light icons appear off-center.
 
* There is no support for scenes or adding devices. This is not something I use so it may be a community-driven feature.
 
* There is no support for scenes or adding devices. This is not something I use so it may be a community-driven feature.
 
* Refreshing a device after a session expires will result in an unhelpful error. Refreshing the page will fix this, but it could be more graceful.
 
* Refreshing a device after a session expires will result in an unhelpful error. Refreshing the page will fix this, but it could be more graceful.

Revision as of 12:19, 7 March 2015

Unhappy with the security around the INSTEON Hub, I decided I wanted to front end it with a secure, modern webserver. I made the following assumptions:

  • I don't want to deal with password management, I want to use an OpenID(-like) solution.
  • All webservers should be TLS encrypted, even if there is no secure content.
  • I have a webserver on my home network that's world-accessible.
  • The webserver is a modern Linux system running php5.
  • I can either attach the Hub to a dedicated network on my webserver or rely on my router to filter traffic to it from only acceptable IP addresses.
  • I use an original Hub, however most of the code is abstracted that adding support for other controllers (or even WEMO via the ouimeaux libraries) should be easy enough.
  • The only browser I tested with is Chrome, but much of it is basic Javascript/HTML so other browsers should work.

Installation

Unpack the files into /var/www/insteon/ or the directory of your choice.

Edit insteon.conf to include your Hub information.

Edit insteon.ini, we're mostly interested in the [devices] section as of now. You can delete the sample entries, the format is:

short_name=insteon_id,device_details,friendly_name
short_name 
A short form of the device name, keep it small, unique, and one word. This is no longer used except as a key.
insteon_id 
The INSTEON ID, usually printed on the device or visible from the app. Use a format that's not mistakable for a number, like xx.xx.xx or xx:xx:xx.
device_details 
The product code for the device, visible from the app and provides a way to identify the type and version of the device. Today I just use this to determine if the device is a dimmer or one of my fan modules, but in theory device-specific icons and behavior are possible.
friendly_name 
What will be displayed in the UI. Avoid commas, but most other characters should be fine.

You can also edit the [other_services] section to choose whether to display links to other home automation sites.

Copy both insteon.conf and insteon.ini to /etc/.

Google+ Authentication

Storing passwords locally is a Very Bad Idea™ unless you're a full-time IT guy. Password reuse is a big problem, and no matter what you think you're storing your passwords incorrectly. So is Google, but they have a large team of full-time IT guys on it. And you can use their password database to make sure there's one less password (including 2FA) you need to remember.

I choose the Google+ Sign-In mechanism. First, go to the Google Developers Console and follow this workflow. Once you're done, under APIs and Auth you can click "credentials." Find the "Client ID" (it looks like a mess of random characters ending in .apps.googleusercontent.com) and copy that value to the client ID in /etc/insteon.ini.

Now you should be able to open up the /insteon page on your web server and see the Google+ login button. Click on it, and log in. You'll be presented with a "Sorry, not authorized." message including your user ID. You can view your profile by entering that ID after https://plus.google.com/. If things are working, you can add that ID to /etc/insteon.ini as a unique user under the [valid_users] section (deleting the placeholders).

Finally, try refreshing the page and see if you can log in.

You can see index.php to see how to present the button, and insteon.php to see how I check the token against Google's APIs and then set a PHP session to let it flow through to other pages without needing additional API calls.

Usage

Just open it up and you'll see a web page that displays a summary of all of your devices. I default to four per row, but you can change this by editing $dev_per_row in insteon.php. The icons are designed to give you a nice, intuitive overview with basic black shapes differentiating between fan controllers and light controllers. There's an off-white circle that appears if a light is on, it will be filled with the level of the light if it's a dimmer. Fans will be animated if they're on, with a fan level indicator in the lower right.

The page is just a snapshot in time, it doesn't automatically update. However in the upper right is a blue refresh icon that will update that device. Updating all devices at once is easier with a page refresh.

Clicking the green power icon in the lower left of the device will bring up a device-specific remote. Clicking buttons should work in (near) realtime and the device will be refreshed when you close the remote (by clicking off the remote).

File Descriptions

This section describes the various files included with the package.

Support Files

insteon 
A shell script I wrote to control INSTEON devices. I use this as a standalone module as well.

This is the script that I started out with, primarily because setting a cron job is easier than configuring scenes and schedules.

Web Code

index.php 
A very basic landing page that displays the login button.
insteon.php 
The main page to render the screen.
insteon.js 
The primary JavaScript for the page.
insteon.css 
Edit this to change the formatting of things.

This is the basic application.

API Calls

status.php 
If you've got a PHP session active, it will pull the light level of device_id. Note that "on" will return 100 and "off" will return 0.
fan_status.php 
If you've got a PHP session active, it will pull the fan status of device_id. Output should be off, low, medium, or high.
set_light.php 
Sets device_id to value - you can call this directly (once you're logged in and have a session active).
set_fan.php 
Like set_light.php but sets the fan status.

I could have done this a bit better, more PHP-contained rather than simply a callout to a shell script. But I already had the script and I'm lazy. It does check if a session is active, so using curl directly isn't easy (and something I'd just do via the shell script), but it should be easy enough to modify if you want other security.

Note that the status API calls will return text beginning with ERROR if there is a failure of some sort. Check the JavaScript console for details if an error icon appears.

Config Files

insteon.conf 
The configuration for the insteon shell script. It can also be placed in ~/.insteon.conf but for www-data that's a little tougher.
insteon.ini 
The configuration for the web-based controller including the user and device database.

Two files since insteon is also a standalone app. You may need to update insteon.ini every time you add or replace a device, but I'm assuming that's not often. As a side effect, it also stores the device ID someplace, useful if your Hub goes wonky. Note that I don't bother storing devices that I can't control or that are directly controllable. This includes the 6-button keypads that control the fans.

Both config files should be moved to /etc/, if they're left in-place they could be downloaded. While they don't contain hugely sensitive data, better safe than sorry.

Image Files

light-off.png 
The standard light (meaning !fan) backdrop, defaults to a black vector art light bulb.
fan-off.png 
The standard fan backdrop, a four-blade ceiling fan.
light-on.png 
An off-white circle positioned over the center of the light or fan backdrops.
fan-on.gif 
An animated fan used when a fan module has a status not equal to off.
fan-low.png, fan-medium.png, fan-high.png 
Used to show an increasing number of bars for the fan speed. Note that fan-off.png is not part of this sequence since a fan that's off doesn't get a speed icon.
loading.gif 
The image displayed at the lower right when the device information is being loaded.
reload.png 
The icon in the upper right to refresh the device information.
power.png 
The icon in the lower left to bring up the remote.
error.png 
An icon displayed in the lower right if there is an error getting the status.

Each of these files is automatically resized, in theory you can just swap them out for other files and things should just work. All files should be roughly square in aspect ratio or you may get scaling issues.

Bugs and To-Do List

  • Refreshing the main page prompts for a submission of form data (the Google+ ID token). I should use a forwarding page for this and rely on PHP session data, but I'm not familiar enough with PHP sessions to tell if they're secure enough. This will also fix an issue with token expiration forcing a login to refresh it periodically.
  • I display dimmer information but I don't allow setting anything other than on/off.
  • On Android devices some light icons appear off-center.
  • There is no support for scenes or adding devices. This is not something I use so it may be a community-driven feature.
  • Refreshing a device after a session expires will result in an unhelpful error. Refreshing the page will fix this, but it could be more graceful.