123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- package service
- import (
- "city_chips/internal/model"
- "city_chips/internal/repository"
- "city_chips/pkg/helper/obix"
- "context"
- "fmt"
- "github.com/pkg/errors"
- "github.com/spf13/viper"
- "go.uber.org/zap"
- "regexp"
- "sync"
- )
- type IntelligentBuildingControlService interface {
- GetIntelligentBuildingControl(ctx context.Context, id int64) (*model.IntelligentBuildingControl, error)
- GetPoint(conds map[string]any, pageNum, pageSize int) (*[]model.Point, int64, error)
- GetPointType() ([]string, error)
- DeviceType() ([]string, error)
- DeviceCount() (int64, error)
- GetDevices(conds map[string]any, pageNum, pageSize int) (map[string]any, int64, error)
- }
- func NewIntelligentBuildingControlService(
- service *Service,
- intelligentBuildingControlRepository repository.IntelligentBuildingControlRepository,
- conf *viper.Viper,
- ) IntelligentBuildingControlService {
- return &intelligentBuildingControlService{
- Service: service,
- intelligentBuildingControlRepository: intelligentBuildingControlRepository,
- conf: conf,
- }
- }
- type intelligentBuildingControlService struct {
- *Service
- intelligentBuildingControlRepository repository.IntelligentBuildingControlRepository
- conf *viper.Viper
- }
- // DeviceCount 获取设备总数
- func (s *intelligentBuildingControlService) DeviceCount() (int64, error) {
- //TODO implement me
- count, err := s.intelligentBuildingControlRepository.DeviceCount()
- if err != nil {
- return 0, err
- }
- return count, nil
- }
- // DeviceType 获取设备类型
- func (s *intelligentBuildingControlService) DeviceType() ([]string, error) {
- //TODO implement me
- poions, err := s.intelligentBuildingControlRepository.DeviceType()
- if err != nil {
- return nil, err
- }
- return poions, nil
- }
- // GetPointType 获取点位类型
- func (s *intelligentBuildingControlService) GetPointType() ([]string, error) {
- poions, err := s.intelligentBuildingControlRepository.GetPointType()
- if err != nil {
- return nil, err
- }
- return poions, nil
- }
- // GetPoint 获取点位列表
- func (s *intelligentBuildingControlService) GetPoint(conds map[string]any, pageNum, pageSize int) (*[]model.Point, int64, error) {
- points, total, err := s.intelligentBuildingControlRepository.GetPoint(conds, pageNum, pageSize)
- if err != nil {
- return &[]model.Point{}, 0, err
- }
- return points, total, err
- }
- func (s *intelligentBuildingControlService) GetIntelligentBuildingControl(ctx context.Context, id int64) (*model.IntelligentBuildingControl, error) {
- return s.intelligentBuildingControlRepository.GetIntelligentBuildingControl(ctx, id)
- }
- // GetDevices 获取设备列表(支持设备 & 点位双重并发)
- func (s *intelligentBuildingControlService) GetDevices(conds map[string]any, pageNum, pageSize int) (map[string]any, int64, error) {
- var total int64
- baseUrl := s.conf.GetString("obix.baseUrl")
- device := make(map[string]any)
- list, total, err := s.intelligentBuildingControlRepository.GetPopintList(conds, pageNum, pageSize)
- if err != nil {
- return nil, 0, errors.New("获取设备列表失败")
- }
- var wg sync.WaitGroup
- var mu sync.Mutex // 保护 device 的写入
- var all *[]model.Point
- for _, v := range list {
- wg.Add(1)
- go func(deviceName string) {
- defer wg.Done()
- all, err = s.intelligentBuildingControlRepository.GetPointAll(map[string]any{"device_name": deviceName})
- if err != nil {
- s.logger.Error("获取设备点位列表失败", zap.String("device", deviceName), zap.Error(err))
- return
- }
- m := make(map[string]any)
- var innerWg sync.WaitGroup
- var innerMu sync.Mutex // 保护 m 的写入
- for _, vl := range *all {
- innerWg.Add(1)
- go func(vl model.Point) {
- defer innerWg.Done()
- url := baseUrl + vl.FullPath
- request, err := obix.SendSecureRequest(url, s.conf.GetString("obix.username"), s.conf.GetString("obix.password"))
- if err != nil {
- s.logger.Error("发送请求失败", zap.String("url", url), zap.Error(err))
- return
- }
- re := regexp.MustCompile(`val="([^"]+)"`)
- matches := re.FindStringSubmatch(request)
- if len(matches) > 1 {
- key := model.PointName[vl.PointName]
- if key != "" {
- value := matches[1]
- switch val := obix.DetectType(value).(type) {
- case int:
- innerMu.Lock()
- m[key] = val
- innerMu.Unlock()
- case float64:
- innerMu.Lock()
- m[key] = fmt.Sprintf("%.2f", val)
- innerMu.Unlock()
- case bool:
- innerMu.Lock()
- if val {
- m[key] = "是"
- } else {
- m[key] = "否"
- }
- innerMu.Unlock()
- default:
- innerMu.Lock()
- m[key] = value
- innerMu.Unlock()
- }
- }
- } else {
- s.logger.Warn("未找到 val 值", zap.String("url", url))
- }
- }(vl)
- }
- innerWg.Wait()
- mu.Lock()
- device[deviceName] = m
- mu.Unlock()
- }(v)
- }
- wg.Wait()
- return device, total, nil
- }
|