|
|
@@ -0,0 +1,365 @@
|
|
|
+package pmc350b
|
|
|
+
|
|
|
+import (
|
|
|
+ "MeterService/core/logger"
|
|
|
+ "MeterService/core/utils"
|
|
|
+ "MeterService/dataStruct"
|
|
|
+ "MeterService/service/downStreamService/proto"
|
|
|
+ "MeterService/service/rtuService"
|
|
|
+ "encoding/json"
|
|
|
+ "math"
|
|
|
+ "reflect"
|
|
|
+ "runtime"
|
|
|
+)
|
|
|
+
|
|
|
+type pmc350bMeter struct {
|
|
|
+}
|
|
|
+
|
|
|
+var (
|
|
|
+ pmc350bCollects = []dataStruct.ParsingDataConfig{
|
|
|
+ {Origin: 0, Amount: 58, Method: pmc350bUIP},
|
|
|
+ {Origin: 32, Amount: 8, Method: pmc350bTemperature},
|
|
|
+ {Origin: 500, Amount: 12, Method: pmc350bEnergy},
|
|
|
+ {Origin: 1400, Amount: 6, Method: pmc350bIHar},
|
|
|
+ {Origin: 1600, Amount: 6, Method: pmc350bUHar},
|
|
|
+ {Origin: 1330, Amount: 4, Method: pmc350bUIUnbalance},
|
|
|
+ {Origin: 1400 + 24, Amount: 54, Method: pmc350bHarmIAbc1},
|
|
|
+ {Origin: 1400 + 84, Amount: 54, Method: pmc350bHarmIAbc2},
|
|
|
+ {Origin: 1400 + 144, Amount: 54, Method: pmc350bHarmIAbc3},
|
|
|
+ {Origin: 1600 + 24, Amount: 54, Method: pmc350bHarmUAbc1},
|
|
|
+ {Origin: 1600 + 84, Amount: 54, Method: pmc350bHarmUAbc2},
|
|
|
+ {Origin: 1600 + 144, Amount: 54, Method: pmc350bHarmUAbc3},
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+func NewPmc350bMeterHandler() proto.MeterHandler {
|
|
|
+ return &pmc350bMeter{}
|
|
|
+}
|
|
|
+
|
|
|
+func (m *pmc350bMeter) Collect(w rtuService.RtuNetPgr, ref *dataStruct.MeterRef) (*dataStruct.CollectData, error) {
|
|
|
+ colData := &dataStruct.CollectData{
|
|
|
+ MeterRef: ref,
|
|
|
+ PT: 1,
|
|
|
+ CT: 1,
|
|
|
+ }
|
|
|
+ for _, v := range pmc350bCollects {
|
|
|
+ if adu, err := w.GetHoldingRegs(v.Origin, v.Amount); err != nil {
|
|
|
+ logger.Error("PMC-350B 采集失败[%s] ERROR:%v", runtime.FuncForPC(reflect.ValueOf(v.Method).Pointer()).Name(), err)
|
|
|
+ return colData, err
|
|
|
+ } else {
|
|
|
+ logger.Debug("======》ADU:%v", adu)
|
|
|
+ v.Method(adu, colData)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return colData, nil
|
|
|
+}
|
|
|
+
|
|
|
+// SetAddress 设置地址
|
|
|
+func (m *pmc350bMeter) SetAddress(w rtuService.RtuNetPgr, addr int) (result bool) {
|
|
|
+ var buf []byte
|
|
|
+ buf = append(buf, utils.HfWord2byte(addr)...)
|
|
|
+ if _, err := w.SetHoldingRegs(6401, 1, buf); err != nil {
|
|
|
+ logger.Error("PMC-350B 设置地址失败 ERROR:%v", err)
|
|
|
+ result = false
|
|
|
+ } else {
|
|
|
+ result = true
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// QueryRatio 查询电表变比
|
|
|
+func (m *pmc350bMeter) GetRatio(w rtuService.RtuNetPgr) (string, bool) {
|
|
|
+ if adu, err := w.GetHoldingRegs(6000, 10); err != nil {
|
|
|
+ logger.Error("PMC-350B 查询电表变比失败 ERROR:%v", err)
|
|
|
+ return "", false
|
|
|
+ } else {
|
|
|
+ var (
|
|
|
+ index = 0
|
|
|
+ n int32
|
|
|
+ )
|
|
|
+ s := &dataStruct.MeterPMC350BParam{}
|
|
|
+ n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.PrimaryVolt = int(n)
|
|
|
+ index += 4
|
|
|
+ n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.SecondVolt = int(n)
|
|
|
+ index += 4
|
|
|
+ n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.PrimaryCurrent = int(n)
|
|
|
+ index += 4
|
|
|
+ n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.SecondCurrent = int(n)
|
|
|
+ index += 4
|
|
|
+ n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.CType = int(n)
|
|
|
+ index += 4
|
|
|
+ str, err := json.Marshal(s)
|
|
|
+ if err != nil {
|
|
|
+ logger.Error("PMC-350B 变比序列化失败 ERROR:%v", err)
|
|
|
+ return "", false
|
|
|
+ }
|
|
|
+ return string(str), true
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// SetRatio 设置电表变比
|
|
|
+func (m *pmc350bMeter) SetRatio(w rtuService.RtuNetPgr, data string) bool {
|
|
|
+ ratio := &dataStruct.MeterPMC350BParam{}
|
|
|
+ if err := json.Unmarshal([]byte(data), ratio); err != nil {
|
|
|
+ logger.Error("PMC-350B 设置电表变比失败,变比数据解析失败 ERROR:%v", err)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ var buf []byte
|
|
|
+ {
|
|
|
+ k := utils.Word2byte(ratio.PrimaryVolt)
|
|
|
+ buf = append(buf, k...)
|
|
|
+ }
|
|
|
+ {
|
|
|
+ k := utils.Word2byte(ratio.SecondVolt)
|
|
|
+ buf = append(buf, k...)
|
|
|
+ }
|
|
|
+ {
|
|
|
+ k := utils.Word2byte(ratio.PrimaryCurrent)
|
|
|
+ buf = append(buf, k...)
|
|
|
+ }
|
|
|
+ {
|
|
|
+ k := utils.Word2byte(ratio.SecondCurrent)
|
|
|
+ buf = append(buf, k...)
|
|
|
+ }
|
|
|
+ {
|
|
|
+ k := utils.Word2byte(ratio.CType)
|
|
|
+ buf = append(buf, k...)
|
|
|
+ }
|
|
|
+ if _, err := w.SetHoldingRegs(6000, 10, buf); err != nil {
|
|
|
+ logger.Error("PMC-350B 设置电表变比失败 ERROR:%v", err)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+func pmc350bUIP(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ var (
|
|
|
+ index = 0
|
|
|
+ m uint32
|
|
|
+ )
|
|
|
+ //ABC相电压
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ s.Ua = math.Float32frombits(m)
|
|
|
+ index += 4
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ s.Ub = math.Float32frombits(m)
|
|
|
+ index += 4
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ s.Uc = math.Float32frombits(m)
|
|
|
+ index += 4
|
|
|
+ //ABC电流
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Ia = math.Float32frombits(m)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Ib = math.Float32frombits(m)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Ic = math.Float32frombits(m)
|
|
|
+ index += 4
|
|
|
+ //ABC、总有功
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Pa = math.Float32frombits(m) * float32(0.001)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Pb = math.Float32frombits(m) * float32(0.001)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Pc = math.Float32frombits(m) * float32(0.001)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.P = math.Float32frombits(m) * float32(0.001)
|
|
|
+
|
|
|
+ //ABC、总无功
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Qa = math.Float32frombits(m) * float32(0.001)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Qb = math.Float32frombits(m) * float32(0.001)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Qc = math.Float32frombits(m) * float32(0.001)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Q = math.Float32frombits(m) * float32(0.001)
|
|
|
+ //视在功率
|
|
|
+ index += 16
|
|
|
+ //ABC、总功率因素
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Pfa = math.Float32frombits(m)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Pfb = math.Float32frombits(m)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Pfc = math.Float32frombits(m)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ s.Pf = math.Float32frombits(m)
|
|
|
+ //频率
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+}
|
|
|
+
|
|
|
+func pmc350bTemperature(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ var (
|
|
|
+ index = 0
|
|
|
+ m uint32
|
|
|
+ f float32
|
|
|
+ )
|
|
|
+ //温度
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ f = math.Float32frombits(m)
|
|
|
+ if math.IsNaN(float64(f)) {
|
|
|
+ s.TemperatureA = float32(0)
|
|
|
+ } else {
|
|
|
+ s.TemperatureA = f
|
|
|
+ }
|
|
|
+ index += 4
|
|
|
+
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ f = math.Float32frombits(m)
|
|
|
+ if math.IsNaN(float64(f)) {
|
|
|
+ s.TemperatureB = float32(0)
|
|
|
+ } else {
|
|
|
+ s.TemperatureB = f
|
|
|
+ }
|
|
|
+ index += 4
|
|
|
+
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ f = math.Float32frombits(m)
|
|
|
+ if math.IsNaN(float64(f)) {
|
|
|
+ s.TemperatureC = float32(0)
|
|
|
+ } else {
|
|
|
+ s.TemperatureC = f
|
|
|
+ }
|
|
|
+ index += 4
|
|
|
+
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ f = math.Float32frombits(m)
|
|
|
+ if math.IsNaN(float64(f)) {
|
|
|
+ s.TemperatureZ = float32(0)
|
|
|
+ } else {
|
|
|
+ s.TemperatureZ = f
|
|
|
+ }
|
|
|
+ index += 4
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func pmc350bEnergy(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ var (
|
|
|
+ index = 0
|
|
|
+ m int32
|
|
|
+ )
|
|
|
+ m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.Tps = float32(m) * float32(0.01)
|
|
|
+ index += 4
|
|
|
+ m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.Fps = float32(m) * float32(0.01)
|
|
|
+ index += 4
|
|
|
+ index += 8
|
|
|
+ m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.Tqs = float32(m) * float32(0.01)
|
|
|
+ index += 4
|
|
|
+ m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
|
|
|
+ s.Fqs = float32(m) * float32(0.01)
|
|
|
+ index += 4
|
|
|
+}
|
|
|
+
|
|
|
+func pmc350bIHar(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarAbc(adu, &s.IaHar, &s.IbHar, &s.IcHar)
|
|
|
+}
|
|
|
+
|
|
|
+func pmc350bUHar(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarAbc(adu, &s.UaHar, &s.UbHar, &s.UcHar)
|
|
|
+}
|
|
|
+
|
|
|
+// ABC相畸变
|
|
|
+func subHarAbc(adu []byte, fa *float32, fb *float32, fc *float32) {
|
|
|
+ var (
|
|
|
+ index = 0
|
|
|
+ m uint32
|
|
|
+ )
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ *fa = math.Float32frombits(m) * float32(10)
|
|
|
+ index += 4
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ *fb = math.Float32frombits(m) * float32(10)
|
|
|
+ index += 4
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ *fc = math.Float32frombits(m) * float32(10)
|
|
|
+ index += 4
|
|
|
+}
|
|
|
+
|
|
|
+func pmc350bUIUnbalance(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ var (
|
|
|
+ index = 0
|
|
|
+ m uint32
|
|
|
+ )
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ s.UUnbalance = math.Float32frombits(m)
|
|
|
+ index += 4
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ s.IUnbalance = math.Float32frombits(m)
|
|
|
+ index += 4
|
|
|
+}
|
|
|
+
|
|
|
+// 3-11
|
|
|
+func pmc350bHarmIAbc1(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarmAbc(0, adu, &s.Hia, &s.Hib, &s.Hic)
|
|
|
+}
|
|
|
+
|
|
|
+// 13-21
|
|
|
+func pmc350bHarmIAbc2(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarmAbc(5, adu, &s.Hia, &s.Hib, &s.Hic)
|
|
|
+}
|
|
|
+
|
|
|
+// 23-31
|
|
|
+func pmc350bHarmIAbc3(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarmAbc(10, adu, &s.Hia, &s.Hib, &s.Hic)
|
|
|
+}
|
|
|
+
|
|
|
+// 3-11
|
|
|
+func pmc350bHarmUAbc1(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarmAbc(0, adu, &s.Hua, &s.Hub, &s.Huc)
|
|
|
+}
|
|
|
+
|
|
|
+// 13-21
|
|
|
+func pmc350bHarmUAbc2(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarmAbc(5, adu, &s.Hua, &s.Hub, &s.Huc)
|
|
|
+}
|
|
|
+
|
|
|
+// 23-31
|
|
|
+func pmc350bHarmUAbc3(adu []byte, s *dataStruct.CollectData) {
|
|
|
+ subHarmAbc(10, adu, &s.Hua, &s.Hub, &s.Huc)
|
|
|
+}
|
|
|
+
|
|
|
+func subHarmAbc(orig int, adu []byte, fa *[15]float32, fb *[15]float32, fc *[15]float32) {
|
|
|
+ var (
|
|
|
+ index = 0
|
|
|
+ m uint32
|
|
|
+ )
|
|
|
+ //ABC相3-11次谐波
|
|
|
+ for i := 0; i < 5; i++ {
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ fa[i+orig] = math.Float32frombits(m) * float32(10)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ fb[i+orig] = math.Float32frombits(m) * float32(10)
|
|
|
+ m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
|
|
|
+ index += 4
|
|
|
+ fc[i+orig] = math.Float32frombits(m) * float32(10)
|
|
|
+ index += 12 //跳过偶次谐波
|
|
|
+ }
|
|
|
+}
|