diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..fa12159 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,58 @@ +--- +kind: pipeline +type: kubernetes +name: build + + +steps: + # - name: test + # image: golang + # commands: + # - go test -v ./... + + # - name: describe + # image: jcollie/git + # commands: + # - git describe --dirty + + - name: build 32 bit arm + image: golang + environment: + GOOS: linux + GOARCH: arm + commands: + - go build -o ble-sensors-${DRONE_BUILD_STARTED} -v . + + - name: copy to hosts + image: appleboy/drone-scp + environment: + GOOS: linux + GOARCH: arm + settings: + host: + - "192.168.4.147" + username: root + key: + from_secret: drone_ssh_private_key + target: + - /opt/ble-sensors + source: + - ble-sensors-${DRONE_BUILD_STARTED} + - ble-sensors.service + - ble-sensors.yaml + + - name: deploy + image: appleboy/drone-ssh + settings: + host: + - "192.168.4.147" + username: root + key: + from_secret: drone_ssh_private_key + script: + - rm -f /opt/ble-sensors/ble-sensors + - mv /opt/ble-sensors/ble-sensors-${DRONE_BUILD_STARTED} /opt/ble-sensors/ble-sensors + - cp /opt/ble-sensors/ble-sensors.service /etc/systemd/system + - systemctl daemon-reload + - systemctl enable ble-sensors.service + - systemctl restart ble-sensors.service diff --git a/.gitignore b/.gitignore index 5070812..112a9d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -/.bluelisten.yaml +/ble-sensors* /bluelisten +/secrets.txt diff --git a/cmd/root.go b/cmd/root.go index 77cc919..9547b70 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,16 +5,18 @@ import ( "os" "github.com/spf13/cobra" + "go.uber.org/zap" - homedir "github.com/mitchellh/go-homedir" "github.com/spf13/viper" ) -var cfgFile string +var configFile string +var debug bool +var logger *zap.Logger // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "bluelisten", + Use: "ble-sensors", Short: "A brief description of your application", Long: `A longer description that spans multiple lines and likely contains examples and usage of using your application. For example: @@ -38,40 +40,32 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - - // Here you will define your flags and configuration settings. - // Cobra supports persistent flags, which, if defined here, - // will be global for your application. - - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.bluescale.yaml)") - - // Cobra also supports local flags, which will only run - // when this action is called directly. - // rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "config file") + rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "Turn debug messages on.") } -// initConfig reads in config file and ENV variables if set. func initConfig() { - if cfgFile != "" { - // Use config file from the flag. - viper.SetConfigFile(cfgFile) + if configFile != "" { + viper.SetConfigFile(configFile) } else { - // Find home directory. - home, err := homedir.Dir() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - viper.AddConfigPath(".") - viper.AddConfigPath(home) - viper.SetConfigName(".bluelisten") + viper.AddConfigPath("/opt/ble-sensors") + viper.SetConfigName("ble-sensors") } - - viper.AutomaticEnv() // read in environment variables that match - - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) + var err error + if debug { + logger, err = zap.NewDevelopment() + } else { + logger, err = zap.NewProduction() } + if err != nil { + fmt.Printf("unable to initialize logger: %s\n", err.Error()) + os.Exit(1) + } + err = viper.ReadInConfig() + if err != nil { + fmt.Printf("unable to open config file: %s\n", err.Error()) + os.Exit(1) + } + logger.Info("found config file", zap.String("filename", viper.ConfigFileUsed())) } diff --git a/cmd/scan.go b/cmd/scan.go index 969a693..a060d0b 100644 --- a/cmd/scan.go +++ b/cmd/scan.go @@ -5,9 +5,10 @@ import ( "os" "time" - "git.ocjtech.us/jeff/bluelisten/lib/bluetooth" - xiaomi_mijia "git.ocjtech.us/jeff/bluelisten/lib/xiaomi/mijia" - xiaomi_scale "git.ocjtech.us/jeff/bluelisten/lib/xiaomi/scale" + "git.ocjtech.us/jeff/ble-sensors/lib/bluetooth" + cleargrass "git.ocjtech.us/jeff/ble-sensors/lib/cleargrass" + xiaomi_mijia "git.ocjtech.us/jeff/ble-sensors/lib/xiaomi/mijia" + xiaomi_scale "git.ocjtech.us/jeff/ble-sensors/lib/xiaomi/scale" "github.com/go-ble/ble" "github.com/go-ble/ble/linux" influxdb2 "github.com/influxdata/influxdb-client-go" @@ -42,17 +43,13 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: - // listenCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + } var client influxdb2.Client var writeAPI influxdb2_api.WriteAPI -var logger *zap.Logger func listen(cmd *cobra.Command, args []string) { - logger, _ = zap.NewDevelopment() - defer logger.Sync() - logger.Debug("starting up") d, err := linux.NewDevice(ble.OptDeviceID(0)) @@ -74,6 +71,7 @@ func listen(cmd *cobra.Command, args []string) { writeAPI.Flush() client.Close() + logger.Sync() } var tileUUID ble.UUID = []byte{0xed, 0xfe} @@ -94,14 +92,15 @@ func advHandler(advertisement ble.Advertisement) { if description != "" { point.AddTag("description", description) } + point.AddTag("measurement", "rssi") point.AddTag("measurement_unit", "dBm") - point.AddField("rssi", advertisement.RSSI()) + point.AddField("value", advertisement.RSSI()) writeAPI.WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), zap.String("description", description), - zap.String("measurement", "RSSI"), + zap.String("measurement", "rssi"), zap.String("measurement_unit", "dBm"), zap.Int("value", advertisement.RSSI())) @@ -117,16 +116,30 @@ func advHandler(advertisement ble.Advertisement) { case sd.UUID.Equal(xiaomi_mijia.XiaomiMijiaHTV1UUID): xiaomi_mijia.ParseXiaomiMijiaSensorData(&writeAPI, logger, timestamp, detector, description, advertisement, index, sd) + case sd.UUID.Equal(cleargrass.CleargrassUUID): + cleargrass.ParseCleargrassSensorData(&writeAPI, logger, timestamp, detector, description, advertisement, index, sd) + case sd.UUID.Equal(tileUUID): - - case sd.UUID.Equal(nestUUID): - - default: - logger.Debug("unknown service data type", + logger.Debug("ignoring tile ble advertisement", zap.String("source", advertisement.Addr().String()), zap.String("description", description), zap.String("name", advertisement.LocalName()), zap.String("uuid", sd.UUID.String())) + + case sd.UUID.Equal(nestUUID): + logger.Debug("ignoring nest ble advertisement", + zap.String("source", advertisement.Addr().String()), + zap.String("description", description), + zap.String("name", advertisement.LocalName()), + zap.String("uuid", sd.UUID.String())) + + default: + logger.Info("unknown service data type", + zap.String("source", advertisement.Addr().String()), + zap.String("description", description), + zap.String("name", advertisement.LocalName()), + zap.String("uuid", sd.UUID.String()), + zap.Binary("data", sd.Data)) } } } diff --git a/go.mod b/go.mod index 3fb3445..dbfcdf7 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module git.ocjtech.us/jeff/bluelisten +module git.ocjtech.us/jeff/ble-sensors go 1.14 @@ -6,7 +6,6 @@ require ( github.com/go-ble/ble v0.0.0-20200407180624-067514cd6e24 github.com/influxdata/influxdb-client-go v1.4.0 github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.0.0 github.com/spf13/viper v1.7.1 diff --git a/go.sum b/go.sum index 9760aa5..a5b97ea 100644 --- a/go.sum +++ b/go.sum @@ -246,6 +246,7 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -273,6 +274,7 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -350,6 +352,7 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f h1:kDxGY2VmgABOe55qheT/TFqUMtcTHnomIPS1iv3G4Ms= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -392,5 +395,6 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/lib/cleargrass/sensor.go b/lib/cleargrass/sensor.go new file mode 100644 index 0000000..09f0ede --- /dev/null +++ b/lib/cleargrass/sensor.go @@ -0,0 +1,114 @@ +package cleargrass + +import ( + "encoding/binary" + "encoding/hex" + "time" + + "github.com/go-ble/ble" + influxdb2 "github.com/influxdata/influxdb-client-go" + influxdb2_api "github.com/influxdata/influxdb-client-go/api" + "go.uber.org/zap" +) + +// https://github.com/alexvenom/XiaomiCleargrassInkDislpay/blob/master/XiaomiClearGrassInk.js + +// CleargrassUUID is the Bluetooth UUID for Cleargrass BLE sensor data +var CleargrassUUID ble.UUID = []byte{0xcd, 0xfd} + +// ParseCleargrassSensorData . +func ParseCleargrassSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Logger, timestamp time.Time, detector string, description string, advertisement ble.Advertisement, index int, sd ble.ServiceData) { + logger.Debug("cleargrass", zap.String("event_data", hex.Dump(sd.Data)), + zap.Int("length", len(sd.Data))) + for eventOffset := 8; eventOffset < len(sd.Data)-2; { + eventType := sd.Data[eventOffset] + eventLength := int(sd.Data[eventOffset+1]) + if eventOffset+eventLength > len(sd.Data) { + logger.Warn("event length exceeds data length") + return + } + eventData := sd.Data[eventOffset+2 : eventOffset+2+eventLength] + eventOffset = eventOffset + 2 + eventLength + + switch eventType { + case 0x01: + if eventLength != 4 { + logger.Warn("temperature/humidity event length should be 4", + zap.String("event_data", hex.Dump(eventData))) + continue + } + temperature := float64(binary.LittleEndian.Uint16(eventData[0:2])) / 10 + point := influxdb2.NewPointWithMeasurement("sensor") + point.SetTime(timestamp) + if detector != "" { + point.AddTag("detector", detector) + } + point.AddTag("address", advertisement.Addr().String()) + + if description != "" { + point.AddTag("description", description) + } + point.AddTag("temperature_unit", "°C") + point.AddField("temperature", temperature) + (*writeAPI).WritePoint(point) + logger.Debug("sending sensor reading", + zap.String("source", advertisement.Addr().String()), + zap.String("description", description), + zap.String("measurement", "temperature"), + zap.String("measurement_unit", "°C"), + zap.Float64("value", temperature)) + + humidity := float64(binary.LittleEndian.Uint16(eventData[2:4])) / 10 + point = influxdb2.NewPointWithMeasurement("sensor") + point.SetTime(timestamp) + if detector != "" { + point.AddTag("detector", detector) + } + point.AddTag("address", advertisement.Addr().String()) + if description != "" { + point.AddTag("description", description) + } + point.AddTag("measurement_unit", "%") + point.AddField("humidity", humidity) + (*writeAPI).WritePoint(point) + logger.Debug("sending sensor reading", + zap.String("source", advertisement.Addr().String()), + zap.String("description", description), + zap.String("measurement", "humidity"), + zap.String("measurement_unit", "%"), + zap.Float64("value", humidity)) + + case 0x02: + if eventLength != 1 { + logger.Warn("battery event length should be 1") + continue + } + battery := int(eventData[0]) + point := influxdb2.NewPointWithMeasurement("sensor") + point.SetTime(timestamp) + if detector != "" { + point.AddTag("detector", detector) + } + point.AddTag("address", advertisement.Addr().String()) + if description != "" { + point.AddTag("description", description) + } + point.AddTag("measurement", "battery") + point.AddTag("measurement_unit", "%") + point.AddField("value", battery) + (*writeAPI).WritePoint(point) + logger.Debug("sending sensor reading", + zap.String("source", advertisement.Addr().String()), + zap.String("description", description), + zap.String("measurement", "battery"), + zap.String("measurement_unit", "%"), + zap.Int("value", battery)) + + default: + logger.Warn("unknown event type", + zap.Uint8("event_type", eventType), + zap.String("event_data", hex.Dump(eventData))) + } + } + +} diff --git a/lib/xiaomi/mijia/sensor.go b/lib/xiaomi/mijia/sensor.go index 1e53e19..9a76319 100644 --- a/lib/xiaomi/mijia/sensor.go +++ b/lib/xiaomi/mijia/sensor.go @@ -5,7 +5,6 @@ import ( "fmt" "time" - "git.ocjtech.us/jeff/bluelisten/lib/bluetooth" "github.com/go-ble/ble" influxdb2 "github.com/influxdata/influxdb-client-go" influxdb2_api "github.com/influxdata/influxdb-client-go/api" @@ -25,9 +24,21 @@ const ( temperatureAndHumidityEvent = 0x100d ) +const ( + isFactoryNewFlag = (1 << iota) + isConnectedFlag + isCentralFlag + isEncryptedFlag + hasMacAddressFlag + hasCapabilitiesFlag + hasEventFlag + hasCustomDataFlag + hasSubtitleFlag + hasBindingFlag +) + // ParseXiaomiMijiaSensorData parses func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Logger, timestamp time.Time, detector string, description string, advertisement ble.Advertisement, index int, sd ble.ServiceData) { - var sensorData struct { frameControl uint16 isFactoryNew bool @@ -63,16 +74,16 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo } } sensorData.frameControl = binary.LittleEndian.Uint16(sd.Data[0:]) - sensorData.isFactoryNew = sensorData.frameControl&(1<<0) != 0 - sensorData.isConnected = sensorData.frameControl&(1<<1) != 0 - sensorData.isCentral = sensorData.frameControl&(1<<2) != 0 - sensorData.isEncrypted = sensorData.frameControl&(1<<3) != 0 - sensorData.hasMacAddress = sensorData.frameControl&(1<<4) != 0 - sensorData.hasCapabilities = sensorData.frameControl&(1<<5) != 0 - sensorData.hasEvent = sensorData.frameControl&(1<<6) != 0 - sensorData.hasCustomData = sensorData.frameControl&(1<<7) != 0 - sensorData.hasSubtitle = sensorData.frameControl&(1<<8) != 0 - sensorData.hasBinding = sensorData.frameControl&(1<<9) != 0 + sensorData.isFactoryNew = sensorData.frameControl&isFactoryNewFlag != 0 + sensorData.isConnected = sensorData.frameControl&isConnectedFlag != 0 + sensorData.isCentral = sensorData.frameControl&isCentralFlag != 0 + sensorData.isEncrypted = sensorData.frameControl&isEncryptedFlag != 0 + sensorData.hasMacAddress = sensorData.frameControl&hasMacAddressFlag != 0 + sensorData.hasCapabilities = sensorData.frameControl&hasCapabilitiesFlag != 0 + sensorData.hasEvent = sensorData.frameControl&hasEventFlag != 0 + sensorData.hasCustomData = sensorData.frameControl&hasCustomDataFlag != 0 + sensorData.hasSubtitle = sensorData.frameControl&hasSubtitleFlag != 0 + sensorData.hasBinding = sensorData.frameControl&hasBindingFlag != 0 sensorData.version = (sensorData.frameControl >> 12) & 0x0f sensorData.productID = binary.LittleEndian.Uint16(sd.Data[2:]) sensorData.frameCounter = uint8(sd.Data[4]) @@ -92,6 +103,11 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo sensorData.capabilityData.central = sensorData.capabilities&(1<<1) != 0 sensorData.capabilityData.secure = sensorData.capabilities&(1<<2) != 0 sensorData.capabilityData.io = sensorData.capabilities & ((1 << 3) | (1 << 4)) // != 0 + logger.Debug("mijia capabilities", + zap.Bool("connectable", sensorData.capabilityData.connectable), + zap.Bool("central", sensorData.capabilityData.central), + zap.Bool("secure", sensorData.capabilityData.secure), + zap.Uint8("io", sensorData.capabilityData.io)) } if sensorData.isEncrypted { logger.Warn("packet is encrypted") @@ -119,12 +135,12 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo } point.AddTag("address", advertisement.Addr().String()) point.AddTag("product_id", fmt.Sprintf("%x", sensorData.productID)) - description := bluetooth.GetDescription(advertisement.Addr()) if description != "" { point.AddTag("description", description) } - point.AddTag("temperature_unit", "°C") - point.AddField("temperature", sensorData.eventData.temperature) + point.AddTag("measaurement", "temperature") + point.AddTag("measurement_unit", "°C") + point.AddField("value", sensorData.eventData.temperature) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), @@ -145,8 +161,9 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo if description != "" { point.AddTag("description", description) } - point.AddTag("humidity_unit", "%") - point.AddField("humidity", sensorData.eventData.humidity) + point.AddTag("measaurement", "humidity") + point.AddTag("measaurement_unit", "%") + point.AddField("value", sensorData.eventData.humidity) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), @@ -167,8 +184,9 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo if description != "" { point.AddTag("description", description) } - point.AddTag("illuminance_unit", "lx") - point.AddField("illuminance", sensorData.eventData.illuminance) + point.AddTag("measurement", "illuminance") + point.AddTag("measurement_unit", "lx") + point.AddField("value", sensorData.eventData.illuminance) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), @@ -189,8 +207,9 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo if description != "" { point.AddTag("description", description) } - point.AddTag("moisture_unit", "%") - point.AddField("moisture", sensorData.eventData.moisture) + point.AddTag("measurement", "moisture") + point.AddTag("measurement_unit", "%") + point.AddField("value", sensorData.eventData.moisture) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), @@ -211,13 +230,14 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo if description != "" { point.AddTag("description", description) } - point.AddTag("conductivity_unit", "µS/cm") - point.AddField("conductivity", sensorData.eventData.conductivity) + point.AddTag("measurement", "conductivity") + point.AddTag("measurement_unit", "µS/cm") + point.AddField("value", sensorData.eventData.conductivity) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), zap.String("description", description), - zap.String("measurement", "RSSI"), + zap.String("measurement", "conducivity"), zap.String("measurement_unit", "µS/cm"), zap.Int16("value", sensorData.eventData.conductivity)) @@ -233,8 +253,9 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo if description != "" { point.AddTag("description", description) } - point.AddTag("battery_unit", "%") - point.AddField("battery", sensorData.eventData.battery) + point.AddTag("measurement", "battery") + point.AddTag("measurement_unit", "%") + point.AddField("value", sensorData.eventData.battery) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), @@ -255,8 +276,9 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo if description != "" { point.AddTag("description", description) } - point.AddTag("temperature_unit", "°C") - point.AddField("temperature", sensorData.eventData.temperature) + point.AddTag("measurement", "temperature") + point.AddTag("measurement_unit", "°C") + point.AddField("value", sensorData.eventData.temperature) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), @@ -276,8 +298,9 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo if description != "" { point.AddTag("description", description) } - point.AddTag("humidity_unit", "%") - point.AddField("humidity", sensorData.eventData.humidity) + point.AddTag("measurement", "humidity") + point.AddTag("measurement_unit", "%") + point.AddField("value", sensorData.eventData.humidity) (*writeAPI).WritePoint(point) logger.Debug("sending sensor reading", zap.String("source", advertisement.Addr().String()), @@ -287,10 +310,12 @@ func ParseXiaomiMijiaSensorData(writeAPI *influxdb2_api.WriteAPI, logger *zap.Lo zap.Float64("value", sensorData.eventData.humidity)) default: - logger.Warn("unknown event type", + logger.Debug("unknown event type", zap.String("source", advertisement.Addr().String()), zap.String("description", description), - zap.Uint16("event_type", sensorData.eventData.eventType)) + zap.Uint16("event_type", sensorData.eventData.eventType), + zap.Binary("data", sd.Data), + zap.Binary("event_data", sd.Data[eventOffset+3:])) } } } diff --git a/main.go b/main.go index e6f8bea..a2df31f 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -import "git.ocjtech.us/jeff/bluelisten/cmd" +import "git.ocjtech.us/jeff/ble-sensors/cmd" func main() { cmd.Execute()