mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-08 05:31:56 +00:00
MSA-63: Device type for Billion Single Phase Smart Meter that has the following attributes - Energy, Power, Voltage, Current, Frequency, Power Factor and Apparent Power.
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* Copyright 2015 Intraix
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Billion Smart Meter
|
||||
*
|
||||
* Author: Intraix
|
||||
* Date: 2015-09-03
|
||||
*/
|
||||
metadata {
|
||||
definition(name: "Billion Smart Meter", namespace: "intraix", author: "Intraix") {
|
||||
capability "Actuator"
|
||||
capability "Sensor"
|
||||
capability "Configuration"
|
||||
capability "Refresh"
|
||||
capability "Switch"
|
||||
capability "Energy Meter"
|
||||
capability "Power Meter"
|
||||
|
||||
// Custom attiributes for capabilities not supported by ST
|
||||
attribute "voltage", "number"
|
||||
attribute "current", "number"
|
||||
attribute "frequency", "number"
|
||||
attribute "powerFactor", "number"
|
||||
attribute "apparentPower", "number"
|
||||
|
||||
fingerprint profileId: "0104", inClusters: "0000,0003,0006,0702", outClusters: ""
|
||||
}
|
||||
|
||||
// simulator metadata
|
||||
simulator {
|
||||
// status messages
|
||||
status "on": "on/off: 1"
|
||||
status "off": "on/off: 0"
|
||||
|
||||
// reply messages
|
||||
reply "zcl on-off on": "on/off: 1"
|
||||
reply "zcl on-off off": "on/off: 0"
|
||||
}
|
||||
|
||||
// UI tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821", nextState: "turningOff"
|
||||
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
|
||||
state "turningOn", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821", nextState: "turningOff"
|
||||
state "turningOff", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 1, height: 1) {
|
||||
state "default", label: "", action: "refresh.refresh", icon: "st.secondary.refresh"
|
||||
}
|
||||
valueTile("energy", "device.energy", decoration: "flat", width: 1, height: 1) {
|
||||
state "energy", label: '${currentValue} kWh'
|
||||
}
|
||||
valueTile("power", "device.power", decoration: "flat", width: 1, height: 1) {
|
||||
state "power", label: '${currentValue} W'
|
||||
}
|
||||
valueTile("voltage", "device.voltage", decoration: "flat", width: 1, height: 1) {
|
||||
state "voltage", label: '${currentValue} V'
|
||||
}
|
||||
valueTile("current", "device.current", decoration: "flat", width: 1, height: 1) {
|
||||
state "current", label: '${currentValue} A'
|
||||
}
|
||||
valueTile("frequency", "device.frequency", decoration: "flat", width: 1, height: 1) {
|
||||
state "frequency", label: '${currentValue} Hz'
|
||||
}
|
||||
valueTile("powerFactor", "device.powerFactor", decoration: "flat", width: 1, height: 1) {
|
||||
state "powerFactor", label: 'Power Factor ${currentValue}'
|
||||
}
|
||||
valueTile("apparentPower", "device.apparentPower", decoration: "flat", width: 1, height: 1) {
|
||||
state "apparentPower", label: '${currentValue} VA'
|
||||
}
|
||||
main(["switch", "energy", "power", "voltage", "current", "frequency", "powerFactor", "apparentPower"])
|
||||
details(["switch", "energy", "power", "voltage", "current", "frequency", "powerFactor", "apparentPower", "refresh"])
|
||||
}
|
||||
}
|
||||
|
||||
// Parse incoming device messages to generate events
|
||||
def parse(String description) {
|
||||
log.debug "Parse description $description"
|
||||
def events = []
|
||||
|
||||
if (description?.startsWith("catchall:")) {
|
||||
def msg = zigbee.parse(description)
|
||||
log.trace msg
|
||||
log.trace "data: $msg.data"
|
||||
} else if (description?.startsWith("read attr -")) {
|
||||
def descMap = parseDescriptionAsMap(description)
|
||||
log.debug "Read attr: $description"
|
||||
if (descMap.cluster == "0006" && descMap.attrId == "0000") {
|
||||
def value = descMap.value.endsWith("01") ? "on" : "off"
|
||||
def event = createEvent(name: "switch", value: value)
|
||||
events.add(event)
|
||||
} else if (descMap.cluster == "0702" && descMap.attrId == "8000") {
|
||||
// Payload length is 21 bytes, which is 42 characters
|
||||
def payload = descMap.raw.substring(descMap.raw.length() - 42, descMap.raw.length())
|
||||
log.trace "payload is $payload"
|
||||
|
||||
// Decode the various parameters from the payload
|
||||
def voltage = Integer.parseInt(payload.substring(0, 4), 16) / 100
|
||||
log.trace "voltage is $voltage"
|
||||
def voltageEvent = createEvent(name: "voltage", value: voltage)
|
||||
events.add(voltageEvent)
|
||||
|
||||
def current = Integer.parseInt(payload.substring(4, 8), 16) / 100
|
||||
log.trace "current is $current"
|
||||
def currentEvent = createEvent(name: "current", value: current)
|
||||
events.add(currentEvent)
|
||||
|
||||
def frequency = Integer.parseInt(payload.substring(8, 12), 16) / 100
|
||||
log.trace "frequency is $frequency"
|
||||
def frequencyEvent = createEvent(name: "frequency", value: frequency)
|
||||
events.add(frequencyEvent)
|
||||
|
||||
def powerFactor = Integer.parseInt(payload.substring(12, 14), 16) / 100
|
||||
log.trace "powerFactor is $powerFactor"
|
||||
def powerFactorEvent = createEvent(name: "powerFactor", value: powerFactor)
|
||||
events.add(powerFactorEvent)
|
||||
|
||||
def activePower = Integer.parseInt(payload.substring(14, 22), 16) / 100
|
||||
log.trace "activePower is $activePower"
|
||||
def powerEvent = createEvent(name: "power", value: activePower)
|
||||
events.add(powerEvent)
|
||||
|
||||
def apparentPower = Integer.parseInt(payload.substring(22, 30), 16) / 100
|
||||
log.trace "apparentPower is $apparentPower"
|
||||
def apparentPowerEvent = createEvent(name: "apparentPower", value: apparentPower)
|
||||
events.add(apparentPowerEvent)
|
||||
|
||||
def mainEnergy = Integer.parseInt(payload.substring(30, 42), 16) / 1000
|
||||
log.trace "mainEnergy is $mainEnergy"
|
||||
def energyEvent = createEvent(name: "energy", value: mainEnergy)
|
||||
events.add(energyEvent)
|
||||
}
|
||||
} else if (description?.startsWith("on/off:")) {
|
||||
log.debug "Switch command"
|
||||
def value = description?.endsWith(" 1") ? "on" : "off"
|
||||
def event = createEvent(name: "switch", value: value)
|
||||
events.add(event)
|
||||
}
|
||||
|
||||
log.debug "Parse returned ${events}"
|
||||
return events
|
||||
}
|
||||
|
||||
def parseDescriptionAsMap(description) {
|
||||
(description - "read attr - ").split(",").inject([:]) { map, param ->
|
||||
def nameAndValue = param.split(":")
|
||||
map += [(nameAndValue[0].trim()): nameAndValue[1].trim()]
|
||||
}
|
||||
}
|
||||
|
||||
// Commands to device
|
||||
def on() {
|
||||
// Fire event for on since meter doesn't suppport zigbee bind
|
||||
sendEvent(name: "switch", value: "on")
|
||||
'zcl on-off on'
|
||||
}
|
||||
|
||||
def off() {
|
||||
// Fire event for off since meter doesn't suppport zigbee bind
|
||||
sendEvent(name: "switch", value: "off")
|
||||
'zcl on-off off'
|
||||
}
|
||||
|
||||
def configure() {
|
||||
meterConfig() + onOffConfig() + refresh()
|
||||
}
|
||||
|
||||
// Meter reporting, min inteval 1 min and reporting interval if no activity as 4 min
|
||||
// min change in value is 01
|
||||
def meterConfig() {
|
||||
[
|
||||
"zcl global send-me-a-report 0x0702 0x8000 0x41 60 240 {01}",
|
||||
"send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
]
|
||||
}
|
||||
|
||||
def onOffConfig() {
|
||||
[
|
||||
"zcl global send-me-a-report 6 0 0x10 300 600 {01}",
|
||||
"send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
]
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
[
|
||||
"st rattr 0x${device.deviceNetworkId} 1 6 0", "delay 500",
|
||||
"st rattr 0x${device.deviceNetworkId} 1 0x0702 0x8000"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user