This project implements a SmartApp and device handlers to allow you to directly communicate with the PowerView hub on your local network and do the following:
- auto-discover registered shades
- auto-discover configured scenes
- set/monitor the shade level
- set/monitor the vanes level
- monitor battery level
- execute scenes
The benefit of using this is that there is no requirement for the default PowerView Account web service or other middlemen like IFTTT--your SmartThings hub will communicate directly with the PowerView hub. Note: due to the way SmartThings works, a connection to the ST cloud is still required.
This project currently does not support:
- reading/editing rooms
- modifying schedules set in PV
- editing scenes
- reading/editing scene collections
- managing PowerView Connect settings
This is primarily for Hunter Douglas Silhouette shades so there is both the vane and shade control. Other shades will likely work, though there will be extraneous functionality that may throw errors. Relying on scenes is likely the easiest way forward in this case.
The shade control panel. Note that the primary action (top circle) is for toggling the vanes on and off. The brightness control is for the shade. The device handler should refresh its state every minute in the background. The "refresh" tile is there if you need to know the state immediately.
The scene control panel. This is implemented as a momentary switch and there is no state tracking info, i.e., the "Recently" tab will always be empty.
This requires you to log in to the SmartThings web-based IDE to add a custom SmartApp and two custom device handlers.
-
Register the following custom components (see tutorial for SmartApps and device handlers):
- Install the
Hunter Douglas PowerView
SmartApp from this repo: owner=johnvey
, name=smartthings-hd-powerview
, branch=master
- Install the
Hunter Douglas PowerView Shade
device handler from this repo - Install the
Hunter Douglas PowerView Scene
device handler from this repo
- Install the
-
Add the newly registered SmartApp via Automation > SmartApps > Add a SmartApp > My Apps section
-
Open the app
-
Enter the IP address of your PowerView hub, click "Done"
-
Wait for the app to discover your shades and scenes
-
Choose the shades you want to control via SmartThings
-
Choose the scenes you want to control via SmartThings
The PowerView hub is a very simple HTTP server. I've documented the API that I've been able to sniff from a hub at Rev. 1, SubRev. 1, Build 847
:
Hunter Douglas PowerView HTTP API
The structure of this SmartThings handler is:
- 1 SmartApp that handles the initial setup and discovery of the connected shades and configured scenes
- 1 device handler instance for each shade
- 1 device handler instance for each scene
Some updates have been made that makes portions of this work with a gen 2 hub. Further investigations are still required to confirm full compatibility. See the Github issue for details.
Programming these handlers was markedly cumbersome due to the poor quality of the documentation. Here are some tips that I wish I knew before I had started:
Tip 1: There are several incantations to have your ST hub communicate directly with a device on your LAN.
This is the most reliable method that I had found:
- instantiate your own
HubAction()
instance - use the
HubAction(map requestConfig, string deviceID, map options)
signature - provide an explicit callback function if you need to parse the response
- use a unique identifier for the device ID, not some kind of hash of the MAC address (the official docs cover this multiple times but the forums are rife with misinformation)
sendRequest(method, path, body=null, callbackFn=null) {
def host = '192.168.1.123:4567'
def contentType = 'application/json'
def deviceId = '18d11666-14de-4a46-9492-86a147ef0e3b'
def hubAction = new physicalgraph.device.HubAction(
[
method: method,
path: path,
HOST: host,
headers: [
'HOST': host, // yes, it is required here and above
'Content-Type': contentType
],
body: body
],
deviceId,
[
callback: callbackFn
]
)
log.debug("sendRequest: ${method} ${host}${path}")
return hubAction
}
Note that this implementation generally requires that you invoke this from a device event, i.e., if the ST framework was the caller that initiated this invocation somewhere up in your call tree. If you decide to invoke this via a timer, e.g. runEvery1Minute()
, then you must invoke via the sendHubCommand()
method. See example.
Tip 2: If you are connecting your GitHub project directly to the ST IDE, make sure your source code file name matches the name
field in the metadata declaration exactly.
If you fail to do this, attempting to use the "Update from repo" functionality will fail with no further explanation. Official doc mention.
Tip 3: Direct embed of a dynamicPage()
inside of the top-level preferences()
block for a SmartApp doesn't work.
Instead of something like
preferences {
dynamicPage(...)
}
use a separate function like:
preferences {
page(name: "singlePagePref")
}
def singlePagePref() {
return dynamicPage() {...}
}
You can use import
to bring in other functionality that makes programming in ST more palatable. For example, I wanted to declare a top-scope "enum", but ran into the sandboxing that ST uses via a class wrapper around your SmartApp. The solution to this was to use the @Field
decorator to effectively hoist my def
s out of the default scope.