Initial commit

This commit is contained in:
bflorian
2015-08-04 15:49:03 -07:00
commit 6ad3c4fd7a
322 changed files with 67201 additions and 0 deletions

View 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")
]
]
]
}