厂家数据接收完成
This commit is contained in:
parent
c977643f79
commit
b86186937b
|
|
@ -3,3 +3,4 @@ cok-ble
|
|||
*.sum
|
||||
*.yml
|
||||
*.yaml
|
||||
logs
|
||||
2
go.mod
2
go.mod
|
|
@ -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
|
||||
|
|
|
|||
8
main.go
8
main.go
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package mosquitto
|
||||
|
||||
type Config struct {
|
||||
Host string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
|
@ -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())
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue