pmc350b.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. package pmc350b
  2. import (
  3. "MeterService/core/logger"
  4. "MeterService/core/utils"
  5. "MeterService/dataStruct"
  6. "MeterService/service/downStreamService/proto"
  7. "MeterService/service/rtuService"
  8. "encoding/json"
  9. "math"
  10. "reflect"
  11. "runtime"
  12. )
  13. type pmc350bMeter struct {
  14. }
  15. var (
  16. pmc350bCollects = []dataStruct.ParsingDataConfig{
  17. {Origin: 0, Amount: 58, Method: pmc350bUIP},
  18. {Origin: 32, Amount: 8, Method: pmc350bTemperature},
  19. {Origin: 500, Amount: 12, Method: pmc350bEnergy},
  20. {Origin: 1400, Amount: 6, Method: pmc350bIHar},
  21. {Origin: 1600, Amount: 6, Method: pmc350bUHar},
  22. {Origin: 1330, Amount: 4, Method: pmc350bUIUnbalance},
  23. {Origin: 1400 + 24, Amount: 54, Method: pmc350bHarmIAbc1},
  24. {Origin: 1400 + 84, Amount: 54, Method: pmc350bHarmIAbc2},
  25. {Origin: 1400 + 144, Amount: 54, Method: pmc350bHarmIAbc3},
  26. {Origin: 1600 + 24, Amount: 54, Method: pmc350bHarmUAbc1},
  27. {Origin: 1600 + 84, Amount: 54, Method: pmc350bHarmUAbc2},
  28. {Origin: 1600 + 144, Amount: 54, Method: pmc350bHarmUAbc3},
  29. }
  30. )
  31. func NewPmc350bMeterHandler() proto.MeterHandler {
  32. return &pmc350bMeter{}
  33. }
  34. func (m *pmc350bMeter) Collect(w rtuService.RtuNetPgr, ref *dataStruct.MeterRef) (*dataStruct.CollectData, error) {
  35. colData := &dataStruct.CollectData{
  36. MeterRef: ref,
  37. PT: 1,
  38. CT: 1,
  39. }
  40. for _, v := range pmc350bCollects {
  41. if adu, err := w.GetHoldingRegs(v.Origin, v.Amount); err != nil {
  42. logger.Error("PMC-350B 采集失败[%s] ERROR:%v", runtime.FuncForPC(reflect.ValueOf(v.Method).Pointer()).Name(), err)
  43. return colData, err
  44. } else {
  45. logger.Debug("======》ADU:%v", adu)
  46. v.Method(adu, colData)
  47. }
  48. }
  49. return colData, nil
  50. }
  51. // SetAddress 设置地址
  52. func (m *pmc350bMeter) SetAddress(w rtuService.RtuNetPgr, addr int) (result bool) {
  53. var buf []byte
  54. buf = append(buf, utils.HfWord2byte(addr)...)
  55. if _, err := w.SetHoldingRegs(6401, 1, buf); err != nil {
  56. logger.Error("PMC-350B 设置地址失败 ERROR:%v", err)
  57. result = false
  58. } else {
  59. result = true
  60. }
  61. return
  62. }
  63. // QueryRatio 查询电表变比
  64. func (m *pmc350bMeter) GetRatio(w rtuService.RtuNetPgr) (string, bool) {
  65. if adu, err := w.GetHoldingRegs(6000, 10); err != nil {
  66. logger.Error("PMC-350B 查询电表变比失败 ERROR:%v", err)
  67. return "", false
  68. } else {
  69. var (
  70. index = 0
  71. n int32
  72. )
  73. s := &dataStruct.MeterPMC350BParam{}
  74. n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  75. s.PrimaryVolt = int(n)
  76. index += 4
  77. n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  78. s.SecondVolt = int(n)
  79. index += 4
  80. n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  81. s.PrimaryCurrent = int(n)
  82. index += 4
  83. n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  84. s.SecondCurrent = int(n)
  85. index += 4
  86. n = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  87. s.CType = int(n)
  88. index += 4
  89. str, err := json.Marshal(s)
  90. if err != nil {
  91. logger.Error("PMC-350B 变比序列化失败 ERROR:%v", err)
  92. return "", false
  93. }
  94. return string(str), true
  95. }
  96. }
  97. // SetRatio 设置电表变比
  98. func (m *pmc350bMeter) SetRatio(w rtuService.RtuNetPgr, data string) bool {
  99. ratio := &dataStruct.MeterPMC350BParam{}
  100. if err := json.Unmarshal([]byte(data), ratio); err != nil {
  101. logger.Error("PMC-350B 设置电表变比失败,变比数据解析失败 ERROR:%v", err)
  102. return false
  103. }
  104. var buf []byte
  105. {
  106. k := utils.Word2byte(ratio.PrimaryVolt)
  107. buf = append(buf, k...)
  108. }
  109. {
  110. k := utils.Word2byte(ratio.SecondVolt)
  111. buf = append(buf, k...)
  112. }
  113. {
  114. k := utils.Word2byte(ratio.PrimaryCurrent)
  115. buf = append(buf, k...)
  116. }
  117. {
  118. k := utils.Word2byte(ratio.SecondCurrent)
  119. buf = append(buf, k...)
  120. }
  121. {
  122. k := utils.Word2byte(ratio.CType)
  123. buf = append(buf, k...)
  124. }
  125. if _, err := w.SetHoldingRegs(6000, 10, buf); err != nil {
  126. logger.Error("PMC-350B 设置电表变比失败 ERROR:%v", err)
  127. return false
  128. }
  129. return true
  130. }
  131. func pmc350bUIP(adu []byte, s *dataStruct.CollectData) {
  132. var (
  133. index = 0
  134. m uint32
  135. )
  136. //ABC相电压
  137. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  138. s.Ua = math.Float32frombits(m)
  139. index += 4
  140. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  141. s.Ub = math.Float32frombits(m)
  142. index += 4
  143. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  144. s.Uc = math.Float32frombits(m)
  145. index += 4
  146. //ABC电流
  147. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  148. index += 4
  149. s.Ia = math.Float32frombits(m)
  150. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  151. index += 4
  152. s.Ib = math.Float32frombits(m)
  153. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  154. index += 4
  155. s.Ic = math.Float32frombits(m)
  156. index += 4
  157. //ABC、总有功
  158. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  159. index += 4
  160. s.Pa = math.Float32frombits(m) * float32(0.001)
  161. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  162. index += 4
  163. s.Pb = math.Float32frombits(m) * float32(0.001)
  164. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  165. index += 4
  166. s.Pc = math.Float32frombits(m) * float32(0.001)
  167. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  168. index += 4
  169. s.P = math.Float32frombits(m) * float32(0.001)
  170. //ABC、总无功
  171. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  172. index += 4
  173. s.Qa = math.Float32frombits(m) * float32(0.001)
  174. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  175. index += 4
  176. s.Qb = math.Float32frombits(m) * float32(0.001)
  177. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  178. index += 4
  179. s.Qc = math.Float32frombits(m) * float32(0.001)
  180. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  181. index += 4
  182. s.Q = math.Float32frombits(m) * float32(0.001)
  183. //视在功率
  184. index += 16
  185. //ABC、总功率因素
  186. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  187. index += 4
  188. s.Pfa = math.Float32frombits(m)
  189. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  190. index += 4
  191. s.Pfb = math.Float32frombits(m)
  192. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  193. index += 4
  194. s.Pfc = math.Float32frombits(m)
  195. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  196. index += 4
  197. s.Pf = math.Float32frombits(m)
  198. //频率
  199. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  200. index += 4
  201. }
  202. func pmc350bTemperature(adu []byte, s *dataStruct.CollectData) {
  203. var (
  204. index = 0
  205. m uint32
  206. f float32
  207. )
  208. //温度
  209. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  210. f = math.Float32frombits(m)
  211. if math.IsNaN(float64(f)) {
  212. s.TemperatureA = float32(0)
  213. } else {
  214. s.TemperatureA = f
  215. }
  216. index += 4
  217. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  218. f = math.Float32frombits(m)
  219. if math.IsNaN(float64(f)) {
  220. s.TemperatureB = float32(0)
  221. } else {
  222. s.TemperatureB = f
  223. }
  224. index += 4
  225. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  226. f = math.Float32frombits(m)
  227. if math.IsNaN(float64(f)) {
  228. s.TemperatureC = float32(0)
  229. } else {
  230. s.TemperatureC = f
  231. }
  232. index += 4
  233. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  234. f = math.Float32frombits(m)
  235. if math.IsNaN(float64(f)) {
  236. s.TemperatureZ = float32(0)
  237. } else {
  238. s.TemperatureZ = f
  239. }
  240. index += 4
  241. }
  242. func pmc350bEnergy(adu []byte, s *dataStruct.CollectData) {
  243. var (
  244. index = 0
  245. m int32
  246. )
  247. m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  248. s.Tps = float32(m) * float32(0.01)
  249. index += 4
  250. m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  251. s.Fps = float32(m) * float32(0.01)
  252. index += 4
  253. index += 8
  254. m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  255. s.Tqs = float32(m) * float32(0.01)
  256. index += 4
  257. m = int32(uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3]))
  258. s.Fqs = float32(m) * float32(0.01)
  259. index += 4
  260. }
  261. func pmc350bIHar(adu []byte, s *dataStruct.CollectData) {
  262. subHarAbc(adu, &s.IaHar, &s.IbHar, &s.IcHar)
  263. }
  264. func pmc350bUHar(adu []byte, s *dataStruct.CollectData) {
  265. subHarAbc(adu, &s.UaHar, &s.UbHar, &s.UcHar)
  266. }
  267. // ABC相畸变
  268. func subHarAbc(adu []byte, fa *float32, fb *float32, fc *float32) {
  269. var (
  270. index = 0
  271. m uint32
  272. )
  273. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  274. *fa = math.Float32frombits(m) * float32(10)
  275. index += 4
  276. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  277. *fb = math.Float32frombits(m) * float32(10)
  278. index += 4
  279. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  280. *fc = math.Float32frombits(m) * float32(10)
  281. index += 4
  282. }
  283. func pmc350bUIUnbalance(adu []byte, s *dataStruct.CollectData) {
  284. var (
  285. index = 0
  286. m uint32
  287. )
  288. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  289. s.UUnbalance = math.Float32frombits(m)
  290. index += 4
  291. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  292. s.IUnbalance = math.Float32frombits(m)
  293. index += 4
  294. }
  295. // 3-11
  296. func pmc350bHarmIAbc1(adu []byte, s *dataStruct.CollectData) {
  297. subHarmAbc(0, adu, &s.Hia, &s.Hib, &s.Hic)
  298. }
  299. // 13-21
  300. func pmc350bHarmIAbc2(adu []byte, s *dataStruct.CollectData) {
  301. subHarmAbc(5, adu, &s.Hia, &s.Hib, &s.Hic)
  302. }
  303. // 23-31
  304. func pmc350bHarmIAbc3(adu []byte, s *dataStruct.CollectData) {
  305. subHarmAbc(10, adu, &s.Hia, &s.Hib, &s.Hic)
  306. }
  307. // 3-11
  308. func pmc350bHarmUAbc1(adu []byte, s *dataStruct.CollectData) {
  309. subHarmAbc(0, adu, &s.Hua, &s.Hub, &s.Huc)
  310. }
  311. // 13-21
  312. func pmc350bHarmUAbc2(adu []byte, s *dataStruct.CollectData) {
  313. subHarmAbc(5, adu, &s.Hua, &s.Hub, &s.Huc)
  314. }
  315. // 23-31
  316. func pmc350bHarmUAbc3(adu []byte, s *dataStruct.CollectData) {
  317. subHarmAbc(10, adu, &s.Hua, &s.Hub, &s.Huc)
  318. }
  319. func subHarmAbc(orig int, adu []byte, fa *[15]float32, fb *[15]float32, fc *[15]float32) {
  320. var (
  321. index = 0
  322. m uint32
  323. )
  324. //ABC相3-11次谐波
  325. for i := 0; i < 5; i++ {
  326. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  327. index += 4
  328. fa[i+orig] = math.Float32frombits(m) * float32(10)
  329. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  330. index += 4
  331. fb[i+orig] = math.Float32frombits(m) * float32(10)
  332. m = uint32(adu[index])<<24 | uint32(adu[index+1])<<16 | uint32(adu[index+2])<<8 | uint32(adu[index+3])
  333. index += 4
  334. fc[i+orig] = math.Float32frombits(m) * float32(10)
  335. index += 12 //跳过偶次谐波
  336. }
  337. }