diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d9594a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/logs/ diff --git a/README.md b/README.md index 6977896..3fbae25 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,21 @@ -# goUpload +# goInOut ## 功能说明: -功能:用于设备采集数据上报第三方。 +功能:用于数据的输入输出处理,可应对各中数据处理场景,典型的设备采集数据上报第三方。 数据入口->各类本地采集软件 数据出口->各类第三方数据接口 -部署环境:用于windows环境 +部署环境:用于windows环境或k8s 镜像部署 ## 启用配置: -goUpload.exe + configFiles目录下的json配置 +app.exe + configFiles目录下的json配置 (configFiles目录下有几个配置就会生效几个功能,实际部署时,不相干的项目配置不要放进去) 支持-软件列表: -------------------- -**统一采集软件** +**统一采集软件_mqtt** -**DAAS振动软件** +**DAAS振动软件_mqtt** -**称重软件** +**称重软件_mqtt** **中科-光电txt** + +**kafka** diff --git a/adaptors/光电光栅中科to明月峡.go b/adaptors/光电光栅中科to明月峡.go index 19b35cd..7e433a7 100644 --- a/adaptors/光电光栅中科to明月峡.go +++ b/adaptors/光电光栅中科to明月峡.go @@ -3,8 +3,8 @@ package adaptors import ( "bytes" "fmt" - "goUpload/consumers/MYX" - "goUpload/utils" + "goInOut/consumers/MYX" + "goInOut/utils" "log" "strconv" "strings" diff --git a/adaptors/光电扰度转路安to江苏省农村公路桥梁监测.go b/adaptors/光电扰度转路安to江苏省农村公路桥梁监测.go new file mode 100644 index 0000000..fee3601 --- /dev/null +++ b/adaptors/光电扰度转路安to江苏省农村公路桥梁监测.go @@ -0,0 +1,84 @@ +package adaptors + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "goInOut/models" + "goInOut/utils" + "log" + "time" +) + +// Adaptor_GDND2LA_JSNCGLQL 光电挠度2路安数据 转换 江苏农村公路桥梁监测系统 +type Adaptor_GDND2LA_JSNCGLQL struct { + IdMap map[string]string + BridgeCode string +} + +func (the Adaptor_GDND2LA_JSNCGLQL) Transform(inTopic, rawMsg string) []NeedPush { + gdnd := models.GDND2luAn{} + json.Unmarshal([]byte(rawMsg), &gdnd) + return the.RawToJSNCGLQL(gdnd) +} + +func (the Adaptor_GDND2LA_JSNCGLQL) RawToJSNCGLQL(raw models.GDND2luAn) (result []NeedPush) { + Atime, err := time.Parse("2006-01-02 15:04:05", raw.Time) + if err != nil { + log.Printf("光电扰度 设备[%s] 数据时间 %s 解析错误", raw.Id, raw.Time) + return + } + + sensorDataList := raw.Value[raw.Id] + //获取对方系统 id + sensorCode := the.getSensorCode(raw.Id) + if sensorCode == "" { + log.Printf("光电扰度 设备[%s] 无匹配的 江苏农村公路桥梁监测系统 测点id,请检查配置文件", raw.Id) + return + } + + topic := fmt.Sprintf("data/%s/%s", the.BridgeCode, sensorCode) + + var transBytes []byte + //添加时间段 + transBytes = append(transBytes, the.getTimeBytes(Atime)...) + + for _, sensorData := range sensorDataList { + + //添加数据值段 + bs := utils.Float32ToBytes(sensorData) + transBytes = append(transBytes, bs...) + } + result = append(result, NeedPush{ + Topic: topic, + Payload: transBytes, + }) + + return result +} +func (the Adaptor_GDND2LA_JSNCGLQL) getSensorCode(rawSensorName string) string { + v, isValid := the.IdMap[rawSensorName] + if !isValid { + v = "" + } + return v +} + +func (the Adaptor_GDND2LA_JSNCGLQL) getTimeBytes(sensorTime time.Time) []byte { + + year := uint16(sensorTime.Year()) + month := int8(sensorTime.Month()) + day := int8(sensorTime.Day()) + hour := int8(sensorTime.Hour()) + minute := int8(sensorTime.Minute()) + second := int8(sensorTime.Second()) + bytesBuffer := bytes.NewBuffer([]byte{}) + binary.Write(bytesBuffer, binary.BigEndian, year) + binary.Write(bytesBuffer, binary.BigEndian, month) + binary.Write(bytesBuffer, binary.BigEndian, day) + binary.Write(bytesBuffer, binary.BigEndian, hour) + binary.Write(bytesBuffer, binary.BigEndian, minute) + binary.Write(bytesBuffer, binary.BigEndian, second) + return bytesBuffer.Bytes() +} diff --git a/adaptors/司南GNSS_MySql库to安心云.go b/adaptors/司南GNSS_MySql库to安心云.go new file mode 100644 index 0000000..80cf393 --- /dev/null +++ b/adaptors/司南GNSS_MySql库to安心云.go @@ -0,0 +1,47 @@ +package adaptors + +import ( + "encoding/json" + "fmt" + "goInOut/consumers/SinoGnssMySQL" + "strconv" +) + +// Adaptor_SINOMYSQL_AXYMQTT 数据 转换 江苏农村公路桥梁监测系统 +type Adaptor_SINOMYSQL_AXYMQTT struct { +} + +func (the Adaptor_SINOMYSQL_AXYMQTT) Transform(gnssDataList []SinoGnssMySQL.GnssData) []NeedPush { + var needPush []NeedPush + allDxFiles := make(map[string][]SinoGnssMySQL.DxFile) + for _, gnssData := range gnssDataList { + OnceDxFiles := allDxFiles[gnssData.GroupName] + OnceDxFiles = append(OnceDxFiles, SinoGnssMySQL.DxFile{ + Module: gnssData.StationName, + Channel: 1, + Timespan: gnssData.Time.UnixMilli(), + //file_mqtt协议里面只解析RV, m=> mm + RawValue: []float64{gnssData.X * 1000, gnssData.Y * 1000, gnssData.H * 1000}, + LimitValue: []float64{}, + PhyValue: []float64{}, + ThemeValue: []float64{}, + }) + allDxFiles[gnssData.GroupName] = OnceDxFiles + } + + for groupName, groupFileList := range allDxFiles { + contentMap := make(map[string]string) + for i, file := range groupFileList { + bs, _ := json.Marshal(file) + contentMap[strconv.Itoa(i)] = string(bs) + } + gpContent, _ := json.Marshal(contentMap) + topic := fmt.Sprintf("SinoGnss/%s/", groupName) + needPush = append(needPush, NeedPush{ + Topic: topic, + Payload: gpContent, + }) + } + + return needPush +} diff --git a/adaptors/安心云es主题to河北矿山监测.go b/adaptors/安心云es主题to河北矿山监测.go index c25e3f5..0549c93 100644 --- a/adaptors/安心云es主题to河北矿山监测.go +++ b/adaptors/安心云es主题to河北矿山监测.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "fmt" - "goUpload/models" + "goInOut/models" "log" "math" "strings" diff --git a/adaptors/安心云最新设备数据toES.go b/adaptors/安心云最新设备数据toES.go new file mode 100644 index 0000000..b300d35 --- /dev/null +++ b/adaptors/安心云最新设备数据toES.go @@ -0,0 +1,148 @@ +package adaptors + +import ( + "encoding/json" + "fmt" + "goInOut/consumers/AXYraw" + "goInOut/dbOperate" + "goInOut/models" + "log" + "sync" + "time" +) + +// Adaptor_AXY_LastRAW 安心云 kafka iota数据 转换 es设备数据 +type Adaptor_AXY_LastRAW struct { + AXYraw.Info + Redis *dbOperate.RedisHelper +} + +func (the Adaptor_AXY_LastRAW) Transform(topic, rawMsg string) *models.EsRaw { + iotaData := models.IotaData{} + json.Unmarshal([]byte(rawMsg), &iotaData) + return the.raw2es(iotaData) +} + +func (the Adaptor_AXY_LastRAW) raw2es(iotaData models.IotaData) *models.EsRaw { + if len(iotaData.Data.Data) == 0 { + return nil + } + + if !iotaData.Data.Success() { + msg, _ := json.Marshal(iotaData.Data.Result) + iotaData.Data.Data["errMsg"] = string(msg) + } + //log.Printf("设备[%s] 数据时间 %s", iotaData.DeviceId, iotaData.TriggerTime) + deviceInfo := the.GetDeviceInfo(iotaData.DeviceId) + + //查不到信息的数据 + if deviceInfo.Name == "" { + log.Printf("设备[%s] 无deviceInfo信息 %s", iotaData.DeviceId, iotaData.TriggerTime) + return nil + } + + dataType := "" + if _dataType, ok := iotaData.Data.Data["_data_type"]; ok { + if v, ok := _dataType.(string); ok { + dataType = v + } + } + devdata := &models.DeviceData{ + DeviceId: iotaData.DeviceId, + Name: deviceInfo.Name, + ThingId: iotaData.ThingId, + StructId: deviceInfo.Structure.Id, + AcqTime: iotaData.TriggerTime, + RealTime: iotaData.RealTime, + ErrCode: 0, + Raw: iotaData.Data.Data, + DeviceInfo: deviceInfo, + DimensionId: iotaData.DimensionId, + DataType: dataType, + } + EsRaws := toEsRaw(devdata) + return EsRaws +} + +var deviceInfoMap = map[string]models.DeviceInfo{} +var deviceInfoMap2 = sync.Map{} + +func (the Adaptor_AXY_LastRAW) GetDeviceInfo(deviceId string) models.DeviceInfo { + if vObj, ok := deviceInfoMap2.Load(deviceId); ok { + if v, ok := vObj.(models.DeviceInfo); ok { + durationMin := time.Now().Sub(v.RefreshTime).Minutes() + if durationMin < 5 { + return v + } + } + } + v, err := the.GetDeviceInfoFromRedis(deviceId) + if err != nil { + log.Printf("设备%s 无法查询到对应信息", deviceId) + } + //deviceInfoMap[deviceId] = v + deviceInfoMap2.Store(deviceId, v) + return v +} + +func (the Adaptor_AXY_LastRAW) GetDeviceInfoFromRedis(deviceId string) (models.DeviceInfo, error) { + Key_Iota_device := "iota_device" + key_Thing_struct := "thing_struct" + key_Iota_meta := "iota_meta" + k1 := fmt.Sprintf("%s:%s", Key_Iota_device, deviceId) + dev := models.IotaDevice{} + thingStruct := models.ThingStruct{} + devMeta := models.DeviceMeta{} + err1 := the.Redis.GetObj(k1, &dev) + if err1 != nil { + return models.DeviceInfo{RefreshTime: time.Now()}, err1 + } + k2 := fmt.Sprintf("%s:%s", key_Thing_struct, dev.ThingId) + err2 := the.Redis.GetObj(k2, &thingStruct) + if err2 != nil { + return models.DeviceInfo{RefreshTime: time.Now()}, err2 + } + k3 := fmt.Sprintf("%s:%s", key_Iota_meta, dev.DeviceMeta.Id) + err3 := the.Redis.GetObj(k3, &devMeta) + if err3 != nil { + return models.DeviceInfo{RefreshTime: time.Now()}, err3 + } + //if err1 != nil || err2 != nil || err3 != nil { + // log.Printf("redis读取异常,err1=%s, err2=%s, err3=%s", err1, err2, err3) + // return models.DeviceInfo{} + //} + + s := models.Structure{ + ThingId: thingStruct.ThingId, + Id: thingStruct.Id, + Name: thingStruct.Name, + OrgId: thingStruct.OrgId, + } + return models.DeviceInfo{ + Id: deviceId, + Name: dev.Name, + Structure: s, + DeviceMeta: devMeta, + RefreshTime: time.Now(), + }, nil +} + +func toEsRaw(deviceData *models.DeviceData) *models.EsRaw { + + if deviceData == nil { + return nil + } + var cstZone = time.FixedZone("CST", 8*3600) // 东八区 用以解决 + dataOutMeta := deviceData.DeviceInfo.DeviceMeta.GetOutputProps() + createNativeRaw := models.EsRaw{ + StructId: deviceData.StructId, + IotaDeviceName: deviceData.Name, + Data: deviceData.Raw, + CollectTime: deviceData.AcqTime.In(cstZone).Format("2006-01-02T15:04:05.000+0800"), + Meta: dataOutMeta, + IotaDevice: deviceData.DeviceId, + CreateTime: time.Now(), + } + + return &createNativeRaw +} diff --git a/adaptors/振动to明月峡.go b/adaptors/振动to明月峡.go index 8c258de..5b17ed8 100644 --- a/adaptors/振动to明月峡.go +++ b/adaptors/振动to明月峡.go @@ -3,8 +3,8 @@ package adaptors import ( "encoding/json" "fmt" - "goUpload/models" - "goUpload/utils" + "goInOut/models" + "goInOut/utils" "log" "strings" "time" diff --git a/adaptors/振动to江苏省农村公路桥梁监测.go b/adaptors/振动to江苏省农村公路桥梁监测.go new file mode 100644 index 0000000..a5cb5dd --- /dev/null +++ b/adaptors/振动to江苏省农村公路桥梁监测.go @@ -0,0 +1,132 @@ +package adaptors + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "goInOut/models" + "goInOut/utils" + "log" + "strconv" + "strings" + "time" +) + +// Adaptor_ZD_JSNCGLQL 数据 转换 江苏农村公路桥梁监测系统 +type Adaptor_ZD_JSNCGLQL struct { + IdMap map[string]string + BridgeCode string +} + +func (the Adaptor_ZD_JSNCGLQL) Transform(inTopic, rawMsg string) []NeedPush { + zd := models.ZD{} + err := json.Unmarshal([]byte(rawMsg), &zd) + if err != nil { + return nil + } + lowerTopic := strings.ToLower(inTopic) + if strings.Contains(lowerTopic, "zdsl") || + strings.Contains(lowerTopic, "cableforce") { + return the.ZDSLtoJSNCGLQL(zd) + } + + return the.ZDtoJSNCGLQL(zd) +} + +func (the Adaptor_ZD_JSNCGLQL) ZDtoJSNCGLQL(zd models.ZD) (result []NeedPush) { + Atime := time.UnixMilli(zd.Ticks) + + sensorDataList := zd.AccValues + //获取对方系统 id + sensorCode := the.getSensorCode(zd.Module) + if sensorCode == "" { + log.Printf("振动 设备[%s] 无匹配的 江苏农村公路桥梁监测系统 测点id,请检查配置文件", zd.Module) + return + } + + topic := fmt.Sprintf("data/%s/%s", the.BridgeCode, sensorCode) + //数据秒数 + seconds := len(zd.AccValues) / zd.Frequency + + for i := 0; i < seconds; i++ { + var transBytes []byte + onceTime := Atime.Add(time.Duration(i) * time.Second) + //1.添加时间段 + transBytes = append(transBytes, the.getTimeBytes(onceTime)...) + + startIndex := (0 + i) * zd.Frequency + endIndex := (1 + i) * zd.Frequency + if endIndex > len(sensorDataList) { + endIndex = len(sensorDataList) + } + subDataList := sensorDataList[startIndex:endIndex] + + for _, sensorData := range subDataList { + + //4.添加数据值段 + bs := utils.Float32ToBytes(sensorData) + transBytes = append(transBytes, bs...) + } + result = append(result, NeedPush{ + Topic: topic, + Payload: transBytes, + }) + } + + return result +} +func (the Adaptor_ZD_JSNCGLQL) ZDSLtoJSNCGLQL(zd models.ZD) (result []NeedPush) { + Atime := time.UnixMilli(zd.Ticks) + + sensorDataList := zd.ThemeValue + //获取对方系统 id + sensorCode := the.getSensorCode(strconv.Itoa(zd.SensorId)) + if sensorCode == "" { + log.Printf("振动索力 设备[%s] 无匹配的 江苏农村公路桥梁监测系统 测点id,请检查配置文件", zd.Module) + return + } + + topic := fmt.Sprintf("data/%s/%s", the.BridgeCode, sensorCode) + + var transBytes []byte + //1.添加时间段 + transBytes = append(transBytes, the.getTimeBytes(Atime)...) + + //数据值段 + bs := utils.Float32ToBytes(sensorDataList[0]) + transBytes = append(transBytes, bs...) + + result = append(result, NeedPush{ + Topic: topic, + Payload: transBytes, + }) + + return result +} + +func (the Adaptor_ZD_JSNCGLQL) getSensorCode(rawSensorName string) string { + v, isValid := the.IdMap[rawSensorName] + if !isValid { + v = "" + } + return v +} + +func (the Adaptor_ZD_JSNCGLQL) getTimeBytes(sensorTime time.Time) []byte { + + year := uint16(sensorTime.Year()) + month := int8(sensorTime.Month()) + day := int8(sensorTime.Day()) + hour := int8(sensorTime.Hour()) + minute := int8(sensorTime.Minute()) + second := int8(sensorTime.Second()) + bytesBuffer := bytes.NewBuffer([]byte{}) + binary.Write(bytesBuffer, binary.BigEndian, year) + binary.Write(bytesBuffer, binary.BigEndian, month) + binary.Write(bytesBuffer, binary.BigEndian, day) + binary.Write(bytesBuffer, binary.BigEndian, hour) + binary.Write(bytesBuffer, binary.BigEndian, minute) + binary.Write(bytesBuffer, binary.BigEndian, second) + return bytesBuffer.Bytes() +} diff --git a/adaptors/振动to湘潭健康监测.go b/adaptors/振动to湘潭健康监测.go index c68edff..09e58ad 100644 --- a/adaptors/振动to湘潭健康监测.go +++ b/adaptors/振动to湘潭健康监测.go @@ -2,7 +2,7 @@ package adaptors import ( "encoding/json" - "goUpload/models" + "goInOut/models" "log" "math" "time" diff --git a/adaptors/振动to重庆资管.go b/adaptors/振动to重庆资管.go index 2469978..08ec265 100644 --- a/adaptors/振动to重庆资管.go +++ b/adaptors/振动to重庆资管.go @@ -3,9 +3,9 @@ package adaptors import ( "crypto/rc4" "encoding/json" - "goUpload/consumers/CQZG/protoFiles" - "goUpload/models" - "goUpload/utils" + "goInOut/consumers/CQZG/protoFiles" + "goInOut/models" + "goInOut/utils" "google.golang.org/protobuf/proto" "log" ) diff --git a/adaptors/欧乐称重to重庆资管.go b/adaptors/欧乐称重to重庆资管.go index 5842290..7afe8d3 100644 --- a/adaptors/欧乐称重to重庆资管.go +++ b/adaptors/欧乐称重to重庆资管.go @@ -4,9 +4,9 @@ import ( "crypto/rc4" "encoding/hex" "encoding/json" - "goUpload/consumers/CQZG/protoFiles" - "goUpload/models" - "goUpload/utils" + "goInOut/consumers/CQZG/protoFiles" + "goInOut/models" + "goInOut/utils" "google.golang.org/protobuf/proto" "log" "strconv" diff --git a/adaptors/知物云主题数据to广州高支模省平台.go b/adaptors/知物云主题数据to广州高支模省平台.go index aed06e8..023a78e 100644 --- a/adaptors/知物云主题数据to广州高支模省平台.go +++ b/adaptors/知物云主题数据to广州高支模省平台.go @@ -3,8 +3,8 @@ package adaptors import ( "encoding/json" "fmt" - "goUpload/consumers/GZGZM" - "goUpload/models" + "goInOut/consumers/GZGZM" + "goInOut/models" "log" "math" "strconv" diff --git a/adaptors/统一采集to明月峡.go b/adaptors/统一采集to明月峡.go index d0b728b..d20b01c 100644 --- a/adaptors/统一采集to明月峡.go +++ b/adaptors/统一采集to明月峡.go @@ -3,7 +3,7 @@ package adaptors import ( "encoding/json" "fmt" - "goUpload/models" + "goInOut/models" "log" "strings" "time" diff --git a/adaptors/统一采集to江苏省农村公路桥梁监测.go b/adaptors/统一采集to江苏省农村公路桥梁监测.go index a79886a..79dba45 100644 --- a/adaptors/统一采集to江苏省农村公路桥梁监测.go +++ b/adaptors/统一采集to江苏省农村公路桥梁监测.go @@ -1,20 +1,23 @@ package adaptors import ( + "bytes" + "encoding/binary" "encoding/json" "fmt" - "goUpload/models" - "goUpload/utils" + "goInOut/models" + "goInOut/utils" "log" "time" ) -// Adaptor_TYCJ_JSNCGLQL 统一采集软件数据 转换 江苏农村公路桥梁监测系统 +// Adaptor_TYCJ_JSNCGLQL 数据 转换 江苏农村公路桥梁监测系统 type Adaptor_TYCJ_JSNCGLQL struct { - IdMap map[string]string + IdMap map[string]string + BridgeCode string } -func (the Adaptor_TYCJ_JSNCGLQL) Transform(rawMsg string) []NeedPush { +func (the Adaptor_TYCJ_JSNCGLQL) Transform(inTopic, rawMsg string) []NeedPush { tycj := models.TYCJ{} json.Unmarshal([]byte(rawMsg), &tycj) return the.TYCJtoJSNCGLQL(tycj) @@ -47,13 +50,12 @@ func (the Adaptor_TYCJ_JSNCGLQL) TYCJtoJSNCGLQL(tycj models.TYCJ) (result []Need log.Printf("统一采集 设备[%s] 无匹配的 江苏农村公路桥梁监测系统 测点id,请检查配置文件", tycj.SensorData.Name) return } - //todo 桥梁编码 - bridgeCode := sensorCode - topic := fmt.Sprintf("data/%s/%s", bridgeCode, sensorCode) + + topic := fmt.Sprintf("data/%s/%s", the.BridgeCode, sensorCode) for _, sensorData := range sensorDataList { - //4.添加数据值段 + //添加数据值段 bs := utils.Float32ToBytes(sensorData) transBytes = append(transBytes, bs...) } @@ -80,14 +82,12 @@ func (the Adaptor_TYCJ_JSNCGLQL) getTimeBytes(sensorTime time.Time) []byte { hour := int8(sensorTime.Hour()) minute := int8(sensorTime.Minute()) second := int8(sensorTime.Second()) - bytes := make([]byte, 0) - bytes = append(bytes, - byte(year), - byte(month), - byte(day), - byte(hour), - byte(minute), - byte(second), - ) - return bytes + bytesBuffer := bytes.NewBuffer([]byte{}) + binary.Write(bytesBuffer, binary.BigEndian, year) + binary.Write(bytesBuffer, binary.BigEndian, month) + binary.Write(bytesBuffer, binary.BigEndian, day) + binary.Write(bytesBuffer, binary.BigEndian, hour) + binary.Write(bytesBuffer, binary.BigEndian, minute) + binary.Write(bytesBuffer, binary.BigEndian, second) + return bytesBuffer.Bytes() } diff --git a/adaptors/统一采集to湘潭健康监测.go b/adaptors/统一采集to湘潭健康监测.go index d5aa38c..5eb8830 100644 --- a/adaptors/统一采集to湘潭健康监测.go +++ b/adaptors/统一采集to湘潭健康监测.go @@ -3,7 +3,7 @@ package adaptors import ( "encoding/hex" "encoding/json" - "goUpload/models" + "goInOut/models" "log" "math" "time" diff --git a/adaptors/统一采集to重庆资管.go b/adaptors/统一采集to重庆资管.go index 654b9d0..71e16aa 100644 --- a/adaptors/统一采集to重庆资管.go +++ b/adaptors/统一采集to重庆资管.go @@ -4,9 +4,9 @@ import ( "crypto/rc4" "encoding/hex" "encoding/json" - "goUpload/consumers/CQZG/protoFiles" - "goUpload/models" - "goUpload/utils" + "goInOut/consumers/CQZG/protoFiles" + "goInOut/models" + "goInOut/utils" "google.golang.org/protobuf/proto" "log" "time" diff --git a/adaptors/视觉位移to魏家滑坡.go b/adaptors/视觉位移to魏家滑坡.go index f57d656..78d8144 100644 --- a/adaptors/视觉位移to魏家滑坡.go +++ b/adaptors/视觉位移to魏家滑坡.go @@ -3,7 +3,7 @@ package adaptors import ( "encoding/json" "fmt" - "goUpload/consumers/WJHP" + "goInOut/consumers/WJHP" "log" "strconv" "time" @@ -25,7 +25,8 @@ func (the Adaptor_SJWY_WJHP) GDRDtoUpload(devModule, rawRecords string) (result return nil } - sensorInfo := the.matchStationId(devModule) + devId := fmt.Sprintf("%s-%s", devModule, d.Pos) + sensorInfo := the.matchStationId(devId) if sensorInfo.StationId == 0 { return nil } diff --git a/build/Dockerfile b/build/Dockerfile index 9d44059..72d634a 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -8,7 +8,7 @@ RUN go env -w GO111MODULE=on RUN CGO_ENABLED=0 go build -a -v -o app.exe main.go -FROM registry.ngaiot.com/base-images/golang:1.20-fs-10 +FROM registry.ngaiot.com/base-images/alpine_3.20_cst:7 WORKDIR /app/ COPY --from=0 /app/app.exe /app COPY --from=0 /app/configFiles /app diff --git a/build/Dockerfile_app b/build/Dockerfile_app new file mode 100644 index 0000000..d131f04 --- /dev/null +++ b/build/Dockerfile_app @@ -0,0 +1,4 @@ +FROM registry.ngaiot.com/base-images/alpine_3.20_cst:7 +WORKDIR /app/ +COPY *.exe configFiles /app/ +CMD ["/app/app.exe"] diff --git a/build/goupload.yaml b/build/go_inout.yaml similarity index 83% rename from build/goupload.yaml rename to build/go_inout.yaml index b8fda46..a172d59 100644 --- a/build/goupload.yaml +++ b/build/go_inout.yaml @@ -1,23 +1,23 @@ apiVersion: apps/v1 #指定API版本标签 kind: Deployment #定义资源的类型/角色,deployment为控制器,service,endpoints metadata: #定义资源的元数据信息 - name: goupload-deployment #定义资源的名称,在同一个namespace空间中必须是唯一的 + name: goinout-deployment #定义资源的名称,在同一个namespace空间中必须是唯一的 namespace: lk #默认default labels: #定义资源标签 - app: yaml-goupload-d + app: yaml-goinout-d spec: replicas: 1 #定义副本数量 selector: #定义选择器 matchLabels: #匹配上边的标签 - app: yaml-goupload-d #名称 + app: yaml-goinout-d #名称 template: #定义模板 metadata: labels: - app: yaml-goupload-d + app: yaml-goinout-d spec: containers: - - name: yaml-goupload #容器名,与标签名要相同 - image: registry.ngaiot.com/local/git-goupload-image:12 + - name: yaml-goinout #容器名,与标签名要相同 + image: registry.ngaiot.com/local/in-out-image:24 imagePullPolicy: IfNotPresent volumeMounts: - name: config @@ -26,14 +26,14 @@ spec: volumes: # volumes和container处于同一层级,别搞错了 - name: config configMap: - name: config-goupload + name: config-goinout --- apiVersion: v1 kind: ConfigMap metadata: - name: config-goupload + name: config-goinout namespace: lk data: #监测因素 统计字段表 config.json: | diff --git a/build/jenkinsfile b/build/jenkinsfile index 5bf55bb..eba005f 100644 --- a/build/jenkinsfile +++ b/build/jenkinsfile @@ -3,12 +3,12 @@ podTemplate { env.IMAGE_NAME = "${IOT_IMAGES_REGISTRY}/${LOCAL}/${JOB_NAME}" env.IMAGE_NAME_SHORT = "${LOCAL}/${JOB_NAME}" - env.CODE_ADDR = "${GIT_ADDRESS}/DevOps/goUpload.git" + env.CODE_ADDR = "https://gitea.anxinyun.cn/lucas2/goInOut.git" stage('Run shell') { - git branch: 'develop', credentialsId: 'gitea-builder', url: "${CODE_ADDR}" + git branch: 'dev', credentialsId: 'gitea-builder', url: "${CODE_ADDR}" - container('golang-builder-1-22') { + container('golang-builder-1-23') { sh''' go env -w GOPROXY=https://goproxy.cn,direct go env -w GO111MODULE=on diff --git a/build/jenkinsfile_image b/build/jenkinsfile_image index 2c2ec1d..e5f3a61 100644 --- a/build/jenkinsfile_image +++ b/build/jenkinsfile_image @@ -1,24 +1,40 @@ podTemplate { node('pod-templ-jenkins-slave-golang') { - + env.IMAGE_NAME = "${IOT_IMAGES_REGISTRY}/${LOCAL}/${JOB_NAME}" env.IMAGE_NAME_SHORT = "${LOCAL}/${JOB_NAME}" env.CODE_ADDR = "https://gitea.anxinyun.cn/lucas2/goUpload.git" - - stage('Run shell') { + + stage('Run shell') { git branch: 'dev', credentialsId: 'gitea-builder', url: "${CODE_ADDR}" - container('golang-builder-1-23') { sh''' - echo "当前目===" - pwd - ls - echo "========" - /kaniko/executor --context=${BUILD_WORKSPACE} --dockerfile=build/Dockerfile --destination=${IMAGE_NAME}:${IMAGE_VERSION} --cache=false --cleanup + git version + git config --global --add url."https://builder:Fs7595!EAT@gitea.anxinyun.cn/".insteadOf "https://gitea.anxinyun.cn/" + unset GOPROXY + go env -w GOPROXY=https://goproxy.cn,direct + go env -w GO111MODULE=on + go env -w GOPRIVATE=gitea.ngaiot.com,gitea.anxinyun.cn + go env -w GOSUMDB=sum.golang.org + go env + go build -a -v -o app.exe main.go + tar -cvf app.tar *.exe configFiles ''' } + + container('image-builder') { + sh''' + echo "当前目===" + pwd + ls + echo "========" + /kaniko/executor --context=${BUILD_WORKSPACE} --dockerfile=build/Dockerfile_app --destination=${IMAGE_NAME}:${IMAGE_VERSION} --cache=false --cleanup + ''' + } + archiveArtifacts artifacts: 'app.tar', followSymlinks: false + buildName "${IMAGE_NAME_SHORT}:${IMAGE_VERSION}" - buildDescription "${IMAGE_NAME}:${IMAGE_VERSION}" + buildDescription "${IMAGE_NAME}:${IMAGE_VERSION}" } } } \ No newline at end of file diff --git a/config/configStruct.go b/config/configStruct.go index 88a7e4a..b12a9f4 100644 --- a/config/configStruct.go +++ b/config/configStruct.go @@ -4,6 +4,11 @@ type Consumer struct { Consumer string `json:"consumer"` } +type DbConfig struct { + Type string `json:"type"` + ConnStr string `json:"connStr"` +} + type MqttConfig struct { Host string `json:"host"` Port int `json:"port"` @@ -18,6 +23,16 @@ type KafkaConfig struct { Topics []string `json:"topics"` } +type EsConfig struct { + Address []string `json:"address"` + Index string `json:"index"` + Auth struct { + UserName string `json:"userName"` + Password string `json:"password"` + } `json:"auth"` + Interval int `json:"interval"` +} + type UdpConfig struct { Host string `json:"host"` Port int `json:"port"` @@ -29,6 +44,15 @@ type HttpConfig struct { Token Token `json:"token,omitempty"` } +type ApiServerConfig struct { + Port uint `json:"port"` + Routers []Router `json:"routers"` +} +type Router struct { + Router string `json:"router"` + IdTemplate string `json:"idTemplate"` +} + type Token struct { Static string `json:"static,omitempty"` RefreshInterval string `json:"refreshInterval,omitempty"` diff --git a/config/init.go b/config/init.go index 9dc18aa..9281734 100644 --- a/config/init.go +++ b/config/init.go @@ -8,7 +8,6 @@ import ( ) func LoadConfigJson() map[string]string { - //加载目录下所有文件 allConfig := make(map[string]string) files, err := os.ReadDir("configFiles") @@ -22,24 +21,16 @@ func LoadConfigJson() map[string]string { log.Printf("非文件[%s]跳过", file.Name()) continue } - // 读取mqtt配置 - configMqttBytes, _ := os.ReadFile(fmt.Sprintf("configFiles/%s", file.Name())) + // 读取配置 + configBytes, _ := os.ReadFile(fmt.Sprintf("configFiles/%s", file.Name())) consumer := new(Consumer) // 将 JSON 格式的数据解析到结构体中 - err = json.Unmarshal(configMqttBytes, &consumer) + err = json.Unmarshal(configBytes, &consumer) if err != nil { log.Printf("读取配置文件[%s]异常 err=%v", consumer.Consumer, err.Error()) continue } - allConfig[consumer.Consumer] = string(configMqttBytes) - //// 读取sensor配置 - //configSensorBytes, _ := os.ReadFile("configSensor.json") - //// 将 JSON 格式的数据解析到结构体中 - //err2 := json.Unmarshal(configSensorBytes, &userConfig.SensorConfig) - //if err2 != nil { - // log.Printf("读取mqtt配置异常 err=%v", err2.Error()) - //} - //allConfig[] + allConfig[consumer.Consumer] = string(configBytes) } return allConfig } diff --git a/configFiles/config_司南GnssMySQL.json b/configFiles/config_司南GnssMySQL.json new file mode 100644 index 0000000..c32c4a1 --- /dev/null +++ b/configFiles/config_司南GnssMySQL.json @@ -0,0 +1,24 @@ +{ + "consumer": "consumerSinoGnssMySQL", + "ioConfig": { + "in": { + "db": { + "type": "mysql", + "connStr": "root:Xuchen@2024@tcp(39.105.5.154:3306)/navi_cloud_sinognss?charset=utf8&parseTime=true" + }, + "cronStr": "0/1 * * * *" + }, + "out": { + "mqtt": { + "host": "10.8.30.160", + "port": 30883, + "userName": "upload", + "password": "", + "clientId": "goInOut_SinoGnssMySQL", + "Topics": [] + } + } + }, + "info": { + } +} \ No newline at end of file diff --git a/configFiles/弃用备份/config_安心云设备数据_最新同步.json b/configFiles/弃用备份/config_安心云设备数据_最新同步.json new file mode 100644 index 0000000..6f576c1 --- /dev/null +++ b/configFiles/弃用备份/config_安心云设备数据_最新同步.json @@ -0,0 +1,36 @@ +{ + "consumer": "consumerAXYraw", + "ioConfig": { + "in": { + "kafka": { + "brokers": [ + "10.8.30.160:30992" + ], + "groupId": "synchronizeRaw_50", + "topics": [ + "RawData" + ] + } + }, + "out": { + "es": { + "address": ["http://10.8.30.160:30092"], + "index": "anxincloud_last_raw", + "auth": { + "userName": "post", + "password": "123" + }, + "interval": 30 + } + } + }, + "info": { + "common": { + }, + "queryComponent":{ + "redis": { + "address": "10.8.30.142:30379" + } + } + } +} \ No newline at end of file diff --git a/configFiles/弃用备份/config_承德金隅水泥_河北矿山_大斜阳.json b/configFiles/弃用备份/config_承德金隅水泥_河北矿山_大斜阳.json index 8c60ede..e5722dd 100644 --- a/configFiles/弃用备份/config_承德金隅水泥_河北矿山_大斜阳.json +++ b/configFiles/弃用备份/config_承德金隅水泥_河北矿山_大斜阳.json @@ -5,7 +5,7 @@ "http": { "url": "https://esproxy.anxinyun.cn/anxincloud_themes/_search" }, - "cronStr": "18 0/1 * * *" + "cronStr": "0/1 * * * *" }, "out": { "file": { diff --git a/configFiles/弃用备份/config_江苏农村公路桥梁.json b/configFiles/弃用备份/config_江苏农村公路桥梁.json index 5c8ed2f..f52f500 100644 --- a/configFiles/弃用备份/config_江苏农村公路桥梁.json +++ b/configFiles/弃用备份/config_江苏农村公路桥梁.json @@ -10,7 +10,9 @@ "clientId": "goUpload_JSNCGLQL", "Topics": [ "upload/uds/+", - "upload/ZD/+" + "upload/ZD/+", + "upload/ZDSL/+", + "upload/gdnd/+" ] } }, @@ -20,26 +22,31 @@ "port": 30883, "userName": "upload", "password": "", - "clientId": "upload1", + "clientId": "goInOut", "Topics": [ - "data/bridgeCode" + "data/{{.bridgeCode}}/{{.sensorCode}}" ] } } }, "info": { - "structUploadCode": "G2320281L0012" + "bridgeCode": "G2320281L0012" }, - "sensorInfoMap": { - "sensorMap": { - "TYCJsensorMap": { - "m1c1": "JY-HSD-G05-001-01", - "m1c2": "LHTDQ-RSG-L04-001-03" - }, - "ZDsensorMap": { - "m1c1": "LHTDQ-VIB-C08-001-01", - "m1c2": "LHTDQ-VIB-L03-001-01" - } + "sensorInfo": { + "TYCJsensorMap": { + "m1c1": "JY-HSD-G05-001-01", + "m1c2": "LHTDQ-RSG-L04-001-03" + }, + "ZDsensorMap": { + "m1c1": "LHTDQ-VIB-C08-001-01", + "m1c2": "LHTDQ-VIB-L03-001-01" + }, + "ZDSLensorMap": { + "333701": "LHTDQ-SL-C08-001-01" + }, + "GDNDsensorMap": { + "DY-DIS-ZG03-01": "LHTDQ-GDND-G03-003-01", + "m3c2": "LHTDQ-GDND-G03-003-02" } } } \ No newline at end of file diff --git a/configFiles/弃用备份/config_转发http2axy60000端口.json b/configFiles/弃用备份/config_转发http2axy60000端口.json new file mode 100644 index 0000000..9056c69 --- /dev/null +++ b/configFiles/弃用备份/config_转发http2axy60000端口.json @@ -0,0 +1,30 @@ +{ + "consumer": "consumerHttpProxy", + "ioConfig": { + "in": { + "apiServer": { + "port": 7000, + "userName": "usr", + "password": "123", + "routers": [ + { + "router": "POST /upload/work/ABStatus", + "idTemplate": "{{.values.ucId}}" + }, + { + "router": "POST /upload/work/ABSHeart", + "idTemplate": "{{.Values.WorkId}}" + } + ] + } + }, + "out": { + "httpPost": { + "url": "http://218.3.126.49:60000", + "method": "post" + } + } + }, + "info": { + } +} \ No newline at end of file diff --git a/configFiles/config_魏家滑坡_视觉位移.json b/configFiles/弃用备份/config_魏家滑坡_视觉位移.json similarity index 100% rename from configFiles/config_魏家滑坡_视觉位移.json rename to configFiles/弃用备份/config_魏家滑坡_视觉位移.json diff --git a/constKey/key.go b/constKey/key.go deleted file mode 100644 index e237c25..0000000 --- a/constKey/key.go +++ /dev/null @@ -1 +0,0 @@ -package constKey diff --git a/consumers/AXYraw/config.go b/consumers/AXYraw/config.go new file mode 100644 index 0000000..300bd34 --- /dev/null +++ b/consumers/AXYraw/config.go @@ -0,0 +1,31 @@ +package AXYraw + +import "goInOut/config" + +type ConfigFile struct { + config.Consumer + IoConfig ioConfig `json:"ioConfig"` + Info Info `json:"info"` +} +type ioConfig struct { + In in `json:"in"` + Out out `json:"out"` +} +type in struct { + Kafka config.KafkaConfig `json:"kafka"` +} + +type out struct { + Es config.EsConfig `json:"es"` +} + +type Info struct { + Common map[string]string `json:"common"` + QueryComponent queryComponent `json:"queryComponent"` +} + +type queryComponent struct { + Redis struct { + Address string `json:"address"` + } `json:"redis"` +} diff --git a/consumers/CDJYSN/config.go b/consumers/CDJYSN/config.go index 9352fd5..52f4bb7 100644 --- a/consumers/CDJYSN/config.go +++ b/consumers/CDJYSN/config.go @@ -1,6 +1,6 @@ package CDJYSN -import "goUpload/config" +import "goInOut/config" type ConfigFile struct { config.Consumer diff --git a/consumers/CQZG/config.go b/consumers/CQZG/config.go index 7b1951b..58fbe19 100644 --- a/consumers/CQZG/config.go +++ b/consumers/CQZG/config.go @@ -1,6 +1,6 @@ package CQZG -import "goUpload/config" +import "goInOut/config" type ConfigFile struct { config.Consumer diff --git a/consumers/GZGZM/config.go b/consumers/GZGZM/config.go index 6a91f52..71b1ea3 100644 --- a/consumers/GZGZM/config.go +++ b/consumers/GZGZM/config.go @@ -1,6 +1,6 @@ package GZGZM -import "goUpload/config" +import "goInOut/config" type ConfigFile struct { config.Consumer diff --git a/consumers/HTJC/config.go b/consumers/HTJC/config.go index bd02b66..6e08e07 100644 --- a/consumers/HTJC/config.go +++ b/consumers/HTJC/config.go @@ -1,6 +1,6 @@ package HTJC -import "goUpload/config" +import "goInOut/config" type ConfigFile struct { config.Consumer diff --git a/consumers/HTTP_PRPXY/config.go b/consumers/HTTP_PRPXY/config.go new file mode 100644 index 0000000..6f8b04c --- /dev/null +++ b/consumers/HTTP_PRPXY/config.go @@ -0,0 +1,25 @@ +package HTTP_PRPXY + +import "goInOut/config" + +type ConfigFile struct { + config.Consumer + IoConfig ioConfig `json:"ioConfig"` + OtherInfo map[string]string `json:"info"` +} +type ioConfig struct { + In In `json:"in"` + Out OUT `json:"out"` +} +type In struct { + ApiServer config.ApiServerConfig `json:"apiServer"` +} + +type OUT struct { + HttpPost config.HttpConfig `json:"httpPost"` +} + +type SensorInfo struct { + Name string `json:"name"` //测点名称 + Code string `json:"code"` //测点编号 宜由“桥名简称-监测类别简称-构件类型编码-截面序号-构件序号-测点编号”组成 +} diff --git a/consumers/HTTP_PRPXY/dataModel.go b/consumers/HTTP_PRPXY/dataModel.go new file mode 100644 index 0000000..15e8f3f --- /dev/null +++ b/consumers/HTTP_PRPXY/dataModel.go @@ -0,0 +1,44 @@ +package HTTP_PRPXY + +type ABStatus struct { + Values ABStatusValues `json:"values"` + Secret string `json:"secret"` + Type string `json:"type"` +} + +type ABStatusValues struct { + CreateTime int64 `json:"createTime"` + Updater string `json:"updater"` + Deleted bool `json:"deleted"` + Id string `json:"id"` + WorkId string `json:"workId"` + UcId string `json:"ucId"` + DeviceCode string `json:"deviceCode"` + UserId string `json:"userId"` + UserName string `json:"userName"` + DataTime int64 `json:"dataTime"` + BeltStatus string `json:"beltStatus"` + DeviceStatus string `json:"deviceStatus"` + StartDate int64 `json:"startDate"` + EndDate int64 `json:"endDate"` + MainVol int `json:"mainVol"` + AscendWorkCertificate string `json:"ascend_work_certificate"` + BeltPoseLeft string `json:"beltPoseLeft"` + BeltPoseRight string `json:"beltPoseRight"` + BeltStatusLeft string `json:"beltStatusLeft"` + BeltStatusRight string `json:"beltStatusRight"` + TickbVol int `json:"tickbVol"` + //Avatar interface{} `json:"avatar"` + //AlarmType interface{} `json:"alarmType"` + //Identity interface{} `json:"identity"` + //IdentityImg interface{} `json:"identityImg"` + //IdentityImgF interface{} `json:"identityImgF"` + //Phone interface{} `json:"phone"` + Versions int `json:"versions"` + //Team interface{} `json:"team"` + Longitude string `json:"longitude"` + Latitude string `json:"latitude"` + Outsource string `json:"outsource"` + LocTime int64 `json:"locTime"` + //WorkLen interface{} `json:"workLen"` +} diff --git a/consumers/JSNCGLQL/config.go b/consumers/JSNCGLQL/config.go index af6f61c..7911724 100644 --- a/consumers/JSNCGLQL/config.go +++ b/consumers/JSNCGLQL/config.go @@ -1,11 +1,12 @@ package JSNCGLQL -import "goUpload/config" +import "goInOut/config" type ConfigFile struct { config.Consumer - IoConfig ioConfig `json:"ioConfig"` - SensorConfig + IoConfig ioConfig `json:"ioConfig"` + SensorConfig `json:"sensorInfo"` + OtherInfo map[string]string `json:"info"` } type ioConfig struct { In In `json:"in"` @@ -22,6 +23,8 @@ type OUT struct { type SensorConfig struct { TYCJsensorMap map[string]string `json:"TYCJsensorMap"` ZDsensorMap map[string]string `json:"ZDsensorMap"` + GDNDsensorMap map[string]string `json:"GDNDsensorMap"` + ZDSLensorMap map[string]string `json:"ZDSLensorMap"` } type SensorInfo struct { diff --git a/consumers/MYX/config.go b/consumers/MYX/config.go index f7ced8c..16c7d78 100644 --- a/consumers/MYX/config.go +++ b/consumers/MYX/config.go @@ -1,6 +1,6 @@ package MYX -import "goUpload/config" +import "goInOut/config" type ConfigFile struct { config.Consumer diff --git a/consumers/SinoGnssMySQL/config.go b/consumers/SinoGnssMySQL/config.go new file mode 100644 index 0000000..2f0ec37 --- /dev/null +++ b/consumers/SinoGnssMySQL/config.go @@ -0,0 +1,27 @@ +package SinoGnssMySQL + +import "goInOut/config" + +type ConfigFile struct { + config.Consumer + IoConfig ioConfig `json:"ioConfig"` + OtherInfo map[string]string `json:"info"` +} +type ioConfig struct { + In In `json:"in"` + Out OUT `json:"out"` +} +type In struct { + Db config.DbConfig `json:"db"` + CronStr string `json:"cronStr"` +} + +type OUT struct { + Mqtt config.MqttConfig `json:"mqtt"` +} + +// 缓存用 +type RecordInfo struct { + Id int64 `json:"id"` + TableName string `json:"table_name"` +} diff --git a/consumers/SinoGnssMySQL/dataModel.go b/consumers/SinoGnssMySQL/dataModel.go new file mode 100644 index 0000000..c127bc9 --- /dev/null +++ b/consumers/SinoGnssMySQL/dataModel.go @@ -0,0 +1,28 @@ +package SinoGnssMySQL + +import "time" + +type GnssData struct { + Id int64 `json:"id" db:"id"` + StationName string `json:"station_name" db:"station_name"` + GroupName string `json:"group_name" db:"group_name"` + Time time.Time `json:"time" db:"time"` + X float64 `json:"x" db:"x"` + Y float64 `json:"y" db:"y"` + H float64 `json:"h" db:"h"` +} + +type DxFile struct { + SensorId int `json:"S"` + Module string `json:"M"` + Channel int `json:"C"` + Error int `json:"R"` + Round int64 `json:"N"` + Timespan int64 `json:"T"` + Req []string `json:"Q"` + Acq []string `json:"A"` + RawValue []float64 `json:"RV"` + LimitValue []float64 `json:"LV"` + PhyValue []float64 `json:"PV"` + ThemeValue []float64 `json:"TV"` +} diff --git a/consumers/WJHP/config.go b/consumers/WJHP/config.go index 33e4bee..005f462 100644 --- a/consumers/WJHP/config.go +++ b/consumers/WJHP/config.go @@ -1,6 +1,6 @@ package WJHP -import "goUpload/config" +import "goInOut/config" type ConfigFile struct { config.Consumer diff --git a/consumers/consumerAXYraw.go b/consumers/consumerAXYraw.go new file mode 100644 index 0000000..50be402 --- /dev/null +++ b/consumers/consumerAXYraw.go @@ -0,0 +1,162 @@ +package consumers + +import ( + "encoding/json" + "goInOut/adaptors" + "goInOut/consumers/AXYraw" + "goInOut/dbOperate" + "goInOut/dbOperate/_kafka" + "goInOut/models" + "log" + "sync" + "time" +) + +type consumerAXYraw struct { + //数据缓存管道 + dataCache chan *models.EsRaw + //具体配置 + ConfigInfo AXYraw.ConfigFile + InKafka _kafka.KafkaHelper + OutEs dbOperate.ESHelper + infoRedis *dbOperate.RedisHelper + sinkRawMap sync.Map + lock sync.Mutex +} + +func (the *consumerAXYraw) LoadConfigJson(cfgStr string) { + // 将 JSON 格式的数据解析到结构体中 + err := json.Unmarshal([]byte(cfgStr), &the.ConfigInfo) + if err != nil { + log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error()) + panic(err) + } +} + +func (the *consumerAXYraw) Initial(cfg string) error { + the.sinkRawMap = sync.Map{} + the.dataCache = make(chan *models.EsRaw, 200) + + the.LoadConfigJson(cfg) + err := the.inputInitial() + if err != nil { + return err + } + err = the.outputInitial() + if err != nil { + return err + } + err = the.infoComponentInitial() + return err +} +func (the *consumerAXYraw) inputInitial() error { + //数据入口 + the.InKafka = _kafka.KafkaHelper{ + Brokers: the.ConfigInfo.IoConfig.In.Kafka.Brokers, + GroupId: the.ConfigInfo.IoConfig.In.Kafka.GroupId, + } + the.InKafka.Initial() + for _, inTopic := range the.ConfigInfo.IoConfig.In.Kafka.Topics { + the.InKafka.Subscribe(inTopic, the.onData) + } + + the.InKafka.Worker() + return nil +} +func (the *consumerAXYraw) outputInitial() error { + //数据出口 + the.OutEs = *dbOperate.NewESHelper( + the.ConfigInfo.IoConfig.Out.Es.Address, + the.ConfigInfo.IoConfig.Out.Es.Auth.UserName, + the.ConfigInfo.IoConfig.Out.Es.Auth.Password, + ) + + return nil +} + +func (the *consumerAXYraw) infoComponentInitial() error { + //数据出口 + addr := the.ConfigInfo.Info.QueryComponent.Redis.Address + the.infoRedis = dbOperate.NewRedisHelper("", addr) + + return nil +} + +func (the *consumerAXYraw) sinkTask() { + intervalSec := the.ConfigInfo.IoConfig.Out.Es.Interval + ticker := time.NewTicker(time.Duration(intervalSec) * time.Second) + defer ticker.Stop() + for { + <-ticker.C + the.toSink() + } +} + +func (the *consumerAXYraw) toSink() { + var raws []models.EsRaw + the.lock.Lock() + defer the.lock.Unlock() + the.sinkRawMap.Range(func(key, value any) bool { + if v, ok := value.(*models.EsRaw); ok { + raws = append(raws, *v) + //零时打日志用 + if v.IotaDevice == logTagDeviceId { + bs, _ := json.Marshal(v) + log.Printf("toSink -> Range 标记设备数据 [%s] %s ", logTagDeviceId, string(bs)) + } + return ok + } else { + log.Printf("!!! toSink -> Range 类型转换异常 [%v]", key) + } + return true + }) + if len(raws) > 0 { + log.Printf("准备写入es %d条", len(raws)) + index := the.ConfigInfo.IoConfig.Out.Es.Index + the.OutEs.BulkWriteRaws2Es(index, raws) + the.sinkRawMap.Clear() + } +} + +const logTagDeviceId = "91da4d1f-fbc7-4dad-bedd-f8ff05c0e0e0" + +func (the *consumerAXYraw) Work() { + go the.sinkTask() + go func() { + for { + pushEsRaw := <-the.dataCache + + if pushEsRaw.IotaDevice == logTagDeviceId { + bs, _ := json.Marshal(pushEsRaw) + log.Printf("存储 标记设备数据 [%s] %s ", logTagDeviceId, string(bs)) + } + + //有效数据存入缓存 + the.lock.Lock() + the.sinkRawMap.Store(pushEsRaw.IotaDevice, pushEsRaw) + the.lock.Unlock() + } + + }() +} +func (the *consumerAXYraw) onData(topic string, msg string) bool { + //if len(msg) > 80 { + // log.Printf("recv:[%s]:%s ...", topic, msg[:80]) + //} + adaptor := adaptors.Adaptor_AXY_LastRAW{ + Redis: the.infoRedis, + } + + needPush := adaptor.Transform(topic, msg) + + if needPush != nil && len(needPush.Meta) > 0 && needPush.Data != nil { + //日志标记 + if needPush.IotaDevice == logTagDeviceId { + bs, _ := json.Marshal(needPush) + log.Printf("onData -> needPush 标记设备数据 [%s] %s ", logTagDeviceId, string(bs)) + } + the.dataCache <- needPush + } + + return true +} diff --git a/consumers/consumerCDJYSN.go b/consumers/consumerCDJYSN.go index b47fc8d..7ea6857 100644 --- a/consumers/consumerCDJYSN.go +++ b/consumers/consumerCDJYSN.go @@ -4,11 +4,11 @@ import ( "encoding/json" "fmt" "github.com/robfig/cron/v3" - "goUpload/adaptors" - "goUpload/consumers/CDJYSN" - "goUpload/dbHelper" - "goUpload/monitors" - "goUpload/utils" + "goInOut/adaptors" + "goInOut/consumers/CDJYSN" + "goInOut/dbOperate" + "goInOut/monitors" + "goInOut/utils" "log" "path" "time" @@ -19,8 +19,8 @@ type consumerCDJYSN struct { dataCache chan []byte //具体配置 ConfigInfo CDJYSN.ConfigFile - //InHttp *dbHelper.HttpHelper - OutFile *dbHelper.FileSaveHelper + //InHttp *dbOperate.HttpHelper + OutFile *dbOperate.FileSaveHelper InHttp monitors.HttpMonitor configCron *cron.Cron } @@ -47,7 +47,7 @@ func (the *consumerCDJYSN) InputInitial() error { the.dataCache = make(chan []byte, 200) //数据入口 the.InHttp = monitors.HttpMonitor{ - HttpClient: &dbHelper.HttpHelper{Url: the.ConfigInfo.IoConfig.In.Http.Url, Token: ""}, + HttpClient: &dbOperate.HttpHelper{Url: the.ConfigInfo.IoConfig.In.Http.Url, Token: ""}, MonitorHelper: &monitors.MonitorHelper{CronStr: the.ConfigInfo.IoConfig.In.CronStr}, } @@ -57,7 +57,7 @@ func (the *consumerCDJYSN) InputInitial() error { } func (the *consumerCDJYSN) OutputInitial() error { //数据出口 - the.OutFile = &dbHelper.FileSaveHelper{ + the.OutFile = &dbOperate.FileSaveHelper{ Directory: the.ConfigInfo.IoConfig.Out.File.Directory, FilenameExtension: the.ConfigInfo.IoConfig.Out.File.FileNameExtension, } diff --git a/consumers/consumerCQZG.go b/consumers/consumerCQZG.go index 4fe9e55..5f0739f 100644 --- a/consumers/consumerCQZG.go +++ b/consumers/consumerCQZG.go @@ -2,9 +2,9 @@ package consumers import ( "encoding/json" - "goUpload/adaptors" - "goUpload/consumers/CQZG" - "goUpload/dbHelper" + "goInOut/adaptors" + "goInOut/consumers/CQZG" + "goInOut/dbOperate" "log" "os" "strings" @@ -16,8 +16,8 @@ type consumerCQZG struct { ch_t500101 chan []byte //具体配置 Info CQZG.ConfigFile - InMqtt *dbHelper.MqttHelper - outMqtt *dbHelper.MqttHelper + InMqtt *dbOperate.MqttHelper + outMqtt *dbOperate.MqttHelper } func (the *consumerCQZG) LoadConfigJson(cfgStr string) { @@ -43,7 +43,7 @@ func (the *consumerCQZG) InputInitial() error { log.Printf("RC4Key=%s", the.Info.Config.Rc4key) the.ch_t500101 = make(chan []byte, 200) //数据入口 - the.InMqtt = dbHelper.MqttInitial( + the.InMqtt = dbOperate.MqttInitial( the.Info.Config.InMqtt.Host, the.Info.Config.InMqtt.Port, the.Info.Config.InMqtt.ClientId, @@ -58,7 +58,7 @@ func (the *consumerCQZG) InputInitial() error { } func (the *consumerCQZG) OutputInitial() error { //数据出口 - the.outMqtt = dbHelper.MqttInitial( + the.outMqtt = dbOperate.MqttInitial( the.Info.Config.OutMqtt.Host, the.Info.Config.OutMqtt.Port, the.Info.Config.OutMqtt.ClientId, diff --git a/consumers/consumerGZGZM.go b/consumers/consumerGZGZM.go index 61e722c..e022e40 100644 --- a/consumers/consumerGZGZM.go +++ b/consumers/consumerGZGZM.go @@ -4,10 +4,10 @@ import ( "crypto/md5" "encoding/json" "fmt" - "goUpload/adaptors" - "goUpload/consumers/GZGZM" - "goUpload/dbHelper" - "goUpload/dbHelper/_kafka" + "goInOut/adaptors" + "goInOut/consumers/GZGZM" + "goInOut/dbOperate" + "goInOut/dbOperate/_kafka" "io" "log" "math/rand" @@ -20,7 +20,7 @@ type consumerGZGZM struct { //具体配置 ConfigInfo GZGZM.ConfigFile InKafka _kafka.KafkaHelper - OutHttp *dbHelper.HttpHelper + OutHttp *dbOperate.HttpHelper } func (the *consumerGZGZM) RegisterPoint(thirdId string, sensorInfo GZGZM.SensorInfo) error { @@ -91,7 +91,7 @@ func (the *consumerGZGZM) inputInitial() error { } func (the *consumerGZGZM) outputInitial() error { //数据出口 - the.OutHttp = &dbHelper.HttpHelper{ + the.OutHttp = &dbOperate.HttpHelper{ Url: the.ConfigInfo.IoConfig.Out.Http.Url, } the.OutHttp.Initial() @@ -135,7 +135,7 @@ func (the *consumerGZGZM) tokenRefresh() { fmt.Sprintf("&random=%s", randomStr16) + fmt.Sprintf("×tamp=%d", timestamp) + fmt.Sprintf("&secret=%s", secret) - tokenHttp := &dbHelper.HttpHelper{ + tokenHttp := &dbOperate.HttpHelper{ Url: queryUrl, } tokenHttp.Initial() diff --git a/consumers/consumerHTJC.go b/consumers/consumerHTJC.go index 69d7260..305acdb 100644 --- a/consumers/consumerHTJC.go +++ b/consumers/consumerHTJC.go @@ -2,9 +2,9 @@ package consumers import ( "encoding/json" - "goUpload/adaptors" - "goUpload/consumers/HTJC" - "goUpload/dbHelper" + "goInOut/adaptors" + "goInOut/consumers/HTJC" + "goInOut/dbOperate" "log" "strings" "time" @@ -15,8 +15,8 @@ type consumerHTJC struct { dataCache chan []byte //具体配置 Info HTJC.ConfigFile - InMqtt *dbHelper.MqttHelper - outUdp *dbHelper.UdpHelper + InMqtt *dbOperate.MqttHelper + outUdp *dbOperate.UdpHelper } func (the *consumerHTJC) LoadConfigJson(cfgStr string) { @@ -40,7 +40,7 @@ func (the *consumerHTJC) Initial(cfg string) error { func (the *consumerHTJC) InputInitial() error { the.dataCache = make(chan []byte, 1000) //数据入口 - the.InMqtt = dbHelper.MqttInitial( + the.InMqtt = dbOperate.MqttInitial( the.Info.Config.InMqtt.Host, the.Info.Config.InMqtt.Port, the.Info.Config.InMqtt.ClientId, @@ -55,7 +55,7 @@ func (the *consumerHTJC) InputInitial() error { } func (the *consumerHTJC) OutputInitial() error { //数据出口 - the.outUdp = &dbHelper.UdpHelper{ + the.outUdp = &dbOperate.UdpHelper{ Host: the.Info.Config.OutUdp.Host, Port: the.Info.Config.OutUdp.Port, } diff --git a/consumers/consumerHTTP_PRPXY.go b/consumers/consumerHTTP_PRPXY.go new file mode 100644 index 0000000..3cd9896 --- /dev/null +++ b/consumers/consumerHTTP_PRPXY.go @@ -0,0 +1,102 @@ +package consumers + +import ( + "encoding/json" + "fmt" + "goInOut/config" + "goInOut/consumers/HTTP_PRPXY" + "goInOut/dbOperate" + "goInOut/utils" + "io" + "log" + "net/http" +) + +type consumerHttpProxy struct { + //数据缓存管道 + routes map[string]config.Router + //具体配置 + Info HTTP_PRPXY.ConfigFile + InApiServer *dbOperate.ApiServerHelper + outHttpPost *dbOperate.HttpHelper +} + +func (the *consumerHttpProxy) LoadConfigJson(cfgStr string) { + // 将 JSON 格式的数据解析到结构体中 + err := json.Unmarshal([]byte(cfgStr), &the.Info) + if err != nil { + log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error()) + panic(err) + } +} + +func (the *consumerHttpProxy) Initial(cfg string) error { + the.routes = map[string]config.Router{} + the.LoadConfigJson(cfg) + err := the.InputInitial() + if err != nil { + return err + } + err = the.OutputInitial() + return err +} +func (the *consumerHttpProxy) InputInitial() error { + //数据入口 + the.InApiServer = dbOperate.NewApiServer( + the.Info.IoConfig.In.ApiServer.Port, + the.Info.IoConfig.In.ApiServer.Routers, + ) + the.InApiServer.Initial() + return nil +} +func (the *consumerHttpProxy) OutputInitial() error { + //数据出口 + the.outHttpPost = &dbOperate.HttpHelper{ + Url: the.Info.IoConfig.Out.HttpPost.Url, + } + the.outHttpPost.Initial() + return nil +} +func (the *consumerHttpProxy) Work() { + go func() { + for _, router := range the.Info.IoConfig.In.ApiServer.Routers { + the.InApiServer.RouteRegister(router.Router, the.onData) + the.routes[router.Router] = router + } + the.InApiServer.Run() + + }() +} +func (the *consumerHttpProxy) onData(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + body, err := io.ReadAll(r.Body) + + log.Printf("收到 %s 请求 %s", r.RequestURI, body) + + bodyObj := map[string]any{} + err = json.Unmarshal(body, &bodyObj) + if err != nil { + log.Printf("body 解析失败,请检查 %s", err.Error()) + return + } + routePath := fmt.Sprintf("%s %s", r.Method, r.RequestURI) + idTemplate := the.routes[routePath] + + id, err := utils.TextTemplateMatch(bodyObj, idTemplate.IdTemplate) + if err != nil { + log.Printf("解析id 失败,请检查 %s", err.Error()) + } + params := map[string]string{ + "id": id, + } + resp := "" + //沿用请求路由 + newUrl := the.outHttpPost.Url + r.URL.String() + resp, err = the.outHttpPost.HttpPostWithParams(newUrl, string(body), params) + if err != nil { + return + } + log.Printf("应答: %s", resp) + defer fmt.Fprintf(w, resp) + +} diff --git a/consumers/consumerJSNCGLQL.go b/consumers/consumerJSNCGLQL.go index aeba710..25c651c 100644 --- a/consumers/consumerJSNCGLQL.go +++ b/consumers/consumerJSNCGLQL.go @@ -2,9 +2,9 @@ package consumers import ( "encoding/json" - "goUpload/adaptors" - "goUpload/consumers/JSNCGLQL" - "goUpload/dbHelper" + "goInOut/adaptors" + "goInOut/consumers/JSNCGLQL" + "goInOut/dbOperate" "log" "strings" "time" @@ -15,8 +15,8 @@ type consumerJSNCGLQL struct { ch chan []adaptors.NeedPush //具体配置 Info JSNCGLQL.ConfigFile - InMqtt *dbHelper.MqttHelper - outMqtt *dbHelper.MqttHelper + InMqtt *dbOperate.MqttHelper + outMqtt *dbOperate.MqttHelper } func (the *consumerJSNCGLQL) LoadConfigJson(cfgStr string) { @@ -40,7 +40,7 @@ func (the *consumerJSNCGLQL) Initial(cfg string) error { func (the *consumerJSNCGLQL) InputInitial() error { the.ch = make(chan []adaptors.NeedPush, 200) //数据入口 - the.InMqtt = dbHelper.MqttInitial( + the.InMqtt = dbOperate.MqttInitial( the.Info.IoConfig.In.Mqtt.Host, the.Info.IoConfig.In.Mqtt.Port, the.Info.IoConfig.In.Mqtt.ClientId, @@ -55,7 +55,7 @@ func (the *consumerJSNCGLQL) InputInitial() error { } func (the *consumerJSNCGLQL) OutputInitial() error { //数据出口 - the.outMqtt = dbHelper.MqttInitial( + the.outMqtt = dbOperate.MqttInitial( the.Info.IoConfig.Out.Mqtt.Host, the.Info.IoConfig.Out.Mqtt.Port, the.Info.IoConfig.Out.Mqtt.ClientId, @@ -95,20 +95,33 @@ func (the *consumerJSNCGLQL) onData(inTopic string, Msg string) { matchTopic := inTopic[:topicPrefixIndex] adaptor := the.getAdaptor(matchTopic) if adaptor != nil { - needPush := adaptor.Transform(inTopic, Msg) + needPush := adaptor.Transform(matchTopic, Msg) if len(needPush) > 0 { the.ch <- needPush } } } func (the *consumerJSNCGLQL) getAdaptor(flag string) (adaptor adaptors.IAdaptor4) { + bridgeCode := "" + if v, ok := the.Info.OtherInfo["bridgeCode"]; ok { + bridgeCode = v + } + if bridgeCode == "" { + panic("无正确的 bridgeCode") + } switch flag { case "upload/uds": log.Printf("[统一采集软件]-上报,准备处理") - //adaptor = adaptors.Adaptor_TYCJ_JSNCGLQL{IdMap: the.Info.TYCJsensorMap} + adaptor = adaptors.Adaptor_TYCJ_JSNCGLQL{IdMap: the.Info.TYCJsensorMap, BridgeCode: bridgeCode} case "upload/ZD": log.Printf("[振动软件]-上报,准备处理") - //adaptor = adaptors.Adaptor_ZD_CQZG{IdMap: the.Info.SensorMap.ZDsensorMCMap, RC4Key: RC4Key} + adaptor = adaptors.Adaptor_ZD_JSNCGLQL{IdMap: the.Info.ZDsensorMap, BridgeCode: bridgeCode} + case "upload/ZDSL": + log.Printf("[振动索力软件]-上报,准备处理") + adaptor = adaptors.Adaptor_ZD_JSNCGLQL{IdMap: the.Info.ZDSLensorMap, BridgeCode: bridgeCode} + case "upload/gdnd": + log.Printf("[光电挠度]-上报,准备处理") + adaptor = adaptors.Adaptor_GDND2LA_JSNCGLQL{IdMap: the.Info.GDNDsensorMap, BridgeCode: bridgeCode} default: log.Printf("[无匹配 %s],不处理", flag) } diff --git a/consumers/consumerMYX.go b/consumers/consumerMYX.go index 51309a6..f31224e 100644 --- a/consumers/consumerMYX.go +++ b/consumers/consumerMYX.go @@ -5,10 +5,10 @@ import ( "encoding/csv" "encoding/json" "fmt" - "goUpload/adaptors" - "goUpload/consumers/MYX" - "goUpload/dbHelper" - "goUpload/monitors" + "goInOut/adaptors" + "goInOut/consumers/MYX" + "goInOut/dbOperate" + "goInOut/monitors" "golang.org/x/text/encoding/unicode" "log" "os" @@ -22,9 +22,9 @@ type consumerMYX struct { dataCache chan []byte //具体配置 Info MYX.ConfigFile - InMqtt *dbHelper.MqttHelper + InMqtt *dbOperate.MqttHelper InFileMonitor *monitors.FileMonitor - outHttpPost *dbHelper.HttpHelper + outHttpPost *dbOperate.HttpHelper } func (the *consumerMYX) LoadConfigJson(cfgStr string) { @@ -48,7 +48,7 @@ func (the *consumerMYX) Initial(cfg string) error { func (the *consumerMYX) InputInitial() error { the.dataCache = make(chan []byte, 200) //mqtt数据入口 - the.InMqtt = dbHelper.MqttInitial( + the.InMqtt = dbOperate.MqttInitial( the.Info.IOConfig.InMqtt.Host, the.Info.IOConfig.InMqtt.Port, the.Info.IOConfig.InMqtt.ClientId, @@ -71,7 +71,7 @@ func (the *consumerMYX) InputInitial() error { } func (the *consumerMYX) OutputInitial() error { //数据出口 - the.outHttpPost = &dbHelper.HttpHelper{ + the.outHttpPost = &dbOperate.HttpHelper{ Url: the.Info.IOConfig.OutHttpPost.Url, } the.outHttpPost.Initial() diff --git a/consumers/consumerManage.go b/consumers/consumerManage.go index ba2ff82..68cb921 100644 --- a/consumers/consumerManage.go +++ b/consumers/consumerManage.go @@ -19,6 +19,18 @@ func GetConsumer(name string) (consumer IConsumer) { case "consumerGZGZM": //工迅-广州高支模平台 consumer = new(consumerGZGZM) + + case "consumerAXYraw": //工迅-广州高支模平台 + consumer = new(consumerAXYraw) + + case "consumerJSNCGLQL": //工迅-广州高支模平台 + consumer = new(consumerJSNCGLQL) + + case "consumerHttpProxy": + consumer = new(consumerHttpProxy) + + case "consumerSinoGnssMySQL": + consumer = new(consumerSinoGnssMySQL) default: consumer = nil } diff --git a/consumers/consumerSinoGnssMySQL.go b/consumers/consumerSinoGnssMySQL.go new file mode 100644 index 0000000..2c4ff97 --- /dev/null +++ b/consumers/consumerSinoGnssMySQL.go @@ -0,0 +1,174 @@ +package consumers + +import ( + "encoding/json" + "fmt" + "goInOut/adaptors" + "goInOut/consumers/SinoGnssMySQL" + "goInOut/dbOperate" + "goInOut/monitors" + "goInOut/utils" + "log" + "os" + "time" +) + +type consumerSinoGnssMySQL struct { + //数据缓存管道 + ch chan []adaptors.NeedPush + //具体配置 + Info SinoGnssMySQL.ConfigFile + InDB *dbOperate.DBHelper + outMqtt *dbOperate.MqttHelper + monitor *monitors.CommonMonitor +} + +func (the *consumerSinoGnssMySQL) LoadConfigJson(cfgStr string) { + // 将 JSON 格式的数据解析到结构体中 + err := json.Unmarshal([]byte(cfgStr), &the.Info) + if err != nil { + log.Printf("读取配置文件[%s]异常 err=%v", cfgStr, err.Error()) + panic(err) + } +} + +func (the *consumerSinoGnssMySQL) Initial(cfg string) error { + the.LoadConfigJson(cfg) + err := the.InputInitial() + if err != nil { + return err + } + err = the.OutputInitial() + return err +} +func (the *consumerSinoGnssMySQL) InputInitial() error { + the.ch = make(chan []adaptors.NeedPush, 200) + //数据入口 + the.InDB = dbOperate.NewDBHelper( + the.Info.IoConfig.In.Db.Type, + the.Info.IoConfig.In.Db.ConnStr) + the.monitor = &monitors.CommonMonitor{ + MonitorHelper: &monitors.MonitorHelper{CronStr: the.Info.IoConfig.In.CronStr}, + } + the.monitor.Start() + the.monitor.RegisterFun(the.onData) + return nil +} +func (the *consumerSinoGnssMySQL) OutputInitial() error { + //数据出口 + the.outMqtt = dbOperate.MqttInitial( + the.Info.IoConfig.Out.Mqtt.Host, + the.Info.IoConfig.Out.Mqtt.Port, + the.Info.IoConfig.Out.Mqtt.ClientId, + the.Info.IoConfig.Out.Mqtt.UserName, + the.Info.IoConfig.Out.Mqtt.Password, + false, //按照具体项目来 + "") + return nil +} +func (the *consumerSinoGnssMySQL) Work() { + go func() { + for { + needPushList := <-the.ch + if len(the.ch) > 0 { + log.Printf("取出ch数据,剩余[%d] ", len(the.ch)) + } + + for _, push := range needPushList { + if push.Topic != "" { + the.outMqtt.Publish(push.Topic, push.Payload) + } + } + + time.Sleep(100 * time.Millisecond) + } + }() +} +func (the *consumerSinoGnssMySQL) onData() { + recordInfo, err := readRecord() + if err != nil { + log.Printf("读取 缓存异常,err=%v", err.Error()) + return + } + sql := fmt.Sprintf(`select d.id,d.station_name,p.group_name,d.time,d.x,d.y,d.h from %s as d +LEFT JOIN datasolution as p +ON d.station_name=p.sn +where p.group_name is not null +and d.id > %d and d.id <= %d +ORDER BY p.group_name;`, recordInfo.TableName, recordInfo.Id, recordInfo.Id+200) + var GnssDatas []SinoGnssMySQL.GnssData + err = the.InDB.Query(&GnssDatas, sql) + if err != nil || len(GnssDatas) == 0 { + log.Printf("当前批次无数据,跳过") + return + } + maxId := MaxId(GnssDatas) + log.Printf("当前批次id=%d => %d", recordInfo.Id, maxId) + recordInfo.Id = maxId + adaptor := the.getAdaptor() + needPush := adaptor.Transform(GnssDatas) + if len(needPush) > 0 { + the.ch <- needPush + } + fileName := "cache.inout" + //发现新月新纪录 + newTableName := tableNameNow() + if recordInfo.TableName != newTableName { + recordInfo.TableName = newTableName + recordInfo.Id = 0 + } + cacheStr, _ := json.Marshal(recordInfo) + err = utils.SaveCache2File(string(cacheStr), fileName) + if err != nil { + log.Panicf("record id to file,error: %v", err.Error()) + } + +} +func (the *consumerSinoGnssMySQL) getAdaptor() (adaptor adaptors.Adaptor_SINOMYSQL_AXYMQTT) { + + return adaptors.Adaptor_SINOMYSQL_AXYMQTT{} +} + +func readRecord() (SinoGnssMySQL.RecordInfo, error) { + fileName := "cache.inout" + //文件存在? + isExist := utils.FileExists(fileName) + if !isExist { + // 文件不存在,创建文件 + file, err := os.Create(fileName) + if err != nil { + log.Panicf("Error creating file: %v", err) + } + defaultRecord := SinoGnssMySQL.RecordInfo{ + Id: 0, + TableName: tableNameNow(), + } + str, _ := json.Marshal(defaultRecord) + _, err = file.WriteString(string(str)) + if err != nil { + log.Panicf("file write error: %v", err.Error()) + return SinoGnssMySQL.RecordInfo{}, err + } + } + recordStr, err := utils.ReadCache2File(fileName) + if err != nil { + panic("") + } + record := SinoGnssMySQL.RecordInfo{} + err = json.Unmarshal([]byte(recordStr), &record) + return record, err +} + +func MaxId(GnssDatas []SinoGnssMySQL.GnssData) int64 { + maxId := GnssDatas[0].Id + for _, data := range GnssDatas { + if data.Id > maxId { + maxId = data.Id + } + } + return maxId +} + +func tableNameNow() string { + return "data_gnss_" + time.Now().Format("200601") +} diff --git a/consumers/consumerWJHP.go b/consumers/consumerWJHP.go index d2996fa..4cdab69 100644 --- a/consumers/consumerWJHP.go +++ b/consumers/consumerWJHP.go @@ -2,10 +2,10 @@ package consumers import ( "encoding/json" - "goUpload/adaptors" - "goUpload/consumers/WJHP" - "goUpload/dbHelper" - "goUpload/monitors" + "goInOut/adaptors" + "goInOut/consumers/WJHP" + "goInOut/dbOperate" + "goInOut/monitors" "log" "strings" "time" @@ -16,9 +16,9 @@ type consumerWJHP struct { dataCache chan []byte //具体配置 Info WJHP.ConfigFile - InMqtt *dbHelper.MqttHelper + InMqtt *dbOperate.MqttHelper InFileMonitor *monitors.FileMonitor - outHttpPost *dbHelper.HttpHelper + outHttpPost *dbOperate.HttpHelper } func (the *consumerWJHP) LoadConfigJson(cfgStr string) { @@ -42,7 +42,7 @@ func (the *consumerWJHP) Initial(cfg string) error { func (the *consumerWJHP) InputInitial() error { the.dataCache = make(chan []byte, 200) //mqtt数据入口 - the.InMqtt = dbHelper.MqttInitial( + the.InMqtt = dbOperate.MqttInitial( the.Info.IOConfig.InMqtt.Host, the.Info.IOConfig.InMqtt.Port, the.Info.IOConfig.InMqtt.ClientId, @@ -58,7 +58,7 @@ func (the *consumerWJHP) InputInitial() error { } func (the *consumerWJHP) OutputInitial() error { //数据出口 - the.outHttpPost = &dbHelper.HttpHelper{ + the.outHttpPost = &dbOperate.HttpHelper{ Url: the.Info.IOConfig.OutHttpPost.Url, } the.outHttpPost.Initial() @@ -78,7 +78,7 @@ func (the *consumerWJHP) Work() { } func (the *consumerWJHP) onData(Topic string, Msg string) { if len(Msg) > 80 { - log.Printf("mqtt-recv:[%s]:%s ...", Topic, Msg[:100]) + log.Printf("mqtt-recv:[%s]:%s ...", Topic, Msg[:80]) } var needPush []byte topicPrefixIndex := strings.LastIndex(Topic, "/") diff --git a/dbHelper/apiServer.go b/dbHelper/apiServer.go deleted file mode 100644 index a75c965..0000000 --- a/dbHelper/apiServer.go +++ /dev/null @@ -1,38 +0,0 @@ -package dbHelper - -import ( - "fmt" - "github.com/gin-gonic/gin" - "log" - "net/http" - "time" -) - -type RouterFunc struct { - relativePath string //相对路由 如/gzm/data/upload - funcType string // 方法类型 如 post ,get - fun func(c *gin.Context) //方法 -} - -type ApiServerHelper struct { - Port uint16 - RoutFun map[string]RouterFunc -} - -func (the *ApiServerHelper) Initial() { - router := gin.Default() - for name, routerFunc := range the.RoutFun { - switch routerFunc.funcType { - case http.MethodGet: - router.GET(routerFunc.relativePath, routerFunc.fun) - case http.MethodPost: - router.GET(routerFunc.relativePath, routerFunc.fun) - default: - log.Printf("不支持的 [%s]方法类型 %s", routerFunc.relativePath, routerFunc.funcType) - continue - } - log.Printf("注册路由 %s,监听地址=%s", name, routerFunc.relativePath) - } - router.Run(fmt.Sprintf("0.0.0.0:%d", the.Port)) - time.Sleep(time.Second * 1) -} diff --git a/dbHelper/_kafka/consumerGroupHandler.go b/dbOperate/_kafka/consumerGroupHandler.go similarity index 96% rename from dbHelper/_kafka/consumerGroupHandler.go rename to dbOperate/_kafka/consumerGroupHandler.go index e10a27f..8e8f9b0 100644 --- a/dbHelper/_kafka/consumerGroupHandler.go +++ b/dbOperate/_kafka/consumerGroupHandler.go @@ -48,7 +48,7 @@ func (h *ConsumerGroupHandler) SubscribeRaw(topic string, fun func(*sarama.Consu func (h *ConsumerGroupHandler) decorateSubscribeString(handler func(string, string) bool) func(*sarama.ConsumerMessage) bool { f := func(cm *sarama.ConsumerMessage) bool { msg := string(cm.Value) - log.Printf("处理topic[%s]数据 offset=[%d]", cm.Topic, cm.Offset) + //log.Printf("处理topic[%s]数据 offset=[%d]", cm.Topic, cm.Offset) return handler(cm.Topic, msg) } return f @@ -82,7 +82,7 @@ func (h *ConsumerGroupHandler) Worker() { config := sarama.NewConfig() config.Consumer.Return.Errors = false config.Version = sarama.V2_0_0_0 - config.Consumer.Offsets.Initial = sarama.OffsetOldest + config.Consumer.Offsets.Initial = sarama.OffsetNewest config.Consumer.Offsets.AutoCommit.Enable = true config.Consumer.Group.Rebalance.GroupStrategies = []sarama.BalanceStrategy{sarama.NewBalanceStrategyRoundRobin()} group, err := sarama.NewConsumerGroup(h.brokers, h.groupId, config) diff --git a/dbHelper/_kafka/kafkaHelper.go b/dbOperate/_kafka/kafkaHelper.go similarity index 100% rename from dbHelper/_kafka/kafkaHelper.go rename to dbOperate/_kafka/kafkaHelper.go diff --git a/dbHelper/_kafka/kafka_test.go b/dbOperate/_kafka/kafka_test.go similarity index 100% rename from dbHelper/_kafka/kafka_test.go rename to dbOperate/_kafka/kafka_test.go diff --git a/dbHelper/_kafka/producerHelper.go b/dbOperate/_kafka/producerHelper.go similarity index 100% rename from dbHelper/_kafka/producerHelper.go rename to dbOperate/_kafka/producerHelper.go diff --git a/dbOperate/apiServerHelper.go b/dbOperate/apiServerHelper.go new file mode 100644 index 0000000..34e17c9 --- /dev/null +++ b/dbOperate/apiServerHelper.go @@ -0,0 +1,58 @@ +package dbOperate + +import ( + "fmt" + "goInOut/config" + "log" + "net/http" +) + +type ApiServerHelper struct { + mux *http.ServeMux + routes []config.Router + port uint + server http.Server +} + +func NewApiServer(port uint, routes []config.Router) *ApiServerHelper { + return &ApiServerHelper{ + mux: http.NewServeMux(), + routes: routes, + port: port, + } +} + +func (the *ApiServerHelper) Initial() { + the.mux = http.NewServeMux() + + // 创建 HTTP 服务器 + the.server = http.Server{ + Handler: the.mux, + Addr: fmt.Sprintf(":%d", the.port), + } + + //the.routeRegister() + +} +func (the *ApiServerHelper) Run() { + log.Printf("apiServer监听端口 %d", the.port) + the.server.ListenAndServe() +} +func (the *ApiServerHelper) routeRegister() { + + for _, route := range the.routes { + the.mux.HandleFunc(route.Router, func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + s := fmt.Sprintf(`{"route":"%s","resp":"安全带状态应答"}`, route) + println("收到请求", route.Router) + fmt.Fprintf(w, s) + }) + log.Printf("注册路由 %s", route) + } +} +func (the *ApiServerHelper) RouteRegister(route string, handler func(w http.ResponseWriter, r *http.Request)) { + + the.mux.HandleFunc(route, handler) + log.Printf("注册路由 %s", route) + +} diff --git a/dbOperate/dbHelper.go b/dbOperate/dbHelper.go new file mode 100644 index 0000000..436c0e9 --- /dev/null +++ b/dbOperate/dbHelper.go @@ -0,0 +1,101 @@ +package dbOperate + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/jmoiron/sqlx" + _ "github.com/lib/pq" + _ "github.com/mattn/go-sqlite3" + "log" + "time" +) + +const ( + postgres = iota + 1 + sqlite3 +) + +type DBHelper struct { + dbClient *sqlx.DB + dbType string + ConnectStr string +} + +func NewDBHelper(dbType string, connectStr string) *DBHelper { + the := &DBHelper{} + switch dbType { + case "postgres": + fallthrough + case "mysql": + fallthrough + case "sqlite3": + fallthrough + case "有效的数据库类型": + the.dbType = dbType + the.ConnectStr = connectStr + default: + log.Panicf("不支持的数据库类型=> %s", dbType) + + } + return the +} + +// sqlite3 => connectStr := os.Getwd() + "/db/cz.db" +// mysql => "user:password@tcp(127.0.0.1:3306)/databaseName" +// pg => "host=192.168.10.64 port=5432 user=postgres password=123456 dbname=headscale sslmode=disable" +func (the *DBHelper) dbOpen() error { + var err error + tdb, err := sqlx.Open(the.dbType, the.ConnectStr) + if err != nil { + return err + } + if err = tdb.Ping(); err != nil { + return err + } + the.dbClient = tdb + return nil +} +func (the *DBHelper) Exec(dbRecordSQL string) error { + if the.dbClient == nil { + if openErr := the.dbOpen(); openErr != nil { + //logger.Info("[%s]数据库链接失败,err=%v\n", time.Now().Format("2006-01-02 15:04:05.000"), openErr) + return openErr + } + } + execResult, execErr := the.dbClient.Exec(dbRecordSQL) + defer the.dbClient.Close() + if execErr != nil { + return execErr + } + if n, err := execResult.RowsAffected(); n > 0 { + return nil + } else { + log.Printf("[%s]执行sql[%s]失败\n", time.Now().Format("2006-01-02 15:04:05.000"), dbRecordSQL) + return err + } + +} + +func (the *DBHelper) Query(dest any, sql string) error { + + start := time.Now() + + if the.dbClient == nil { + if err := the.dbOpen(); err != nil { + log.Printf("数据库链接失败:%s", err.Error()) + return err + } + } + err := the.dbClient.Select(dest, sql) + if err != nil { + log.Printf("数据库查询失败:%s,\n sql=%s", err.Error(), sql) + } + + durTime := time.Since(start).Seconds() + log.Printf("查询耗时:%v s", durTime) + return err + +} + +func (the *DBHelper) Close() error { + return the.Close() +} diff --git a/dbOperate/db_test.go b/dbOperate/db_test.go new file mode 100644 index 0000000..dcb339f --- /dev/null +++ b/dbOperate/db_test.go @@ -0,0 +1,37 @@ +package dbOperate + +import ( + "goInOut/models" + "testing" +) + +type res struct { + RLLYCJ string `json:"LLYCJ"` + RLLCacheMap string `json:"LLCacheMap"` +} + +func TestRedis(t *testing.T) { + addr := "10.8.30.160:30379" + redis := NewRedisHelper("", addr) + + key1 := "RLLYCJ" + //v := redis.Get(key1) + //println(v) + + key2 := "RLLCacheMap" + res1 := res{} + + v2 := redis.MGet(&res1, key1, key2) + println(v2) +} + +func TestPg(t *testing.T) { + dbType := "postgres" + connectStr := "host=10.8.30.32 port=5432 user=postgres password=123 dbname=NBJJ1215-T sslmode=disable" + db := NewDBHelper(dbType, connectStr) + sql := "select * from t_agg_way" + var r []models.AggWay + db.Query(&r, sql) + println("===") + +} diff --git a/dbOperate/elasticsearchHelper.go b/dbOperate/elasticsearchHelper.go new file mode 100644 index 0000000..502b760 --- /dev/null +++ b/dbOperate/elasticsearchHelper.go @@ -0,0 +1,269 @@ +package dbOperate + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + elasticsearch6 "github.com/elastic/go-elasticsearch/v6" + "github.com/elastic/go-elasticsearch/v6/esapi" + "goInOut/models" + "io" + "log" + "strings" +) + +type ESHelper struct { + addresses []string + //org string + esClient *elasticsearch6.Client +} + +func NewESHelper(addresses []string, user, pwd string) *ESHelper { + es, _ := elasticsearch6.NewClient(elasticsearch6.Config{ + Addresses: addresses, + Username: user, + Password: pwd, + }) + res, err := es.Info() + if err != nil { + log.Fatalf("Error getting response: %s", err) + } + log.Printf("链接到es[%s]info=%v", elasticsearch6.Version, res) + return &ESHelper{ + addresses: addresses, + esClient: es, + } +} +func (the *ESHelper) SearchRaw(index, reqBody string) []models.HitRaw { + body := &bytes.Buffer{} + body.WriteString(reqBody) + response, err := the.esClient.Search( + the.esClient.Search.WithIndex(index), + the.esClient.Search.WithBody(body), + ) + defer response.Body.Close() + if err != nil { + return nil + } + r := models.EsRawResp{} + // Deserialize the response into a map. + if err := json.NewDecoder(response.Body).Decode(&r); err != nil { + log.Fatalf("Error parsing the response body: %s", err) + } + return r.Hits.Hits +} +func (the *ESHelper) Search(index, reqBody string) { + body := &bytes.Buffer{} + body.WriteString(reqBody) + response, err := the.esClient.Search( + the.esClient.Search.WithIndex(index), + the.esClient.Search.WithBody(body), + ) + + if err != nil { + //return nil, err + } + log.Println(response.Status()) + var r map[string]any + // Deserialize the response into a map. + if err := json.NewDecoder(response.Body).Decode(&r); err != nil { + log.Fatalf("Error parsing the response body: %s", err) + } + // Print the response status, number of results, and request duration. + log.Printf( + "[%s] %d hits; took: %dms", + response.Status(), + int(r["hits"].(map[string]any)["total"].(float64)), + int(r["took"].(float64)), + ) + + for _, hit := range r["hits"].(map[string]any)["hits"].([]any) { + + source := hit.(map[string]any)["_source"] + log.Printf(" * ID=%s, %s", hit.(map[string]any)["_id"], source) + } + log.Println(strings.Repeat("=", 37)) +} +func (the *ESHelper) request(index, reqBody string) (map[string]any, error) { + // Set up the request object. + req := esapi.IndexRequest{ + Index: index, + //DocumentID: strconv.Itoa(i + 1), + Body: strings.NewReader(reqBody), + Refresh: "true", + } + // Perform the request with the client. + res, err := req.Do(context.Background(), the.esClient) + if err != nil { + log.Fatalf("Error getting response: %s", err) + } + defer res.Body.Close() + var r map[string]any + if res.IsError() { + log.Printf("[%s] Error indexing document ID=%d", res.Status(), 0) + } else { + // Deserialize the response into a map. + + if err := json.NewDecoder(res.Body).Decode(&r); err != nil { + log.Printf("Error parsing the response body: %s", err) + } else { + // Print the response status and indexed document version. + log.Printf("[%s] %s; version=%d", res.Status(), r["result"], int(r["_version"].(float64))) + } + } + return r, err +} + +func (the *ESHelper) searchRaw(index, reqBody string) (models.IotaData, error) { + respmap, err := the.request(index, reqBody) + if respmap != nil { + + } + iotaDatas := models.IotaData{} + return iotaDatas, err +} + +func (the *ESHelper) searchThemes(index, reqBody string) (models.EsThemeResp, error) { + body := &bytes.Buffer{} + body.WriteString(reqBody) + response, err := the.esClient.Search( + the.esClient.Search.WithIndex(index), + the.esClient.Search.WithBody(body), + ) + defer response.Body.Close() + if err != nil { + //return nil, err + } + log.Println(response.Status()) + r := models.EsThemeResp{} + // Deserialize the response into a map. + if err := json.NewDecoder(response.Body).Decode(&r); err != nil { + log.Fatalf("Error parsing the response body: %s", err) + } + return r, err +} +func (the *ESHelper) SearchLatestStationData(index string, sensorId int) (models.EsTheme, error) { + //sensorId := 178 + queryBody := fmt.Sprintf(`{ + "size": 1, + "query": { + "term": { + "sensor": { + "value": %d + } + } + }, + "sort": [ + { + "collect_time": { + "order": "desc" + } + } + ] +}`, sensorId) + //index := "go_native_themes" + themes, err := the.searchThemes(index, queryBody) + + var theme models.EsTheme + if len(themes.Hits.Hits) > 0 { + theme = themes.Hits.Hits[0].Source + } + + return theme, err +} +func (the *ESHelper) BulkWrite(index, reqBody string) { + + body := &bytes.Buffer{} + body.WriteString(reqBody) + bulkRequest := esapi.BulkRequest{ + Index: index, + Body: body, + DocumentType: "_doc", + } + res, err := bulkRequest.Do(context.Background(), the.esClient) + defer res.Body.Close() + if err != nil { + log.Panicf("es 写入[%s],err=%s", index, err.Error()) + return + } + respBody, _ := io.ReadAll(res.Body) + if res.StatusCode != 200 && res.StatusCode != 201 { + log.Panicf("es 写入失败,err=%s \n body=%s", string(respBody), reqBody) + } + //log.Printf("es 写入[%s],完成,res=%s ", index, respBody) + +} + +func (the *ESHelper) BulkWriteWithLog(index, reqBody string) { + + body := &bytes.Buffer{} + body.WriteString(reqBody) + bulkRequest := esapi.BulkRequest{ + Index: index, + Body: body, + DocumentType: "_doc", + } + res, err := bulkRequest.Do(context.Background(), the.esClient) + defer res.Body.Close() + if err != nil { + log.Panicf("es 写入[%s],err=%s", index, err.Error()) + return + } + respBody, _ := io.ReadAll(res.Body) + if res.StatusCode != 200 && res.StatusCode != 201 { + log.Panicf("es 写入失败,err=%s \n body=%s", string(respBody), reqBody) + } + log.Printf("es 写入[%s],完成,res=%s ", index, respBody) + +} + +func (the *ESHelper) BulkWriteRaws2Es(index string, raws []models.EsRaw) { + + //log 测试用 + const logTagDeviceId = "91da4d1f-fbc7-4dad-bedd-f8ff05c0e0e0" + + logTag := false + + body := strings.Builder{} + for _, raw := range raws { + // scala => val id = UUID.nameUUIDFromBytes(s"${v.deviceId}-${v.acqTime.getMillis}".getBytes("UTF-8")).toString + source, _ := json.Marshal(raw) + _id := raw.IotaDevice + s := fmt.Sprintf( + `{"index": {"_index": "%s","_id": "%s"}} +%s +`, index, _id, source) + body.WriteString(s) + + if raw.IotaDevice == logTagDeviceId { + log.Printf("BulkWriteRaws2Es 标记设备数据 [%s] %s ", logTagDeviceId, string(s)) + logTag = true + } + } + if logTag { //追踪数据 + the.BulkWriteWithLog(index, body.String()) + } else { + the.BulkWrite(index, body.String()) + } + +} + +func (the *ESHelper) BulkWriteRaws2EsLast(index string, raws []models.EsRaw) { + body := strings.Builder{} + for _, raw := range raws { + source, _ := json.Marshal(raw) + _id := raw.IotaDevice + s := fmt.Sprintf( + `{"index": {"_index": "%s","_id": "%s"}} +%s +`, index, _id, source) + body.WriteString(s) + } + the.BulkWrite(index, body.String()) + +} + +func (the *ESHelper) Close() { + +} diff --git a/dbHelper/fileSaveHelper.go b/dbOperate/fileSaveHelper.go similarity index 97% rename from dbHelper/fileSaveHelper.go rename to dbOperate/fileSaveHelper.go index 1402c90..f1455f6 100644 --- a/dbHelper/fileSaveHelper.go +++ b/dbOperate/fileSaveHelper.go @@ -1,4 +1,4 @@ -package dbHelper +package dbOperate import ( "io" diff --git a/dbHelper/httpHelper.go b/dbOperate/httpHelper.go similarity index 84% rename from dbHelper/httpHelper.go rename to dbOperate/httpHelper.go index 75932cc..a180e91 100644 --- a/dbHelper/httpHelper.go +++ b/dbOperate/httpHelper.go @@ -1,4 +1,4 @@ -package dbHelper +package dbOperate import ( "bytes" @@ -8,9 +8,9 @@ import ( "log" "mime/multipart" "net/http" + "net/url" "os" "strings" - "time" ) type HttpHelper struct { @@ -23,8 +23,6 @@ type HttpHelper struct { func (the *HttpHelper) Initial() { the.client = http.Client{} - time.Sleep(time.Second * 1) - } func (the *HttpHelper) HttpGet(queryBody string) string { url := the.Url @@ -49,6 +47,8 @@ func (the *HttpHelper) HttpGetWithHeader(queryBody string, headerMap map[string] for k, v := range headerMap { req.Header.Set(k, v) } + //取消证书校验,避免证书过期问题 + client.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} resp, err := client.Do(req) if err != nil { @@ -93,6 +93,37 @@ func (the *HttpHelper) PublishWithHeader(messageBytes []byte, headers map[string } return resp, err } +func (the *HttpHelper) HttpPostWithParams(urlStr, queryBody string, params map[string]string) (string, error) { + tr := &http.Transport{ + DisableKeepAlives: true, + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + UrlParams := url.Values{} + for k, v := range params { + UrlParams.Set(k, v) + } + targetUrl, _ := url.ParseRequestURI(urlStr) + targetUrl.RawQuery = UrlParams.Encode() + + req, err := http.NewRequest("POST", targetUrl.String(), strings.NewReader(queryBody)) + req.Header.Set("Content-Type", "application/json") + + log.Printf("http post 开始请求,%s", targetUrl) + resp, err := client.Do(req) + if err != nil { + fmt.Println("请求POST异常 ", err, resp) + return "", err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println("请求ReadAll异常 ", err, resp) + return "", err + } + return string(body), err +} // 静态方法 func HttpGet(url string, queryBody string) string { @@ -109,6 +140,7 @@ func HttpGet(url string, queryBody string) string { return string(body) } +// 静态方法 func HttpPost(url string, queryBody string) (string, error) { client := &http.Client{} req, err := http.NewRequest("POST", url, strings.NewReader(queryBody)) @@ -129,6 +161,7 @@ func HttpPost(url string, queryBody string) (string, error) { return string(body), err } +// 静态方法 func HttpPostWithHeader(url string, queryBody string, headers map[string]string) (string, error) { tr := &http.Transport{ DisableKeepAlives: true, @@ -160,6 +193,7 @@ func HttpPostWithHeader(url string, queryBody string, headers map[string]string) return string(body), err } +// 静态方法 func HttpPostFormDataWithHeader(url string, queryBody string, headers map[string]string) (string, error) { tr := &http.Transport{ DisableKeepAlives: true, @@ -173,7 +207,7 @@ func HttpPostFormDataWithHeader(url string, queryBody string, headers map[string req.Header.Add(k, v) } - fmt.Printf("http post 开始请求,%s,\n,%s \n", url, req) + fmt.Printf("http post 开始请求,%s,\n,%v \n", url, req) resp, err := client.Do(req) if err != nil { fmt.Println("请求POST异常 ", err, resp) @@ -191,6 +225,7 @@ func HttpPostFormDataWithHeader(url string, queryBody string, headers map[string return string(body), err } +// 静态方法 func UploadFile(url string, headers map[string]string, bodyParams map[string]string, fileName string) ([]byte, error) { body := new(bytes.Buffer) // 创建 multipart writer diff --git a/dbHelper/influxDBHelper.go b/dbOperate/influxDBHelper.go similarity index 97% rename from dbHelper/influxDBHelper.go rename to dbOperate/influxDBHelper.go index ef31874..23dbd09 100644 --- a/dbHelper/influxDBHelper.go +++ b/dbOperate/influxDBHelper.go @@ -1,4 +1,4 @@ -package dbHelper +package dbOperate import ( "context" @@ -85,7 +85,7 @@ from(bucket:"%v") } // check for an error if result.Err() != nil { - fmt.Printf("query parsing error: %\n", result.Err().Error()) + fmt.Printf("query parsing error: %s \n", result.Err().Error()) } } else { log.Printf("influxDB 查询异常 %s", err.Error()) diff --git a/dbHelper/mqttHelper.go b/dbOperate/mqttHelper.go similarity index 91% rename from dbHelper/mqttHelper.go rename to dbOperate/mqttHelper.go index 00af870..6a74fc7 100644 --- a/dbHelper/mqttHelper.go +++ b/dbOperate/mqttHelper.go @@ -1,4 +1,4 @@ -package dbHelper +package dbOperate import ( "crypto/tls" @@ -25,7 +25,7 @@ type subscribeCall struct { } func (the *MqttHelper) reConn2Subscribe(client mqtt.Client) { - log.Println("mqtt触发重连后的重订阅") + log.Println("mqtt触发链接后的自动订阅") for _, call := range the.subscribeCalls { the.Subscribe(call.topic, call.f) } @@ -83,19 +83,18 @@ func NewTlsConfig(sslPath string) *tls.Config { func (the *MqttHelper) Publish(topic string, messageBytes []byte) { if the.client != nil { - token := the.client.Publish(topic, 0, false, messageBytes) + token := the.client.Publish(topic, 1, false, messageBytes) token.Wait() //the.client.Disconnect(200) - fmt.Printf("[%s] -[%v]推送Msg 长度=%d \n", topic, the.client.IsConnected(), len(messageBytes)) + log.Printf("[%s] -[%v]推送Msg 长度=%d \n", topic, the.client.IsConnected(), len(messageBytes)) } } func (the *MqttHelper) Subscribe(topic string, myCallback func(topic string, callMsg string)) { var callback mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { - log.Printf("收到数据 [%v] TOPIC: %s,MSGLen: %v", msg.MessageID(), msg.Topic(), len(msg.Payload())) + //log.Printf("收到数据 [%v] TOPIC: %s,MSGLen: %v", msg.MessageID(), msg.Topic(), len(msg.Payload())) Msg := string(msg.Payload()) myCallback(msg.Topic(), Msg) - //log.Println("消息处理结束") } log.Printf("=================开始订阅 %s [%s]=================", the.Host, topic) t := the.client.Subscribe(topic, 1, callback) diff --git a/dbOperate/redisHelper.go b/dbOperate/redisHelper.go new file mode 100644 index 0000000..4cdf550 --- /dev/null +++ b/dbOperate/redisHelper.go @@ -0,0 +1,133 @@ +package dbOperate + +import ( + "context" + "encoding/json" + "errors" + "github.com/redis/go-redis/v9" + "log" + "time" +) + +type RedisHelper struct { + rdb redis.UniversalClient + isReady bool + ctx context.Context +} + +func NewRedisHelper(master string, address ...string) *RedisHelper { + r := &RedisHelper{ctx: context.Background()} + r.InitialCluster(master, address...) + return r + +} + +func (the *RedisHelper) InitialCluster(master string, address ...string) { + + the.rdb = redis.NewUniversalClient(&redis.UniversalOptions{ + Addrs: address, + MasterName: master, + }) + log.Printf("redis 初始化完成 %s", address) + the.isReady = true +} + +func (the *RedisHelper) Get(key string) string { + val, err := the.rdb.Get(the.ctx, key).Result() + if errors.Is(err, redis.Nil) { + log.Printf("%s does not exist", key) + } else if err != nil { + panic(err) + } else { + //log.Printf("get key => %s =%s", key, val) + } + return val +} + +func (the *RedisHelper) GetObj(keys string, addr any) error { + err := the.rdb.Get(the.ctx, keys).Scan(addr) + if errors.Is(err, redis.Nil) { + log.Printf("%s does not exist", keys) + } else if err != nil { + es := err.Error() + log.Printf("err=%s ", es) + return err + } + return nil +} +func (the *RedisHelper) SetObj(keys string, obj any) error { + rs, err := the.rdb.Set(the.ctx, keys, obj, time.Minute*5).Result() + log.Printf("rs=%s ", rs) + if err != nil { + log.Printf("err=%s ", err.Error()) + } + return err +} +func (the *RedisHelper) GetLRange(keys string, addr any) error { + err := the.rdb.LRange(the.ctx, keys, 0, -1).ScanSlice(addr) + if errors.Is(err, redis.Nil) { + log.Printf("%s does not exist", keys) + } else if err != nil { + log.Printf("err=%s ", err.Error()) + return err + } + return nil +} +func (the *RedisHelper) MGet(addr any, keys ...string) error { + err := the.rdb.MGet(the.ctx, keys...).Scan(addr) + if errors.Is(err, redis.Nil) { + log.Printf("%s does not exist", keys) + } else if err != nil { + log.Printf("err=%s ", err.Error()) + return err + } + + return err +} +func (the *RedisHelper) MGetObj(addr any, keys ...string) error { + err := the.rdb.MGet(the.ctx, keys...).Scan(addr) + if errors.Is(err, redis.Nil) { + log.Printf("%s does not exist", keys) + } else if err != nil { + log.Printf("err=%s ", err.Error()) + return err + } + return nil +} +func (the *RedisHelper) HMGetObj(addr any, key, field string) error { + rp, err := the.rdb.HMGet(the.ctx, key, field).Result() + if errors.Is(err, redis.Nil) { + log.Printf("%s does not exist", key) + return err + } else if err != nil { + log.Printf("err=%s ", err.Error()) + return err + } + for _, i := range rp { + if v, ok := i.(string); ok { + err := json.Unmarshal([]byte(v), addr) + if err != nil { + return err + } + } + } + //todo scan有问题 后续待排查 + return nil + + //err := the.rdb.HMGet(the.ctx, key, field).Scan(addr) + //if errors.Is(err, redis.Nil) { + // log.Printf("%s does not exist", key) + //} else if err != nil { + // log.Printf("err=%s ", err.Error()) + // return err + //} + //return nil +} + +func (the *RedisHelper) SRem(key string, members ...string) int64 { + return the.rdb.SRem(the.ctx, key, members).Val() +} + +func (the *RedisHelper) SAdd(key string, members ...string) int64 { + return the.rdb.SAdd(the.ctx, key, members).Val() +} diff --git a/dbHelper/udpHelper.go b/dbOperate/udpHelper.go similarity index 98% rename from dbHelper/udpHelper.go rename to dbOperate/udpHelper.go index f96da6a..c9135ca 100644 --- a/dbHelper/udpHelper.go +++ b/dbOperate/udpHelper.go @@ -1,4 +1,4 @@ -package dbHelper +package dbOperate import ( "fmt" diff --git a/go.mod b/go.mod index ebc56e6..26bab5d 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,17 @@ -module goUpload +module goInOut -go 1.21 +go 1.23 require ( github.com/IBM/sarama v1.43.3 github.com/eclipse/paho.mqtt.golang v1.4.3 - github.com/gin-gonic/gin v1.9.1 + github.com/elastic/go-elasticsearch/v6 v6.8.10 + github.com/go-sql-driver/mysql v1.8.1 github.com/influxdata/influxdb-client-go/v2 v2.13.0 + github.com/jmoiron/sqlx v1.4.0 + github.com/lib/pq v1.10.9 + github.com/mattn/go-sqlite3 v1.14.24 + github.com/redis/go-redis/v9 v9.7.0 github.com/robfig/cron/v3 v3.0.1 golang.org/x/text v0.17.0 google.golang.org/protobuf v1.31.0 @@ -14,20 +19,14 @@ require ( ) require ( + filippo.io/edwards25519 v1.1.0 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/bytedance/sonic v1.10.0-rc3 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect - github.com/chenzhuoyu/iasm v0.9.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/eapache/go-resiliency v1.7.0 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.1 // indirect - github.com/goccy/go-json v0.10.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -40,25 +39,11 @@ require ( github.com/jcmturner/gofork v1.7.6 // indirect github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect - github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect github.com/oapi-codegen/runtime v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.9 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - golang.org/x/arch v0.4.0 // indirect golang.org/x/crypto v0.26.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2c506ad..64a1995 100644 --- a/go.sum +++ b/go.sum @@ -1,23 +1,22 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/IBM/sarama v1.43.3 h1:Yj6L2IaNvb2mRBop39N7mmJAHBVY3dTPncr3qGVkxPA= github.com/IBM/sarama v1.43.3/go.mod h1:FVIRaLrhK3Cla/9FfRF5X9Zua2KpS3SYIXxhac1H+FQ= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0= -github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= -github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= @@ -26,30 +25,17 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= +github.com/elastic/go-elasticsearch/v6 v6.8.10 h1:2lN0gJ93gMBXvkhwih5xquldszpm8FlUwqG5sPzr6a8= +github.com/elastic/go-elasticsearch/v6 v6.8.10/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= -github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= @@ -79,64 +65,40 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6 github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/oapi-codegen/runtime v1.0.0 h1:P4rqFX5fMFWqRzY9M/3YF9+aPSPPB06IzP2P7oOxrWo= github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18B34OO356yJ/A= -github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= +github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= -golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= @@ -161,9 +123,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -184,13 +143,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/logs/logInfo.log b/logs/logInfo.log deleted file mode 100644 index 811d38c..0000000 --- a/logs/logInfo.log +++ /dev/null @@ -1,18 +0,0 @@ -2024/10/17 11:33:20.528503 main.go:24: =================log start================= -2024/10/17 11:33:20.540075 main.go:25: ==> -2024/10/17 11:33:20.540075 main.go:30: 进程启动 -2024/10/17 11:33:20.540075 init.go:20: 加载配置文件:config_魏家滑坡_视觉位移.json -2024/10/17 11:33:20.540592 init.go:20: 加载配置文件:弃用备份 -2024/10/17 11:33:20.540592 init.go:22: 非文件[弃用备份]跳过 -2024/10/17 11:33:22.546148 mqttHelper.go:48: mqtt连接状态异常 tcp://10.8.30.160:1883(u:wjhp-sjwy-upload,p:123456,cid:wjhp-sjwy-upload) [err=network Error : dial tcp 10.8.30.160:1883: connectex: No connection could be made because the target machine actively refused it.] -2024/10/17 11:33:22.546148 mqttHelper.go:49: mqtt重连,30s后尝试,剩余次数=3 -2024/10/17 11:33:53.265276 main.go:24: =================log start================= -2024/10/17 11:33:53.285624 main.go:25: ==> -2024/10/17 11:33:53.285624 main.go:30: 进程启动 -2024/10/17 11:33:53.286127 init.go:20: 加载配置文件:config_魏家滑坡_视觉位移.json -2024/10/17 11:33:53.286698 init.go:20: 加载配置文件:弃用备份 -2024/10/17 11:33:53.286698 init.go:22: 非文件[弃用备份]跳过 -2024/10/17 11:33:53.289208 mqttHelper.go:28: mqtt触发重连后的重订阅 -2024/10/17 11:33:55.290027 mqttHelper.go:100: =================开始订阅 10.8.30.160 [/fs-flexometer/admin123]================= -2024/10/17 11:34:12.251376 mqttHelper.go:28: mqtt触发重连后的重订阅 -2024/10/17 11:34:12.251376 mqttHelper.go:100: =================开始订阅 10.8.30.160 [/fs-flexometer/admin123]================= diff --git a/main.go b/main.go index eea8e6d..1446613 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,8 @@ package main import ( "fmt" - "goUpload/config" - "goUpload/consumers" + "goInOut/config" + "goInOut/consumers" "gopkg.in/natefinch/lumberjack.v2" "io" "log" @@ -22,7 +22,6 @@ func init() { log.SetFlags(log.LstdFlags | log.Lshortfile | log.Lmicroseconds) log.SetOutput(multiWriter) log.Println("=================log start=================") - log.Println("==>") } func main() { diff --git a/main_test.go b/main_test.go index 4f8c711..26e5667 100644 --- a/main_test.go +++ b/main_test.go @@ -4,14 +4,17 @@ import ( "bytes" "crypto/rc4" "encoding/hex" - "goUpload/utils" + "fmt" + "goInOut/utils" "log" + "sync" "testing" "text/template" "time" ) func TestCRC16CCITT(t *testing.T) { + hexs := "0a16080718a8ea8fab06620c0a0471bd54c11204e01d8641" hexs = "0a2f080210f8b6d5d01218b395bffec3313a1e0a08a75fed41a75fed41120892c5d64292c5d6421a08f6c8a74379c9a743" Hexdata, _ := hex.DecodeString(hexs) @@ -50,3 +53,23 @@ func TestTemplate(t *testing.T) { bs := b.String() log.Println(bs) } + +func TestRangeMap(t *testing.T) { + m := sync.Map{} + //存数据 + m.Store(1, 1) + m.Store(2, 2) + m.Store(3, 3) + m.Store(4, 4) + m.Store(5, 5) + + //遍历map + m.Range(func(key, value interface{}) bool { + log.Printf("开始遍历 %v", key) + if key.(int) == 2 { + return false + } + fmt.Println(key, value) + return true + }) +} diff --git a/models/GDND2LA.go b/models/GDND2LA.go new file mode 100644 index 0000000..26b77ea --- /dev/null +++ b/models/GDND2LA.go @@ -0,0 +1,7 @@ +package models + +type GDND2luAn struct { + Id string `json:"id"` + Time string `json:"time"` + Value map[string][]float32 `json:"value"` +} diff --git a/models/IotaData.go b/models/IotaData.go new file mode 100644 index 0000000..87d386e --- /dev/null +++ b/models/IotaData.go @@ -0,0 +1,40 @@ +package models + +import ( + "time" +) + +type IotaData struct { + UserId string `json:"userId"` + ThingId string `json:"thingId"` + DimensionId string `json:"dimensionId"` + DimCapId string `json:"dimCapId"` + CapId string `json:"capId"` + DeviceId string `json:"deviceId"` + ScheduleId string `json:"scheduleId"` + TaskId string `json:"taskId"` + JobId int `json:"jobId"` + JobRepeatId int `json:"jobRepeatId"` + TriggerTime time.Time `json:"triggerTime"` + RealTime time.Time `json:"realTime"` + FinishTime time.Time `json:"finishTime"` + Seq int `json:"seq"` + Released bool `json:"released"` + Data Data `json:"data"` +} + +type Data struct { + Type int `json:"type"` + Data map[string]any `json:"data"` + Result struct { + Code int `json:"code"` + Msg string `json:"msg"` + Detail string `json:"detail"` + ErrTimes int `json:"errTimes"` + Dropped bool `json:"dropped"` + } `json:"result"` +} + +func (the *Data) Success() bool { + return the.Result.Code == 0 +} diff --git a/models/aggWay.go b/models/aggWay.go new file mode 100644 index 0000000..01d2cd6 --- /dev/null +++ b/models/aggWay.go @@ -0,0 +1,6 @@ +package models + +type AggWay struct { + Id int64 `db:"id"` + Name string `db:"name"` +} diff --git a/models/constant.go b/models/constant.go new file mode 100644 index 0000000..def8050 --- /dev/null +++ b/models/constant.go @@ -0,0 +1,6 @@ +package models + +const ( + RawTypeVib = "vib" + RawTypeDiag = "diag" +) diff --git a/models/deviceData.go b/models/deviceData.go new file mode 100644 index 0000000..a6045ec --- /dev/null +++ b/models/deviceData.go @@ -0,0 +1,107 @@ +package models + +import ( + "time" +) + +type DeviceData struct { + DeviceId string + Name string + ThingId string + StructId int + TaskId string + AcqTime time.Time + RealTime time.Time + ErrCode int + Raw map[string]any + RawUnit map[string]string + DeviceInfo DeviceInfo + DimensionId string + //数据类型 常见有 comm="" ,RawTypeVib="vib" + DataType string +} + +func (d *DeviceData) GetVibrationData() VibrationData { + vibData := VibrationData{} + if d.DataType == RawTypeVib { + if v, ok := d.Raw["filterFreq"]; ok { + if vv, ok := v.(float64); ok { + vibData.FilterFreq = vv + } + } + + if v, ok := d.Raw["sampleFreq"]; ok { + if vv, ok := v.(float64); ok { + vibData.SampleFreq = vv + } + } + + if v, ok := d.Raw["gainAmplifier"]; ok { + if vv, ok := v.(float64); ok { + vibData.GainAmplifier = byte(vv) + } + } + + if v, ok := d.Raw["version"]; ok { + if vv, ok := v.(float64); ok { + vibData.Version = byte(vv) + } + } + + if v, ok := d.Raw["triggerType"]; ok { + if vv, ok := v.(float64); ok { + vibData.TriggerType = byte(vv) + } + } + + if v, ok := d.Raw["physicalvalue"]; ok { + + if vSlice, ok := v.([]any); ok { + for _, vObj := range vSlice { + if vv, ok := vObj.(float64); ok { + vibData.Data = append(vibData.Data, vv) + } + } + + } + + //去直流 + if len(vibData.Data) > 0 { + avg := func(dataArray []float64) float64 { + sum := 0.0 + for _, f := range dataArray { + sum += f + } + return sum / float64(len(dataArray)) + }(vibData.Data) //common_calc.GetAvg(vibData.Data) + + for i := 0; i < len(vibData.Data); i++ { + vibData.Data[i] = vibData.Data[i] - avg + } + } + } + + } + return vibData +} + +// VibrationData 振动数据 +type VibrationData struct { + Version byte + SampleFreq float64 + FilterFreq float64 + GainAmplifier byte + TriggerType byte + Data []float64 // 原始波形数据 + Unit string +} + +func (v *VibrationData) FormatParams() map[string]any { + return map[string]any{ + "sampleFreq": v.SampleFreq, + "version": v.Version, + "filterFreq": v.FilterFreq, + "gainAmplifier": v.GainAmplifier, + "triggerType": v.TriggerType, + } +} diff --git a/models/deviceInfo.go b/models/deviceInfo.go new file mode 100644 index 0000000..53329c2 --- /dev/null +++ b/models/deviceInfo.go @@ -0,0 +1,70 @@ +package models + +import ( + "encoding/json" + "fmt" + "time" +) + +type DeviceInfo struct { + Id string `json:"id"` + Name string `json:"name"` + Structure Structure `json:"structure"` + DeviceMeta DeviceMeta `json:"device_meta"` + RefreshTime time.Time +} + +type DeviceMeta struct { + Id string `json:"id"` + Name string `json:"name"` + Model string `json:"model"` + Properties []IotaProperty `json:"properties"` + Capabilities []IotaCapability `json:"capabilities"` +} + +func (m *DeviceMeta) GetOutputProps() (out map[string]string) { + out = make(map[string]string) + if len(m.Capabilities) == 0 { + return + } + for _, property := range m.Capabilities[0].Properties { + info := fmt.Sprintf("%s(%s)", property.ShowName, property.Unit) + out[property.Name] = info + } + return +} +func (m *DeviceMeta) GetOutputUnit() (out map[string]string) { + out = make(map[string]string) + if len(m.Capabilities) == 0 { + return + } + for _, property := range m.Capabilities[0].Properties { + out[property.Name] = property.Unit + } + return +} + +// redis序列化 +func (m *DeviceMeta) MarshalBinary() (data []byte, err error) { + return json.Marshal(m) +} + +// redis序列化 +func (m *DeviceMeta) UnmarshalBinary(data []byte) error { + return json.Unmarshal(data, m) + +} + +type IotaCapability struct { + CapabilityCategoryId int `json:"capabilityCategoryId"` + Id string `json:"id"` + Name string `json:"name"` + Properties []IotaProperty `json:"properties"` +} + +type IotaProperty struct { + Category string `json:"category"` + Name string `json:"name"` + ShowName string `json:"showName"` + Unit string `json:"unit"` +} diff --git a/models/esRaw.go b/models/esRaw.go new file mode 100644 index 0000000..a09dc67 --- /dev/null +++ b/models/esRaw.go @@ -0,0 +1,37 @@ +package models + +import "time" + +type EsRaw struct { + StructId int `json:"structId"` + IotaDeviceName string `json:"iota_device_name"` + Data map[string]any `json:"data"` + CollectTime string `json:"collect_time"` + Meta map[string]string `json:"meta"` + IotaDevice string `json:"iota_device"` + CreateTime time.Time `json:"create_time"` +} + +type EsRawResp struct { + Took int `json:"took"` + TimedOut bool `json:"timed_out"` + Shards struct { + Total int `json:"total"` + Successful int `json:"successful"` + Skipped int `json:"skipped"` + Failed int `json:"failed"` + } `json:"_shards"` + Hits struct { + Total int `json:"total"` + MaxScore float64 `json:"max_score"` + Hits []HitRaw `json:"hits"` + } `json:"hits"` +} + +type HitRaw struct { + Index string `json:"_index"` + Type string `json:"_type"` + Id string `json:"_id"` + Score float64 `json:"_score"` + Source EsRaw `json:"_source"` +} diff --git a/models/esTheme.go b/models/esTheme.go new file mode 100644 index 0000000..ae31dbb --- /dev/null +++ b/models/esTheme.go @@ -0,0 +1,41 @@ +package models + +import "time" + +type EsTheme struct { + SensorName string `json:"sensor_name"` + FactorName string `json:"factor_name"` + FactorProtoCode string `json:"factor_proto_code"` + Data map[string]any `json:"data"` + FactorProtoName string `json:"factor_proto_name"` + Factor int `json:"factor"` + CollectTime time.Time `json:"collect_time"` + Sensor int `json:"sensor"` + Structure int `json:"structure"` + IotaDevice []string `json:"iota_device"` + CreateTime time.Time `json:"create_time"` +} + +type EsThemeResp struct { + Took int `json:"took"` + TimedOut bool `json:"timed_out"` + Shards struct { + Total int `json:"total"` + Successful int `json:"successful"` + Skipped int `json:"skipped"` + Failed int `json:"failed"` + } `json:"_shards"` + Hits struct { + Total int `json:"total"` + MaxScore float64 `json:"max_score"` + Hits []HitTheme `json:"hits"` + } `json:"hits"` +} + +type HitTheme struct { + Index string `json:"_index"` + Type string `json:"_type"` + Id string `json:"_id"` + Score float64 `json:"_score"` + Source EsTheme `json:"_source"` +} diff --git a/models/iotaDevice.go b/models/iotaDevice.go new file mode 100644 index 0000000..56ee80f --- /dev/null +++ b/models/iotaDevice.go @@ -0,0 +1,25 @@ +package models + +import ( + "encoding/json" +) + +type IotaDevice struct { + Id string `json:"id"` + Name string `json:"name"` + Properties string `json:"properties"` + DeviceMetaId string `json:"deviceMetaId"` + ThingId string `json:"thingId"` + DeviceMeta DeviceMeta `json:"deviceMeta"` +} + +// redis序列化 +func (m *IotaDevice) MarshalBinary() (data []byte, err error) { + return json.Marshal(m) +} + +// redis序列化 +func (m *IotaDevice) UnmarshalBinary(data []byte) error { + return json.Unmarshal(data, m) + +} diff --git a/models/savoirTheme.go b/models/savoirTheme.go index 8a320f5..515298a 100644 --- a/models/savoirTheme.go +++ b/models/savoirTheme.go @@ -47,11 +47,3 @@ type SavoirTheme struct { DataEmpty bool `json:"dataEmpty"` RawAgg bool `json:"rawAgg"` } - -type Structure struct { - ThingId string `json:"thingId"` - Id int `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - OrgId int `json:"orgId"` -} diff --git a/models/structure.go b/models/structure.go new file mode 100644 index 0000000..a10a230 --- /dev/null +++ b/models/structure.go @@ -0,0 +1,31 @@ +package models + +import ( + "encoding/json" +) + +type Structure struct { + ThingId string `json:"thingId"` + Id int `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + OrgId int `json:"orgId"` +} + +type ThingStruct struct { + ThingId string `json:"thingId"` + Id int `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + OrgId int `json:"orgId"` +} + +// redis序列化 +func (m *ThingStruct) MarshalBinary() (data []byte, err error) { + return json.Marshal(m) +} + +// redis序列化 +func (m *ThingStruct) UnmarshalBinary(data []byte) error { + return json.Unmarshal(data, m) +} diff --git a/monitors/commonMonitor.go b/monitors/commonMonitor.go new file mode 100644 index 0000000..c702665 --- /dev/null +++ b/monitors/commonMonitor.go @@ -0,0 +1,14 @@ +package monitors + +type CommonMonitor struct { + *MonitorHelper +} + +func (the *CommonMonitor) RegisterFun(fun func()) { + the.registerFun(fun) +} + +func (the *CommonMonitor) Start() { + the.initial() + the.monitorStart() +} diff --git a/monitors/httpMonitor.go b/monitors/httpMonitor.go index 83c31d6..b3d14cb 100644 --- a/monitors/httpMonitor.go +++ b/monitors/httpMonitor.go @@ -1,9 +1,9 @@ package monitors -import "goUpload/dbHelper" +import "goInOut/dbOperate" type HttpMonitor struct { - HttpClient *dbHelper.HttpHelper + HttpClient *dbOperate.HttpHelper *MonitorHelper } diff --git a/testUnit/mqttPush_test.go b/testUnit/mqttPush_test.go index 07c19a5..468d65e 100644 --- a/testUnit/mqttPush_test.go +++ b/testUnit/mqttPush_test.go @@ -2,8 +2,8 @@ package testUnit import ( "encoding/hex" - "goUpload/consumers/CQZG/protoFiles" - "goUpload/dbHelper" + "goInOut/consumers/CQZG/protoFiles" + "goInOut/dbOperate" "google.golang.org/protobuf/proto" "log" "testing" @@ -34,7 +34,7 @@ func TestMqttUpload(t *testing.T) { hexStr := hex.EncodeToString(dataStr) log.Println(err, hexStr) - mqHelpers := dbHelper.MqttHelper{ + mqHelpers := dbOperate.MqttHelper{ Host: "mqtt.datahub.anxinyun.cn", Port: 1883, ClientId: "lzwjdq500101-lk", diff --git a/testUnit/mqttRecv_test.go b/testUnit/mqttRecv_test.go index 590f977..187fe3a 100644 --- a/testUnit/mqttRecv_test.go +++ b/testUnit/mqttRecv_test.go @@ -1,14 +1,14 @@ package testUnit import ( - "goUpload/dbHelper" + "goInOut/dbOperate" "log" "testing" "time" ) func TestMqttRecv(t *testing.T) { - mqHelpers := dbHelper.MqttHelper{ + mqHelpers := dbOperate.MqttHelper{ Host: "10.8.30.160", Port: 30883, ClientId: "lzwjdq500101-lk", diff --git a/testUnit/udpPush_test.go b/testUnit/udpPush_test.go index a229867..4e125ba 100644 --- a/testUnit/udpPush_test.go +++ b/testUnit/udpPush_test.go @@ -1,14 +1,14 @@ package testUnit import ( - "goUpload/dbHelper" + "goInOut/dbOperate" "strconv" "testing" "time" ) func TestUDP_push(t *testing.T) { - udp := dbHelper.UdpHelper{ + udp := dbOperate.UdpHelper{ Host: "10.8.30.110", Port: 8888, } diff --git a/testUnit/安心云http转发_test.go b/testUnit/安心云http转发_test.go new file mode 100644 index 0000000..b18b483 --- /dev/null +++ b/testUnit/安心云http转发_test.go @@ -0,0 +1,80 @@ +package testUnit + +import ( + "encoding/json" + "fmt" + "goInOut/models" + "goInOut/utils" + "testing" + "time" +) + +// 定义一个结构体,包含嵌套的结构体字段 +type Person struct { + Name Name `json:"name"` +} + +type Name struct { + First string `json:"first"` + Last string `json:"last"` +} + +func Test_httpProxy(t *testing.T) { + +} + +func Test_template(t *testing.T) { + // 创建一个Person实例 + person := Person{ + Name: Name{ + First: "John", + Last: "Doe", + }, + } + + templateStr := "Hello, {{.Name.First}} !" + sbs, err := utils.TextTemplateMatch(person, templateStr) + println(sbs) + if err != nil { + fmt.Println(err.Error()) + } +} + +func Test_timeHandler(t *testing.T) { + rawMsg := `{ + "userId": "ce2d7eb2-e56e-422e-8bbe-95dfa18e32f8", + "thingId": "14862308-083e-46e1-a422-d7d6a1e2825d", + "dimensionId": "47386f69-c5aa-4ae7-b6cc-0490a1dc0b14", + "dimCapId": "0d561c0b-4dca-4104-abc0-1f0c40a71382", + "capId": "d4965875-354b-4294-87f4-c4ba9f9260ab", + "deviceId": "9c43a09c-3c65-42d3-9a54-42b87e0e5af2", + "scheduleId": "1cfebf18-81a2-489e-bcfb-efc294d8ce3d", + "taskId": "b58858ed-9e23-4ac9-9f9c-44f9e057aee9", + "jobId": 1, + "jobRepeatId": 1, + "triggerTime": "2024-12-04T18:23:04+16:00", + "realTime": "0001-01-01T00:00:00Z", + "finishTime": "2024-12-04T10:23:07.909922675+08:00", + "seq": 0, + "released": false, + "data": { + "type": 1, + "data": { + "physicalvalue": 0 + }, + "result": { + "code": 0, + "msg": "", + "detail": null, + "errTimes": 0, + "dropped": false + } + } + }` + + iotaData := models.IotaData{} + json.Unmarshal([]byte(rawMsg), &iotaData) + var cstZone = time.FixedZone("CST", 8*3600) // 东八区 + time := iotaData.TriggerTime.In(cstZone).Format("2006-01-02T15:04:05.000+0800") + println(time) +} diff --git a/testUnit/江苏智感测试_test.go b/testUnit/江苏智感测试_test.go new file mode 100644 index 0000000..ce3cd3c --- /dev/null +++ b/testUnit/江苏智感测试_test.go @@ -0,0 +1,82 @@ +package testUnit + +import ( + "goInOut/adaptors" + "log" + "testing" +) + +func Test_江苏智感_应变(t *testing.T) { + + Msg := ` +{ + "dtuInfo": { + "id": 0, + "code": "COM3" + }, + "sensorData": { + "id": 25, + "name": "m1c1", + "module": "1", + "channel": "1", + "factorType": 23, + "productCode": "MD-BM15", + "structId": 0, + "data": { + "RawValues": [ + 880.05609130859375, + 17.250148773193359, + 426.63839721679687 + ], + "ThemeValues": [ + 1.254 + ] + }, + "time": "2022-01-06T14:30:00.000" + } +} +` + adp := adaptors.Adaptor_TYCJ_JSNCGLQL{ + IdMap: map[string]string{ + "m1c1": "JY-HSD-G05-001-01", + "m1c2": "LHTDQ-RSG-L04-001-03", + }, + BridgeCode: "G2320281L0012", + } + matchTopic := "upload/uds" + bytes := adp.Transform(matchTopic, Msg) + log.Println(bytes) +} + +func Test_江苏智感_加速度(t *testing.T) { + + Msg := ` +{"Sensorid":0,"Module":"m1c1","Channel":0,"Frequency":64,"ThemeValue":[1290.0560302734375],"RawValues":[],"AccValues":[1283.558,1284.225,1286.149,1287.802,1287.162,1286.052,1285.919,1285.773,1286.345,1285.923,1284.865,1285.24,1288.555,1288.9,1287.835,1288.205,1287.185,1287.119,1287.266,1286.979,1285.803,1286.851,1287.067,1287.282,1287.172,1286.887,1286.604,1287.944,1286.895,1287.764,1286.149,1285.606,1285.447,1286.035,1286.664,1287.94,1288.193,1288.365,1287.828,1287.639,1287.858,1287.992,1285.109,1285.098,1286.7,1283.96,1281.883,1283.221,1283.583,1283.806,1282.911,1282.179,1283.079,1282.504,1284.522,1286.981,1284.942,1285.352,1285.596,1288.592,1288.793,1287.406,1286.885,1287.607,1287.616,1286.512,1286.281,1286.677,1287.126,1286.622,1287.835,1287.268,1287.061,1286.665,1286.321,1287.955,1286.342,1286.35,1287.045,1286.6,1287.67,1286.765,1287.035,1287.429,1286.95,1287.701,1286.382,1285.629,1286.349,1286.22,1286.385,1287.926,1287.003,1287.861,1287.389,1288.281,1287.455,1285.3,1281.458,1282.176,1281.003,1283.045,1281.604,1282.898,1283.73,1283.065,1286.091,1287.463,1286.47,1287.904,1285.849,1286.24,1286.013,1286.467,1286.961,1287.042,1286.644,1287.27,1288.123,1287.752,1285.579,1285.215,1286.282,1286.038,1288.313,1286.403,1287.222,1287.147,1287.155,1287.766,1287.685,1287.22,1285.948,1285.644,1285.732,1286.822,1284.651,1287.573,1288.755,1287.204,1287.215,1286.546,1287.779,1287.461,1287.261,1287.112,1285.633,1286.964,1284.911,1282.031,1282.651,1282.792,1281.49,1283.697,1284.439,1282.987,1282.633,1285.909,1287.203,1287.085,1286.828,1286.973,1286.6,1286.978,1287.342,1287.173,1287.739,1287.287,1285.743,1286.837,1287.119,1287.099,1286.57,1286.836,1287.283,1287.848,1287.425,1287.75,1287.379,1287.477,1287.71,1286.578,1286.598,1285.528,1284.935,1287.748,1286.924,1285.9,1286.639,1287.234,1286.739,1287.12,1287.303,1286.17,1287.147,1286.728,1287.065,1287.525,1288.273,1286.184,1281.403,1282.91,1281.808,1282.329,1282.956,1282.863,1282.729,1282.614,1283.559,1287.289,1286.861,1287.313,1286.948,1286.503,1287.279,1285.792,1286.561,1287.33,1286.951,1286.991,1287.235,1287.722,1287.887,1286.974,1286.155,1284.995,1286.333,1286.915,1287.601,1287.448,1286.553,1286.767,1286.683,1287.65,1285.951,1286.473,1286.353,1285.941,1287.345,1286.674,1286.36,1287.314,1288.718,1287.83,1287.572,1287.111,1285.09,1285.877,1288.153,1287.014,1286.571,1281.341,1281.411,1283.615,1282.956,1283.173,1281.949,1283.055,1281.925,1284.661,1286.98,1286.799,1284.792,1286.272,1287.713,1287.54,1287.277,1287.003,1286.236,1286.127,1286.212,1286.821,1285.552,1286.892,1286.142,1286.603,1287.823,1288.396,1286.097,1287.426,1286.819,1286.106,1287.076,1287.694,1287.083,1285.96,1285.901,1286.317,1286.804,1288.028,1287.198,1286.265,1287.487,1286.414,1285.199,1286.589,1287.173,1287.463,1286.624,1287.407,1287.174,1287.54,1287.172,1283.417,1282.739,1282.229,1283.015,1282.275,1281.815,1282.354,1281.723,1284.979,1286.85,1287.041,1288.11,1286.83,1288.184,1285.855,1286.403,1286.685,1286.467,1287.283,1287.551,1287.436,1286.994,1286.233,1286.406,1288.472,1287.488,1286.166,1285.151,1287.579,1285.786,1287.102,1286.715,1286.666,1287.493,1286.989,1286.22,1287.545,1287.492,1286.591,1286.585,1287.814,1286.214,1286.1,1286.22,1287.941,1287.596,1286.543,1284.793,1285.451,1286.007,1289.132,1286.96,1279.971,1281.845,1282.387,1281.058,1285.151,1284.551,1281.236,1279.194,1288.642,1290.056,1286.935,1283.34,1286.059,1287.746,1287.682,1286.13,1286.172,1286.42,1286.798,1285.858,1284.875,1287.204,1290.049,1286.584,1286.496,1285.701,1286.298,1287.167,1287.503,1287.216,1286.467,1286.108,1286.719,1286.527,1287.631,1287.962,1287.21,1286.235,1286.989,1287.259,1288.137,1287.806,1287.502,1286.343,1286.299,1286.223,1287.184,1286.833,1287.693,1286.567,1285.928,1286.286,1288.519,1287.179,1287.033,1284.763,1282.308,1281.642,1283.903,1284.142,1283.739,1283.061,1283.307,1284.041,1287.126,1285.124,1287.493,1286.533,1286.712,1287.735,1286.521,1286.554,1287.046,1287.546,1287.954,1286.08,1286.406,1287.175,1286.907,1288.021,1286.836,1285.811,1287.812,1287.266,1287.916,1287.564,1286.408,1287.211,1286.643,1287.072,1286.808,1286.365,1286.246,1286.881,1286.847,1287.475,1287.4,1286.331,1286.663,1287.023,1287.161,1287.37,1287.171,1287.047,1286.715,1286.47,1286.66,1282.351,1282.151,1283.441,1282.901,1281.451,1281.676,1282.603,1283.968,1284.577,1285.785,1287.704,1287.127,1286.802,1286.686,1286.673,1287.171,1287.124,1285.387,1286.783,1286.004,1286.445,1287.15,1285.825,1287.762,1286.766,1285.524,1287.877,1287.365,1288.04,1286.488,1286.407,1287.895,1287.278,1287.562,1286.483,1287.384,1286.389,1285.975,1287.131,1285.426,1286.492,1287.561,1286.014,1287.05,1287.219,1286.822,1286.877,1287.364,1287.314,1286.927,1285.281,1282.653,1281.295,1281.666,1283.219,1283.365,1282.89,1284.118,1282.197,1284.389,1287.169,1286.626,1287.005,1286.096,1286.474,1286.059,1286.343,1287.167,1286.047,1287.655,1287.304,1286.792,1286.654,1287.3,1287.629,1287.337,1287.196,1286.366,1286.523,1286.629,1287.573,1287.273,1286.901,1287.367,1285.342,1286.544,1286.887,1287.3,1287.595,1286.443,1286.708,1287.099,1286.704,1287.069,1287.274,1286.51,1286.811,1287.001,1286.823,1287.035,1286.314,1287.507,1285.01,1281.964,1282.232,1282.319,1282.138,1282.72,1282.123,1283.028,1282.796,1285.902,1288.454,1287.503,1287.666,1285.778,1285.491,1286.983,1286.555,1285.776,1286.037,1286.463,1286.654,1287.353,1287.528,1288.568,1287.532,1287.218,1286.551,1285.815,1286.325,1285.448,1284.984,1286.994,1286.52,1286.433,1286.96,1287.798,1287.983,1287.301,1286.586,1286.367,1286.422,1285.92,1287.512,1286.184,1286.806,1286.364,1286.644,1286.688,1287.103,1287.515,1286.27,1284.878,1281.038,1281.646,1282.527,1283.223,1283.38,1281.987,1283.303,1284.225,1284.689,1287.298,1288.455,1285.868,1284.704,1286.34,1287.643,1286.828,1286.646,1288.855,1285.898,1286.506,1287.87,1287.976,1285.677,1285.493,1285.95,1286.863,1286.209,1286.112,1289.21,1285.76,1286.915,1287.091,1289.131,1286.426,1286.499,1287.025,1286.893,1285.055,1287.412,1286.577,1286.094,1286.085,1288.727,1286.047,1287.58,1287.028,1287.951,1286.708,1285.614,1286.601,1286.553,1285.596,1282.528,1283.466,1283.629,1282.531,1281.852,1283.951,1283.003,1283.309,1285.412,1286.119,1285.514,1287.11,1287.287,1286.589,1286.598,1287.78,1287.226,1287.694,1287.078,1287.701,1285.96,1286.416,1285.518,1286.934,1287.772,1287.673,1286.301,1285.751,1285.979,1287.035,1287.798,1287.917,1287.163,1285.706,1286.077,1286.123,1286.195,1287.396,1286.197,1286.558,1287.565,1287.967,1287.69,1287.164,1286.822,1286.987,1286.908,1285.514,1284.941,1285.402,1285.604,1282.453,1281.451,1282.278,1282.705,1283.972,1282.641,1283.361,1282.587,1282.896,1285.251,1285.01,1286.276,1286.682,1286.416,1287.078,1287.479,1287.083,1286.677,1287.03,1285.882,1287.047,1286.739,1285.664,1286.585,1287.704,1287.122,1286.613,1286.68,1287.692,1288.113,1287.8,1284.877,1285.702,1287.093,1286.048,1285.703,1286.235,1286.829,1287.403,1288.46,1288.443,1286.486,1286.538,1286.761,1286.667,1286.109,1286.681,1285.623,1285.763,1286.536,1287.008,1284.437,1284.234,1284.624,1282.37,1281.838,1281.906,1282.036,1282.407,1283.255,1286.755,1286.883,1286.434,1285.64,1286.954,1287.271,1287.293,1286.856,1285.474,1285.801,1287.444,1286.325,1286.404,1288.053,1287.579,1287.416,1287.047,1286.819,1286.81,1285.6,1286.096,1286.427,1286.55,1286.111,1287.046,1288.806,1286.769,1287.56,1287.159,1286.776,1286.883,1286.663,1287.103,1287.384,1286.442,1285.09,1287.351,1286.622,1287.092,1287.763,1285.808,1287.262,1285.574,1284.355,1282.202,1283.086,1282.154,1283.932,1281.525,1284.45,1281.963,1283.211,1287.808,1285.826,1286.701,1286.511,1287.275,1285.845,1287.26,1285.649,1288.315,1285.728,1288.651,1283.918,1289.333,1285.703,1286.663,1284.853,1288.673,1285.389,1288.397,1285.521,1288.097,1286.962,1287.077,1285.815,1286.675,1285.927,1287.53,1286.473,1286.77,1286.158,1286.553,1287.022,1286.681,1287.22,1286.963,1286.086,1286.276,1286.802,1287.171,1286.945,1287.299,1285.57,1282.056,1282.78,1284.338,1281.902,1281.848,1281.227,1281.763,1282.609,1285.833,1288.023,1286.73,1285.987,1286.712,1286.406,1287.841,1286.869,1286.823,1286.593,1285.136,1285.329,1286.885,1287.674,1288.369,1286.67,1286.4,1287.057,1287.103,1287.718,1288.267,1286.296,1286.51,1286.214,1287.028,1286.836,1286.843,1285.888,1286.823,1285.485,1286.929,1286.59,1287.135,1287.917,1286.977,1286.586,1287.352,1286.613,1287.55,1287.129,1287.362,1286.535,1286.757,1283.066,1281.336,1284.242,1283.616,1283.288,1282.874,1281.563,1281.958,1282.932,1285.939,1286.963,1287.15,1286.189,1287.213,1285.844,1287.996,1286.727,1288.238,1287.656,1286.012,1286.037,1286.098,1286.569,1287.575,1285.839,1286.152,1285.38,1286.497,1288.594,1287.064,1289.636,1286.801,1285.665,1285.205,1287.558,1286.886,1287.047,1285.505,1286.401,1287.239,1287.56,1287.164,1288.486,1285.868,1287.726,1285.942,1286.623,1284.694,1284.519,1287.368,1286.749,1287.277,1284.375,1281.643,1284.162,1283.594,1282.816,1283.447,1282.23,1281.0,1282.981,1287.075,1287.664,1285.063,1287.511,1287.749,1287.511,1287.406,1287.211,1286.361,1286.739,1286.135,1284.888,1286.347,1287.521,1287.621,1286.847,1289.124,1285.882,1286.465,1287.085,1286.725,1286.791,1286.201,1285.534,1286.27,1286.357,1288.729,1287.372,1287.269,1288.298,1287.33,1286.977,1286.834,1285.826,1286.727,1285.953,1286.118,1286.986,1285.661,1287.026,1287.562,1288.117,1283.1,1281.138,1282.944,1282.387,1283.56,1282.14,1282.933,1279.861,1283.522,1287.204,1286.33,1287.948,1286.243,1287.162,1286.378,1286.174,1286.413,1287.103,1287.055,1287.177,1287.378,1286.513,1286.386,1285.263,1287.291,1288.412,1287.152,1286.932,1286.816,1287.122,1287.301,1287.083,1287.006,1286.536,1286.166,1285.569,1286.045,1286.871,1287.419,1287.584,1288.096,1286.963,1286.254,1287.006,1287.76,1287.819,1286.847,1286.074,1285.459,1285.853,1288.16,1287.328,1283.378,1282.478,1282.112,1281.693,1283.291,1282.254,1282.274,1281.599,1285.067,1286.967,1286.181,1287.858,1288.191,1288.16,1287.051,1286.188,1286.104,1286.827,1285.824,1284.779,1286.701,1286.874,1287.405,1286.049,1287.403,1287.537,1288.402,1286.674,1284.76,1286.702,1287.558,1286.526,1286.747,1287.562,1285.535,1285.252,1287.727,1287.346,1287.81,1286.984,1286.262,1286.984,1286.668,1286.972,1286.368,1286.49,1286.38,1286.736,1287.805,1286.229,1284.934,1282.827,1283.378,1282.972,1281.71,1283.295,1282.905,1283.571,1284.294,1283.62,1282.494,1282.88,1285.508,1286.384,1286.493,1286.504,1286.304,1286.718,1286.906,1287.064,1286.27,1285.965,1286.442,1286.418,1286.163,1286.583,1287.278,1287.612,1288.094,1288.468,1288.306,1286.801,1286.706,1286.365,1286.95,1286.321,1285.954,1285.893,1286.006,1287.233,1286.345,1287.48,1286.642,1286.046,1286.861,1287.833,1286.711,1285.718,1285.68,1286.413,1286.76,1287.274,1287.389,1286.769,1286.74,1286.646,1282.183,1284.407,1282.296,1282.043,1282.836,1282.091,1281.59,1280.458,1284.796,1286.199,1286.829,1287.968,1287.003,1286.545,1286.693,1287.391,1286.572,1286.218,1285.611,1286.587,1287.415,1288.021,1286.934,1287.077,1288.356,1288.383,1286.513,1286.695,1285.854,1285.658,1286.14,1286.322,1284.842,1286.174,1285.979,1287.77,1288.084,1289.207,1287.656,1286.2,1287.191,1287.967,1287.801,1286.333,1286.241,1286.428,1286.479,1286.276,1287.606,1286.341,1286.717,1285.172,1282.115,1282.454,1280.736,1281.015,1283.212,1283.598,1283.801,1283.281,1287.353,1288.189,1288.436,1287.371,1286.224,1286.165,1287.077,1286.25,1285.952,1285.241,1285.573,1286.977,1286.964,1286.76,1286.231,1286.539,1288.356,1289.22,1287.855,1286.951,1287.058,1286.488,1287.065,1286.678,1286.765,1284.203,1285.798,1287.134,1287.502,1286.082,1286.699,1286.688,1285.628,1287.353,1286.634,1287.286,1287.545,1287.34,1287.899,1287.161,1287.355,1286.706,1284.482,1282.292,1282.076,1281.688,1281.399,1282.855,1281.976,1283.479,1281.957,1286.168,1287.614,1286.838,1287.763,1287.323,1286.427,1285.76,1286.437,1287.596,1287.364,1288.067,1287.172,1287.145,1286.311,1286.718,1286.785,1286.608,1285.885,1285.736,1285.829,1285.926,1286.223,1286.182,1286.619,1287.046,1288.033,1287.752,1288.137,1287.387,1286.882,1287.082,1286.183,1287.142,1286.605,1287.15,1287.054,1286.063,1285.58,1284.388,1285.481,1286.888,1286.55,1285.919,1283.113,1283.082,1283.921,1283.391,1283.332,1283.436,1283.52,1283.584,1284.007,1286.229,1285.53,1285.647,1286.587,1286.695,1286.568,1286.016,1286.747,1286.585,1286.023,1286.538,1287.076,1286.612,1286.585,1287.692,1287.292,1286.983,1286.385,1286.697,1287.866,1287.72,1287.172,1286.789,1286.87,1286.631,1286.879,1285.239,1286.052,1286.474,1287.053,1285.763,1287.144,1286.907,1287.172,1288.15,1287.891,1286.922,1286.754,1287.337,1288.245,1287.257,1286.719,1283.051,1282.062,1282.02,1282.051,1281.665,1282.32,1281.07,1281.269,1284.605,1287.353,1286.62,1287.115,1287.706,1288.189,1287.669,1287.823,1286.808,1286.599,1287.549,1287.717,1287.23,1286.135,1284.82,1285.645,1286.774,1286.554,1287.265,1286.383,1287.3,1287.079,1287.438,1286.951,1287.081,1287.731,1286.535,1286.301,1286.222,1287.112,1286.141,1286.87,1287.238,1287.564,1286.639,1286.448,1286.601,1286.518,1286.654,1286.522,1285.531,1285.847,1287.357,1287.344,1283.16,1282.775,1282.403,1283.791,1283.233,1282.453,1282.529,1282.163,1284.13,1287.345,1287.029,1286.369,1286.698,1286.649,1287.001,1286.672,1286.338,1285.734,1285.609,1286.437,1286.4,1286.993,1286.98,1287.275,1287.215,1287.737,1287.577,1287.673,1287.061,1286.69,1286.808,1286.961,1286.585,1286.085,1285.736,1286.892,1286.798,1285.427,1286.753,1287.271,1286.77,1286.762,1286.792,1286.904,1287.716,1287.555,1287.769,1287.969,1286.516,1286.901,1286.375,1285.908,1282.354,1282.019,1282.061,1282.232,1282.346,1283.591,1283.187,1286.669,1287.989,1286.536,1287.182,1287.543,1286.755,1285.329,1286.844,1286.832,1286.948,1288.058,1288.047,1286.066,1285.498,1286.29,1286.828,1286.933,1287.857,1286.612,1287.137,1287.57,1286.09,1286.333,1287.246,1287.487,1287.779,1286.142,1287.006,1287.447,1286.597,1287.219,1287.765,1286.746,1286.208,1286.956,1287.681,1287.335,1286.322,1286.077,1286.909,1287.594,1287.471,1286.045,1286.612,1282.826,1284.378,1282.486,1283.658,1281.604,1284.295,1284.266,1283.346,1283.079,1285.921,1287.653,1287.694,1285.988,1287.586,1285.553,1287.501,1285.198,1287.481,1287.156,1287.546,1285.34,1287.323,1287.277,1287.544,1286.826,1285.854,1286.492,1286.501,1287.07,1287.728,1286.556,1285.737,1287.682,1286.03,1286.135,1287.948,1287.11,1285.907,1285.787,1288.462,1288.164,1285.157,1287.582,1287.088,1286.816,1287.469,1287.729,1286.476,1285.585,1285.312,1287.443,1285.736,1282.637,1283.479,1281.9,1282.962,1282.77,1282.723,1283.839,1282.281,1286.799,1287.363,1286.487,1287.094,1286.028,1287.489,1288.106,1286.853,1286.638,1285.877,1287.285,1288.44,1285.759,1285.386,1286.165,1286.062,1288.534,1287.947,1287.837,1287.032,1286.729,1287.23,1287.396,1286.968,1286.734,1286.991,1287.053,1285.468,1285.946,1286.943,1287.153,1287.824,1286.636,1286.511,1286.718,1287.673,1288.427,1287.848,1286.387,1286.417,1286.506,1287.554,1285.775,1281.244,1282.377,1282.625,1283.188,1283.092,1283.247,1282.985,1282.771,1286.758,1287.992,1287.07,1286.831,1286.275,1287.167,1286.591,1287.4,1286.273,1286.871,1285.972,1287.59,1285.751,1288.517,1286.471,1286.98,1287.985,1286.587,1287.435,1287.703,1286.762,1287.171,1287.922,1286.512,1286.113,1286.209,1287.463,1286.23,1286.282,1287.243,1286.056,1286.741,1288.533,1287.361,1287.597,1286.444,1288.079,1288.295,1287.322,1285.954,1284.931,1285.836,1287.481,1283.27,1282.536,1283.266,1282.852,1284.533,1283.197,1283.425,1283.067,1283.069,1287.195,1286.031,1285.915,1286.718,1286.151,1287.616,1287.734,1287.057,1287.891,1288.125,1287.75,1286.974,1286.334,1286.501,1287.948,1286.133,1287.892,1287.263,1286.471,1285.63,1286.886,1287.595,1287.866,1286.591,1286.733,1286.509,1287.526,1287.288,1286.353,1287.418,1288.28,1287.298,1287.056,1286.061,1287.811,1287.784,1286.554,1286.201,1286.216,1286.925,1286.484,1286.573,1283.228,1283.355,1282.716,1282.841,1284.272,1284.131,1282.64,1281.912,1283.765,1285.849,1287.334,1286.747,1286.247,1288.573,1287.865,1286.632,1287.264,1288.054,1288.622,1287.302,1285.913,1285.016,1287.292,1286.573,1286.343,1285.553,1287.301,1287.501,1289.178,1286.986,1288.65,1287.667,1288.084,1285.203,1286.971,1286.036,1287.595,1286.405,1286.812,1286.314,1287.289,1286.798,1286.782,1286.731,1287.74,1287.659,1286.583,1286.095,1287.041,1286.229,1287.005,1286.261,1283.294,1283.958,1282.936,1283.865,1281.911,1283.581,1282.916,1281.482,1284.596,1286.513,1286.171,1286.83,1286.46,1287.114,1287.241,1287.027,1287.346,1287.643,1287.624,1286.998,1284.787,1286.401,1286.143,1286.424,1287.045,1286.744,1287.906,1287.715,1286.711,1287.144,1286.576,1286.704,1287.456,1285.925,1286.075,1286.533,1286.303,1287.488,1287.899,1288.212,1287.785,1287.298,1287.215,1287.474,1287.103,1286.953,1286.182,1286.028,1286.259,1286.682,1288.243,1284.502,1282.826,1283.845,1282.079,1283.218,1283.081,1283.842,1283.313,1283.197,1286.019,1286.516,1286.654,1287.426,1287.095,1287.693,1287.569,1286.34,1286.151,1286.798,1287.275,1288.411,1286.678,1287.185,1286.861,1287.526,1287.605,1287.918,1287.96,1287.328,1286.635,1286.899,1286.244,1286.73,1286.953,1285.974,1286.705,1286.525,1286.472,1283.65,1283.266,1284.176,1284.131,1283.098,1282.851,1281.792,1281.723,1284.038,1285.342,1285.554,1286.665,1287.613,1288.897,1288.72,1287.787,1287.399,1287.759,1288.072,1287.06,1284.859,1285.292,1286.828,1287.417,1287.039,1284.981,1286.565,1287.801,1288.05,1287.529,1286.728,1286.677,1287.283,1286.74,1286.596,1286.497,1286.284,1286.981,1288.138,1288.065,1286.723,1285.518,1287.589,1288.061,1287.268,1286.055,1286.19,1286.132,1286.789,1287.58,1286.192,1285.964,1282.568,1283.216,1283.787,1283.133,1282.371,1280.992,1282.85,1282.268,1284.81,1286.802,1287.325,1287.902,1287.264,1288.314,1287.697,1286.111,1286.838,1286.82,1286.973,1285.953,1285.23,1284.403,1287.062,1287.679,1287.76,1287.488,1287.18,1287.678,1288.925,1288.214,1287.013,1286.648,1286.564,1287.495,1287.698,1286.906,1284.682,1285.708,1288.063,1286.989,1286.501,1285.788,1286.426,1287.656,1287.342,1288.263,1286.943,1286.895,1288.418,1288.748,1288.194,1286.041,1281.748,1282.461,1283.889,1283.017,1282.92,1281.059,1282.128,1285.824,1287.173,1287.02,1286.45,1287.233,1288.464,1289.04,1288.523,1285.986,1286.51,1288.513,1287.087,1286.389,1285.809,1286.077,1286.895,1286.933,1287.436,1286.56,1286.303,1286.477,1286.732,1287.347,1287.058,1286.446,1286.33,1287.375,1288.133,1288.372,1286.711,1287.21,1285.883,1287.234,1286.01,1287.365,1286.137,1286.838,1287.596,1287.945,1286.496,1286.179,1287.184,1288.172,1283.761,1283.663,1283.281],"Ticks":1730362944840,"ThemeItems":null} +` + adp := adaptors.Adaptor_ZD_JSNCGLQL{ + IdMap: map[string]string{ + "m1c1": "LHTDQ-JSD-C08-001-01", + "m1c2": "LHTDQ-JSD-L03-001-01", + }, + BridgeCode: "G2320281L0012", + } + matchTopic := "upload/ZD" + bytes := adp.Transform(matchTopic, Msg) + log.Println(bytes) +} + +func Test_江苏智感_光电挠度(t *testing.T) { + + Msg := ` +{"id":"DY-DIS-ZG03-01","time":"2024-11-14 08:55:10","value":{"DY-DIS-ZG03-01":[-0.1338,-0.1458,-0.1549,-0.1566,-0.1473,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338,-0.1338]}} +` + adp := adaptors.Adaptor_GDND2LA_JSNCGLQL{ + IdMap: map[string]string{ + "DY-DIS-ZG03-01": "LHTDQ-DIS-C08-001-01", + }, + BridgeCode: "G2320281L0012", + } + matchTopic := "upload/GDND" + bytes := adp.Transform(matchTopic, Msg) + log.Println(bytes) +} diff --git a/testUnit/湘潭监测测试_test.go b/testUnit/湘潭监测测试_test.go index 67be7a3..b8c6ffa 100644 --- a/testUnit/湘潭监测测试_test.go +++ b/testUnit/湘潭监测测试_test.go @@ -1,7 +1,7 @@ package testUnit import ( - "goUpload/adaptors" + "goInOut/adaptors" "log" "testing" ) diff --git a/utils/cacheFile.go b/utils/cacheFile.go new file mode 100644 index 0000000..17ae27f --- /dev/null +++ b/utils/cacheFile.go @@ -0,0 +1,53 @@ +package utils + +import ( + "fmt" + "log" + "os" +) + +func SaveCache2File(cacheStr string, fileName string) error { + // 打开文件,如果文件不存在则创建 + file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666) + if err != nil { + log.Println("Error opening file:", err) + return err + } + defer file.Close() + + // 将变量写入文件 + _, err = file.WriteString(cacheStr) + if err != nil { + log.Println("Error writing to file:", err) + } + return err + +} + +func ReadCache2File(fileName string) (string, error) { + // 打开文件 + file, err := os.Open(fileName) + if err != nil { + log.Println("Error opening file:", err) + return "", err + } + defer file.Close() + + // 读取文件内容 + var content string + _, err = fmt.Fscanf(file, "%s", &content) + if err != nil { + log.Println("Error reading from file:", err) + } + return content, err +} + +func FileExists(filePath string) bool { + _, err := os.Stat(filePath) + if err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} diff --git a/utils/textTemplateHandler.go b/utils/textTemplateHandler.go new file mode 100644 index 0000000..4da4159 --- /dev/null +++ b/utils/textTemplateHandler.go @@ -0,0 +1,22 @@ +package utils + +import ( + "strings" + "text/template" +) + +func TextTemplateMatch(obj any, textTemplate string) (string, error) { + // 定义模板字符串 + tmpl, err := template.New("template").Parse(textTemplate) + if err != nil { + panic(err) + } + + sb := strings.Builder{} + err = tmpl.Execute(&sb, obj) + if err != nil { + return "", err + } + sbs := sb.String() + return sbs, err +} diff --git a/utils/valueHelper.go b/utils/valueHelper.go index 505bf80..aeefa3e 100644 --- a/utils/valueHelper.go +++ b/utils/valueHelper.go @@ -41,6 +41,6 @@ func LimitStringLength(s string, maxLength int) string { func Float32ToBytes(float float32) []byte { bits := math.Float32bits(float) bytes := make([]byte, 4) - binary.LittleEndian.PutUint32(bytes, bits) + binary.BigEndian.PutUint32(bytes, bits) return bytes }