intelligentbuildingcontrol.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package service
  2. import (
  3. "city_chips/internal/model"
  4. "city_chips/internal/repository"
  5. "city_chips/pkg/helper/obix"
  6. "context"
  7. "fmt"
  8. "github.com/pkg/errors"
  9. "github.com/spf13/viper"
  10. "go.uber.org/zap"
  11. "regexp"
  12. "sync"
  13. )
  14. type IntelligentBuildingControlService interface {
  15. GetIntelligentBuildingControl(ctx context.Context, id int64) (*model.IntelligentBuildingControl, error)
  16. GetPoint(conds map[string]any, pageNum, pageSize int) (*[]model.Point, int64, error)
  17. GetPointType() ([]string, error)
  18. DeviceType() ([]string, error)
  19. DeviceCount() (int64, error)
  20. GetDevices(conds map[string]any, pageNum, pageSize int) (map[string]any, int64, error)
  21. }
  22. func NewIntelligentBuildingControlService(
  23. service *Service,
  24. intelligentBuildingControlRepository repository.IntelligentBuildingControlRepository,
  25. conf *viper.Viper,
  26. ) IntelligentBuildingControlService {
  27. return &intelligentBuildingControlService{
  28. Service: service,
  29. intelligentBuildingControlRepository: intelligentBuildingControlRepository,
  30. conf: conf,
  31. }
  32. }
  33. type intelligentBuildingControlService struct {
  34. *Service
  35. intelligentBuildingControlRepository repository.IntelligentBuildingControlRepository
  36. conf *viper.Viper
  37. }
  38. // DeviceCount 获取设备总数
  39. func (s *intelligentBuildingControlService) DeviceCount() (int64, error) {
  40. //TODO implement me
  41. count, err := s.intelligentBuildingControlRepository.DeviceCount()
  42. if err != nil {
  43. return 0, err
  44. }
  45. return count, nil
  46. }
  47. // DeviceType 获取设备类型
  48. func (s *intelligentBuildingControlService) DeviceType() ([]string, error) {
  49. //TODO implement me
  50. poions, err := s.intelligentBuildingControlRepository.DeviceType()
  51. if err != nil {
  52. return nil, err
  53. }
  54. return poions, nil
  55. }
  56. // GetPointType 获取点位类型
  57. func (s *intelligentBuildingControlService) GetPointType() ([]string, error) {
  58. poions, err := s.intelligentBuildingControlRepository.GetPointType()
  59. if err != nil {
  60. return nil, err
  61. }
  62. return poions, nil
  63. }
  64. // GetPoint 获取点位列表
  65. func (s *intelligentBuildingControlService) GetPoint(conds map[string]any, pageNum, pageSize int) (*[]model.Point, int64, error) {
  66. points, total, err := s.intelligentBuildingControlRepository.GetPoint(conds, pageNum, pageSize)
  67. if err != nil {
  68. return &[]model.Point{}, 0, err
  69. }
  70. return points, total, err
  71. }
  72. func (s *intelligentBuildingControlService) GetIntelligentBuildingControl(ctx context.Context, id int64) (*model.IntelligentBuildingControl, error) {
  73. return s.intelligentBuildingControlRepository.GetIntelligentBuildingControl(ctx, id)
  74. }
  75. // GetDevices 获取设备列表(支持设备 & 点位双重并发)
  76. func (s *intelligentBuildingControlService) GetDevices(conds map[string]any, pageNum, pageSize int) (map[string]any, int64, error) {
  77. var total int64
  78. baseUrl := s.conf.GetString("obix.baseUrl")
  79. device := make(map[string]any)
  80. list, total, err := s.intelligentBuildingControlRepository.GetPopintList(conds, pageNum, pageSize)
  81. if err != nil {
  82. return nil, 0, errors.New("获取设备列表失败")
  83. }
  84. var wg sync.WaitGroup
  85. var mu sync.Mutex // 保护 device 的写入
  86. var all *[]model.Point
  87. for _, v := range list {
  88. wg.Add(1)
  89. go func(deviceName string) {
  90. defer wg.Done()
  91. all, err = s.intelligentBuildingControlRepository.GetPointAll(map[string]any{"device_name": deviceName})
  92. if err != nil {
  93. s.logger.Error("获取设备点位列表失败", zap.String("device", deviceName), zap.Error(err))
  94. return
  95. }
  96. m := make(map[string]any)
  97. var innerWg sync.WaitGroup
  98. var innerMu sync.Mutex // 保护 m 的写入
  99. for _, vl := range *all {
  100. innerWg.Add(1)
  101. go func(vl model.Point) {
  102. defer innerWg.Done()
  103. url := baseUrl + vl.FullPath
  104. request, err := obix.SendSecureRequest(url, s.conf.GetString("obix.username"), s.conf.GetString("obix.password"))
  105. if err != nil {
  106. s.logger.Error("发送请求失败", zap.String("url", url), zap.Error(err))
  107. return
  108. }
  109. re := regexp.MustCompile(`val="([^"]+)"`)
  110. matches := re.FindStringSubmatch(request)
  111. if len(matches) > 1 {
  112. key := model.PointName[vl.PointName]
  113. if key != "" {
  114. value := matches[1]
  115. switch val := obix.DetectType(value).(type) {
  116. case int:
  117. innerMu.Lock()
  118. m[key] = val
  119. innerMu.Unlock()
  120. case float64:
  121. innerMu.Lock()
  122. m[key] = fmt.Sprintf("%.2f", val)
  123. innerMu.Unlock()
  124. case bool:
  125. innerMu.Lock()
  126. if val {
  127. m[key] = "是"
  128. } else {
  129. m[key] = "否"
  130. }
  131. innerMu.Unlock()
  132. default:
  133. innerMu.Lock()
  134. m[key] = value
  135. innerMu.Unlock()
  136. }
  137. }
  138. } else {
  139. s.logger.Warn("未找到 val 值", zap.String("url", url))
  140. }
  141. }(vl)
  142. }
  143. innerWg.Wait()
  144. mu.Lock()
  145. device[deviceName] = m
  146. mu.Unlock()
  147. }(v)
  148. }
  149. wg.Wait()
  150. return device, total, nil
  151. }