def signalStrength(self): """ Checks the modem's cellular network signal strength Override from gsmmodem to change the timeout, as Iridium phones take a while to get the signal strength. :raise CommandError: if an error occurs :return: The network signal strength as an integer between 0 and 99, or -1 if it is unknown :rtype: int """ # Should check CREG first in line with Iridium spec section 5.94 csq = self.CSQ_REGEX.match( self.write('AT+CSQ', waitForResponse=True, timeout=60, parseError=True, writeTerm='\r', expectedResponseTermSeq=None)[0]) if csq: ss = int(csq.group(1)) return ss if ss != 99 else -1 else: raise CommandError("invalid response for AT+CSQ")
def initiateOldSBDSession(self): # +SBDI: 1, 7, 0, 0, 0, 0 #response = ['+SBDI: 1, 7, 0, 0, 0, 0', 'OK'] response = self.write('AT+SBDI', timeout=300) sbdi = self.SBDI_REGEX.match(response[0]) if sbdi: ret = SBDTransferStatus() # Convert to SBDIX-compatible numbers ret.lastOutboundTransferStatus = int(sbdi.group(1)) if int(sbdi.group(1)) < 2: ret.lastOutboundTransferStatus = 0 else: # Error ret.lastOutboundTransferStatus = 5 ret.outboundMSN = int(sbdi.group(2)) ret.lastInboundTransferStatus = int(sbdi.group(3)) ret.inboundMSN = int(sbdi.group(4)) if sbdi.group(1) == "2": # Error ocurrred during outbound transfer ret.outboundMsgPresent = True if sbdi.group(5) != "0": ret.inboundMsgPresent = True ret.inboundMessagesQueuedAtServer = int(sbdi.group(6)) return ret else: raise CommandError()
def writeSBDMessageToIsu(self, msg): response = self.write('AT+SBDWB=' + format(len(msg.data)), expectedResponseTermSeq='READY') ready = self.SBDWB_READY_REGEX.match(response[0]) if ready: messageData = msg.data + msg.generateChecksum #response = self.write(messageData, writeTerm=b'') response = self.write(bytesWrapper(messageData), writeTerm=b'') code = self.SBDWB_RESP_REGEX.match(response[0]) if int(code.group(1)) == 0: ret = self.getSBDStatus msg.sequence = ret.outboundMSN return ret else: raise CommandError() else: raise CommandError()
def readSBDMessageFromIsu(self): ret = self.getSBDStatus # Get the sequence number response = self.write('AT+SBDRB') byteResponse = bytes(response[0], 'iso-8859-1') if len(byteResponse) < 4: raise CommandError() msgLen = int(byteResponse[0]) * 256 msgLen = int(byteResponse[1]) + msgLen if len(byteResponse) != (msgLen + 2 + 2): raise CommandError() binData = byteResponse[2:(len(byteResponse) - 2)] binMsg = SBDBinaryMessage(ret.inboundMSN, binData) #checksum = binMsg.generateChecksum cksum = byteResponse[(len(byteResponse) - 2):len(byteResponse)] if binMsg.validateChecksum(cksum) == False: raise CommandError() return binMsg
def gpsLocation(self): response = self.write('AT+GPSPOS') gpspos = self.GPSPOS_REGEX.match(response[0]) if gpspos: # 00.0000,N,000.0000,E,V lat = int(gpspos.group(1)) + (int(gpspos.group(2)) / 10000) lon = int(gpspos.group(4)) + (int(gpspos.group(5)) / 10000) return [lat, lon] else: raise CommandError()
def systemTime(self, iridiumEra=2): """ Determines the current Iridium network time @raise CommandError: if an error occurs @param iridiumEra: Start of Iridium clock base (0=1996, 1=2007, 2=2014 (default)) @return The current GMT time as reported by the Iridium unit @type datetime.datetime """ response = self.write('AT-MSSTM') msstm = self.MSSTM_REGEX.match(response[0]) if msstm: return self.iridiumToDatetime(msstm.group(1)) else: raise CommandError()
def getSBDStatus(self): # +SBDS: 1, 5, 0, -1 response = self.write('AT+SBDS') sbds = self.SBDS_REGEX.match(response[0]) if sbds: ret = ISUSBDStatus() ret.outboundMSN = int(sbds.group(2)) ret.inboundMSN = int(sbds.group(4)) if sbds.group(1) == "1": ret.outboundMsgPresent = True if sbds.group(3) == "1": ret.inboundMsgPresent = True return ret else: raise CommandError()
def initiateSBDSession(self): # +SBDIX: 0, 8, 0, 0, 0, 0 #response = ['+SBDIX: 0, 8, 0, 0, 0, 0', 'OK'] response = self.write('AT+SBDIX', timeout=300) sbdi = self.SBDIX_REGEX.match(response[0]) if sbdi: ret = SBDTransferStatus() ret.lastOutboundTransferStatus = int(sbdi.group(1)) ret.outboundMSN = int(sbdi.group(2)) ret.lastInboundTransferStatus = int(sbdi.group(3)) ret.inboundMSN = int(sbdi.group(4)) if int(sbdi.group( 1)) > 5: # Error ocurrred during outbound transfer ret.outboundMsgPresent = True if sbdi.group(5) != "0": ret.inboundMsgPresent = True ret.inboundMessagesQueuedAtServer = int(sbdi.group(6)) return ret else: raise CommandError()
def geoLocation(self): response = self.write('AT-MSGEO') msgeo = self.MSGEO_REGEX.match(response[0]) if msgeo: # -MSGEO: 4024,-100,4924,2c781713 # lat 50.73489178019171 lon -1.423558380252216 time 2016-06-26 18:05:30.789999 iridiumX = int(msgeo.group(1)) iridiumY = int(msgeo.group(2)) iridiumZ = int(msgeo.group(3)) # From: Weisstein, Eric W. "Spherical Coordinates." From MathWorld--A Wolfram Web Resource. # http://mathworld.wolfram.com/SphericalCoordinates.html iridiumR = math.sqrt( math.pow(iridiumX, 2) + math.pow(iridiumY, 2) + math.pow(iridiumZ, 2)) # Their phi is actually degrees from the north pole, so we move the base to the equator # by subtracting it from 90. lat = 90 - (math.degrees(math.acos(iridiumZ / iridiumR))) lon = math.degrees(math.atan(iridiumY / iridiumX)) fixTime = self.iridiumToDatetime(msgeo.group(4)) # print('lat '+format(lat)+' lon '+format(lon)+' time '+format(fixTime)) return [lat, lon, fixTime] else: raise CommandError()
def datetimeToIridium(self, dt): """ Converts a datetime object to Iridium network time @raise CommandError: if an error occurs @param dt: datetime.datetime object to convert @return The Iridium time representing the given datetime @type int """ epochSeconds = dt.timestamp() # This is a float epochMilliseconds = epochSeconds * 1000 # Assume era2 (current at time of writing) unless we end up negative iridiumMillis = epochMilliseconds - self._iridiumEraBases[2] if iridiumMillis < 0: iridiumMillis = epochMilliseconds - self._iridiumEraBases[1] if iridiumMillis < 0: iridiumMillis = epochMilliseconds - self._iridiumEraBases[0] if iridiumMillis < 0: # We're in trouble: the time is before the start of the Iridium network! raise CommandError() iridiumTime = int(iridiumMillis / 90) return iridiumTime