intelligentbuildingcontrol.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. package handler
  2. import (
  3. "city_chips/internal/model"
  4. "city_chips/internal/service"
  5. "city_chips/pkg/helper/obix"
  6. "city_chips/pkg/helper/resp"
  7. "encoding/json"
  8. "fmt"
  9. "go.uber.org/zap"
  10. "math/rand"
  11. "regexp"
  12. "sync"
  13. "time"
  14. "github.com/spf13/viper"
  15. "github.com/gin-gonic/gin"
  16. )
  17. type IntelligentBuildingControlHandler struct {
  18. *Handler
  19. intelligentBuildingControlService service.IntelligentBuildingControlService
  20. conf *viper.Viper
  21. }
  22. func NewIntelligentBuildingControlHandler(
  23. handler *Handler,
  24. intelligentBuildingControlService service.IntelligentBuildingControlService,
  25. conf *viper.Viper,
  26. ) *IntelligentBuildingControlHandler {
  27. return &IntelligentBuildingControlHandler{
  28. Handler: handler,
  29. intelligentBuildingControlService: intelligentBuildingControlService,
  30. conf: conf,
  31. }
  32. }
  33. // 智能楼宇控制系统
  34. // 示例:创建一个报警记录
  35. func generateAlarm() model.AlarmList {
  36. return model.AlarmList{
  37. Id: rand.Intn(100),
  38. Name: model.GetRandomItem(model.DeviceNames),
  39. State: rand.Intn(2), // 假设0为正常,1为报警
  40. Date: time.Now().Format("2006-01-02 15:04:05"),
  41. Location: model.GetRandomItem(model.Locations),
  42. AlarmContent: model.GetRandomItem(model.AlarmContents),
  43. }
  44. }
  45. func (h *IntelligentBuildingControlHandler) GetIntelligentBuildingControl(ctx *gin.Context) {
  46. m := make(map[string]any)
  47. var device []model.AlarmList
  48. for i := 0; i < 20; i++ {
  49. alarm := generateAlarm()
  50. device = append(device, alarm)
  51. }
  52. count, err := h.intelligentBuildingControlService.DeviceCount()
  53. if err != nil {
  54. resp.HandleError(ctx, 1201, "查询设备总数失败", nil)
  55. return
  56. }
  57. m["DeviceCount"] = count //设备总数
  58. m["StopState"] = rand.Intn(100) //停止状态
  59. m["RunState"] = rand.Intn(100) //运行状态
  60. m["FaultState"] = rand.Intn(1000) //故障状态
  61. m["DeviceList"] = device //设备列表
  62. resp.HandleSuccess(ctx, m)
  63. }
  64. func (h *IntelligentBuildingControlHandler) GetPoint(ctx *gin.Context) {
  65. pointName := ctx.PostForm("pointName")
  66. deviceType := ctx.PostForm("deviceType")
  67. building := ctx.PostForm("building")
  68. floor := ctx.PostForm("floor")
  69. section := ctx.PostForm("section")
  70. device_name := ctx.PostForm("deviceName")
  71. conds := make(map[string]any)
  72. var pointType []model.PointType
  73. if pointName != "" {
  74. conds["point_name"] = pointName
  75. }
  76. if deviceType != "" {
  77. conds["device_type"] = deviceType
  78. }
  79. if building != "" {
  80. conds["building"] = building
  81. }
  82. if floor != "" {
  83. conds["floor"] = floor
  84. }
  85. if section != "" {
  86. conds["section"] = section
  87. }
  88. if device_name != "" {
  89. conds["device_name"] = device_name
  90. }
  91. baseUrl := h.conf.GetString("obix.baseUrl")
  92. points, err := h.intelligentBuildingControlService.GetPoint(conds)
  93. if err != nil {
  94. resp.HandleError(ctx, 1201, "查询点位失败", nil)
  95. return
  96. }
  97. var wg sync.WaitGroup
  98. var mutex sync.Mutex // 保护切片并发写入
  99. m := make(map[string]string)
  100. sem := make(chan struct{}, 10) // 最大并发数为10
  101. for _, v := range *points {
  102. url := baseUrl + v.FullPath
  103. wg.Add(1)
  104. sem <- struct{}{}
  105. go func(url string, pointName string) {
  106. defer func() {
  107. <-sem
  108. wg.Done()
  109. }()
  110. request, err := obix.SendSecureRequest(url, h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
  111. if err != nil {
  112. h.logger.Error("发送请求失败", zap.Error(err))
  113. return
  114. }
  115. re := regexp.MustCompile(`val="([^"]+)"`)
  116. matches := re.FindStringSubmatch(request)
  117. mutex.Lock()
  118. defer mutex.Unlock()
  119. if len(matches) > 1 {
  120. s := model.PointName[pointName]
  121. m[s] = matches[1]
  122. pointType = append(pointType, model.PointType{Type: m})
  123. } else {
  124. h.logger.Warn("未找到 val 值", zap.String("url", url))
  125. }
  126. }(url, v.PointName)
  127. }
  128. // 等待所有协程完成
  129. wg.Wait()
  130. // 统一返回结果
  131. resp.HandleSuccess(ctx, pointType)
  132. }
  133. func (h *IntelligentBuildingControlHandler) GetGetPointSSE(ctx *gin.Context) {
  134. // 设置响应头
  135. ctx.Header("Content-Type", "text/event-stream")
  136. ctx.Header("Cache-Control", "no-cache")
  137. ctx.Header("Connection", "keep-alive")
  138. // 监听客户端断开连接
  139. conn := true
  140. notify := ctx.Writer.CloseNotify()
  141. type Response struct {
  142. RequestId string `protobuf:"bytes,1,opt,name=requestId,proto3" json:"requestId,omitempty"`
  143. Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
  144. Msg string `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"`
  145. Data any `json:"data"`
  146. }
  147. pointName := ctx.Query("pointName")
  148. deviceType := ctx.Query("deviceType")
  149. building := ctx.Query("building")
  150. floor := ctx.Query("floor")
  151. section := ctx.Query("section")
  152. device_name := ctx.Query("deviceName")
  153. conds := make(map[string]any)
  154. if pointName != "" {
  155. conds["point_name"] = pointName
  156. }
  157. if deviceType != "" {
  158. conds["device_type"] = deviceType
  159. }
  160. if building != "" {
  161. conds["building"] = building
  162. }
  163. if floor != "" {
  164. conds["floor"] = floor
  165. }
  166. if section != "" {
  167. conds["section"] = section
  168. }
  169. if device_name != "" {
  170. conds["device_name"] = device_name
  171. }
  172. baseUrl := h.conf.GetString("obix.baseUrl")
  173. var response Response
  174. for conn {
  175. select {
  176. case <-notify:
  177. conn = false
  178. fmt.Println("断开连接")
  179. return
  180. default:
  181. m := make(map[string]any)
  182. points, err := h.intelligentBuildingControlService.GetPoint(conds)
  183. if err != nil {
  184. resp.HandleError(ctx, 1201, "查询点位失败", nil)
  185. conn = false
  186. }
  187. for _, v := range *points {
  188. url := baseUrl + v.FullPath
  189. request, err := obix.SendSecureRequest(url, h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
  190. if err != nil {
  191. h.logger.Error("发送请求失败", zap.Error(err))
  192. conn = false
  193. return
  194. }
  195. re := regexp.MustCompile(`val="([^"]+)"`)
  196. matches := re.FindStringSubmatch(request)
  197. if len(matches) > 1 {
  198. s := model.PointName[v.PointName]
  199. if s != "" {
  200. value := matches[1]
  201. switch val := obix.DetectType(value).(type) {
  202. case int:
  203. m[s] = val
  204. case float64:
  205. m[s] = fmt.Sprintf("%.2f", val) // 保留两位小数输出
  206. case bool:
  207. if val {
  208. m[s] = "是"
  209. } else {
  210. m[s] = "否"
  211. }
  212. default:
  213. m[s] = value // 原样输出字符串
  214. }
  215. }
  216. } else {
  217. h.logger.Warn("未找到 val 值", zap.String("url", url))
  218. conn = false
  219. }
  220. }
  221. response.Code = 200
  222. response.RequestId = ctx.ClientIP()
  223. response.Msg = "success"
  224. response.Data = m
  225. res, _ := json.Marshal(&response)
  226. fmt.Fprintf(ctx.Writer, "data: %s\n\n", string(res))
  227. ctx.Writer.Flush()
  228. time.Sleep(10 * time.Second)
  229. }
  230. }
  231. }
  232. // GetPointType 获取点位类型
  233. func (h *IntelligentBuildingControlHandler) GetPointType(ctx *gin.Context) {
  234. var tempS1 model.NumericPoint
  235. // var xmlData = `<?xml version="1.0" encoding="UTF-8"?>
  236. //<real val="27.49811553955078" display="27.50 °C {ok}" unit="obix:units/celsius">
  237. // <str name="facets" val="units=u:celsius;°C;(K);+273.15;" display="units=°C"/>
  238. // <ref name="proxyExt" display="analogInput:1:Present Value:-1:REAL"/>
  239. // <real name="out" val="27.49811553955078" display="27.50 °C {ok}"/>
  240. // <ref name="tag" display="Point Tag"/>
  241. //</real>`
  242. //err2 := ctx.ShouldBindXML(&tempS1)
  243. //err2 := xml.Unmarshal([]byte(xmlData), &tempS1)
  244. //if err2 != nil {
  245. // resp.HandleError(ctx, 1201, "绑定XML失败", nil)
  246. // return
  247. //}
  248. request, err2 := obix.SendSecureRequest("https://10.1.201.253/obix/config/Drivers/BacnetNetwork/DDC_9B_1F_1a/points/PAU/PAU_9B_1F_1/PAUAlr1", h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
  249. if err2 != nil {
  250. resp.HandleError(ctx, 1201, "发送请求失败", nil)
  251. return
  252. }
  253. fmt.Println(request, "===========")
  254. fmt.Println(tempS1)
  255. points, err := h.intelligentBuildingControlService.GetPointType()
  256. if err != nil {
  257. resp.HandleError(ctx, 1201, "查询点位类型失败", nil)
  258. return
  259. }
  260. resp.HandleSuccess(ctx, points)
  261. }
  262. func (h *IntelligentBuildingControlHandler) GetDeviceType(ctx *gin.Context) {
  263. points, err := h.intelligentBuildingControlService.DeviceType()
  264. if err != nil {
  265. resp.HandleError(ctx, 1201, "查询设备类型失败", nil)
  266. return
  267. }
  268. m := make(map[string]string)
  269. for _, v := range points {
  270. m[v] = model.DeviceType[v]
  271. }
  272. resp.HandleSuccess(ctx, m)
  273. }