From eBower Wiki
Jump to: navigation, search
(Bugs and To-Do List)
(Google+ Authentication)
Line 36: Line 36:
 
== Google+ Authentication ==
 
== 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 [http://www.google.com/landing/2step/ 2FA]) you need to remember.
+
I've moved this section to [[Google_Plus_Authentication]].
 
 
I choose the [https://developers.google.com/+/web/signin/ Google+ Sign-In mechanism]. First, go to the [https://console.developers.google.com/project Google Developers Console] and follow [https://developers.google.com/+/web/signin/javascript-flow#step_1_create_a_client_id_and_client_secret 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 <tt>.apps.googleusercontent.com</tt>) and copy that value to the client ID in <tt>/etc/insteon.ini</tt>.
 
 
 
Now you should be able to open up the <tt>/insteon</tt> 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 <tt>https://plus.google.com/</tt>. If things are working, you can add that ID to <tt>/etc/insteon.ini</tt> as a unique user under the <tt>[valid_users]</tt> section (deleting the placeholders).
 
 
 
Finally, try refreshing the page and see if you can log in.
 
 
 
You can see <tt>index.php</tt> to see how to present the button, and <tt>insteon.php</tt> 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 =
 
= Usage =

Revision as of 19:55, 29 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

Run the following and put the files into /var/www/insteon/ or the directory of your choice.

git clone https://github.com/jdbower/insteon.git

Go into the insteon directory and run chmod 755 insteon.

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,off-when-away,room
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.
off-when-away 
Either true or false, determines whether clicking the Away link will turn off the device. For example, leave the grow lights on but turn off the closet lights.
room 
A short version name of the room in which the device resides.

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

Move both insteon.conf and insteon.ini to /etc/. You should now be able to run the insteon shell script manually to make sure you can see the status of your devices.

Google+ Authentication

I've moved this section to Google_Plus_Authentication.

Usage

Just open it up and you'll see a web page that displays a summary of all of your devices broken down by room. 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.

Light Icon ExampleFan Icon Example

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).

I also now support pulling data from your Nest account:

Nest Data Example

Here we see that the current temperature is 77°F, the set temperature is 71°F, the fan is on, and the Nest is set to Away. This assumes at most one Nest per room and there are icons for heating and cooling. The Nest data is like the device data, a snapshot in time rather than a polled refresh mechanism. However, I do refresh the Nest data with every device refresh because it's fairly lightweight and doesn't cause affect the Hub polling at all.

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.
login.php 
A transitional page that parses the data the Google+ login gives, authorizes the user, and sets the session. It also displays the login failed message.
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.
nest.php 
Shows the current state of each nest.

I could have done this a bit better, more PHP-contained rather than simply a callout to a shell script (sort of like now nest.php is structured). 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.
nest.png, dropbox.png 
Sample logos that can be used to generate links to related services. Check out insteon.ini for examples on how to use them.
away.png 
Away icon to batch turn off devices and as a Nest indicator.
hvac-heat.png, hvac-cool.png, hvac-fan.png 
Nest-related icons to show current state.

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

Things I want to add/fix:

  • I display dimmer information but I don't allow setting anything other than on/off.
  • Away mode seems to enable things simultaneously, this should be changed to sequentially.
  • CLEANUP: I've got a lot of silly prints which would be more readable as a heredoc.
  • Away mode doesn't set the Nest to away. But if I set the Nest to away I need some way to setting it back.
  • I support these outdated Fahrenheit units, I don't know why... At least if you have the Nest set to C it will report appropriately.
  • When the Nest is away I still show the non-away temperature setting. I don't know if this is confusing or not...
  • I refresh the Nest temperature with every device refresh, I should show an icon when this happens.
  • When there's both a fan and light status error I only show the fan error.
  • The device database is now a lot more complex than when I started, I should move it to some sort of multi-dimensional array.

Things I'm not sure I care about:

  • I don't have support for rooms. In theory that should be easy enough, but I'm uncertain if it adds clutter.
  • 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.

Things pending the next push:

  • I added a favicon.
  • Temperature now displays to the tenths place for Celsius users where it's meaningful (Nest correctly stores the value in Celsius so displaying Fahrenheit values to the tenths place creates rounding issues for set temperatures).
  • Rather than check the JavaScript Console, I set the title of the Error icon.
  • Switched to using an off-the-shelf php class for Nest access - beat trying to get my own away mode to work. Stay tuned for more Nest awesomeness.