Hopefully this helps other users avoid the headaches I found while trying to integrate my Milights with Smartthings. In the following instructions substitute MiLight with Limitless LED, Easyblub, etc since as far as I’m aware they all work the same or just as a general purpose URL requester.
Here is the Android method:($3.90 for Google App)
Requirements:
-My MiLight app installed to SmartThings (code listed below and also hosted on BitBucket: https://bitbucket.org/BrianFreund/http-url-requester)
-The MiLight Controller (know the IP and Port it’s using)
-$3.90 for the App Store on Google
-An Android phone on the network capable of running the app “Automagic * Automation” & “UDP Sender” (Also need the IP address for this)
-
Download and install an app called Automagic * Automation ($3.90) similar to Tasker ($2.99) however I was easily able to set up what I needed where Tasker I’m not sure is capable.
-
Download and install an app called UDP Sender (Free)
-
Create a “Flow” in Automagic that when an HTTP Request is made, triggers the UDP Sender app as a Plugin to send the HEX codes from http://www.limitlessled.com/dev/
-
Create a SmartApp that, based on your preferences, will send the HTTP POST request to your Androids local IP, through the Automagic app which activates the UDP Sender, that controls the lights, all simply on your WiFi network!
-
Repeat and rinse as necessary for whatever custom events/triggers you need
Here is a YouTube video I created demonstrating installation to integration: https://www.youtube.com/watch?v=kZm5q54WU6U
I want to call out Patrick Stuart (@pstuart) and Jason E (@jasone for their extraordinary help with their forum posting in aiding others with code. Definitely helped me get to where this is today as simple as it is.
Here is the Server method: (Free)
Requirements:
-My MiLight SmartThings app (code listed below and also hosted on BitBucket: https://bitbucket.org/BrianFreund/http-url-requester)
-The http-to-shell node server and associated files (hosted also on BitBucket: https://bitbucket.org/jschraub/http-to-shell
-Node version 6.9.2 or higher & NPM
-Linux/Mac/Windows machine, ideally “always-on” to run the http-to-shell server
-The MiLight Controller (again, need the IP it’s using)
- First ensure you have the required programs: NPM and Node version 6.9.2+ (for me installing node through this link worked a charm on my linux machine: “wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash”, afterwards I ran “nvm install node”, for windows I recommend using the installer located at: http://nodejs.org/ and run the same “npm install -ls” after completion)
- Then start by pulling the latest files from the repository at https://bitbucket.org/jschraub/http-to-shell. This will have the server.js file as well as the registered-commands.js file, essentially these two are what we’ll be configuring.
- Using NPM run “npm install -ls” while in the http-to-shell directory.
- Edit your url triggers and commands in the “registered-commands.js” file, examples are listed inside the file for you but here’s a quick breakdown,
url: ‘/milight/1/on’ this is the url that should match from the MiLight app in SmartThings, anything really works so I usually just describe the location e.i. url: ‘/hallwayon’ (don’t forget your / )
type: ‘milight’ default for using the native MiLight commands, the other choice is ‘shell’ but is only used for running external scripts, I now no longer need this functionality but definitely could be useful in the future or if you have other programming experience I’m sure this could trigger a multitude of things
ip: ‘192.168.1.200’ this is your milight controller’s IP address
zone: 1 your MiLight zone naturally
bulbType: ‘rgbw’ depends on your bulb but could be either rgb, rgbw, or white
color: ‘white’ this is default to turn your rgbw to white but if you define the color {0-255} it will turn that color after turning on, e.i. color: 176 would make it red, note the lack of quote when defining a number rather than ‘white’, also it’s unnecessary if not changing the color or leaving it as whatever it was last.
brightness: 100 has a range of 0-100 and is also unnecessary if no adjustments are required
off: false defaults to false so you can omit this entirely when turning on but needs to become true when turning off, the other optional options (color & brightness) become dismissed - After you’ve configured everything (double and triple check your syntax, I lost count of the errors I had due to missing commas or forward-slash) then you should be able to run the server using “node server.js” and it will start with a default port of 9512 (configurable in the server.js file itself, though I’d be careful editing in that file)
- Send the url from the MiLight SmartThings app triggered by your switch and it should then log on the server that it recognizes the command and also what url command was received. Not to mention your bulb should change accordingly.
Acknowledgement shout out to Marcus Wittig from https://github.com/mwittig/node-milight-promise & https://jsfiddle.net/WittigMarcus/p0xw0jks/ for not only the MiLight Library API but also for a color selector that will show you the correct number that corresponds to the RGB for defining color in the registered-commands.js file.
/**
* HTTP Requests
*
* Copyright 2015 Brian Freund (Credit goes to Patrick Stuart (@pstuart) and Jason E (jasone) for their code examples I copied plus of course the SmartThings Documentation which helped immensely)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
definition(
name: "HTTP URL Requester V2",
namespace: "brianfreund",
author: "Brian Freund",
description: "A SmartApp that when sends URL requests to a device that triggers when a switch is turned on or off. Designed for MiLights.",
category: "Convenience",
iconUrl: "http://apk-dl.com/detail/image/com.lierda.wifi-w250.png",
iconX2Url: "http://apk-dl.com/detail/image/com.lierda.wifi-w250.png",
iconX3Url: "http://apk-dl.com/detail/image/com.lierda.wifi-w250.png")
preferences {
section("Execute HTTP Request attached to switch") {
input "theswitch", "capability.switch", required: true, title: "Which switch?"
}
section("Network Information"){
input("DeviceIP", "string", title:"Device IP Address", description: "Please enter your URL Device's IP Address", defaultValue: "192.168.1.195" , required: true, displayDuringSetup: true)
input("DevicePort", "string", title:"Device Port", description: "Please enter your Device's Port", defaultValue: 9512 , required: true, displayDuringSetup: true)
input("PathOn", "string", title:"Path", description: "Enter a path for when the switch turns on", required: false, displayDuringSetup: true)
input("PathOff", "string", title:"Path", description: "Enter a path for when the switch turns off", required: false, displayDuringSetup: true)
}
}
def installed() {
initialize()
}
def updated() {
unsubscribe()
initialize()
}
def initialize() {
subscribe(theswitch, "switch", switchHandler)
}
def switchHandler(evt) {
if (evt.value == "on") {
onSwitches()
} else if (evt.value == "off") {
offSwitches()
}
}
def onSwitches() {
def host = DeviceIP
def port = DevicePort
def hosthex = convertIPtoHex(DeviceIP)
def porthex = convertPortToHex(DevicePort)
def deviceNetworkId = "$hosthex:$porthex"
def ip = "$DeviceIP:$DevicePort"
sendHubCommand(new physicalgraph.device.HubAction("""POST $PathOn HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))
log.debug "$ip was sent $PathOn via $deviceNetworkId"
log.debug "host is $host, port is $port, hosthex is $hosthex, porthex is $porthex, deviceNetworkId is $deviceNetworkId, ip is $ip"
}
def offSwitches() {
def host = DeviceIP
def port = DevicePort
def hosthex = convertIPtoHex(DeviceIP)
def porthex = convertPortToHex(DevicePort)
def deviceNetworkId = "$hosthex:$porthex"
def ip = "$DeviceIP:$DevicePort"
sendHubCommand(new physicalgraph.device.HubAction("""POST $PathOff HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))
log.debug "$ip was sent $PathOff via $deviceNetworkId"
log.debug "host is $host, port is $port, hosthex is $hosthex, porthex is $porthex, deviceNetworkId is $deviceNetworkId, ip is $ip"
}
private String convertIPtoHex(host) {
String hosthex = host.tokenize( '.' ).collect { String.format( '%02x', it.toInteger() ) }.join()
log.debug "the returned host is $hosthex"
return hosthex
}
private String convertPortToHex(port) {
String porthex = port.toString().format( '%04x', port.toInteger() )
log.debug "the returned port is $porthex"
return porthex
}