nmea0183_converter.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. """
  2. @Date :2021/5/21/00219:10:57
  3. @Desc : 波浪传感器解析器
  4. """
  5. from tools.format_value import format_value
  6. from logging_config import sm140_converter as logger
  7. import binascii
  8. from converter import Converter
  9. class NEMA0183Converter(Converter):
  10. def __init__(self, name):
  11. self._name = name
  12. def convert(self, config, data):
  13. logger.info(f"[{self._name}]原始接收数据: len: {len(data)}, values: {data}")
  14. data = data.decode().split("\r\n")
  15. logger.info(f"[{self._name}]解码分割: len: {len(data)}, values: {data}")
  16. for i in data:
  17. if self.checksum(i):
  18. res = self.check_type(config, i)
  19. return res
  20. else:
  21. logger.info(f"checksum校验失败:{i}")
  22. return "error"
  23. def make_checksum(self, data):
  24. '''
  25. Calculates a checksum from a NMEA sentence.
  26. Keyword arguments:
  27. data -- the NMEA sentence to create
  28. '''
  29. csum = 0
  30. i = 0
  31. # Remove ! or $ and *xx in the sentence
  32. data = data[1:data.rfind('*')]
  33. while (i < len(data)):
  34. input = binascii.b2a_hex(data[i].encode("utf8"))
  35. input = int(input, 16)
  36. # xor
  37. csum = csum ^ input
  38. i += 1
  39. return csum
  40. def checksum(self, data):
  41. '''
  42. Reads the checksum of an NMEA sentence.
  43. Keyword arguments:
  44. data -- the NMEA sentence to check
  45. '''
  46. try:
  47. # Create an integer of the two characters after the *, to the right
  48. supplied_csum = int(data[data.rfind('*') + 1:data.rfind('*') + 3], 16)
  49. except:
  50. return ''
  51. # Create the checksum
  52. csum = self.make_checksum(data)
  53. # Compare and return
  54. if csum == supplied_csum:
  55. return True
  56. else:
  57. return False
  58. def check_type(self, config, data):
  59. dict = {}
  60. data = data.split('*')
  61. # Splits up the NMEA data by comma
  62. data = data[0].split(',')
  63. logger.info(f"[{self._name}]进一步格式化数据: len: {len(data)}, values: {data}")
  64. if data[0] == '$PMIRWM':
  65. for index in config:
  66. name = 'c' + str(index['serial_number'])
  67. address = int(index['address'])
  68. dict[name] = format_value(index, data[address])
  69. logger.info(f"[{self._name}]解析后数据: len: {len(dict)}, values: {dict}")
  70. return dict
  71. def nmea2utc(self, data):
  72. '''
  73. Converts NMEA utc format to more standardized format.
  74. '''
  75. time = data[1][0:2] + ':' + data[1][2:4] + ':' + data[1][4:6]
  76. date = '20' + data[9][4:6] + '-' + data[9][2:4] + '-' + data[9][0:2]
  77. return date + 'T' + time + 'Z'
  78. '''
  79. data = "$PMIRR,20210325,033351.719,0.000,0.000,V,0.00*0F"
  80. data2 = data.split('*')
  81. data2 = data2[0].split(',')
  82. logger.debug(data2[0][3:6])
  83. c = NEMA0183Converter(None)
  84. d = c.checksum(data)
  85. logger.debug(d)
  86. logger.debug(c.nmea2utc(data2[1]))
  87. '''