found it. after you create the app, the “browse” feature appears and i can see dropcam connect code. i “hacked” a device type to add the switch feature you provided, but leveraged the credentials/uid from the parent app:
metadata {
// Automatically generated. Make future change here.
definition (name: "Dropcam (Switch)", namespace: "we", author: "the people") {
capability "Actuator"
capability "Image Capture"
capability "Switch"
capability "Refresh"
capability "Polling"
}
simulator {
status "image": "raw:C45F5708D89A4F3CB1A7EEEE2E0C73D900, image:C45F5708D89A4F3CB1A7EEEE2E0C73D9, result:00"
reply "take C45F5708D89A4F3CB1A7EEEE2E0C73D9": "raw:C45F5708D89A4F3CB1A7EEEE2E0C73D900, image:C45F5708D89A4F3CB1A7EEEE2E0C73D9, result:00"
}
tiles {
standardTile("camera", "device.image", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: true) {
state "default", label: "", action: "", icon: "st.camera.dropcam-centered", backgroundColor: "#FFFFFF"
}
carouselTile("cameraDetails", "device.image", width: 3, height: 2) { }
standardTile("take", "device.image", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false) {
state "take", label: "Take", action: "Image Capture.take", icon: "st.camera.dropcam", backgroundColor: "#FFFFFF", nextState:"taking"
state "taking", label:'Taking', action: "", icon: "st.camera.dropcam", backgroundColor: "#53a7c0"
state "image", label: "Take", action: "Image Capture.take", icon: "st.camera.dropcam", backgroundColor: "#FFFFFF", nextState:"taking"
}
standardTile("switch", "device.switch", canChangeIcon: true) {
state "on", label: 'On', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: 'Off', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "camera"
details(["cameraDetails", "take", "switch", "refresh"])
}
}
def uninstalled() {
parent?.removeChildFromSettings(this)
}
// parse events into attributes
def parse(String description)
{
log.debug "Parsing '${description}'"
// TODO: handle 'image' attribute
// TODO: handle '' attribute
}
// handle commands
def take()
{
if (!isStreamingEnabled())
{
log.debug "unable to take picture, camera off"
return
}
//else
log.debug "Executing 'take'"
def dni = device.deviceNetworkId
log.debug "Executing 'take' with dni $dni"
log.debug "Executing 'take' with dni $dni and parent $parent with app ${parent.installedSmartApp}"
def imageBytes = parent.takePicture(dni, null)
log.debug "got bytes"
if(imageBytes)
{
storeImage(getPictureName(), imageBytes)
}
}
private getPictureName()
{
def pictureUuid = java.util.UUID.randomUUID().toString().replaceAll('-', '')
return device.deviceNetworkId + "_$pictureUuid" + ".jpg"
}
//custom code
def updated() {
refresh()
}
def on() {
log.debug "Turning Dropcam on"
setProperties("streaming.enabled", true)
sendEvent(name: "switch", value: "on", isStateChange: true)
}
def off() {
log.debug "Turning Dropcam off"
setProperties("streaming.enabled", false)
sendEvent(name: "switch", value: "off", isStateChange: true)
}
def poll() {
refresh()
}
def refresh() {
//log.debug "Refreshing Dropcam" + getCameraUuid()
//log.debug "parent qs: " + parent.validUserAgent()
//log.debug "cookie: " + getCookieValue()
log.debug "Refreshing Dropcam"
//log.debug "streaming enabled: " + isStreamingEnabled()
def items = getProperties()
def streamingEnabled = isStreamingEnabled()
if (streamingEnabled) {
sendEvent(name: "switch", value: "on", isStateChange: true)
} else {
sendEvent(name: "switch", value: "off", isStateChange: true)
}
log.debug "Switch is now $streamingEnabled"
}
private getProperties() {
def content
httpGet(
[
uri: "https://www.dropcam.com",
path: "/api/v1/dropcams.get_properties",
query: [uuid: getCameraUuid()],
headers: [Cookie: getCookieValue(), 'User-Agent': validUserAgent()],
requestContentType: "application/x-www-form-urlencoded"
],
{ response -> content = response.data; log.debug "dropcams.get_properties response: '${response.data.inspect()}'" }
)
def props = content?.items
if (props) {
return props[0]
}
return [:]
}
private setProperties(key, value) {
def success = false
def uuid = getCameraUuid()
httpPost(
[
uri: "https://www.dropcam.com",
path: "/api/v1/dropcams.set_property",
headers: [Cookie: getCookieValue(), 'User-Agent': validUserAgent()],
requestContentType: "application/x-www-form-urlencoded",
body: "uuid=$uuid&key=$key&value=$value"
],
{ response -> success = (response.status == 200); log.debug "dropcams.set_property response: '${response.data.inspect()}'" }
)
return success
}
private getCameraUuid() {
device.deviceNetworkId.split(/\./)?.last()
}
private validUserAgent() {
parent.validUserAgent()
}
private getCookieValue() {
parent.state.cookie
}
private isStreamingEnabled()
{
def items = getProperties()
def streamingEnabled = items?.'streaming.enabled'
if (streamingEnabled == null) {
return false
}
//else
if (streamingEnabled) {
return true
} else {
return false
}
}