def save_spot(dimap, queueitem): msgid, msg = queueitem if 'DATE' in msg: timestamp = time.mktime(email.utils.parsedate(msg["DATE"])) else: LOGGER.info("Can't find date in " + str(msg.__dict__)) dimap.flag(msgid) return try: sbd = { 'ID': msg['X-SPOT-Messenger'], 'LT': float(msg['X-SPOT-Latitude']), 'LG': float(msg['X-SPOT-Longitude']), 'Type': msg['X-SPOT-Type'], 'LOCALTU': msg['X-Spot-Time'], 'TU': timestamp, 'DR': 0, 'AL': 0, 'VL': 0, 'TY': 'spot' } if not lat_long_isvalid(sbd['LT'], sbd['LG']): raise ValueError('Lon/Lat {},{} is not valid.'.format(sbd['LG'], sbd['LT'])) except ValueError as e: LOGGER.error("Couldn't parse {}, error: {}".format(sbd, e)) dimap.flag(msgid) return LoggedPoint.parse_sbd(sbd) dimap.delete(msgid)
def save_mp70(dimap, queueitem): ''' mp70/rv50 device type using comma separated output Sample email content and associated fields: Device_ID, Battery_Voltage, Latitude, Longitude, Speed_km/h, Heading, Time_UTC N681260193011034,12.09,-031.99275,+115.88458,0,0,01/11/2019 06:57:40 ''' msgid, msg = queueitem sbd = {"RAW": msg.get_payload().strip().split(",")} try: sbd["ID"] = sbd["RAW"][0] sbd["LT"] = float(sbd["RAW"][2]) sbd["LG"] = float(sbd["RAW"][3]) if not lat_long_isvalid(sbd['LT'], sbd['LG']): raise ValueError('Lon/Lat {},{} is not valid.'.format(sbd['LG'], sbd['LT'])) sbd["TU"] = time.mktime(datetime.strptime(sbd["RAW"][6], "%m/%d/%Y %H:%M:%S").timetuple()) sbd["VL"] = int(sbd["RAW"][4]) sbd["DR"] = int(sbd["RAW"][5]) sbd["TY"] = 'other' except ValueError as e: LOGGER.error(e) dimap.flag(msgid) return try: LoggedPoint.parse_sbd(sbd) except Exception as e: LOGGER.error(e) dimap.flag(msgid) return dimap.delete(msgid)
def save_dplus(dimap, queueitem): msgid, msg = queueitem sbd = {"RAW": msg.get_payload().strip().split("|")} try: deviceid = sbd["ID"] = int(sbd["RAW"][0]) sbd["LT"] = float(sbd["RAW"][4]) sbd["LG"] = float(sbd["RAW"][5]) if not lat_long_isvalid(sbd['LT'], sbd['LG']): raise ValueError('Lon/Lat {},{} is not valid.'.format(sbd['LG'], sbd['LT'])) sbd["TU"] = time.mktime(datetime.strptime(sbd["RAW"][1], "%d-%m-%y %H:%M:%S").timetuple()) sbd["VL"] = int(sbd["RAW"][6]) * 1000 sbd["DR"] = int(sbd["RAW"][7]) sbd["AL"] = int(sbd["RAW"][9]) sbd["TY"] = 'dplus' except ValueError as e: LOGGER.error(e) dimap.flag(msgid) return try: LoggedPoint.parse_sbd(sbd) except Exception as e: LOGGER.error(e) dimap.flag(msgid) return dimap.delete(msgid)
def save_spot(queueitem): msgid, msg = queueitem if 'DATE' in msg: timestamp = time.mktime(email.utils.parsedate(msg["DATE"])) else: logger.info("Can't find date in " + str(msg.__dict__)) dimap.flag(msgid) return try: sbd = { 'ID': msg['X-SPOT-Messenger'], 'LT': msg['X-SPOT-Latitude'], 'LG': msg['X-SPOT-Longitude'], 'Type': msg['X-SPOT-Type'], 'LOCALTU': msg['X-Spot-Time'], 'TU': timestamp, 'DR': 0, 'AL': 0, 'VL': 0 } except ValueError as e: logger.warning("Couldn't parse {}, error: {}".format(sbd, e)) dimap.flag(msgid) return LoggedPoint.parse_sbd(sbd) dimap.delete(msgid)
def save_iriditrak(dimap, queueitem): msgid, msg = queueitem try: deviceid = int(msg["SUBJECT"].replace('SBD Msg From Unit: ', '')) except ValueError: dimap.flag(msgid) return attachment = None for part in msg.walk(): if part.get_content_maintype() != 'multipart': attachment = part.get_payload(decode=True) # Make sure email is from iridium and has valid timestamp received = filter(lambda val: val.find("(HELO sbd.iridium.com)") > -1, msg.values()) if 'DATE' in msg: timestamp = time.mktime(email.utils.parsedate(msg["DATE"])) elif len(received) == 1: timestamp = time.mktime(email.utils.parsedate(received[0].split(';')[-1].strip())) else: LOGGER.info("Can't find date in " + str(msg.__dict__)) sbd = {'ID': deviceid, 'TU': timestamp, 'TY': 'iriditrak'} # BEAM binary message, 10byte or 20byte if len(attachment) <= 20: try: raw = struct.unpack("<BBBBBBBBBBIHHH"[:len(attachment) + 1], attachment) # Byte 1 Equation byte, use to detect type of message sbd['EQ'] = raw[0] # BEAM 10byte and 20byte binary messages if sbd['EQ'] in [1, 2, 3, 4, 18, 19, 25, 26]: # Byte 2: SSSS:GPS:Lat:Lng:Msd (SSSS = SQ, Msd = Most Significant Digit of Longitude) sbd['SQ'] = int('0' + bin(raw[1])[2:][-8:-4], 2) Lat = int(bin(raw[1])[2:][-3]) * '-' Lng = int(bin(raw[1])[2:][-2]) * '-' LngH = bin(raw[1])[2:][-1] # Byte 3,4 (Latitude HHMM) LatH = str(int('0' + bin(raw[2])[2:][-4:], 2)) + str(int('0' + bin(raw[2])[2:][-8:-4], 2)) LatM = str(int('0' + bin(raw[3])[2:][-4:], 2)) + str(int('0' + bin(raw[3])[2:][-8:-4], 2)) # Byte 5,6 (Latitude .MMMM) LatM += '.' + str(int('0' + bin(raw[4])[2:][-4:], 2)) + str(int('0' + bin(raw[4])[2:][-8:-4], 2)) LatM += str(int('0' + bin(raw[5])[2:][-4:], 2)) + str(int('0' + bin(raw[5])[2:][-8:-4], 2)) sbd['LT'] = float(Lat + str(int(LatH) + float(LatM) / 60)) # Byte 7,8 (Longitude HHMM) LngH += str(int('0' + bin(raw[6])[2:][-4:], 2)) + str(int('0' + bin(raw[6])[2:][-8:-4], 2)) LngM = str(int('0' + bin(raw[7])[2:][-4:], 2)) + str(int('0' + bin(raw[7])[2:][-8:-4], 2)) # Byte 9,10 (Longitude .MMMM) LngM += '.' + str(int('0' + bin(raw[8])[2:][-4:], 2)) + str(int('0' + bin(raw[8])[2:][-8:-4], 2)) LngM += str(int('0' + bin(raw[9])[2:][-4:], 2)) + str(int('0' + bin(raw[9])[2:][-8:-4], 2)) sbd['LG'] = float(Lng + str(int(LngH) + float(LngM) / 60)) if not lat_long_isvalid(sbd['LT'], sbd['LG']): raise ValueError('Lon/Lat {},{} is not valid.'.format(sbd['LG'], sbd['LT'])) if len(raw) == 14: # Byte 11,12,13,14 is unix time, but local to the device?? # use email timestamp because within 10 secs and fairly accurate # might have future issues with delayed retransmits sbd['LOCALTU'] = raw[10] # Byte 15,16 are speed in 10 m/h sbd['VL'] = raw[11] * 10 # Byte 17,18 is altitude in m above sea level sbd['AL'] = raw[12] # Byte 19,20 is direction in degrees sbd['DR'] = raw[13] LOGGER.debug(str(sbd)) else: LOGGER.warning("Don't know how to read " + force_text(sbd['EQ']) + " - " + force_text(raw)) dimap.flag(msgid) return except Exception as e: LOGGER.error(force_text(e)) dimap.flag(msgid) return else: LOGGER.warning("Flagging IridiTrak message {}".format(msgid)) dimap.flag(msgid) return LoggedPoint.parse_sbd(sbd) dimap.delete(msgid)
def save_iriditrak(queueitem): msgid, msg = queueitem try: deviceid = int(msg["SUBJECT"].replace('SBD Msg From Unit: ', '')) except ValueError: dimap.flag(msgid) return attachment = None for part in msg.walk(): if part.get_content_maintype() != 'multipart': attachment = part.get_payload(decode=True) # Make sure email is from iridium and has valid timestamp received = filter(lambda val: val.find("(HELO sbd.iridium.com)") > -1, msg.values()) if 'DATE' in msg: timestamp = time.mktime(email.utils.parsedate(msg["DATE"])) elif len(received) == 1: timestamp = time.mktime(email.utils.parsedate(received[0].split(';')[-1].strip())) else: logger.info("Can't find date in " + str(msg.__dict__)) sbd = {'ID': deviceid, 'TU': timestamp} # Normal BEAM sbdtext message if attachment.find(',') == 0: for field in ['SQ', 'FU', 'DD', 'LT', 'LG', 'TU', 'VL', 'DR', 'AL']: try: sbd[field] = sbdfield(attachment, field) except: pass try: sbd['LOCALTU'] = sbd['FU'] sbd['FU'] = None except: pass # BEAM binary message, 10byte or 20byte elif len(attachment) <= 20: try: raw = struct.unpack("<BBBBBBBBBBIHHH"[:len(attachment)+1], attachment) # Byte 1 Equation byte, use to detect type of message sbd['EQ'] = raw[0] # BEAM 10byte and 20byte binary messages if sbd['EQ'] in [1, 2, 3, 4, 18, 25, 26]: # Byte 2: SSSS:GPS:Lat:Lng:Msd (SSSS = SQ, Msd = Most Significant Digit of Longitude) sbd['SQ'] = int('0'+bin(raw[1])[2:][-8:-4], 2) GPS = int(bin(raw[1])[2:][-4]) Lat = int(bin(raw[1])[2:][-3]) * '-' Lng = int(bin(raw[1])[2:][-2]) * '-' LngH = bin(raw[1])[2:][-1] # Byte 3,4 (Latitude HHMM) LatH = str(int('0'+bin(raw[2])[2:][-4:], 2)) + str(int('0'+bin(raw[2])[2:][-8:-4], 2)) LatM = str(int('0'+bin(raw[3])[2:][-4:], 2)) + str(int('0'+bin(raw[3])[2:][-8:-4], 2)) # Byte 5,6 (Latitude .MMMM) LatM += '.' + str(int('0'+bin(raw[4])[2:][-4:], 2)) + str(int('0'+bin(raw[4])[2:][-8:-4], 2)) LatM += str(int('0'+bin(raw[5])[2:][-4:], 2)) + str(int('0'+bin(raw[5])[2:][-8:-4], 2)) sbd['LT'] = float(Lat + str(int(LatH) + float(LatM) / 60)) # Byte 7,8 (Longitude HHMM) LngH += str(int('0'+bin(raw[6])[2:][-4:], 2)) + str(int('0'+bin(raw[6])[2:][-8:-4], 2)) LngM = str(int('0'+bin(raw[7])[2:][-4:], 2)) + str(int('0'+bin(raw[7])[2:][-8:-4], 2)) # Byte 9,10 (Longitude .MMMM) LngM += '.' + str(int('0'+bin(raw[8])[2:][-4:], 2)) + str(int('0'+bin(raw[8])[2:][-8:-4], 2)) LngM += str(int('0'+bin(raw[9])[2:][-4:], 2)) + str(int('0'+bin(raw[9])[2:][-8:-4], 2)) sbd['LG'] = float(Lng + str(int(LngH) + float(LngM) / 60)) if len(raw) == 14: # Byte 11,12,13,14 is unix time, but local to the device?? # use email timestamp because within 10 secs and fairly accurate # might have future issues with delayed retransmits sbd['LOCALTU'] = raw[10] # Byte 15,16 are speed in 10 m/h sbd['VL'] = raw[11] * 10 # Byte 17,18 is altitude in m above sea level sbd['AL'] = raw[12] # Byte 19,20 is direction in degrees sbd['DR'] = raw[13] logger.debug(str(sbd)) else: logger.warning("Don't know how to read " + force_text(sbd['EQ']) + " - " + force_text(raw)) dimap.flag(msgid) return except Exception as e: logger.warning("error: " + force_text(e)) dimap.flag(msgid) return else: logger.warning("Extra stuff") dimap.flag(msgid) return LoggedPoint.parse_sbd(sbd) dimap.delete(msgid)
def save_dplus(queueitem): msgid, msg = queueitem sbd = {"RAW": msg.get_payload().strip().split("|")} deviceid = sbd["ID"] = int(sbd["RAW"][0]) try: sbd["LT"] = float(sbd["RAW"][4]) sbd["LG"] = float(sbd["RAW"][5]) sbd["TU"] = time.mktime(datetime.strptime(sbd["RAW"][1], "%d-%m-%y %H:%M:%S").timetuple()) sbd["VL"] = int(sbd["RAW"][6]) * 1000 sbd["DR"] = int(sbd["RAW"][7]) sbd["AL"] = int(sbd["RAW"][9]) except ValueError, e: logger.warning(e) dimap.flag(msgid) return LoggedPoint.parse_sbd(sbd) dimap.delete(msgid) def save_spot(queueitem): msgid, msg = queueitem if 'DATE' in msg: timestamp = time.mktime(email.utils.parsedate(msg["DATE"])) else: logger.info("Can't find date in " + str(msg.__dict__)) dimap.flag(msgid) return try: sbd = { 'ID': msg['X-SPOT-Messenger'], 'LT': msg['X-SPOT-Latitude'],