devmgr.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "github.com/sirupsen/logrus"
  6. "lc/common/protocol"
  7. )
  8. type ModelInfo struct {
  9. TID uint16
  10. Flag int
  11. }
  12. type Device interface {
  13. Start()
  14. Stop()
  15. UpdateInfo(devinfo protocol.DevInfo)
  16. GetDevInfo() *protocol.DevInfo
  17. UpdateModel(tid uint16, flag int)
  18. }
  19. func CreateDevice(t uint8, devinfo *protocol.DevInfo) Device {
  20. var device Device
  21. switch t {
  22. case 0:
  23. device = NewModbusRtu(devinfo)
  24. case 1:
  25. device = NewConcentrator(devinfo)
  26. case 2:
  27. device = NewYmLampController(devinfo)
  28. default:
  29. logrus.Errorf("AddDevices:不支持的协议的设备:mode=%d", t)
  30. }
  31. return device
  32. }
  33. var _onceGetDeviceMgr sync.Once
  34. var _singleSerialMgr *DeviceMgr
  35. func GetDeviceMgr() *DeviceMgr {
  36. _onceGetDeviceMgr.Do(func() {
  37. _singleSerialMgr = &DeviceMgr{mapDevice: make(map[string]Device)}
  38. })
  39. return _singleSerialMgr
  40. }
  41. type DeviceMgr struct {
  42. mu sync.Mutex
  43. mapDevice map[string]Device
  44. }
  45. func validateDevInfos(devinfos []protocol.DevInfo) error {
  46. for i := range devinfos {
  47. v := &devinfos[i]
  48. if v.DevCode == "" {
  49. return fmt.Errorf("DevCode 不能为空")
  50. }
  51. if v.TID == 0 {
  52. return fmt.Errorf("设备[%s]的 TID 不能为 0,请指定正确的物模型ID", v.DevCode)
  53. }
  54. if v.ProtocolType > 2 {
  55. return fmt.Errorf("设备[%s]的 ProtocolType=%d 不支持,仅支持 0(ModbusRTU) 1(Zigbee) 2(裕明485)", v.DevCode, v.ProtocolType)
  56. }
  57. // 同批次内 DevCode 唯一性
  58. for j := i + 1; j < len(devinfos); j++ {
  59. if v.DevCode == devinfos[j].DevCode {
  60. return fmt.Errorf("同一文件中 DevCode=%s 重复", v.DevCode)
  61. }
  62. }
  63. // 同批次内同一 Code 下 DevID 冲突检测
  64. for j := i + 1; j < len(devinfos); j++ {
  65. if v.Code == devinfos[j].Code && v.DevID == devinfos[j].DevID {
  66. return fmt.Errorf("同一串口[Code=%d]下 DevID=%d 冲突(设备 %s 和 %s)", v.Code, v.DevID, v.DevCode, devinfos[j].DevCode)
  67. }
  68. }
  69. }
  70. return nil
  71. }
  72. func (o *DeviceMgr) checkDevIDConflict(v *protocol.DevInfo) error {
  73. for _, exist := range o.mapDevice {
  74. ei := exist.GetDevInfo()
  75. if ei.Code == v.Code && ei.DevID == v.DevID && ei.DevCode != v.DevCode {
  76. return fmt.Errorf("串口[Code=%d]下 DevID=%d 已被设备[%s]占用,设备[%s]不能使用相同地址",
  77. v.Code, v.DevID, ei.DevCode, v.DevCode)
  78. }
  79. }
  80. return nil
  81. }
  82. // AddDevices 新增
  83. func (o *DeviceMgr) AddDevices(devinfos []protocol.DevInfo) {
  84. if err := validateDevInfos(devinfos); err != nil {
  85. logrus.Errorf("AddDevices: 配置校验失败: %v", err)
  86. return
  87. }
  88. o.mu.Lock()
  89. defer o.mu.Unlock()
  90. for _, v := range devinfos {
  91. if _, ok := o.mapDevice[v.DevCode]; ok {
  92. logrus.Errorf("AddDevices:已添加该设备,不可重复添加:devcode=%s", v.DevCode)
  93. continue
  94. }
  95. if err := o.checkDevIDConflict(&v); err != nil {
  96. logrus.Errorf("AddDevices: %v", err)
  97. continue
  98. }
  99. di := v
  100. if device := CreateDevice(v.ProtocolType, &di); device != nil {
  101. device.Start()
  102. o.mapDevice[v.DevCode] = device
  103. }
  104. }
  105. }
  106. // RemoveDevice 删除
  107. func (o *DeviceMgr) RemoveDevice(devcode string) {
  108. o.mu.Lock()
  109. defer o.mu.Unlock()
  110. if device, ok := o.mapDevice[devcode]; ok {
  111. device.Stop()
  112. delete(o.mapDevice, devcode)
  113. }
  114. }
  115. // UpdateDevices 新增或修改
  116. func (o *DeviceMgr) UpdateDevices(code uint8, devinfos []protocol.DevInfo) {
  117. if len(devinfos) > 0 {
  118. if err := validateDevInfos(devinfos); err != nil {
  119. logrus.Errorf("UpdateDevices: 配置校验失败: %v", err)
  120. return
  121. }
  122. }
  123. //先遍历devinfos
  124. mapDevinfos := make(map[string]*protocol.DevInfo)
  125. for _, v := range devinfos {
  126. mapDevinfos[v.DevCode] = &v
  127. }
  128. o.mu.Lock()
  129. defer o.mu.Unlock()
  130. if len(devinfos) == 0 {
  131. for k, v := range o.mapDevice {
  132. if v.GetDevInfo().Code == code {
  133. v.Stop()
  134. delete(o.mapDevice, k)
  135. }
  136. }
  137. return
  138. }
  139. //先删除不再用的设备
  140. for k, v := range o.mapDevice {
  141. if v.GetDevInfo().Code != code {
  142. continue
  143. }
  144. if _, ok := mapDevinfos[k]; !ok {
  145. v.Stop()
  146. delete(o.mapDevice, k)
  147. }
  148. }
  149. //再添加新的设备或更新设备
  150. for _, v := range devinfos {
  151. if device, ok := o.mapDevice[v.DevCode]; ok {
  152. old := device.GetDevInfo()
  153. if v.ProtocolType == old.ProtocolType { //设备类型没变
  154. device.UpdateInfo(v) //更新设备信息
  155. if v.TID != old.TID { //更新物模型信息
  156. device.UpdateModel(v.TID, 3)
  157. }
  158. continue
  159. } else {
  160. device.Stop()
  161. delete(o.mapDevice, v.DevCode)
  162. }
  163. } else {
  164. if err := o.checkDevIDConflict(&v); err != nil {
  165. logrus.Errorf("UpdateDevices: %v", err)
  166. continue
  167. }
  168. }
  169. if device := CreateDevice(v.ProtocolType, &v); device != nil {
  170. device.Start()
  171. o.mapDevice[v.DevCode] = device
  172. }
  173. }
  174. }
  175. // GetDevice 查询
  176. func (o *DeviceMgr) GetDevice(devcode string) Device {
  177. o.mu.Lock()
  178. defer o.mu.Unlock()
  179. if device, ok := o.mapDevice[devcode]; ok {
  180. return device
  181. }
  182. return nil
  183. }
  184. // StopDevice 停止
  185. func (o *DeviceMgr) StopDevice(devcode string) {
  186. o.mu.Lock()
  187. defer o.mu.Unlock()
  188. if device, ok := o.mapDevice[devcode]; ok {
  189. device.Stop()
  190. delete(o.mapDevice, devcode)
  191. }
  192. }
  193. // StopAllDevice 停止所有
  194. func (o *DeviceMgr) StopAllDevice() {
  195. o.mu.Lock()
  196. defer o.mu.Unlock()
  197. for k, v := range o.mapDevice {
  198. v.Stop()
  199. delete(o.mapDevice, k)
  200. }
  201. }
  202. // UpdateModel 更新模型
  203. func (o *DeviceMgr) UpdateModel(tid uint16, flag int) {
  204. o.mu.Lock()
  205. defer o.mu.Unlock()
  206. for _, v := range o.mapDevice {
  207. v.UpdateModel(tid, flag)
  208. }
  209. }