From dbc038d5318d53ac7c14e26386588c48c621a591 Mon Sep 17 00:00:00 2001
From: zhangzengfei <zhangzengfei@smartai.com>
Date: 星期五, 13 九月 2024 11:51:45 +0800
Subject: [PATCH] fix config
---
service/nvcs.go | 268 ++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 231 insertions(+), 37 deletions(-)
diff --git a/service/nvcs.go b/service/nvcs.go
index e2f3f2b..fbff0ac 100644
--- a/service/nvcs.go
+++ b/service/nvcs.go
@@ -2,23 +2,52 @@
import (
"bytes"
+ "encoding/binary"
+ "encoding/hex"
"encoding/json"
"fmt"
- "github.com/gin-gonic/gin"
"io/ioutil"
"net"
"net/http"
+ "strings"
"time"
"gat1400Exchange/config"
"gat1400Exchange/models"
"gat1400Exchange/pkg/logger"
+ "gat1400Exchange/rfid"
+ "gat1400Exchange/util"
+ "github.com/gin-gonic/gin"
+ "github.com/google/uuid"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
)
-type ElevatorStatus struct {
+type A1SetFloorFrame struct {
+ Header [16]byte // Fixed 16-byte header
+ Command byte // 1 byte command
+ MAC [6]byte // 6 bytes MAC address
+ DataLength uint16 // 2 bytes data length
+ Data []byte // Data area, length defined by DataLength
+ Checksum uint16 // 2 bytes CRC16 checksum
+}
+
+// Convert frame to byte slice
+func (f *A1SetFloorFrame) toBytes(includeChecksum bool) []byte {
+ buf := new(bytes.Buffer)
+ binary.Write(buf, binary.LittleEndian, f.Header)
+ binary.Write(buf, binary.LittleEndian, f.Command)
+ binary.Write(buf, binary.LittleEndian, f.MAC)
+ binary.Write(buf, binary.LittleEndian, f.DataLength)
+ buf.Write(f.Data)
+ if includeChecksum {
+ binary.Write(buf, binary.LittleEndian, f.Checksum)
+ }
+ return buf.Bytes()
+}
+
+type A1ElevatorStatus struct {
TotalFloors int `json:"TotalFloors"`
Floor int `json:"Floor"`
FloorName string `json:"FloorName"`
@@ -26,15 +55,15 @@
Speed string `json:"Speed"`
}
-type Elevator struct {
- Name string `json:"Name"`
- IP string `json:"IP"`
- Status ElevatorStatus `json:"Status"`
- Alarm []interface{} `json:"Alarm"` // You might want to define a specific type for alarms
+type A1Elevator struct {
+ Name string `json:"Name"`
+ IP string `json:"IP"`
+ Status A1ElevatorStatus `json:"Status"`
+ Alarm []interface{} `json:"Alarm"` // You might want to define a specific type for alarms
}
type A1ElevatorData struct {
- Elevator []Elevator `json:"Elevator"`
+ Elevator []A1Elevator `json:"Elevator"`
}
const (
@@ -42,6 +71,97 @@
RunUp
RunDown
)
+
+var ElevatorRunState int
+var RunningCorrectTaskId string
+
+func A1CorrectFloor() {
+ if RunningCorrectTaskId != "" || config.RFIDConf.EPC == "" {
+ return
+ }
+
+ taskId := uuid.New().String()
+ RunningCorrectTaskId = taskId
+
+ rfidReader := rfid.NewReader(config.RFIDConf.DevName, 115200, 5)
+ defer rfidReader.CloseSerial()
+
+ err := rfidReader.OpenSerial()
+ if err != nil {
+ logger.Error(err.Error())
+ return
+ }
+
+ isFind, err := rfidReader.ScanSpecificEPC(config.RFIDConf.EPC, 5)
+ if isFind && RunningCorrectTaskId == taskId {
+ frame := NewA1SetFloorFrame(config.NVCSConf.Mac, config.RFIDConf.Position)
+ address := "192.168.10.253:50000"
+ err := A1SendFrame(frame, address)
+ if err != nil {
+ logger.Warn(err.Error())
+ } else {
+ logger.Debug("The floor has been calibrated.")
+ }
+ }
+}
+
+func calculateCRC16(data []byte) uint16 {
+ var crc16 uint16 = 0xFFFF
+
+ for i := 0; i < len(data); i++ {
+ crc16 ^= uint16(data[i])
+ for j := 0; j < 8; j++ {
+ if crc16&0x0001 != 0 {
+ crc16 >>= 1
+ crc16 ^= 0xA001
+ } else {
+ crc16 >>= 1
+ }
+ }
+ }
+
+ return crc16
+}
+
+// Create a new frame based on provided data
+func NewA1SetFloorFrame(macAddr string, floor uint8) *A1SetFloorFrame {
+ b, err := hex.DecodeString(macAddr)
+ if err != nil {
+ return nil
+ }
+
+ if len(b) != 6 {
+ return nil
+ }
+
+ var mac [6]byte
+ copy(mac[:], b)
+
+ //b, err = hex.DecodeString(floor)
+ frame := &A1SetFloorFrame{
+ Header: [16]byte{0x45, 0x4c, 0x45, 0x56, 0x41, 0x54, 0x4f, 0x52, 0x2d, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x00},
+ Command: 0x0c,
+ MAC: mac,
+ DataLength: 1,
+ Data: []byte{floor},
+ }
+
+ frame.Checksum = calculateCRC16(frame.toBytes(false)) // Calculate CRC without including the checksum itself
+
+ return frame
+}
+
+func A1SendFrame(frame *A1SetFloorFrame, address string) error {
+ conn, err := net.Dial("udp", address)
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+
+ // Send frame
+ _, err = conn.Write(frame.toBytes(true))
+ return err
+}
// 瀵规帴缃戠粶瑙嗛瀛楃鍙犲姞鍣�,鎺ユ敹udp鍙戦�佺殑妤煎眰淇℃伅, 鏇存柊device鍦板潃
func NVCSA1UDPServer() {
@@ -65,7 +185,7 @@
logger.Info("UDP server listening on port %s...", port)
- var runState string
+ var lastFloor int
// 鏃犻檺寰幆绛夊緟鎺ユ敹鏁版嵁
for {
// 鍒涘缓涓�涓紦鍐插尯鏉ュ瓨鍌ㄦ帴鏀剁殑鏁版嵁
@@ -95,51 +215,60 @@
continue
}
- // 璁板綍鐢垫杩愯鐘舵��, 鍙褰曚笂琛屽拰涓嬭
- if data.Elevator[0].Status.RunDir == RunUp {
- runState = "涓�"
- } else if data.Elevator[0].Status.RunDir == RunDown {
- runState = "涓�"
+ elevator := data.Elevator[0]
+
+ var runStateStr string
+ if config.NVCSConf.RunState {
+ if elevator.Status.RunDir == RunUp {
+ runStateStr = "涓�"
+ } else if elevator.Status.RunDir == RunDown {
+ runStateStr = "涓�"
+ }
}
- // 宸插埌鏈�涓嬪眰
- if data.Elevator[0].Status.Floor == 0 {
- runState = "涓�"
- }
- if data.Elevator[0].Status.Floor == data.Elevator[0].Status.TotalFloors {
- runState = "涓�"
+ if !config.NVCSConf.RunState {
+ runStateStr = ""
}
// 璁剧疆osd 鏍煎紡 "1F涓� 鍥� 鏋�"
if config.NVCSConf.OSD != "" {
- floorText := fmt.Sprintf("%s%s %s", data.Elevator[0].Status.FloorName, runState, config.NVCSConf.OSD)
+ floorText := fmt.Sprintf("%s%s %s", data.Elevator[0].Status.FloorName, runStateStr, config.NVCSConf.OSD)
// 璋冪敤hik api 灏嗘枃瀛楁坊鍔犲埌osd鐨勫乏涓嬭
AddFloorToOSD(floorText)
}
- if data.Elevator[0].Status.RunDir > 0 {
- continue
+ // correct floor when elevator stopped.
+ if elevator.Status.RunDir == 0 {
+ go A1CorrectFloor()
+ } else {
+ RunningCorrectTaskId = ""
+ if lastFloor == elevator.Status.Floor {
+ continue
+ }
}
-
- elevator := data.Elevator[0]
// 绋嬪簭閮ㄧ讲鍦ㄨ澶囩, 瀛楃鍙犲姞鍣ㄤ笂鎶ョ殑鍚嶇О鍏佽涓虹┖. 鍦ㄤ簯绔�, 鍚嶇О蹇呴』涓庢憚鍍忔満鐩稿悓
if elevator.Name == "" {
elevator.Name = "1"
}
- var d = models.Positions{
- DeviceId: elevator.Name,
- Pos: elevator.Status.FloorName,
- CreateTime: time.Now().Unix(),
- TimeString: time.Now().Format("2006-01-02 15:04:05"),
- }
+ lastFloor = elevator.Status.Floor
- err = d.Save()
- if err != nil {
- logger.Warn("Device position update error:%s", err.Error())
- }
+ go func() {
+ var d = models.Positions{
+ DeviceId: elevator.Name,
+ Pos: elevator.Status.FloorName,
+ RunDir: elevator.Status.RunDir,
+ CreateTime: time.Now().Unix(),
+ TimeString: time.Now().Format("2006-01-02 15:04:05"),
+ }
+
+ err = d.Save()
+ if err != nil {
+ logger.Warn("Device position update error:%s", err.Error())
+ }
+ }()
}
}
@@ -169,13 +298,55 @@
Floor string `json:"Floor"`
Status string `json:"Status"`
TFloor int64 `json:"TFloor"`
+ Speed string `json:"Speed"`
} `json:"State"`
}
+type A2ElevatorConfig struct {
+ FloorData []string `json:"floordata"`
+}
+
+var A2TopFloor string
+var A2BottomFloor string
+
+func GetA2ElevatorConfig() {
+ url := "http://192.168.10.253/cgi-bin/liftnum.cgi"
+ payload := []byte("{\"display\":1}")
+ header := map[string]string{
+ "Cookie": "eyJuYW1lIjoiYWRtaW4iLCAicGFzZCI6ImFkbWluMTIzIn0=",
+ }
+
+ rsp, err := util.HttpPost(url, header, payload)
+ if err != nil {
+ logger.Warn("Get A2 floor data failure,%s", err.Error())
+ return
+ }
+
+ var configData A2ElevatorConfig
+ err = json.Unmarshal(rsp, &configData)
+ if err != nil {
+ logger.Warn("Unmarshal A2 floor data failure,%s", err.Error())
+ return
+ }
+
+ if len(configData.FloorData) > 0 {
+ A2BottomFloor, A2TopFloor = configData.FloorData[0], configData.FloorData[len(configData.FloorData)-1]
+ }
+
+ logger.Info("A2 floor config total:%d, bottomFloor:%s, topFloor:%s", len(configData.FloorData), A2BottomFloor, A2TopFloor)
+}
+
func NVCSA2WebServer() {
+ // 鍏堣幏鍙栨�绘ゼ灞傛暟, 璁板綍鏈�楂樺眰
+ //GetA2ElevatorConfig()
+
r := gin.Default()
+
r.POST("/", func(c *gin.Context) {
var req A2ElevatorData
+ var runState string
+ var iRunState int
+
err := c.BindJSON(&req)
if err != nil {
c.JSON(http.StatusBadRequest, nil)
@@ -184,9 +355,31 @@
logger.Debug("Received A2 report data %+v", req)
+ // 璁板綍鐢垫杩愯鐘舵��
+ if strings.Contains(req.State.Status, "涓�") {
+ runState = "涓�"
+ iRunState = RunUp
+ } else if strings.Contains(req.State.Status, "涓�") {
+ runState = "涓�"
+ iRunState = RunDown
+ }
+
+ //// 宸插埌鏈�涓嬪眰
+ //if req.State.Floor == A2BottomFloor {
+ // runState = "涓�"
+ // iRunState = RunUp
+ //}
+ //if req.State.Floor == A2TopFloor {
+ // runState = "涓�"
+ // iRunState = RunDown
+ //}
+
+ if !config.NVCSConf.RunState {
+ runState = ""
+ }
+
if config.NVCSConf.OSD != "" {
- floorText := req.State.Floor
- floorText = floorText + " " + config.NVCSConf.OSD
+ floorText := fmt.Sprintf("%s%s %s", req.State.Floor, runState, config.NVCSConf.OSD)
// 璋冪敤hik api 灏嗘枃瀛楁坊鍔犲埌osd鐨勫乏涓嬭
AddFloorToOSD(floorText)
@@ -195,6 +388,7 @@
var d = models.Positions{
DeviceId: req.Id,
Pos: req.State.Floor,
+ RunDir: iRunState,
CreateTime: time.Now().Unix(),
TimeString: time.Now().Format("2006-01-02 15:04:05"),
}
--
Gitblit v1.8.0