package main import ( "fmt" "github.com/sirupsen/logrus" "lc/common/models" "math" "sort" "sync" "time" "github.com/thinkgos/timing/v3" "lc/common/protocol" "lc/common/util" ) func truncateNaive(f float64, unit float64) float64 { return math.Trunc(f/unit) * unit } func Precision(f float64, prec int, round bool) float64 { pow10N := math.Pow10(prec) if round { return math.Trunc((f+0.5/pow10N)*pow10N) / pow10N } return math.Trunc((f)*pow10N) / pow10N } var mapRtuUploadManager sync.Map type RtuUploadManager struct { DataLock sync.Mutex Rtuinfo *protocol.DevInfo Datatime time.Time Data map[uint16]float64 Timer *timing.Timing LiguidDataMgr *LiguidDataMgr //液位计专用 } func NewRtuUploadManager(rtuinfo *protocol.DevInfo) *RtuUploadManager { o := RtuUploadManager{ Rtuinfo: rtuinfo, Data: make(map[uint16]float64), Timer: timing.New().Run(), } if rtuinfo.DevType == 4 && (rtuinfo.TID == 3 || rtuinfo.TID == 5) { o.LiguidDataMgr = &LiguidDataMgr{} } logrus.Infof("NewRtuUploadManager rtuinfo = %v \n", rtuinfo) o.Timer.AddJobFunc(o.SendData, time.Duration(o.Rtuinfo.SendCloud)*time.Millisecond) return &o } func (o *RtuUploadManager) Stop() { o.Timer.Close() o.DataLock.Lock() defer o.DataLock.Unlock() o.Rtuinfo = nil o.Data = nil } func (o *RtuUploadManager) AddData(data map[uint16]float64) { o.DataLock.Lock() defer o.DataLock.Unlock() //液位计需要追加深度数据 if o.Rtuinfo.DevType == 4 && (o.Rtuinfo.TID == 3 || o.Rtuinfo.TID == 5) { for k, v := range data { o.Data[k] = v if k == 1 { fval := o.LiguidDataMgr.Adjust(o.Rtuinfo.Height, v) o.Data[2] = fval } } } else { for k, v := range data { o.Data[k] = v } } // PrintMap(o.Data) o.Datatime = util.MlNow() } func (o *RtuUploadManager) SendData() { o.DataLock.Lock() defer func() { o.Data = make(map[uint16]float64) o.DataLock.Unlock() o.Timer.AddJobFunc(o.SendData, time.Duration(o.Rtuinfo.SendCloud)*time.Millisecond) }() if len(o.Data) == 0 { return } var obj protocol.Pack_UploadData if str, err := obj.EnCode(o.Rtuinfo.DevCode, appConfig.GID, GetNextUint64(), nil, o.Rtuinfo.TID, o.Data); err == nil { topic := GetTopic(o.GetDevType(), o.Rtuinfo.DevCode, protocol.TP_MODBUS_DATA) GetMQTTMgr().Publish(topic, str, 0, ToAll) //上传消息 modbus rtu } } func (o *RtuUploadManager) GetDevType() string { if o.Rtuinfo.DevType == 1 { return protocol.DT_CONCENTRATOR } else if o.Rtuinfo.DevType == 2 { return protocol.DT_ENVIRONMENT } else if o.Rtuinfo.DevType == 4 { return protocol.DT_LIQUID } else if o.Rtuinfo.DevType == 5 { return protocol.DT_ROAD_COND } else if o.Rtuinfo.DevType == uint8(models.CableGuardian) { return protocol.DT_CableGuardian } return "unknown" } type kv struct { Key uint16 Value float64 } func PrintMap(m map[uint16]float64) { var ss []kv for k, v := range m { ss = append(ss, kv{k, v}) } sort.Slice(ss, func(i, j int) bool { //return ss[i].Key > ss[j].Key // 降序 return ss[i].Key < ss[j].Key // 升序 }) for _, kv := range ss { fmt.Printf("%d, %0.3f\n", kv.Key, kv.Value) } }