-
Notifications
You must be signed in to change notification settings - Fork 11
/
SP600
179 lines (160 loc) · 7.88 KB
/
SP600
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
*
* Salus SP600 Smart Plug Driver v2 (20th Jan 2021)
*
*/
metadata {
definition (name: "Salus SP600 Smart Plug", namespace: "Salus", author: "Andrew Davison", importUrl: "https://raw.githubusercontent.com/birdslikewires/hubitat/master/drivers/salus_sp600.groovy") {
capability "Actuator"
capability "Configuration"
capability "Initialize"
capability "Outlet"
capability "PowerMeter"
capability "Refresh"
capability "Switch"
fingerprint profileId: "0104", inClusters: "0000, 0001, 0003, 0004, 0005, 0006, 0402, 0702, FC01", outClusters: "0019", manufacturer: "Computime", model: "SP600", deviceJoinName: "Salus SP600 Smart Plug"
}
}
preferences {
input name: "RepW", type: "number", title: "power reporting level in W", required: true
input name: "RepMin", type: "number", title: "power reporting min (seconds), if a change above reporting level wait this long befor sending report", required: true, defaultValue: 15
input name: "RepMax", type: "number", title: "power reporting max (seconds), if no reports sent in this window send report after this time", required: true , defaultValue: 1200
input name: "infoLogging", type: "bool", title: "Enable info logging", defaultValue: true
input name: "debugLogging", type: "bool", title: "Enable debug logging", defaultValue: false
input name: "traceLogging", type: "bool", title: "Enable trace logging", defaultValue: false
}
def installed() {
device.updateSetting("infoLogging",[value:"true",type:"bool"])
device.updateSetting("debugLogging",[value:"false",type:"bool"])
device.updateSetting("traceLogging",[value:"false",type:"bool"])
device.updateSetting("RepMin",[value:15,type:"number"])
device.updateSetting("RepW",[value:50,type:"number"])
device.updateSetting("RepMax",[value:1201,type:"number"])
log.info "${device} Paired!"
//configure is automaticly called after
}
def initialize() { // Runs on reboot, or can be triggered manually.
int randomSixty = 1 + (Math.random() * 58) // Stagger our device init refreshes or we run the risk of DDoS attacking our hub on reboot!
runIn(randomSixty, sendZigbeeCommands, [data:zigbee.onOffConfig()])
runIn(randomSixty*2,refresh)
//schedule("${randomSixty} ${randomSixty} ${randomTwentyFour}/${checkEveryHours} * * ? *", refresh)
log.info "${device} Initialised zigbee config in $randomSixty seconds"
}
def configure() { // Runs after installed() when a device is paired or rejoined when, or can be triggered manually.
unschedule()
if (debugLogging == true){ runIn(3600,debugLogOff)}
if (traceLogging == true){ runIn(1800,traceLogOff)}
/*
state.remove("checkPhase")
state.remove("bin")
state.remove("presenceUpdated")
*/
log.info "${device} configured, debug logging=$debugLogging , trace logging=$traceLogging , info logging=$infoLogging , "
powerMeteringConfig()
initialize()
}
def updated() { // Runs whenever preferences are saved.
log.info "${device} updated"
configure()
}
void traceLogOff(){
device.updateSetting("traceLogging",[value:"false",type:"bool"])
log.trace "${device} : Trace Logging : Automatically Disabled"
}
void debugLogOff(){
device.updateSetting("debugLogging",[value:"false",type:"bool"])
log.trace "${device} : Debug Logging : Automatically Disabled"
}
void reportToDev(map) {
String receivedData = map.data
if (infoLogging == true || debugLogging == true || traceLogging == true) log.warn "${device} : UNKNOWN DATA!Received : cluster: ${map.cluster}, clusterId: ${map.clusterId}, attrId: ${map.attrId}, command: ${map.command} with value: ${map.value} and data: ${receivedData}"
}
def powerMeteringConfig() {
if(RepMin == null || RepW == null || RepMax == null){
log.warn "${device} : null value detected max=$maxReportTime s, min=$minReportTime s, change=$reportableChange w"
installed()
}
else{
int minReportTime = settings.RepMin
int reportableChange = settings.RepW
int maxReportTime = settings.RepMax
log.trace "${device} : Power config max=$maxReportTime s, min=$minReportTime s, change=$reportableChange w"
sendZigbeeCommands(zigbee.configureReporting(0x0702, 0x0400, DataType.INT24, minReportTime, maxReportTime, reportableChange))
}
}
def off() {
sendZigbeeCommands(zigbee.off())
}
def on() {
sendZigbeeCommands(zigbee.on())
}
def refresh() {
if(infoLogging == true || traceLogging == true || debugLogging == true) log.trace "${device} :Sending Refresh command"
sendZigbeeCommands(zigbee.readAttribute(0x0702, 0x0400))
sendZigbeeCommands(zigbee.onOffRefresh())
}
def parse(String description) {
// Primary parse routine.
if (debugLogging == true) log.debug "${device} : Parse : $description"
Map descriptionMap = zigbee.parseDescriptionAsMap(description)
if (descriptionMap) processMap(descriptionMap)
else reportToDev(description)
}
void processMap(map) {
if (debugLogging == true) log.debug "${device} : processMap() : ${map}"
// Relay configuration and response handling.
if (map.cluster == '0006' || map.clusterId == '0006') {
if (map.command == '01' || map.command == '0A') { // 01 - Prompted Refresh 0A - Automated Refresh
//Relay refresh
if (map.value == '01') {
sendEvent(name: 'switch', value: 'on')
if (infoLogging == true) log.info "${device} : Switch : On Relay Report ${map.command} ${map.value}"
}
else {
sendEvent(name: 'switch', value: 'off')
if (infoLogging == true) log.info "${device} : Switch : Off Relay Report ${map.command} ${map.value}"
}
}
// Relay Configuration
else if (map.command == '07') {
if (infoLogging == true) log.info "${device} : Relay Configuration : Successful"
}
// Relay State Confirmations - digiatl control
else if (map.command == '0B') {
if (map.data[0] == '01') {
sendEvent(name: 'switch', value: 'on', descriptionText:'Digital command')
if (infoLogging == true) log.info "${device} : Switch : On Digital"
}
else {
sendEvent(name: 'switch', value: 'off', descriptionText:'Digital command')
if (infoLogging == true) log.info "${device} : Switch : Off Digital"
}
}
else if (map.command == '00') {
if (debugLogging == true) log.debug "${device} : skipping state counter message : ${map}"
}
else reportToDev(map)
}
// Power configuration and response handling.
else if (map.cluster == '0702' || map.clusterId == '0702') {
if (map.command == '07') {
if (infoLogging == true) log.info "${device} : Power Reporting Configuration : Successful" // Power Configuration
}
else if (map.command == '01' || map.command == '0A') { // Power Usage //01 - Prompted Refresh ,0A - Automated Refresh
int powerValue = zigbee.convertHexToInt(map.value)
sendEvent(name: 'power', value: powerValue, unit: 'W')
if (debugLogging == true) log.debug "${device} : power hex value : ${map.value}"
if (infoLogging == true) log.info "${device} : power sensor reports : ${powerValue} W"
}
else reportToDev(map)
}
else if (map.cluster == '8021' || map.clusterId == '8021') if (traceLogging == true) log.trace "${device} : skipping discovery message : ${map}"
else if (map.cluster == '8032' || map.clusterId == '8032') if (traceLogging == true) log.trace "${device} : skipping management routing response message : ${map}"
else if (map.cluster == '8038' || map.clusterId == '8038') if (traceLogging == true) log.trace "${device} : skipping management network update notify message : ${map}"
else reportToDev(map)
}
void sendZigbeeCommands(List<String> cmds) {
// All hub commands go through here for immediate transmission and to avoid some method() weirdness.
if (traceLogging == true) log.trace "${device} : sendZigbeeCommands to transmit : ${cmds}"
sendHubCommand(new hubitat.device.HubMultiAction(cmds, hubitat.device.Protocol.ZIGBEE))
}