intelligentbuildingcontrol.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. "strconv"
  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. pageNum, err := strconv.Atoi(ctx.PostForm("pageNum"))
  72. pageSize, err := strconv.Atoi(ctx.PostForm("pageSize"))
  73. conds := make(map[string]any)
  74. //var pointType []model.PointType
  75. if pointName != "" {
  76. conds["point_name"] = pointName
  77. }
  78. if deviceType != "" {
  79. conds["device_type"] = deviceType
  80. }
  81. if building != "" {
  82. conds["building"] = building
  83. }
  84. if floor != "" {
  85. conds["floor"] = floor
  86. }
  87. if section != "" {
  88. conds["section"] = section
  89. }
  90. if device_name != "" {
  91. conds["device_name"] = device_name
  92. }
  93. //baseUrl := h.conf.GetString("obix.baseUrl")
  94. point, total, err := h.intelligentBuildingControlService.GetPoint(conds, pageNum, pageSize)
  95. if err != nil {
  96. resp.HandleError(ctx, 1201, "查询点位失败", nil)
  97. return
  98. }
  99. //
  100. //var wg sync.WaitGroup
  101. //var mutex sync.Mutex // 保护切片并发写入
  102. //m := make(map[string]string)
  103. //sem := make(chan struct{}, 10) // 最大并发数为10
  104. //
  105. //for _, v := range *points {
  106. // url := baseUrl + v.FullPath
  107. // wg.Add(1)
  108. // sem <- struct{}{}
  109. // go func(url string, pointName string) {
  110. // defer func() {
  111. // <-sem
  112. // wg.Done()
  113. // }()
  114. //
  115. // request, err := obix.SendSecureRequest(url, h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
  116. // if err != nil {
  117. // h.logger.Error("发送请求失败", zap.Error(err))
  118. // return
  119. // }
  120. //
  121. // re := regexp.MustCompile(`val="([^"]+)"`)
  122. // matches := re.FindStringSubmatch(request)
  123. //
  124. // mutex.Lock()
  125. // defer mutex.Unlock()
  126. //
  127. // if len(matches) > 1 {
  128. // s := model.PointName[pointName]
  129. // m[s] = matches[1]
  130. // pointType = append(pointType, model.PointType{Type: m})
  131. // } else {
  132. // h.logger.Warn("未找到 val 值", zap.String("url", url))
  133. // }
  134. // }(url, v.PointName)
  135. //}
  136. //
  137. //// 等待所有协程完成
  138. //wg.Wait()
  139. // 统一返回结果
  140. resp.PageHandleSuccess(ctx, point, total, pageNum, pageSize)
  141. }
  142. // GetGetPoint 获取点位设备数据
  143. func (h *IntelligentBuildingControlHandler) GetGetPoint(ctx *gin.Context) {
  144. pointName := ctx.Query("pointName")
  145. deviceType := ctx.Query("deviceType")
  146. building := ctx.Query("building")
  147. floor := ctx.Query("floor")
  148. section := ctx.Query("section")
  149. device_name := ctx.Query("deviceName")
  150. conds := make(map[string]any)
  151. if pointName != "" {
  152. conds["point_name"] = pointName
  153. }
  154. if deviceType != "" {
  155. conds["device_type"] = deviceType
  156. }
  157. if building != "" {
  158. conds["building"] = building
  159. }
  160. if floor != "" {
  161. conds["floor"] = floor
  162. }
  163. if section != "" {
  164. conds["section"] = section
  165. }
  166. if device_name != "" {
  167. conds["device_name"] = device_name
  168. }
  169. baseUrl := h.conf.GetString("obix.baseUrl")
  170. m := make(map[string]any)
  171. points, _, err := h.intelligentBuildingControlService.GetPoint(conds, 1, 100)
  172. if err != nil {
  173. resp.HandleError(ctx, 1201, "查询点位失败", nil)
  174. }
  175. for _, v := range *points {
  176. url := baseUrl + v.FullPath
  177. request, err := obix.SendSecureRequest(url, h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
  178. if err != nil {
  179. h.logger.Error("发送请求失败", zap.Error(err))
  180. return
  181. }
  182. re := regexp.MustCompile(`val="([^"]+)"`)
  183. matches := re.FindStringSubmatch(request)
  184. if len(matches) > 1 {
  185. s := model.PointName[v.PointName]
  186. if s != "" {
  187. value := matches[1]
  188. switch val := obix.DetectType(value).(type) {
  189. case int:
  190. m[s] = val
  191. case float64:
  192. m[s] = fmt.Sprintf("%.2f", val) // 保留两位小数输出
  193. case bool:
  194. if val {
  195. m[s] = "是"
  196. } else {
  197. m[s] = "否"
  198. }
  199. default:
  200. m[s] = value // 原样输出字符串
  201. }
  202. }
  203. } else {
  204. h.logger.Warn("未找到 val 值", zap.String("url", url))
  205. }
  206. }
  207. resp.HandleSuccess(ctx, m)
  208. }
  209. func (h *IntelligentBuildingControlHandler) GetGetPointSSE(ctx *gin.Context) {
  210. // 设置响应头
  211. ctx.Header("Content-Type", "text/event-stream")
  212. ctx.Header("Cache-Control", "no-cache")
  213. ctx.Header("Connection", "keep-alive")
  214. // 监听客户端断开连接
  215. conn := true
  216. notify := ctx.Writer.CloseNotify()
  217. type Response struct {
  218. RequestId string `protobuf:"bytes,1,opt,name=requestId,proto3" json:"requestId,omitempty"`
  219. Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
  220. Msg string `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"`
  221. Data any `json:"data"`
  222. }
  223. pointName := ctx.Query("pointName")
  224. deviceType := ctx.Query("deviceType")
  225. building := ctx.Query("building")
  226. floor := ctx.Query("floor")
  227. section := ctx.Query("section")
  228. device_name := ctx.Query("deviceName")
  229. conds := make(map[string]any)
  230. if pointName != "" {
  231. conds["point_name"] = pointName
  232. }
  233. if deviceType != "" {
  234. conds["device_type"] = deviceType
  235. }
  236. if building != "" {
  237. conds["building"] = building
  238. }
  239. if floor != "" {
  240. conds["floor"] = floor
  241. }
  242. if section != "" {
  243. conds["section"] = section
  244. }
  245. if device_name != "" {
  246. conds["device_name"] = device_name
  247. }
  248. baseUrl := h.conf.GetString("obix.baseUrl")
  249. var response Response
  250. for conn {
  251. select {
  252. case <-notify:
  253. conn = false
  254. fmt.Println("断开连接")
  255. return
  256. default:
  257. m := make(map[string]any)
  258. points, _, err := h.intelligentBuildingControlService.GetPoint(conds, 1, 100)
  259. if err != nil {
  260. resp.HandleError(ctx, 1201, "查询点位失败", nil)
  261. conn = false
  262. }
  263. for _, v := range *points {
  264. url := baseUrl + v.FullPath
  265. request, err := obix.SendSecureRequest(url, h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
  266. if err != nil {
  267. h.logger.Error("发送请求失败", zap.Error(err))
  268. conn = false
  269. return
  270. }
  271. re := regexp.MustCompile(`val="([^"]+)"`)
  272. matches := re.FindStringSubmatch(request)
  273. if len(matches) > 1 {
  274. s := model.PointName[v.PointName]
  275. if s != "" {
  276. value := matches[1]
  277. switch val := obix.DetectType(value).(type) {
  278. case int:
  279. m[s] = val
  280. case float64:
  281. m[s] = fmt.Sprintf("%.2f", val) // 保留两位小数输出
  282. case bool:
  283. if val {
  284. m[s] = "是"
  285. } else {
  286. m[s] = "否"
  287. }
  288. default:
  289. m[s] = value // 原样输出字符串
  290. }
  291. }
  292. } else {
  293. h.logger.Warn("未找到 val 值", zap.String("url", url))
  294. conn = false
  295. }
  296. }
  297. response.Code = 200
  298. response.RequestId = ctx.ClientIP()
  299. response.Msg = "success"
  300. response.Data = m
  301. res, _ := json.Marshal(&response)
  302. fmt.Fprintf(ctx.Writer, "data: %s\n\n", string(res))
  303. ctx.Writer.Flush()
  304. time.Sleep(10 * time.Second)
  305. }
  306. }
  307. }
  308. // GetPointType 获取点位类型
  309. func (h *IntelligentBuildingControlHandler) GetPointType(ctx *gin.Context) {
  310. points, err := h.intelligentBuildingControlService.GetPointType()
  311. if err != nil {
  312. resp.HandleError(ctx, 1201, "查询点位类型失败", nil)
  313. return
  314. }
  315. resp.HandleSuccess(ctx, points)
  316. }
  317. // GetDeviceType 获取设备类型
  318. func (h *IntelligentBuildingControlHandler) GetDeviceType(ctx *gin.Context) {
  319. points, err := h.intelligentBuildingControlService.DeviceType()
  320. if err != nil {
  321. resp.HandleError(ctx, 1201, "查询设备类型失败", nil)
  322. return
  323. }
  324. m := make(map[string]string)
  325. for _, v := range points {
  326. m[v] = model.DeviceType[v]
  327. }
  328. resp.HandleSuccess(ctx, m)
  329. }
  330. // GetDevices 获取设备列表
  331. func (h *IntelligentBuildingControlHandler) GetDevices(ctx *gin.Context) {
  332. conds := make(map[string]any)
  333. pageNum, err := strconv.Atoi(ctx.Query("pageNum"))
  334. pageSize, err := strconv.Atoi(ctx.Query("pageSize"))
  335. device_type := ctx.Query("device_type")
  336. if len(device_type) == 0 || device_type == "" {
  337. resp.HandleError(ctx, 1201, "设备类型不能为空", nil)
  338. }
  339. conds["device_type"] = device_type
  340. if err != nil {
  341. resp.HandleError(ctx, 1201, "获取分页参数失败", nil)
  342. return
  343. }
  344. devices, total, err := h.intelligentBuildingControlService.GetDevices(conds, pageNum, pageSize)
  345. if err != nil {
  346. resp.HandleError(ctx, 1201, "查询设备类型失败", nil)
  347. return
  348. }
  349. resp.PageHandleSuccess(ctx, devices, total, pageNum, pageSize)
  350. }