Very nice work. I only have cameras and am interested in being able to automate the enabling of motion recording...so I took the plug driver and edited for the camera. From the SDK, I was able to parse through the properties and can now see the status for on/off, online, motion enabled recording, and sound enabled recording. Unfortunately I cannot get the on/off commands to work. I think it is the same action as the plug but I'm certainly not an expert. I know enough to be dangerous.
I am willing to update code and test if you have any recommendations.
FWIW, I commented out the refreshing scheduling during testing.
I also had to update the app, adding
'Camera': [label: 'Camera', driver: 'WyzeHub Camera']
to the drivermap so I could install.
/*
* Import URL:
*
* DON'T BE A DICK PUBLIC LICENSE
*
* Version 1.1, December 2016
*
* Copyright (C) 2021 Jake Lehner
*
* Everyone is permitted to copy and distribute verbatim or modified
* copies of this license document.
*
* DON'T BE A DICK PUBLIC LICENSE
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
*
* 1. Do whatever you like with the original work, just don't be a dick.
*
* Being a dick includes - but is not limited to - the following instances:
*
* 1a. Outright copyright infringement - Don't just copy this and change the name.
* 1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
* 1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
*
* 2. If you become rich through modifications, related works/services, or supporting the original work,
* share the love. Only a dick would make loads off this work and not buy the original work's
* creator(s) a pint.
*
* 3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
* you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.
*
*/
import groovy.transform.Field
public static String version() { return "v1.0.5" }
public String deviceModel() { return 'WLPP1CFH' }
@Field static final String wyze_action_power_on = 'power_on'
@Field static final String wyze_action_power_off = 'power_off'
@Field static final String wyze_property_power = 'P3'
@Field static final String wyze_property_device_online = 'P5'
@Field static final String wyze_property_motion_record = 'P1047'
@Field static final String wyze_property_sound_record = 'P1048'
@Field static final String wyze_property_power_value_on = '1'
@Field static final String wyze_property_power_value_off = '0'
@Field static final String wyze_property_device_online_value_true = '1'
@Field static final String wyze_property_device_online_value_false = '0'
@Field static final String wyze_property_device_motion_record_value_true = '1'
@Field static final String wyze_property_device_motion_record_value_false = '0'
@Field static final String wyze_property_device_sound_record_value_true = '1'
@Field static final String wyze_property_device_sound_record_value_false = '0'
metadata {
definition(
name: "WyzeHub Camera",
namespace: "jakelehner",
author: "Jake Lehner",
importUrl: ""
) {
capability "Outlet"
capability "Refresh"
attribute "motionRecord", "bool"
attribute "soundRecord", "bool"
attribute "online", "bool"
}
preferences
{
}
}
void installed() {
log.debug "installed()"
// TODO Make Configurable
unschedule('refresh')
//schedule('0/10 * * * * ? *', 'refresh')
refresh()
initialize()
}
void updated() {
log.debug "updated()"
initialize()
}
void initialize() {
log.debug "initialize()"
}
void parse(String description) {
log.warn("Running unimplemented parse for: '${description}'")
}
def refresh() {
app = getApp()
logInfo("Refresh Device")
app.apiGetDevicePropertyList(device.deviceNetworkId, deviceModel()) { propertyList ->
createDeviceEventsFromPropertyList(propertyList)
}
// TODO Make Configurable
keepFresh = true
keepFreshSeconds = 10
//runIn(keepFreshSeconds, 'refresh')
}
def on() {
app = getApp()
logInfo("'On' Pressed")
app.apiRunAction(device.deviceNetworkId, deviceModel(), wyze_action_power_on)
}
def off() {
app = getApp()
logInfo("'Off' Pressed")
app.apiRunAction(device.deviceNetworkId, deviceModel(), wyze_action_power_off)
}
void createDeviceEventsFromPropertyList(List propertyList) {
app = getApp()
logInfo(propertyList)
String eventName, eventUnit
def eventValue // could be String or number
propertyList.each { property ->
propertyValue = property.value ?: property.pvalue ?: null
switch(property.pid) {
// Switch State
case wyze_action_power_on:
case wyze_action_power_off:
case wyze_property_power:
eventName = "switch"
eventUnit = null
if(propertyValue == wyze_property_power_value_on) {
eventValue = "on"
} else if(propertyValue == wyze_action_power_on) {
eventValue = "on"
} else {
eventValue = "off"
}
if (device.currentValue(eventName) != eventValue) {
logDebug("Updating Property 'switch' to ${eventValue}")
app.doSendDeviceEvent(device, eventName, eventValue, eventUnit)
}
break
// Device Online
case wyze_property_device_online:
eventName = "online"
eventUnit = null
eventValue = propertyValue == wyze_property_device_online_value_true ? "true" : "false"
if (device.currentValue(eventName) != eventValue) {
logDebug("Updating Property 'online' to ${eventValue}")
app.doSendDeviceEvent(device, eventName, eventValue, eventUnit)
}
break
// Event Recording based on motion
case wyze_property_motion_record:
eventName = "motion_enabled"
eventUnit = null
eventValue = propertyValue == wyze_property_device_motion_record_value_true ? "true" : "false"
if (device.currentValue(eventName) != eventValue) {
logDebug("Updating Property 'motionRecord' to ${eventValue}")
app.doSendDeviceEvent(device, eventName, eventValue, eventUnit)
}
break
// Event Recording based on sound
case wyze_property_sound_record:
eventName = "sound_enabled"
eventUnit = null
eventValue = propertyValue == wyze_property_device_sound_record_value_true ? "true" : "false"
if (device.currentValue(eventName) != eventValue) {
logDebug("Updating Property 'soundRecord' to ${eventValue}")
app.doSendDeviceEvent(device, eventName, eventValue, eventUnit)
}
break
}
}
}
private getApp() {
app = getParent()
while(app && app.name != "WyzeHub") {
app = app.getParent()
}
return app
}
private void logDebug(message) {
app = getApp()
app.logDebug("[${device.label}] " + message)
}
private void logInfo(message) {
app = getApp()
app.logInfo("[${device.label}] " + message)
}
private void logWarn(message) {
app = getApp()
app.logWarn("[${device.label}] " + message)
}
private void logError(message) {
app = getApp()
app.logError("[${device.label}] " + message)
}