ble-sensors/lib/xiaomi/scale/scale_v2.go

96 lines
2.5 KiB
Go
Raw Normal View History

2020-08-08 19:00:41 -05:00
package scale
import (
"bytes"
"encoding/binary"
"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 {
2020-08-13 00:46:28 -05:00
point := influxdb2.NewPointWithMeasurement("weight")
2020-09-04 20:03:59 -05:00
point.SetTime(timestamp)
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)
point.AddField("value", weight)
2020-09-04 20:03:59 -05:00
(*writeAPI).WritePoint(point)
2020-08-08 19:00:41 -05:00
if hasImpedance {
2020-09-04 20:03:59 -05:00
point := influxdb2.NewPointWithMeasurement("impedance")
point.SetTime(timestamp)
if detector != "" {
point.AddTag("detector", detector)
}
point.AddTag("address", advertisement.Addr().String())
if description != "" {
point.AddTag("description", description)
}
point.AddTag("unit", "kg")
2020-08-08 19:00:41 -05:00
point.AddField("impedance", scaleData.Impedance)
2020-09-04 20:03:59 -05:00
(*writeAPI).WritePoint(point)
2020-08-08 19:00:41 -05:00
}
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
}
}