| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- package main
- import (
- "fmt"
- "sync"
- "github.com/sirupsen/logrus"
- "lc/common/protocol"
- )
- type ModelInfo struct {
- TID uint16
- Flag int
- }
- type Device interface {
- Start()
- Stop()
- UpdateInfo(devinfo protocol.DevInfo)
- GetDevInfo() *protocol.DevInfo
- UpdateModel(tid uint16, flag int)
- }
- func CreateDevice(t uint8, devinfo *protocol.DevInfo) Device {
- var device Device
- switch t {
- case 0:
- device = NewModbusRtu(devinfo)
- case 1:
- device = NewConcentrator(devinfo)
- case 2:
- device = NewYmLampController(devinfo)
- default:
- logrus.Errorf("AddDevices:不支持的协议的设备:mode=%d", t)
- }
- return device
- }
- var _onceGetDeviceMgr sync.Once
- var _singleSerialMgr *DeviceMgr
- func GetDeviceMgr() *DeviceMgr {
- _onceGetDeviceMgr.Do(func() {
- _singleSerialMgr = &DeviceMgr{mapDevice: make(map[string]Device)}
- })
- return _singleSerialMgr
- }
- type DeviceMgr struct {
- mu sync.Mutex
- mapDevice map[string]Device
- }
- func validateDevInfos(devinfos []protocol.DevInfo) error {
- for i := range devinfos {
- v := &devinfos[i]
- if v.DevCode == "" {
- return fmt.Errorf("DevCode 不能为空")
- }
- if v.TID == 0 {
- return fmt.Errorf("设备[%s]的 TID 不能为 0,请指定正确的物模型ID", v.DevCode)
- }
- if v.ProtocolType > 2 {
- return fmt.Errorf("设备[%s]的 ProtocolType=%d 不支持,仅支持 0(ModbusRTU) 1(Zigbee) 2(裕明485)", v.DevCode, v.ProtocolType)
- }
- // 同批次内 DevCode 唯一性
- for j := i + 1; j < len(devinfos); j++ {
- if v.DevCode == devinfos[j].DevCode {
- return fmt.Errorf("同一文件中 DevCode=%s 重复", v.DevCode)
- }
- }
- // 同批次内同一 Code 下 DevID 冲突检测
- for j := i + 1; j < len(devinfos); j++ {
- if v.Code == devinfos[j].Code && v.DevID == devinfos[j].DevID {
- return fmt.Errorf("同一串口[Code=%d]下 DevID=%d 冲突(设备 %s 和 %s)", v.Code, v.DevID, v.DevCode, devinfos[j].DevCode)
- }
- }
- }
- return nil
- }
- func (o *DeviceMgr) checkDevIDConflict(v *protocol.DevInfo) error {
- for _, exist := range o.mapDevice {
- ei := exist.GetDevInfo()
- if ei.Code == v.Code && ei.DevID == v.DevID && ei.DevCode != v.DevCode {
- return fmt.Errorf("串口[Code=%d]下 DevID=%d 已被设备[%s]占用,设备[%s]不能使用相同地址",
- v.Code, v.DevID, ei.DevCode, v.DevCode)
- }
- }
- return nil
- }
- // AddDevices 新增
- func (o *DeviceMgr) AddDevices(devinfos []protocol.DevInfo) {
- if err := validateDevInfos(devinfos); err != nil {
- logrus.Errorf("AddDevices: 配置校验失败: %v", err)
- return
- }
- o.mu.Lock()
- defer o.mu.Unlock()
- for _, v := range devinfos {
- if _, ok := o.mapDevice[v.DevCode]; ok {
- logrus.Errorf("AddDevices:已添加该设备,不可重复添加:devcode=%s", v.DevCode)
- continue
- }
- if err := o.checkDevIDConflict(&v); err != nil {
- logrus.Errorf("AddDevices: %v", err)
- continue
- }
- di := v
- if device := CreateDevice(v.ProtocolType, &di); device != nil {
- device.Start()
- o.mapDevice[v.DevCode] = device
- }
- }
- }
- // RemoveDevice 删除
- func (o *DeviceMgr) RemoveDevice(devcode string) {
- o.mu.Lock()
- defer o.mu.Unlock()
- if device, ok := o.mapDevice[devcode]; ok {
- device.Stop()
- delete(o.mapDevice, devcode)
- }
- }
- // UpdateDevices 新增或修改
- func (o *DeviceMgr) UpdateDevices(code uint8, devinfos []protocol.DevInfo) {
- if len(devinfos) > 0 {
- if err := validateDevInfos(devinfos); err != nil {
- logrus.Errorf("UpdateDevices: 配置校验失败: %v", err)
- return
- }
- }
- //先遍历devinfos
- mapDevinfos := make(map[string]*protocol.DevInfo)
- for _, v := range devinfos {
- mapDevinfos[v.DevCode] = &v
- }
- o.mu.Lock()
- defer o.mu.Unlock()
- if len(devinfos) == 0 {
- for k, v := range o.mapDevice {
- if v.GetDevInfo().Code == code {
- v.Stop()
- delete(o.mapDevice, k)
- }
- }
- return
- }
- //先删除不再用的设备
- for k, v := range o.mapDevice {
- if v.GetDevInfo().Code != code {
- continue
- }
- if _, ok := mapDevinfos[k]; !ok {
- v.Stop()
- delete(o.mapDevice, k)
- }
- }
- //再添加新的设备或更新设备
- for _, v := range devinfos {
- if device, ok := o.mapDevice[v.DevCode]; ok {
- old := device.GetDevInfo()
- if v.ProtocolType == old.ProtocolType { //设备类型没变
- device.UpdateInfo(v) //更新设备信息
- if v.TID != old.TID { //更新物模型信息
- device.UpdateModel(v.TID, 3)
- }
- continue
- } else {
- device.Stop()
- delete(o.mapDevice, v.DevCode)
- }
- } else {
- if err := o.checkDevIDConflict(&v); err != nil {
- logrus.Errorf("UpdateDevices: %v", err)
- continue
- }
- }
- if device := CreateDevice(v.ProtocolType, &v); device != nil {
- device.Start()
- o.mapDevice[v.DevCode] = device
- }
- }
- }
- // GetDevice 查询
- func (o *DeviceMgr) GetDevice(devcode string) Device {
- o.mu.Lock()
- defer o.mu.Unlock()
- if device, ok := o.mapDevice[devcode]; ok {
- return device
- }
- return nil
- }
- // StopDevice 停止
- func (o *DeviceMgr) StopDevice(devcode string) {
- o.mu.Lock()
- defer o.mu.Unlock()
- if device, ok := o.mapDevice[devcode]; ok {
- device.Stop()
- delete(o.mapDevice, devcode)
- }
- }
- // StopAllDevice 停止所有
- func (o *DeviceMgr) StopAllDevice() {
- o.mu.Lock()
- defer o.mu.Unlock()
- for k, v := range o.mapDevice {
- v.Stop()
- delete(o.mapDevice, k)
- }
- }
- // UpdateModel 更新模型
- func (o *DeviceMgr) UpdateModel(tid uint16, flag int) {
- o.mu.Lock()
- defer o.mu.Unlock()
- for _, v := range o.mapDevice {
- v.UpdateModel(tid, flag)
- }
- }
|