123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- package handler
- import (
- "city_chips/internal/model"
- "city_chips/internal/service"
- "city_chips/pkg/helper/obix"
- "city_chips/pkg/helper/resp"
- "encoding/json"
- "fmt"
- "go.uber.org/zap"
- "math/rand"
- "regexp"
- "sync"
- "time"
- "github.com/spf13/viper"
- "github.com/gin-gonic/gin"
- )
- type IntelligentBuildingControlHandler struct {
- *Handler
- intelligentBuildingControlService service.IntelligentBuildingControlService
- conf *viper.Viper
- }
- func NewIntelligentBuildingControlHandler(
- handler *Handler,
- intelligentBuildingControlService service.IntelligentBuildingControlService,
- conf *viper.Viper,
- ) *IntelligentBuildingControlHandler {
- return &IntelligentBuildingControlHandler{
- Handler: handler,
- intelligentBuildingControlService: intelligentBuildingControlService,
- conf: conf,
- }
- }
- // 智能楼宇控制系统
- // 示例:创建一个报警记录
- func generateAlarm() model.AlarmList {
- return model.AlarmList{
- Id: rand.Intn(100),
- Name: model.GetRandomItem(model.DeviceNames),
- State: rand.Intn(2), // 假设0为正常,1为报警
- Date: time.Now().Format("2006-01-02 15:04:05"),
- Location: model.GetRandomItem(model.Locations),
- AlarmContent: model.GetRandomItem(model.AlarmContents),
- }
- }
- func (h *IntelligentBuildingControlHandler) GetIntelligentBuildingControl(ctx *gin.Context) {
- m := make(map[string]any)
- var device []model.AlarmList
- for i := 0; i < 20; i++ {
- alarm := generateAlarm()
- device = append(device, alarm)
- }
- count, err := h.intelligentBuildingControlService.DeviceCount()
- if err != nil {
- resp.HandleError(ctx, 1201, "查询设备总数失败", nil)
- return
- }
- m["DeviceCount"] = count //设备总数
- m["StopState"] = rand.Intn(100) //停止状态
- m["RunState"] = rand.Intn(100) //运行状态
- m["FaultState"] = rand.Intn(1000) //故障状态
- m["DeviceList"] = device //设备列表
- resp.HandleSuccess(ctx, m)
- }
- func (h *IntelligentBuildingControlHandler) GetPoint(ctx *gin.Context) {
- pointName := ctx.PostForm("pointName")
- deviceType := ctx.PostForm("deviceType")
- building := ctx.PostForm("building")
- floor := ctx.PostForm("floor")
- section := ctx.PostForm("section")
- device_name := ctx.PostForm("deviceName")
- conds := make(map[string]any)
- var pointType []model.PointType
- if pointName != "" {
- conds["point_name"] = pointName
- }
- if deviceType != "" {
- conds["device_type"] = deviceType
- }
- if building != "" {
- conds["building"] = building
- }
- if floor != "" {
- conds["floor"] = floor
- }
- if section != "" {
- conds["section"] = section
- }
- if device_name != "" {
- conds["device_name"] = device_name
- }
- baseUrl := h.conf.GetString("obix.baseUrl")
- points, err := h.intelligentBuildingControlService.GetPoint(conds)
- if err != nil {
- resp.HandleError(ctx, 1201, "查询点位失败", nil)
- return
- }
- var wg sync.WaitGroup
- var mutex sync.Mutex // 保护切片并发写入
- m := make(map[string]string)
- sem := make(chan struct{}, 10) // 最大并发数为10
- for _, v := range *points {
- url := baseUrl + v.FullPath
- wg.Add(1)
- sem <- struct{}{}
- go func(url string, pointName string) {
- defer func() {
- <-sem
- wg.Done()
- }()
- request, err := obix.SendSecureRequest(url, h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
- if err != nil {
- h.logger.Error("发送请求失败", zap.Error(err))
- return
- }
- re := regexp.MustCompile(`val="([^"]+)"`)
- matches := re.FindStringSubmatch(request)
- mutex.Lock()
- defer mutex.Unlock()
- if len(matches) > 1 {
- s := model.PointName[pointName]
- m[s] = matches[1]
- pointType = append(pointType, model.PointType{Type: m})
- } else {
- h.logger.Warn("未找到 val 值", zap.String("url", url))
- }
- }(url, v.PointName)
- }
- // 等待所有协程完成
- wg.Wait()
- // 统一返回结果
- resp.HandleSuccess(ctx, pointType)
- }
- func (h *IntelligentBuildingControlHandler) GetGetPointSSE(ctx *gin.Context) {
- // 设置响应头
- ctx.Header("Content-Type", "text/event-stream")
- ctx.Header("Cache-Control", "no-cache")
- ctx.Header("Connection", "keep-alive")
- // 监听客户端断开连接
- conn := true
- notify := ctx.Writer.CloseNotify()
- type Response struct {
- RequestId string `protobuf:"bytes,1,opt,name=requestId,proto3" json:"requestId,omitempty"`
- Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
- Msg string `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"`
- Data any `json:"data"`
- }
- pointName := ctx.Query("pointName")
- deviceType := ctx.Query("deviceType")
- building := ctx.Query("building")
- floor := ctx.Query("floor")
- section := ctx.Query("section")
- device_name := ctx.Query("deviceName")
- conds := make(map[string]any)
- if pointName != "" {
- conds["point_name"] = pointName
- }
- if deviceType != "" {
- conds["device_type"] = deviceType
- }
- if building != "" {
- conds["building"] = building
- }
- if floor != "" {
- conds["floor"] = floor
- }
- if section != "" {
- conds["section"] = section
- }
- if device_name != "" {
- conds["device_name"] = device_name
- }
- baseUrl := h.conf.GetString("obix.baseUrl")
- var response Response
- for conn {
- select {
- case <-notify:
- conn = false
- fmt.Println("断开连接")
- return
- default:
- m := make(map[string]any)
- points, err := h.intelligentBuildingControlService.GetPoint(conds)
- if err != nil {
- resp.HandleError(ctx, 1201, "查询点位失败", nil)
- conn = false
- }
- for _, v := range *points {
- url := baseUrl + v.FullPath
- request, err := obix.SendSecureRequest(url, h.conf.GetString("obix.username"), h.conf.GetString("obix.password"))
- if err != nil {
- h.logger.Error("发送请求失败", zap.Error(err))
- conn = false
- return
- }
- re := regexp.MustCompile(`val="([^"]+)"`)
- matches := re.FindStringSubmatch(request)
- if len(matches) > 1 {
- s := model.PointName[v.PointName]
- if s != "" {
- value := matches[1]
- switch val := obix.DetectType(value).(type) {
- case int:
- m[s] = val
- case float64:
- m[s] = fmt.Sprintf("%.2f", val) // 保留两位小数输出
- case bool:
- if val {
- m[s] = "是"
- } else {
- m[s] = "否"
- }
- default:
- m[s] = value // 原样输出字符串
- }
- }
- } else {
- h.logger.Warn("未找到 val 值", zap.String("url", url))
- conn = false
- }
- }
- response.Code = 200
- response.RequestId = ctx.ClientIP()
- response.Msg = "success"
- response.Data = m
- res, _ := json.Marshal(&response)
- fmt.Fprintf(ctx.Writer, "data: %s\n\n", string(res))
- ctx.Writer.Flush()
- time.Sleep(10 * time.Second)
- }
- }
- }
- // GetPointType 获取点位类型
- func (h *IntelligentBuildingControlHandler) GetPointType(ctx *gin.Context) {
- var tempS1 model.NumericPoint
- // var xmlData = `<?xml version="1.0" encoding="UTF-8"?>
- //<real val="27.49811553955078" display="27.50 °C {ok}" unit="obix:units/celsius">
- // <str name="facets" val="units=u:celsius;°C;(K);+273.15;" display="units=°C"/>
- // <ref name="proxyExt" display="analogInput:1:Present Value:-1:REAL"/>
- // <real name="out" val="27.49811553955078" display="27.50 °C {ok}"/>
- // <ref name="tag" display="Point Tag"/>
- //</real>`
- //err2 := ctx.ShouldBindXML(&tempS1)
- //err2 := xml.Unmarshal([]byte(xmlData), &tempS1)
- //if err2 != nil {
- // resp.HandleError(ctx, 1201, "绑定XML失败", nil)
- // return
- //}
- 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"))
- if err2 != nil {
- resp.HandleError(ctx, 1201, "发送请求失败", nil)
- return
- }
- fmt.Println(request, "===========")
- fmt.Println(tempS1)
- points, err := h.intelligentBuildingControlService.GetPointType()
- if err != nil {
- resp.HandleError(ctx, 1201, "查询点位类型失败", nil)
- return
- }
- resp.HandleSuccess(ctx, points)
- }
- func (h *IntelligentBuildingControlHandler) GetDeviceType(ctx *gin.Context) {
- points, err := h.intelligentBuildingControlService.DeviceType()
- if err != nil {
- resp.HandleError(ctx, 1201, "查询设备类型失败", nil)
- return
- }
- m := make(map[string]string)
- for _, v := range points {
- m[v] = model.DeviceType[v]
- }
- resp.HandleSuccess(ctx, m)
- }
|