厂家数据接收完成

This commit is contained in:
wyh 2022-03-04 11:31:06 +08:00
parent c977643f79
commit b86186937b
7 changed files with 207 additions and 61 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ cok-ble
*.sum
*.yml
*.yaml
logs

2
go.mod
View File

@ -3,11 +3,11 @@ module myschools.me/wyh/ble-april
go 1.16
require (
github.com/eclipse/paho.mqtt.golang v1.3.5
github.com/gin-gonic/gin v1.7.7
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lestrrat-go/strftime v1.0.5 // indirect
github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/shirou/gopsutil v2.21.11+incompatible
github.com/sirupsen/logrus v1.8.1

View File

@ -6,6 +6,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"myschools.me/wyh/ble-april/gin"
"myschools.me/wyh/ble-april/mosquitto"
"myschools.me/wyh/ble-april/service"
)
@ -22,9 +23,14 @@ func main() {
"func": "main",
}).Fatalf("%s", err.Error())
}
mosquitto.Init(&mosquitto.Config{
Host: viper.GetString("mosquitto.host"),
Username: viper.GetString("mosquitto.username"),
Password: viper.GetString("mosquitto.password"),
})
//ble服务
service.BleService()
service.BleDelivery()
go service.BleMessagePush()
go service.BleCacheClear()
go service.Bletokeninit()

7
mosquitto/config.go Normal file
View File

@ -0,0 +1,7 @@
package mosquitto
type Config struct {
Host string
Username string
Password string
}

23
mosquitto/handler.go Normal file
View File

@ -0,0 +1,23 @@
package mosquitto
import (
"fmt"
MQTT "github.com/eclipse/paho.mqtt.golang"
)
var connHandler MQTT.OnConnectHandler = func(client MQTT.Client) {
token := client.Subscribe("#", 0, serviceHandler)
if token.Wait() && token.Error() != nil {
fmt.Println(token.Error())
}
}
var connLostHandler MQTT.ConnectionLostHandler = func(client MQTT.Client, err error) {
fmt.Println(err.Error())
}
//具体业务订阅的处理,此处为示例
var serviceHandler MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
fmt.Println(msg.Topic())
}

103
mosquitto/mosquitto.go Normal file
View File

@ -0,0 +1,103 @@
package mosquitto
import (
"encoding/json"
"errors"
MQTT "github.com/eclipse/paho.mqtt.golang"
)
var (
clientSubscribe, clientDistribute MQTT.Client
config *Config
)
func Init(c *Config) {
config = c
if config == nil {
config = &Config{
Host: "tcp://127.0.0.1:1883",
}
}
}
func Options() *MQTT.ClientOptions {
opts := MQTT.NewClientOptions()
opts.AddBroker(config.Host)
opts.Username = config.Username
opts.Password = config.Password
return opts
}
func New() (MQTT.Client, error) {
if clientDistribute != nil {
return clientDistribute, nil
}
opts := Options()
clientDistribute = MQTT.NewClient(opts)
token := clientDistribute.Connect()
if token.Wait() && token.Error() != nil {
clientDistribute = nil
return nil, token.Error()
}
return clientDistribute, nil
}
//订阅当事件为nil时可获取client
func Subscribe(connHandler MQTT.OnConnectHandler, lostHandler MQTT.ConnectionLostHandler) error {
if connHandler == nil {
return errors.New("handler is nil")
}
opts := Options()
opts.OnConnect = connHandler //当连接成功后调用注册
if lostHandler != nil {
opts.OnConnectionLost = lostHandler
}
if clientSubscribe == nil {
clientSubscribe = MQTT.NewClient(opts)
}
token := clientSubscribe.Connect()
if token.Wait() && token.Error() != nil {
clientSubscribe = nil
return token.Error()
}
return nil
}
//取消订阅
func UnSubscribe(topic string) {
if clientSubscribe == nil {
return
}
c := clientSubscribe
c.Unsubscribe(topic)
c.Disconnect(250)
}
//分发
func Distribute(topic *string, qos int, retained bool, payload *[]byte) error {
c, err := New()
if err != nil {
return err
}
token := c.Publish(*topic, byte(qos), retained, *payload)
if token.Wait() && token.Error() != nil {
return token.Error()
}
return nil
}
//分发Object
func DistributeObject(topic *string, qos int, retained bool, obj interface{}) error {
payload, err := json.Marshal(obj)
if err != nil {
return err
}
return Distribute(topic, qos, retained, &payload)
}

View File

@ -1,24 +1,23 @@
package service
import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
"time"
"github.com/paypal/gatt"
"github.com/paypal/gatt/examples/option"
MQTT "github.com/eclipse/paho.mqtt.golang"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/mem"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"github.com/vmihailenco/msgpack"
"myschools.me/wyh/ble-april/mosquitto"
)
var m map[string]*IBeancon
@ -94,47 +93,46 @@ func Bletokeninit() {
}
//蓝牙接收服务
func BleService() {
go func() {
dev, err := gatt.NewDevice(option.DefaultClientOptions...)
if err != nil {
log.Fatalf("Failed to open device, err:%s\n", err)
var connHandler MQTT.OnConnectHandler = func(client MQTT.Client) {
token := client.Subscribe("gw/april", 0, serviceHandler)
if token.Wait() && token.Error() != nil {
fmt.Println(token.Error())
}
}
var connLostHandler MQTT.ConnectionLostHandler = func(client MQTT.Client, err error) {
fmt.Println(err.Error())
}
//具体业务订阅的处理,此处为示例
var serviceHandler MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
out1 := make(map[string]interface{}, 0)
if err := msgpack.Unmarshal(msg.Payload(), &out1); err != nil {
logrus.WithFields(logrus.Fields{
"func": "NewiBeacon",
}).Warnf("%s", err.Error())
return
}
// 解析out1.device
bles := BleDecode(out1["devices"].([]interface{}))
for _, d := range bles {
chn <- &IBeancon{
DeviceID: fmt.Sprintf("%s:%s:%s:%s:%s:%s", d.Mac[0:2], d.Mac[2:4], d.Mac[4:6], d.Mac[6:8], d.Mac[8:10], d.Mac[10:12]),
HappenTime: time.Now(),
Updated: time.Now().Unix(),
}
dev.Handle(
gatt.PeripheralDiscovered(onPerhipheralDiscovered),
)
dev.Init(onStateChanged)
}()
}
func onStateChanged(device gatt.Device, s gatt.State) {
switch s {
case gatt.StatePoweredOn:
device.Scan([]gatt.UUID{}, true)
return
default:
device.StopScanning()
}
}
func onPerhipheralDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
//小于设定阈值不处理
if rssi < viper.GetInt("option.rssi") {
return
}
// 实例化蓝牙数据
b, err := NewiBeacon(a.ManufacturerData, p.ID())
if err != nil {
return
}
if beacon := m[b.DeviceID]; beacon != nil {
beacon.Updated = b.HappenTime.Unix()
m[b.DeviceID] = beacon
func BleDelivery() {
if err := mosquitto.Subscribe(connHandler, connLostHandler); err != nil {
logrus.WithFields(logrus.Fields{
"func": "BleDelivery",
}).Warnf("%s", err.Error())
return
}
// 更新持续时长和更新时间
chn <- b
}
// 取出数据进行处理
@ -293,30 +291,23 @@ type BeaconAprilBag struct {
type BeaconApril struct {
AdvType string
Mac string
Rssi int
Rssi string
AdvertisementData string
}
func NewiBeacon(data []byte, mac string) (*IBeancon, error) {
out1 := &BeaconAprilBag{}
if err := msgpack.Unmarshal(data, &out1); err != nil {
logrus.WithFields(logrus.Fields{
"func": "NewiBeacon",
}).Warnf("%s", err.Error())
return nil, err
}
// 解析out1.device
// bytes.Split()
// func NewiBeacon(data []byte, mac string) (*IBeancon, error) {
if len(data) < 25 || binary.BigEndian.Uint32(data) != 0x4c000215 {
return nil, errors.New("not an iBeacon")
}
beacon := new(IBeancon)
beacon.DeviceID = mac
beacon.HappenTime = time.Now()
beacon.Updated = time.Now().Unix()
return beacon, nil
}
// // bytes.Split()
// if len(data) < 25 || binary.BigEndian.Uint32(data) != 0x4c000215 {
// return nil, errors.New("not an iBeacon")
// }
// beacon := new(IBeancon)
// beacon.DeviceID = blespril.Mac
// beacon.HappenTime = time.Now()
// beacon.Updated = time.Now().Unix()
// return beacon, nil
// }
// 清除缓存
func BleCacheClear() {
@ -335,3 +326,18 @@ func BleCacheClear() {
time.Sleep(time.Duration(t/5) * time.Second)
}
}
// 蓝牙解密
func BleDecode(data []interface{}) []*BeaconApril {
bles := make([]*BeaconApril, 0)
for _, val := range data {
vals := strings.ToUpper(hex.EncodeToString(val.([]byte)))
bles = append(bles, &BeaconApril{
AdvType: vals[0:2],
Mac: vals[2:14],
Rssi: vals[14:16],
AdvertisementData: vals[16:],
})
}
return bles
}