mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-17 13:10:52 +00:00
Initial commit
This commit is contained in:
189
devicetypes/smartthings/wireless-scale.src/wireless-scale.groovy
Normal file
189
devicetypes/smartthings/wireless-scale.src/wireless-scale.groovy
Normal file
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Smart Body Analyzer
|
||||
*
|
||||
* Author: SmartThings
|
||||
* Date: 2013-09-27
|
||||
*/
|
||||
metadata {
|
||||
definition (name: "Wireless Scale", namespace: "smartthings", author: "SmartThings") {
|
||||
capability "Polling"
|
||||
|
||||
attribute "weight", "string"
|
||||
attribute "leanMass", "string"
|
||||
attribute "fatRatio", "string"
|
||||
attribute "fatMass", "string"
|
||||
|
||||
command "storeGraphImage"
|
||||
}
|
||||
|
||||
simulator {
|
||||
// TODO: define status and reply messages here
|
||||
}
|
||||
|
||||
tiles {
|
||||
standardTile("icon", "icon", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false) {
|
||||
state "default", label: "Withings", action: "", icon: "st.Bath.bath2", backgroundColor: "#FFFFFF"
|
||||
}
|
||||
|
||||
plotTile("weightGraph", "device.weight", "scatter", width:2, height:1, content:"weightPoints")
|
||||
valueTile("weight", "device.weight", width: 1, height: 1) {
|
||||
state("weight", label:'${currentValue} lbs', unit:"lbs", inactiveLabel: false)
|
||||
}
|
||||
|
||||
plotTile("fatGraph", "device.fatRatio", "scatter", width:2, height:1, content:"fatPoints")
|
||||
valueTile("fatRatio", "device.fatRatio", width: 1, height: 1) {
|
||||
state("fatRatio", label:'${currentValue}% bodyfat', unit:"bodyfat", inactiveLabel: false)
|
||||
}
|
||||
|
||||
standardTile("refresh", "command.refresh", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:'', action:"polling.poll", icon:"st.secondary.refresh"
|
||||
}
|
||||
|
||||
main "icon"
|
||||
details(["weightGraph", "weight", "fatGraph", "fatRatio", "refresh"])
|
||||
}
|
||||
}
|
||||
|
||||
mappings {
|
||||
path("/weightPoints") {
|
||||
action: [
|
||||
GET: "weightPoints"
|
||||
]
|
||||
}
|
||||
path("/fatPoints") {
|
||||
action: [
|
||||
GET: "fatPoints"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
log.debug "Parsing '${description}'"
|
||||
}
|
||||
|
||||
def parse(Map event) {
|
||||
log.debug "Parsing '${event}'"
|
||||
|
||||
if(event.status == 200 && event.data)
|
||||
{
|
||||
parent.parse(event)
|
||||
return null
|
||||
}
|
||||
else if(["weight", "leanMass", "fatRatio", "fatMass"].contains(event.name) && event.date)
|
||||
{
|
||||
def dateString = event.date
|
||||
data["measure.${event.name}.$dateString"] = event.value
|
||||
|
||||
def old = "measure.${event.name}." + (new Date() - 30).format('yyyy-MM-dd')
|
||||
data.findAll { it.key.startsWith("measure.${event.name}.") && it.key < old }.collect { it.key }.each { state.remove(it) }
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
def storeGraphImage(String name, ByteArrayInputStream is, String contentType) {
|
||||
storeImage(name, is, contentType)
|
||||
}
|
||||
|
||||
def poll() {
|
||||
log.debug "Executing 'poll'"
|
||||
parent.poll()
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
log.debug "Executing 'refresh'"
|
||||
sendEvent(name:"refreshing", description:"Refreshing Withings data", displayed:true)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
def measurementPoints(name) {
|
||||
def points = []
|
||||
|
||||
def wdata = normalizeMeasurementPoints(name)
|
||||
log.debug "data: ${wdata}"
|
||||
def allValues = wdata.collect { it.y }
|
||||
log.debug "allValues: ${allValues}"
|
||||
|
||||
def min = allValues.min()
|
||||
def max = allValues.max()
|
||||
|
||||
def minMax = [:]
|
||||
minMax[min] = min
|
||||
minMax[max] = max
|
||||
log.debug "minMax: $minMax"
|
||||
|
||||
wdata.reverse().each { it ->
|
||||
points << plotPoint(it.x, it.y, minMax)
|
||||
}
|
||||
log.debug "points: ${points}"
|
||||
|
||||
return points.reverse()
|
||||
}
|
||||
|
||||
private normalizeMeasurementPoints(name) {
|
||||
def measurementData = data.findAll { it.key.startsWith("measure.${name}.") }
|
||||
log.debug "measurementData: ${measurementData}"
|
||||
|
||||
def normalizedData = []
|
||||
measurementData.each { k, v ->
|
||||
def d = Date.parse('yyyy-MM-dd', k - "measure.${name}.")
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(d)
|
||||
// BUG: DOES NOT HANDLE NEW YEAR PROPERLY
|
||||
// Should concat YEAR + (PAD_LEFT(DAY_OF_YEAR))
|
||||
// 2013365 == Dec. 31, 2013
|
||||
// 2014001 == Jan. 1, 2014
|
||||
normalizedData << [x:cal.get(Calendar.DAY_OF_YEAR), y:v]
|
||||
}
|
||||
log.debug "normalizedData: ${normalizedData}"
|
||||
|
||||
normalizedData.sort{ it.x }
|
||||
}
|
||||
|
||||
private plotPoint(x, y, minMax) {
|
||||
def removed = minMax.remove(y) != null
|
||||
|
||||
return [
|
||||
color:"",
|
||||
fillColor: removed ? "" : "#f3f3f3",
|
||||
symbolStyle:"elipse",
|
||||
point:y,
|
||||
label: removed ? "${y}" : "",
|
||||
x:x,
|
||||
y:y
|
||||
]
|
||||
}
|
||||
|
||||
def weightPoints() {
|
||||
return [
|
||||
"title":"My Weight",
|
||||
"plots":[
|
||||
"weight":[
|
||||
"points":measurementPoints("weight")
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
def fatPoints() {
|
||||
return [
|
||||
"title":"Bodyfat %",
|
||||
"plots":[
|
||||
"fat":[
|
||||
"points":measurementPoints("fatRatio")
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user