|
|
@@ -15,140 +15,140 @@ import (
|
|
|
)
|
|
|
|
|
|
func init() {
|
|
|
- // 启动后台协程定期更新电调模型数据
|
|
|
- go func() {
|
|
|
- // 初始化延迟1秒执行,避免系统启动时的资源竞争
|
|
|
- time.Sleep(1 * time.Second)
|
|
|
-
|
|
|
- // 定时每5秒获取一次数据
|
|
|
- ticker := time.NewTicker(5 * time.Second)
|
|
|
- defer ticker.Stop()
|
|
|
-
|
|
|
- for {
|
|
|
- select {
|
|
|
- case <-ticker.C:
|
|
|
- updateElectricalData()
|
|
|
- }
|
|
|
- }
|
|
|
- }()
|
|
|
+ // // 启动后台协程定期更新电调模型数据
|
|
|
+ // go func() {
|
|
|
+ // // 初始化延迟1秒执行,避免系统启动时的资源竞争
|
|
|
+ // time.Sleep(1 * time.Second)
|
|
|
+
|
|
|
+ // // 定时每5秒获取一次数据
|
|
|
+ // ticker := time.NewTicker(5 * time.Second)
|
|
|
+ // defer ticker.Stop()
|
|
|
+
|
|
|
+ // for {
|
|
|
+ // select {
|
|
|
+ // case <-ticker.C:
|
|
|
+ // updateElectricalData()
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }()
|
|
|
}
|
|
|
|
|
|
-// updateElectricalData 从电调服务获取数据并更新模型
|
|
|
-func updateElectricalData() {
|
|
|
- defer func() {
|
|
|
- if r := recover(); r != nil {
|
|
|
- fmt.Printf("更新电调数据时发生错误: %v\n", r)
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- // 获取 ElectricModelManager 单例实例
|
|
|
- manager := models.GetInstance()
|
|
|
-
|
|
|
- // 获取模型列表副本,避免长时间持有锁
|
|
|
- manager.Mutex.RLock()
|
|
|
- modelsCopy := make(map[string]models.EViewMapModel)
|
|
|
- for k, v := range manager.Models {
|
|
|
- modelsCopy[k] = v
|
|
|
- }
|
|
|
- manager.Mutex.RUnlock()
|
|
|
-
|
|
|
- // 如果 Models 为空,不进行任何处理
|
|
|
- if len(modelsCopy) == 0 {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 遍历已有模型并分别更新
|
|
|
- for _, viewMapModel := range modelsCopy {
|
|
|
- if len(viewMapModel.Models) > 0 && time.Since(viewMapModel.LastBatchUpdate) >= 5*time.Second {
|
|
|
- // 获取第一个模型作为参考来构建请求参数
|
|
|
- firstModel := viewMapModel.Models[0]
|
|
|
-
|
|
|
- // 从配置获取电调服务地址
|
|
|
- electricalIP, err := beego.AppConfig.String("ElectricalIP")
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("读取电调服务IP配置失败: %v\n", err)
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- electricalPort, err := beego.AppConfig.Int("ElectricalPort")
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("读取电调服务端口配置失败: %v\n", err)
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- // 构造电调服务地址
|
|
|
- electricalAddr := fmt.Sprintf("http://%s:%d/ServerCtrl/AllEqpmtList", electricalIP, electricalPort)
|
|
|
-
|
|
|
- // 准备请求数据
|
|
|
- type RequestData struct {
|
|
|
- LineID int `json:"lineID"`
|
|
|
- StationID int `json:"StationID"`
|
|
|
- ViewID int `json:"ViewID"`
|
|
|
- }
|
|
|
- reqData := RequestData{
|
|
|
- LineID: firstModel.LineID,
|
|
|
- // StationID: firstModel.StationID,
|
|
|
- // ViewID: firstModel.ViewID,
|
|
|
- }
|
|
|
-
|
|
|
- // 将请求数据转换为JSON
|
|
|
- reqBody, err := json.Marshal(reqData)
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("构造请求数据失败: %v\n", err)
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- // 发送POST请求获取数据
|
|
|
- resp, err := http.Post(electricalAddr, "application/json", bytes.NewBuffer(reqBody))
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("调用电调服务获取所有设备列表接口失败: %v\n", err)
|
|
|
- continue
|
|
|
- }
|
|
|
+// // updateElectricalData 从电调服务获取数据并更新模型
|
|
|
+// func updateElectricalData() {
|
|
|
+// defer func() {
|
|
|
+// if r := recover(); r != nil {
|
|
|
+// fmt.Printf("更新电调数据时发生错误: %v\n", r)
|
|
|
+// }
|
|
|
+// }()
|
|
|
|
|
|
- // 读取响应体
|
|
|
- bodyBytes, err := io.ReadAll(resp.Body)
|
|
|
- resp.Body.Close()
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("读取电调服务响应失败: %v\n", err)
|
|
|
- continue
|
|
|
- }
|
|
|
+// // 获取 ElectricModelManager 单例实例
|
|
|
+// manager := models.GetInstance()
|
|
|
|
|
|
- // 检查响应状态
|
|
|
- if resp.StatusCode != http.StatusOK {
|
|
|
- fmt.Printf("电调服务返回异常状态码: %d,响应内容: %s\n", resp.StatusCode, string(bodyBytes))
|
|
|
- continue
|
|
|
- }
|
|
|
+// // 获取模型列表副本,避免长时间持有锁
|
|
|
+// manager.Mutex.RLock()
|
|
|
+// modelsCopy := make(map[string]models.EViewMapModel)
|
|
|
+// for k, v := range manager.Models {
|
|
|
+// modelsCopy[k] = v
|
|
|
+// }
|
|
|
+// manager.Mutex.RUnlock()
|
|
|
|
|
|
- // 解析JSON响应
|
|
|
- var result map[string]interface{}
|
|
|
- if err := json.Unmarshal(bodyBytes, &result); err != nil {
|
|
|
- fmt.Printf("解析电调服务响应失败: %v\n", err)
|
|
|
- continue
|
|
|
- }
|
|
|
+// // 如果 Models 为空,不进行任何处理
|
|
|
+// if len(modelsCopy) == 0 {
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- // 检查是否有data字段
|
|
|
- if data, exists := result["data"]; exists {
|
|
|
- // 解析data中的设备列表并更新到模型管理器
|
|
|
- var equipments []models.DiandiaoModel
|
|
|
- if equipBytes, err := json.Marshal(data); err == nil {
|
|
|
- if err := json.Unmarshal(equipBytes, &equipments); err == nil {
|
|
|
- // 更新总包设备数据 (在更新时加锁)
|
|
|
- manager.UpdateBatchData(equipments)
|
|
|
- fmt.Printf("成功更新线路%d的电调模型数据\n", firstModel.LineID)
|
|
|
- } else {
|
|
|
- fmt.Printf("解析设备列表失败: %v\n", err)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+// // 遍历已有模型并分别更新
|
|
|
+// for _, viewMapModel := range modelsCopy {
|
|
|
+// if len(viewMapModel.Models) > 0 && time.Since(viewMapModel.LastBatchUpdate) >= 5*time.Second {
|
|
|
+// // 获取第一个模型作为参考来构建请求参数
|
|
|
+// firstModel := viewMapModel.Models[0]
|
|
|
+
|
|
|
+// // 从配置获取电调服务地址
|
|
|
+// electricalIP, err := beego.AppConfig.String("ElectricalIP")
|
|
|
+// if err != nil {
|
|
|
+// fmt.Printf("读取电调服务IP配置失败: %v\n", err)
|
|
|
+// continue
|
|
|
+// }
|
|
|
+
|
|
|
+// electricalPort, err := beego.AppConfig.Int("ElectricalPort")
|
|
|
+// if err != nil {
|
|
|
+// fmt.Printf("读取电调服务端口配置失败: %v\n", err)
|
|
|
+// continue
|
|
|
+// }
|
|
|
+
|
|
|
+// // 构造电调服务地址
|
|
|
+// electricalAddr := fmt.Sprintf("http://%s:%d/ServerCtrl/AllEqpmtList", electricalIP, electricalPort)
|
|
|
+
|
|
|
+// // 准备请求数据
|
|
|
+// type RequestData struct {
|
|
|
+// LineID int `json:"lineID"`
|
|
|
+// StationID int `json:"StationID"`
|
|
|
+// ViewID int `json:"ViewID"`
|
|
|
+// }
|
|
|
+// reqData := RequestData{
|
|
|
+// LineID: firstModel.LineID,
|
|
|
+// // StationID: firstModel.StationID,
|
|
|
+// // ViewID: firstModel.ViewID,
|
|
|
+// }
|
|
|
+
|
|
|
+// // 将请求数据转换为JSON
|
|
|
+// reqBody, err := json.Marshal(reqData)
|
|
|
+// if err != nil {
|
|
|
+// fmt.Printf("构造请求数据失败: %v\n", err)
|
|
|
+// continue
|
|
|
+// }
|
|
|
+
|
|
|
+// // 发送POST请求获取数据
|
|
|
+// resp, err := http.Post(electricalAddr, "application/json", bytes.NewBuffer(reqBody))
|
|
|
+// if err != nil {
|
|
|
+// fmt.Printf("调用电调服务获取所有设备列表接口失败: %v\n", err)
|
|
|
+// continue
|
|
|
+// }
|
|
|
+
|
|
|
+// // 读取响应体
|
|
|
+// bodyBytes, err := io.ReadAll(resp.Body)
|
|
|
+// resp.Body.Close()
|
|
|
+// if err != nil {
|
|
|
+// fmt.Printf("读取电调服务响应失败: %v\n", err)
|
|
|
+// continue
|
|
|
+// }
|
|
|
+
|
|
|
+// // 检查响应状态
|
|
|
+// if resp.StatusCode != http.StatusOK {
|
|
|
+// fmt.Printf("电调服务返回异常状态码: %d,响应内容: %s\n", resp.StatusCode, string(bodyBytes))
|
|
|
+// continue
|
|
|
+// }
|
|
|
+
|
|
|
+// // 解析JSON响应
|
|
|
+// var result map[string]interface{}
|
|
|
+// if err := json.Unmarshal(bodyBytes, &result); err != nil {
|
|
|
+// fmt.Printf("解析电调服务响应失败: %v\n", err)
|
|
|
+// continue
|
|
|
+// }
|
|
|
+
|
|
|
+// // 检查是否有data字段
|
|
|
+// if data, exists := result["data"]; exists {
|
|
|
+// // 解析data中的设备列表并更新到模型管理器
|
|
|
+// var equipments []models.DiandiaoModel
|
|
|
+// if equipBytes, err := json.Marshal(data); err == nil {
|
|
|
+// if err := json.Unmarshal(equipBytes, &equipments); err == nil {
|
|
|
+// // 更新总包设备数据 (在更新时加锁)
|
|
|
+// manager.UpdateBatchData(equipments)
|
|
|
+// fmt.Printf("成功更新线路%d的电调模型数据\n", firstModel.LineID)
|
|
|
+// } else {
|
|
|
+// fmt.Printf("解析设备列表失败: %v\n", err)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
type EDispatchController struct {
|
|
|
beego.Controller
|
|
|
}
|
|
|
|
|
|
-// /courserun/eqpmtvalue 更新电调设备状态
|
|
|
+// /courserun/eqpmtstatus 更新电调设备状态
|
|
|
func (c *EDispatchController) Eqpmtvalue() {
|
|
|
var req models.DiandiaoModel
|
|
|
|
|
|
@@ -392,82 +392,15 @@ func (c *EDispatchController) UpdateTestStatus() {
|
|
|
|
|
|
}
|
|
|
|
|
|
-// // /serverCtrl/alleqpmtlist 获取所有设备列表
|
|
|
-// func (c *EDispatchController) AllEqpmtList() {
|
|
|
-// // 定义与testStatus.json文件匹配的结构体
|
|
|
-// type jsonData struct {
|
|
|
-// DataID string `json:"dataId"`
|
|
|
-// DataName string `json:"dataName"`
|
|
|
-// Value string `json:"value"`
|
|
|
-// ID string `json:"id"`
|
|
|
-// }
|
|
|
-
|
|
|
-// // 读取testStatus.json文件
|
|
|
-// filePath := "static/testStatus.json"
|
|
|
-// data, err := os.ReadFile(filePath)
|
|
|
-// if err != nil {
|
|
|
-// c.Ctx.Output.SetStatus(500)
|
|
|
-// c.Data["json"] = map[string]interface{}{
|
|
|
-// "code": 500,
|
|
|
-// "msg": "读取文件失败: " + err.Error(),
|
|
|
-// }
|
|
|
-// c.ServeJSON()
|
|
|
-// return
|
|
|
-// }
|
|
|
-
|
|
|
-// // 解析JSON数据
|
|
|
-// var jsonDataList []jsonData
|
|
|
-// err = json.Unmarshal(data, &jsonDataList)
|
|
|
-// if err != nil {
|
|
|
-// c.Ctx.Output.SetStatus(500)
|
|
|
-// c.Data["json"] = map[string]interface{}{
|
|
|
-// "code": 500,
|
|
|
-// "msg": "解析JSON失败: " + err.Error(),
|
|
|
-// }
|
|
|
-// c.ServeJSON()
|
|
|
-// return
|
|
|
-// }
|
|
|
-
|
|
|
-// // 转换为EquipmentData结构体
|
|
|
-// type EquipmentData struct {
|
|
|
-// DataID string `json:"dataId"`
|
|
|
-// DataName string `json:"dataName"`
|
|
|
-// Value string `json:"value"`
|
|
|
-// ID string `json:"id"`
|
|
|
-// }
|
|
|
-// //动态生成值 1-3改变
|
|
|
-
|
|
|
-// // 初始化随机数种子
|
|
|
-// rand.Seed(time.Now().UnixNano())
|
|
|
-
|
|
|
-// // 生成1-3之间的随机数
|
|
|
-// nValue := rand.Intn(3) + 1
|
|
|
-
|
|
|
-// var equipmentDataList []EquipmentData
|
|
|
-// for _, item := range jsonDataList {
|
|
|
-// equipment := EquipmentData{
|
|
|
-// DataID: item.DataID,
|
|
|
-// DataName: item.DataName,
|
|
|
-// Value: fmt.Sprintf("%d", nValue),
|
|
|
-// ID: item.ID,
|
|
|
-// }
|
|
|
-// equipmentDataList = append(equipmentDataList, equipment)
|
|
|
-// }
|
|
|
-
|
|
|
-// // 返回结果
|
|
|
-// c.Data["json"] = equipmentDataList
|
|
|
-// c.ServeJSON()
|
|
|
-
|
|
|
-// }
|
|
|
-
|
|
|
// /serverCtrl/alleqpmtlist 获取所有设备列表
|
|
|
func (c *EDispatchController) AllEqpmtList() {
|
|
|
// 转换缓存数据为指定格式
|
|
|
type EquipmentData struct {
|
|
|
- DataID string `json:"dataId"`
|
|
|
- DataName string `json:"dataName"`
|
|
|
- Value string `json:"value"`
|
|
|
- ID string `json:"id"`
|
|
|
+ DataID string `json:"dataId"`
|
|
|
+ DataName string `json:"dataName"`
|
|
|
+ Value string `json:"value"`
|
|
|
+ ID string `json:"id"`
|
|
|
+ EqpmtTypeID int `json:"eqpmtTypeID"`
|
|
|
}
|
|
|
|
|
|
// 从配置文件读取电调服务IP和端口
|
|
|
@@ -491,6 +424,12 @@ func (c *EDispatchController) AllEqpmtList() {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ // 获取全量数据更新间隔配置,默认10秒
|
|
|
+ fullDataIntervalSeconds := 10
|
|
|
+ if interval, err := beego.AppConfig.Int("EGetAllDataInterval"); err == nil {
|
|
|
+ fullDataIntervalSeconds = interval
|
|
|
+ }
|
|
|
+
|
|
|
// 构造电调服务地址
|
|
|
electricalAddr := fmt.Sprintf("http://%s:%d/ServerCtrl/AllEqpmtList", electricalIP, electricalPort)
|
|
|
|
|
|
@@ -533,48 +472,18 @@ func (c *EDispatchController) AllEqpmtList() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 生成请求key
|
|
|
- model := models.DiandiaoModel{
|
|
|
- LineID: lineID,
|
|
|
- }
|
|
|
- key := model.GenerateModelKey()
|
|
|
+ // 使用客户端IP作为客户端标识
|
|
|
+ clientID := c.Ctx.Input.IP()
|
|
|
|
|
|
// 获取 ElectricModelManager 单例实例
|
|
|
manager := models.GetInstance()
|
|
|
|
|
|
- // 检查缓存中是否存在对应key的数据,且最后更新时间在5秒内
|
|
|
- if viewMapModel, exists := manager.GetModelByKey(key); exists {
|
|
|
- // 检查最后总包更新时间是否在2秒内
|
|
|
- if time.Since(viewMapModel.LastBatchUpdate) <= 2*time.Second || time.Since(viewMapModel.LastDeviceUpdate) <= 2*time.Second {
|
|
|
+ // 注册客户端
|
|
|
+ manager.RegisterClient(clientID)
|
|
|
+ // 注意:不再在函数退出时注销客户端,而是由 ElectricModelManager 内部定期清理长时间未访问的客户端
|
|
|
|
|
|
- var equipmentsData []EquipmentData
|
|
|
- for _, model := range viewMapModel.Models {
|
|
|
- equip := EquipmentData{
|
|
|
- DataID: model.EqpmtStrID,
|
|
|
- ID: model.EqpmtStrID,
|
|
|
- DataName: model.EqpmtStdName,
|
|
|
- }
|
|
|
-
|
|
|
- switch model.CMDType {
|
|
|
- case 0: //设备状态
|
|
|
- equip.Value = fmt.Sprintf("%d", model.EqpmtStatus)
|
|
|
- case 1: //设备数据控制
|
|
|
- equip.Value = fmt.Sprintf("%d", model.FValue)
|
|
|
- }
|
|
|
- equipmentsData = append(equipmentsData, equip)
|
|
|
- }
|
|
|
- c.Data["json"] = equipmentsData
|
|
|
-
|
|
|
- // // 使用缓存数据
|
|
|
- // c.Data["json"] = map[string]interface{}{
|
|
|
- // "code": 200,
|
|
|
- // "msg": "获取所有设备列表成功(缓存)",
|
|
|
- // "data": equipmentsData,
|
|
|
- // }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
+ // 检查是否应该发送全量数据
|
|
|
+ shouldSendFullData := manager.ShouldSendFullData(fullDataIntervalSeconds)
|
|
|
|
|
|
// 准备请求数据
|
|
|
type RequestData struct {
|
|
|
@@ -654,12 +563,16 @@ func (c *EDispatchController) AllEqpmtList() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 构建当前设备数据映射
|
|
|
+ currentDataMapping := make(map[string]string)
|
|
|
var equipmentsData []EquipmentData
|
|
|
+ // isFirst := true
|
|
|
for _, model := range equipments {
|
|
|
equip := EquipmentData{
|
|
|
- DataID: model.EqpmtStrID,
|
|
|
- ID: model.EqpmtStrID,
|
|
|
- DataName: model.EqpmtStdName,
|
|
|
+ DataID: model.EqpmtStrID,
|
|
|
+ ID: model.EqpmtStrID,
|
|
|
+ DataName: model.EqpmtStdName,
|
|
|
+ EqpmtTypeID: model.EqpmtTypeID,
|
|
|
}
|
|
|
|
|
|
if model.CMDType == 0 { //设备状态
|
|
|
@@ -667,17 +580,43 @@ func (c *EDispatchController) AllEqpmtList() {
|
|
|
} else if model.CMDType == 1 { //设备数据控制
|
|
|
equip.Value = fmt.Sprintf("%d", model.FValue)
|
|
|
}
|
|
|
+ // if isFirst {
|
|
|
+ // // 生成0到100之间的随机整数
|
|
|
+ // equip.Value = fmt.Sprintf("%d", rand.Intn(101))
|
|
|
+ // isFirst = false
|
|
|
+
|
|
|
+ // }
|
|
|
+
|
|
|
+ // 添加到当前数据映射
|
|
|
+ currentDataMapping[model.EqpmtStrID] = equip.Value
|
|
|
equipmentsData = append(equipmentsData, equip)
|
|
|
}
|
|
|
|
|
|
- c.Data["json"] = equipmentsData
|
|
|
+ // 如果应该发送全量数据
|
|
|
+ if shouldSendFullData {
|
|
|
+ c.Data["json"] = equipmentsData
|
|
|
+ manager.UpdateFullDataTimestamp()
|
|
|
+ manager.UpdateClientData(clientID, currentDataMapping)
|
|
|
+ } else {
|
|
|
+ // 否则只返回变化的数据
|
|
|
+ changedData := manager.CompareWithClientData(clientID, currentDataMapping)
|
|
|
+
|
|
|
+ // 构建变化的设备数据列表
|
|
|
+ var changedEquipmentsData []EquipmentData
|
|
|
+ for _, equip := range equipmentsData {
|
|
|
+ if _, changed := changedData[equip.ID]; changed {
|
|
|
+ changedEquipmentsData = append(changedEquipmentsData, equip)
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // // 返回响应
|
|
|
- // c.Data["json"] = map[string]interface{}{
|
|
|
- // "code": 200,
|
|
|
- // "msg": "获取所有设备列表成功",
|
|
|
- // "data": equipmentsData,
|
|
|
- // }
|
|
|
+ // 确保不会返回nil,即使没有变化也返回空数组
|
|
|
+ if changedEquipmentsData == nil {
|
|
|
+ changedEquipmentsData = []EquipmentData{}
|
|
|
+ }
|
|
|
+ c.Data["json"] = changedEquipmentsData
|
|
|
+ // 更新客户端数据记录
|
|
|
+ manager.UpdateClientData(clientID, currentDataMapping)
|
|
|
+ }
|
|
|
} else {
|
|
|
// 如果没有data字段,返回整个响应
|
|
|
c.Data["json"] = map[string]interface{}{
|
|
|
@@ -690,236 +629,236 @@ func (c *EDispatchController) AllEqpmtList() {
|
|
|
c.ServeJSON()
|
|
|
}
|
|
|
|
|
|
-// /serverCtrl/alleqpmtlist2 获取所有设备列表 测试使用
|
|
|
-func (c *EDispatchController) AllEqpmtList2() {
|
|
|
- // 转换缓存数据为指定格式
|
|
|
- type EquipmentData struct {
|
|
|
- DataID string `json:"dataId"`
|
|
|
- DataName string `json:"dataName"`
|
|
|
- Value string `json:"value"`
|
|
|
- ID string `json:"id"`
|
|
|
- }
|
|
|
-
|
|
|
- // 从配置文件读取电调服务IP和端口
|
|
|
- electricalIP, err := beego.AppConfig.String("ElectricalIP")
|
|
|
- if err != nil {
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "读取电调服务IP配置失败: " + err.Error(),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- electricalPort, err := beego.AppConfig.Int("ElectricalPort")
|
|
|
- if err != nil {
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "读取电调服务端口配置失败: " + err.Error(),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 构造电调服务地址
|
|
|
- electricalAddr := fmt.Sprintf("http://%s:%d/ServerCtrl/AllEqpmtList", electricalIP, electricalPort)
|
|
|
-
|
|
|
- // 获取最新的课程运行记录以获取线路号
|
|
|
- o := orm.NewOrm()
|
|
|
- var latestCourse models.CourseRunLog
|
|
|
- err = o.QueryTable(new(models.CourseRunLog)).
|
|
|
- OrderBy("-RunLogID").
|
|
|
- One(&latestCourse)
|
|
|
-
|
|
|
- if err != nil && err != orm.ErrNoRows {
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "查询最新课程运行记录失败: " + err.Error(),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 如果没有找到运行记录,默认线路号为0
|
|
|
- lineID := 0
|
|
|
- if err != orm.ErrNoRows {
|
|
|
- // 根据运行课程ID查询课程信息以获取线路号
|
|
|
- var courseInfo models.CourseInfo
|
|
|
- err = o.QueryTable(new(models.CourseInfo)).
|
|
|
- Filter("CourseID", latestCourse.RunCourseID).
|
|
|
- One(&courseInfo)
|
|
|
-
|
|
|
- if err != nil && err != orm.ErrNoRows {
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "查询课程信息失败: " + err.Error(),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if err != orm.ErrNoRows {
|
|
|
- lineID = courseInfo.LineNo
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 生成请求key
|
|
|
- model := models.DiandiaoModel{
|
|
|
- LineID: lineID,
|
|
|
- }
|
|
|
- key := model.GenerateModelKey()
|
|
|
-
|
|
|
- // 获取 ElectricModelManager 单例实例
|
|
|
- manager := models.GetInstance()
|
|
|
-
|
|
|
- // 检查缓存中是否存在对应key的数据,且最后更新时间在5秒内
|
|
|
- if viewMapModel, exists := manager.GetModelByKey(key); exists {
|
|
|
- // 检查最后总包更新时间是否在5秒内
|
|
|
- if time.Since(viewMapModel.LastBatchUpdate) <= 5*time.Second || time.Since(viewMapModel.LastDeviceUpdate) <= 5*time.Second {
|
|
|
+// // /serverCtrl/alleqpmtlist2 获取所有设备列表 测试使用
|
|
|
+// func (c *EDispatchController) AllEqpmtList2() {
|
|
|
+// // 转换缓存数据为指定格式
|
|
|
+// type EquipmentData struct {
|
|
|
+// DataID string `json:"dataId"`
|
|
|
+// DataName string `json:"dataName"`
|
|
|
+// Value string `json:"value"`
|
|
|
+// ID string `json:"id"`
|
|
|
+// }
|
|
|
|
|
|
- var equipmentsData []EquipmentData
|
|
|
- for _, model := range viewMapModel.Models {
|
|
|
- equip := EquipmentData{
|
|
|
- DataID: model.EqpmtStrID,
|
|
|
- ID: model.EqpmtStrID,
|
|
|
- DataName: model.EqpmtStdName,
|
|
|
- }
|
|
|
+// // 从配置文件读取电调服务IP和端口
|
|
|
+// electricalIP, err := beego.AppConfig.String("ElectricalIP")
|
|
|
+// if err != nil {
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "读取电调服务IP配置失败: " + err.Error(),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- switch model.CMDType {
|
|
|
- case 0: //设备状态
|
|
|
- equip.Value = fmt.Sprintf("%d", model.EqpmtStatus)
|
|
|
- case 1: //设备数据控制
|
|
|
- equip.Value = fmt.Sprintf("%d", model.FValue)
|
|
|
- }
|
|
|
- equipmentsData = append(equipmentsData, equip)
|
|
|
- }
|
|
|
+// electricalPort, err := beego.AppConfig.Int("ElectricalPort")
|
|
|
+// if err != nil {
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "读取电调服务端口配置失败: " + err.Error(),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- c.Data["json"] = equipmentsData
|
|
|
+// // 构造电调服务地址
|
|
|
+// electricalAddr := fmt.Sprintf("http://%s:%d/ServerCtrl/AllEqpmtList", electricalIP, electricalPort)
|
|
|
|
|
|
- // 使用缓存数据
|
|
|
- // c.Data["json"] = map[string]interface{}{
|
|
|
- // "code": 200,
|
|
|
- // "msg": "获取所有设备列表成功(缓存)",
|
|
|
- // "data": equipmentsData,
|
|
|
- // }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
+// // 获取最新的课程运行记录以获取线路号
|
|
|
+// o := orm.NewOrm()
|
|
|
+// var latestCourse models.CourseRunLog
|
|
|
+// err = o.QueryTable(new(models.CourseRunLog)).
|
|
|
+// OrderBy("-RunLogID").
|
|
|
+// One(&latestCourse)
|
|
|
|
|
|
- // 准备请求数据
|
|
|
- type RequestData struct {
|
|
|
- LineID int `json:"lineID"`
|
|
|
- StationID int `json:"StationID"`
|
|
|
- ViewID int `json:"ViewID"`
|
|
|
- }
|
|
|
- reqData := RequestData{
|
|
|
- LineID: lineID,
|
|
|
- StationID: 0,
|
|
|
- ViewID: 0,
|
|
|
- }
|
|
|
+// if err != nil && err != orm.ErrNoRows {
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "查询最新课程运行记录失败: " + err.Error(),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- // 将请求数据转换为JSON
|
|
|
- reqBody, err := json.Marshal(reqData)
|
|
|
- if err != nil {
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "构造请求数据失败: " + err.Error(),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
+// // 如果没有找到运行记录,默认线路号为0
|
|
|
+// lineID := 0
|
|
|
+// if err != orm.ErrNoRows {
|
|
|
+// // 根据运行课程ID查询课程信息以获取线路号
|
|
|
+// var courseInfo models.CourseInfo
|
|
|
+// err = o.QueryTable(new(models.CourseInfo)).
|
|
|
+// Filter("CourseID", latestCourse.RunCourseID).
|
|
|
+// One(&courseInfo)
|
|
|
+
|
|
|
+// if err != nil && err != orm.ErrNoRows {
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "查询课程信息失败: " + err.Error(),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- // 调用电调服务获取所有设备列表接口,使用POST方法
|
|
|
- resp, err := http.Post(electricalAddr, "application/json", bytes.NewBuffer(reqBody))
|
|
|
- if err != nil {
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "调用电调服务获取所有设备列表接口失败: " + err.Error(),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
- defer resp.Body.Close()
|
|
|
+// if err != orm.ErrNoRows {
|
|
|
+// lineID = courseInfo.LineNo
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
- // 检查响应状态
|
|
|
- if resp.StatusCode != http.StatusOK {
|
|
|
- bodyBytes, _ := io.ReadAll(resp.Body)
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": fmt.Sprintf("电调服务返回异常状态码: %d,响应内容: %s", resp.StatusCode, string(bodyBytes)),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
+// // 生成请求key
|
|
|
+// model := models.DiandiaoModel{
|
|
|
+// LineID: lineID,
|
|
|
+// }
|
|
|
+// key := model.GenerateModelKey()
|
|
|
+
|
|
|
+// // 获取 ElectricModelManager 单例实例
|
|
|
+// manager := models.GetInstance()
|
|
|
+
|
|
|
+// // 检查缓存中是否存在对应key的数据,且最后更新时间在5秒内
|
|
|
+// if viewMapModel, exists := manager.GetModelByKey(key); exists {
|
|
|
+// // 检查最后总包更新时间是否在5秒内
|
|
|
+// if time.Since(viewMapModel.LastBatchUpdate) <= 5*time.Second || time.Since(viewMapModel.LastDeviceUpdate) <= 5*time.Second {
|
|
|
+
|
|
|
+// var equipmentsData []EquipmentData
|
|
|
+// for _, model := range viewMapModel.Models {
|
|
|
+// equip := EquipmentData{
|
|
|
+// DataID: model.EqpmtStrID,
|
|
|
+// ID: model.EqpmtStrID,
|
|
|
+// DataName: model.EqpmtStdName,
|
|
|
+// }
|
|
|
+
|
|
|
+// switch model.CMDType {
|
|
|
+// case 0: //设备状态
|
|
|
+// equip.Value = fmt.Sprintf("%d", model.EqpmtStatus)
|
|
|
+// case 1: //设备数据控制
|
|
|
+// equip.Value = fmt.Sprintf("%d", model.FValue)
|
|
|
+// }
|
|
|
+// equipmentsData = append(equipmentsData, equip)
|
|
|
+// }
|
|
|
+
|
|
|
+// c.Data["json"] = equipmentsData
|
|
|
+
|
|
|
+// // 使用缓存数据
|
|
|
+// // c.Data["json"] = map[string]interface{}{
|
|
|
+// // "code": 200,
|
|
|
+// // "msg": "获取所有设备列表成功(缓存)",
|
|
|
+// // "data": equipmentsData,
|
|
|
+// // }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
- // 读取并解析响应体
|
|
|
- bodyBytes, err := io.ReadAll(resp.Body)
|
|
|
- if err != nil {
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "读取电调服务响应失败: " + err.Error(),
|
|
|
- }
|
|
|
- c.ServeJSON()
|
|
|
- return
|
|
|
- }
|
|
|
+// // 准备请求数据
|
|
|
+// type RequestData struct {
|
|
|
+// LineID int `json:"lineID"`
|
|
|
+// StationID int `json:"StationID"`
|
|
|
+// ViewID int `json:"ViewID"`
|
|
|
+// }
|
|
|
+// reqData := RequestData{
|
|
|
+// LineID: lineID,
|
|
|
+// StationID: 0,
|
|
|
+// ViewID: 0,
|
|
|
+// }
|
|
|
|
|
|
- // 尝试解析JSON响应
|
|
|
- var result map[string]interface{}
|
|
|
- if err := json.Unmarshal(bodyBytes, &result); err != nil {
|
|
|
- // 如果不是JSON格式,作为字符串返回
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 200,
|
|
|
- "msg": "获取所有设备列表成功",
|
|
|
- "data": string(bodyBytes),
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 如果是JSON格式,检查是否有data字段
|
|
|
- if data, exists := result["data"]; exists {
|
|
|
- // 解析data中的设备列表并更新到模型管理器
|
|
|
- var equipments []models.DiandiaoModel
|
|
|
- if equipBytes, err := json.Marshal(data); err == nil {
|
|
|
- if err := json.Unmarshal(equipBytes, &equipments); err == nil {
|
|
|
- // 更新总包设备数据
|
|
|
- manager.UpdateBatchData(equipments)
|
|
|
- }
|
|
|
- }
|
|
|
+// // 将请求数据转换为JSON
|
|
|
+// reqBody, err := json.Marshal(reqData)
|
|
|
+// if err != nil {
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "构造请求数据失败: " + err.Error(),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- var equipmentsData []EquipmentData
|
|
|
- for _, model := range equipments {
|
|
|
- equip := EquipmentData{
|
|
|
- DataID: model.EqpmtStrID,
|
|
|
- ID: model.EqpmtStrID,
|
|
|
- DataName: model.EqpmtStdName,
|
|
|
- }
|
|
|
+// // 调用电调服务获取所有设备列表接口,使用POST方法
|
|
|
+// resp, err := http.Post(electricalAddr, "application/json", bytes.NewBuffer(reqBody))
|
|
|
+// if err != nil {
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "调用电调服务获取所有设备列表接口失败: " + err.Error(),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
+// defer resp.Body.Close()
|
|
|
|
|
|
- if model.CMDType == 0 { //设备状态
|
|
|
- equip.Value = fmt.Sprintf("%d", model.EqpmtStatus)
|
|
|
- } else if model.CMDType == 1 { //设备数据控制
|
|
|
- equip.Value = fmt.Sprintf("%d", model.FValue)
|
|
|
- }
|
|
|
- equipmentsData = append(equipmentsData, equip)
|
|
|
- }
|
|
|
+// // 检查响应状态
|
|
|
+// if resp.StatusCode != http.StatusOK {
|
|
|
+// bodyBytes, _ := io.ReadAll(resp.Body)
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": fmt.Sprintf("电调服务返回异常状态码: %d,响应内容: %s", resp.StatusCode, string(bodyBytes)),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- c.Data["json"] = equipmentsData
|
|
|
+// // 读取并解析响应体
|
|
|
+// bodyBytes, err := io.ReadAll(resp.Body)
|
|
|
+// if err != nil {
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "读取电调服务响应失败: " + err.Error(),
|
|
|
+// }
|
|
|
+// c.ServeJSON()
|
|
|
+// return
|
|
|
+// }
|
|
|
|
|
|
- // // 返回响应
|
|
|
- // c.Data["json"] = map[string]interface{}{
|
|
|
- // "code": 200,
|
|
|
- // "msg": "获取所有设备列表成功",
|
|
|
- // "data": equipmentsData,
|
|
|
- // }
|
|
|
- } else {
|
|
|
- // 如果没有data字段,返回整个响应
|
|
|
- c.Data["json"] = map[string]interface{}{
|
|
|
- "code": 500,
|
|
|
- "msg": "获取所有设备列表失败",
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+// // 尝试解析JSON响应
|
|
|
+// var result map[string]interface{}
|
|
|
+// if err := json.Unmarshal(bodyBytes, &result); err != nil {
|
|
|
+// // 如果不是JSON格式,作为字符串返回
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 200,
|
|
|
+// "msg": "获取所有设备列表成功",
|
|
|
+// "data": string(bodyBytes),
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// // 如果是JSON格式,检查是否有data字段
|
|
|
+// if data, exists := result["data"]; exists {
|
|
|
+// // 解析data中的设备列表并更新到模型管理器
|
|
|
+// var equipments []models.DiandiaoModel
|
|
|
+// if equipBytes, err := json.Marshal(data); err == nil {
|
|
|
+// if err := json.Unmarshal(equipBytes, &equipments); err == nil {
|
|
|
+// // 更新总包设备数据
|
|
|
+// manager.UpdateBatchData(equipments)
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+// var equipmentsData []EquipmentData
|
|
|
+// for _, model := range equipments {
|
|
|
+// equip := EquipmentData{
|
|
|
+// DataID: model.EqpmtStrID,
|
|
|
+// ID: model.EqpmtStrID,
|
|
|
+// DataName: model.EqpmtStdName,
|
|
|
+// }
|
|
|
+
|
|
|
+// if model.CMDType == 0 { //设备状态
|
|
|
+// equip.Value = fmt.Sprintf("%d", model.EqpmtStatus)
|
|
|
+// } else if model.CMDType == 1 { //设备数据控制
|
|
|
+// equip.Value = fmt.Sprintf("%d", model.FValue)
|
|
|
+// }
|
|
|
+// equipmentsData = append(equipmentsData, equip)
|
|
|
+// }
|
|
|
+
|
|
|
+// c.Data["json"] = equipmentsData
|
|
|
+
|
|
|
+// // // 返回响应
|
|
|
+// // c.Data["json"] = map[string]interface{}{
|
|
|
+// // "code": 200,
|
|
|
+// // "msg": "获取所有设备列表成功",
|
|
|
+// // "data": equipmentsData,
|
|
|
+// // }
|
|
|
+// } else {
|
|
|
+// // 如果没有data字段,返回整个响应
|
|
|
+// c.Data["json"] = map[string]interface{}{
|
|
|
+// "code": 500,
|
|
|
+// "msg": "获取所有设备列表失败",
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
- c.ServeJSON()
|
|
|
-}
|
|
|
+// c.ServeJSON()
|
|
|
+// }
|
|
|
|
|
|
// /serverctrl/seteqpmtoper 设置电调设备操作
|
|
|
func (c *EDispatchController) Seteqpmtoper() {
|
|
|
@@ -1350,17 +1289,19 @@ func (c *EDispatchController) GetEqpmtFault() {
|
|
|
|
|
|
// 转换为UI需要的格式
|
|
|
type UIFaultData struct {
|
|
|
- SeqNo int `json:"SeqNo"`
|
|
|
- EqpmtID string `json:"EqpmtID"`
|
|
|
- EqpmtName string `json:"EqpmtName"`
|
|
|
- FaultID int `json:"FaultID"`
|
|
|
- FaultTime int `json:"FaultTime"`
|
|
|
+ SeqNo int `json:"SeqNo"`
|
|
|
+ EqpmtID string `json:"EqpmtID"`
|
|
|
+ EqpmtName string `json:"EqpmtName"`
|
|
|
+ FaultID int `json:"FaultID"`
|
|
|
+ FaultTime int `json:"FaultTime"`
|
|
|
+ EqpmtTypeID int `json:"EqpmtTypeID"`
|
|
|
}
|
|
|
|
|
|
var uiData []UIFaultData
|
|
|
seqNo := 1
|
|
|
for _, item := range faultData {
|
|
|
eqpmtID, _ := item["EqpmtID"].(string)
|
|
|
+ EqpmtTypeID, _ := item["EqpmtTypeID"].(int)
|
|
|
|
|
|
// 解析设备故障数组
|
|
|
eqpmtFault, ok := item["EqpmtFault"].([]interface{})
|
|
|
@@ -1388,11 +1329,12 @@ func (c *EDispatchController) GetEqpmtFault() {
|
|
|
secondsAgo := int(time.Since(faultTime).Seconds())
|
|
|
|
|
|
uiFault := UIFaultData{
|
|
|
- SeqNo: seqNo,
|
|
|
- EqpmtID: eqpmtID,
|
|
|
- EqpmtName: "", // 原始数据中未提供设备名称,留空
|
|
|
- FaultID: int(faultID),
|
|
|
- FaultTime: secondsAgo,
|
|
|
+ SeqNo: seqNo,
|
|
|
+ EqpmtID: eqpmtID,
|
|
|
+ EqpmtName: "", // 原始数据中未提供设备名称,留空
|
|
|
+ FaultID: int(faultID),
|
|
|
+ FaultTime: secondsAgo,
|
|
|
+ EqpmtTypeID: int(EqpmtTypeID),
|
|
|
}
|
|
|
|
|
|
uiData = append(uiData, uiFault)
|