2020-08-08 19:00:41 -05:00
|
|
|
package scale
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"log"
|
|
|
|
"time"
|
|
|
|
|
2020-08-09 07:23:47 -05:00
|
|
|
"github.com/go-ble/ble"
|
2020-08-08 19:00:41 -05:00
|
|
|
influxdb2 "github.com/influxdata/influxdb-client-go"
|
|
|
|
influxdb2_api "github.com/influxdata/influxdb-client-go/api"
|
2020-08-09 07:23:47 -05:00
|
|
|
"go.uber.org/zap"
|
2020-08-08 19:00:41 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
// XiaomiScaleV2UUID is BLE UUID for Xiaomi Scale V2
|
|
|
|
var XiaomiScaleV2UUID ble.UUID = []byte{0x1b, 0x18}
|
|
|
|
|
|
|
|
// ParseXiaomiScaleV2 parses V2 scale service data
|
2020-08-09 07:23:47 -05:00
|
|
|
func ParseXiaomiScaleV2(writeAPI *influxdb2_api.WriteAPI, logger *zap.Logger, timestamp time.Time, detector string, description string, advertisement ble.Advertisement, index int, sd ble.ServiceData) {
|
2020-08-08 19:00:41 -05:00
|
|
|
|
|
|
|
var scaleData struct {
|
|
|
|
RawUnit uint8
|
|
|
|
ControlByte uint8
|
|
|
|
Year uint16
|
|
|
|
Month uint8
|
|
|
|
Day uint8
|
|
|
|
Hour uint8
|
|
|
|
Minute uint8
|
|
|
|
Second uint8
|
|
|
|
Impedance uint16
|
|
|
|
RawWeight uint16
|
|
|
|
}
|
|
|
|
err := binary.Read(bytes.NewBuffer(sd.Data), binary.LittleEndian, &scaleData)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
isStabilized := (scaleData.ControlByte & (1 << 5)) != 0
|
|
|
|
hasImpedance := (scaleData.ControlByte & (1 << 1)) != 0
|
|
|
|
|
|
|
|
var originalUnit string
|
|
|
|
var weight float64
|
|
|
|
|
|
|
|
switch scaleData.RawUnit {
|
|
|
|
case 3:
|
|
|
|
originalUnit = "lbs"
|
|
|
|
weight = float64(scaleData.RawWeight) / 100.0 * 0.453592
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
originalUnit = "kg"
|
|
|
|
weight = float64(scaleData.RawWeight) / 200.0
|
|
|
|
|
|
|
|
default:
|
|
|
|
originalUnit = "unknown"
|
|
|
|
weight = float64(scaleData.RawWeight)
|
|
|
|
}
|
|
|
|
|
|
|
|
if isStabilized {
|
|
|
|
loc, err := time.LoadLocation("Local")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
scaleTimestamp := time.Date(
|
|
|
|
int(scaleData.Year),
|
|
|
|
time.Month(scaleData.Month),
|
|
|
|
int(scaleData.Day),
|
|
|
|
int(scaleData.Hour),
|
|
|
|
int(scaleData.Minute),
|
|
|
|
int(scaleData.Second),
|
|
|
|
0,
|
|
|
|
loc)
|
|
|
|
difference := timestamp.Sub(scaleTimestamp)
|
|
|
|
|
2020-08-13 00:46:28 -05:00
|
|
|
point := influxdb2.NewPointWithMeasurement("weight")
|
2020-08-08 19:00:41 -05:00
|
|
|
point.SetTime(scaleTimestamp)
|
2020-08-09 07:23:47 -05:00
|
|
|
if detector != "" {
|
|
|
|
point.AddTag("detector", detector)
|
2020-08-08 19:00:41 -05:00
|
|
|
}
|
2020-08-09 07:23:47 -05:00
|
|
|
point.AddTag("address", advertisement.Addr().String())
|
2020-08-13 00:46:28 -05:00
|
|
|
if description != "" {
|
|
|
|
point.AddTag("description", description)
|
|
|
|
}
|
|
|
|
point.AddTag("unit", "kg")
|
|
|
|
point.AddTag("original_unit", originalUnit)
|
2020-08-09 07:23:47 -05:00
|
|
|
point.AddField("time_difference", difference.Seconds())
|
2020-08-13 00:46:28 -05:00
|
|
|
point.AddField("value", weight)
|
2020-08-08 19:00:41 -05:00
|
|
|
if hasImpedance {
|
|
|
|
point.AddField("impedance", scaleData.Impedance)
|
|
|
|
}
|
|
|
|
(*writeAPI).WritePoint(point)
|
|
|
|
|
2020-08-09 07:23:47 -05:00
|
|
|
logger.Debug("xiaomi v2 scale",
|
|
|
|
zap.String("name", advertisement.LocalName()),
|
|
|
|
zap.String("source", advertisement.Addr().String()),
|
|
|
|
zap.String("description", description),
|
|
|
|
zap.Bool("is_stabilized", isStabilized),
|
|
|
|
zap.Bool("has_impedance", hasImpedance),
|
|
|
|
zap.Float64("weight", weight))
|
|
|
|
|
2020-08-08 19:00:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|