Skip to content

Instantly share code, notes, and snippets.

@Bostonncity
Forked from jhavard/gsm.py
Created December 6, 2015 08:05
Show Gist options
  • Save Bostonncity/f2e9110400d176137938 to your computer and use it in GitHub Desktop.
Save Bostonncity/f2e9110400d176137938 to your computer and use it in GitHub Desktop.
Decoder for WSR-88D General Status Message
import struct
BLOCK_DIVIDER = 10
LENGTH_OF_BLOCK = 11
MODE_OF_OPERATION = 12
VCP = 14
ELEVATION_CUTS = 15
ELEVATION_01 = 16
ELEVATION_02 = 17
ELEVATION_03 = 18
ELEVATION_04 = 19
ELEVATION_05 = 20
ELEVATION_06 = 21
ELEVATION_07 = 22
ELEVATION_08 = 23
ELEVATION_09 = 24
ELEVATION_10 = 25
ELEVATION_11 = 26
ELEVATION_12 = 27
ELEVATION_13 = 28
ELEVATION_14 = 29
ELEVATION_15 = 30
ELEVATION_16 = 31
ELEVATION_17 = 32
ELEVATION_18 = 33
ELEVATION_19 = 34
ELEVATION_20 = 35
RDA_STATUS = 36
RDA_ALARMS = 37
DATA_TRANS_ENABLE = 38
RPG_OP_STATUS = 39
RPG_ALARMS = 40
RPG_STATUS = 41
RPG_NBAND_STATUS = 42
REFL_CALIB_CORR = 43
PRODUCT_AVAILABILITY = 44
SUPER_RES_CUTS = 45
CLUTTER_MITIGATION_DECISION_STATUS = 46
VERT_CHAN_REFL_CALIB_CORR = 47
RDA_BUILD_NUMBER = 48
RDA_CHAN_NUMBER = 49
# RESERVED = 50
# RESERVED = 51
BUILD_VERSION = 52
ELEVATION_21 = 53
ELEVATION_22 = 54
ELEVATION_23 = 55
ELEVATION_24 = 56
ELEVATION_25 = 57
VCP_SUPL_DATA = 58
# 59 .. 100 SPARE
class GSM:
def __init__(self, msg):
self.msg = msg
# if it starts with SOH, it's probably in WMO-ish format
# if it starts with NXUS64, it's in archive format
# otherwise, it's bogus
if msg[0] == '\x01':
self.base = 39
elif msg[0:6] == 'NXUS64':
self.base = 28
else:
raise ValueError
self.block_divider = self._get_unsigned(BLOCK_DIVIDER)
self.length_of_block = self._get_unsigned(LENGTH_OF_BLOCK)
self.mode = self._get_unsigned(MODE_OF_OPERATION)
self.vcp = self._get_unsigned(VCP)
self.cuts = self._get_unsigned(ELEVATION_CUTS)
self.rda_status = self._get_unsigned(RDA_STATUS)
self.rda_alarms = self._get_unsigned(RDA_ALARMS)
self.dt_enab = self._get_unsigned(DATA_TRANS_ENABLE)
self.rpg_op_status = self._get_unsigned(RPG_OP_STATUS)
self.rpg_alarms = self._get_unsigned(RPG_ALARMS)
self.rpg_status = self._get_unsigned(RPG_STATUS)
self.rpg_nband_status = self._get_unsigned(RPG_NBAND_STATUS)
self.refl_calib_corr = self._get_unsigned(REFL_CALIB_CORR)
self.product_availability = self._get_unsigned(PRODUCT_AVAILABILITY)
self.super_res_cuts = self._get_unsigned(SUPER_RES_CUTS)
self.clutter_mds = self._get_unsigned(CLUTTER_MITIGATION_DECISION_STATUS)
self.vcrcc = self._get_unsigned(VERT_CHAN_REFL_CALIB_CORR)
self.rpg_build = self._get_unsigned(RDA_BUILD_NUMBER)
self.rda_chan_num = self._get_unsigned(RDA_CHAN_NUMBER)
self.build_ver = self._get_unsigned(BUILD_VERSION)
self.vcp_supl_data = self._get_unsigned(VCP_SUPL_DATA)
self.elev = self._get_elevations()
def _get_signed(self, element):
return struct.unpack('>h', self.msg[self.base+(element*2):self.base+(element*2)+2])[0]
def _get_unsigned(self, element):
return struct.unpack('>H', self.msg[self.base+(element*2):self.base+(element*2)+2])[0]
def _get_elevation(self, elev):
if elev < 21:
base = 15
else:
base = 53
return self._get_signed(base+elev)
def _get_elevations(self):
return [self._get_elevation(x) for x in range(1,26)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment