ϪfVfdZddlZddlZddlmZddlmZddlmZm Z ddl m Z m Z m Z ddlmZddlmZdd lmZmZGd d e ZGd d e ZGdde ZdZdZGddee j4ZGdde j8Zee j<GddZgdZ y)a Classes for working with NMEA 0183 sentence producing devices. This standard is generally just called "NMEA", which is actually the name of the body that produces the standard, not the standard itself.. For more information, read the blog post on NMEA by ESR (the gpsd maintainer) at U{http://esr.ibiblio.org/?p=801}. Unfortunately, official specifications on NMEA 0183 are only available at a cost. More information can be found on the Wikipedia page: U{https://en.wikipedia.org/wiki/NMEA_0183}. The official standard may be obtained through the NMEA's website: U{http://www.nmea.org/content/nmea_standards/nmea_0183_v_410.asp}. @since: 14.0 N)reduce) implementer) ValueConstantValues) _sentencebase ipositioning)Angles) LineReceiver) iterbytes nativeStringc4eZdZdZdZdZdZdZdZdZ dZ d Z d Z y ) GPGGAFixQualitiesav The possible fix quality indications for GPGGA sentences. @cvar INVALID_FIX: The fix is invalid. @cvar GPS_FIX: There is a fix, acquired using GPS. @cvar DGPS_FIX: There is a fix, acquired using differential GPS (DGPS). @cvar PPS_FIX: There is a fix, acquired using the precise positioning service (PPS). @cvar RTK_FIX: There is a fix, acquired using fixed real-time kinematics. This means that there was a sufficient number of shared satellites with the base station, usually yielding a resolution in the centimeter range. This was added in NMEA 0183 version 3.0. This is also called Carrier-Phase Enhancement or CPGPS, particularly when used in combination with GPS. @cvar FLOAT_RTK_FIX: There is a fix, acquired using floating real-time kinematics. The same comments apply as for a fixed real-time kinematics fix, except that there were insufficient shared satellites to acquire it, so instead you got a slightly less good floating fix. Typical resolution in the decimeter range. @cvar DEAD_RECKONING: There is currently no more fix, but this data was computed using a previous fix and some information about motion (either from that fix or from other sources) using simple dead reckoning. Not particularly reliable, but better-than-nonsense data. @cvar MANUAL: There is no real fix from this device, but the location has been manually entered, presumably with data obtained from some other positioning method. @cvar SIMULATED: There is no real fix, but instead it is being simulated. 012345678N) __name__ __module__ __qualname____doc__ INVALID_FIXGPS_FIXDGPS_FIXPPS_FIXRTK_FIX FLOAT_RTK_FIXDEAD_RECKONINGMANUAL SIMULATED:/usr/lib/python3/dist-packages/twisted/positioning/nmea.pyrr%s6:KGHGGMN FIr'rc0eZdZdZedZedZy)GPGLLGPRMCFixQualitiesa The possible fix quality indications in GPGLL and GPRMC sentences. Unfortunately, these sentences only indicate whether data is good or void. They provide no other information, such as what went wrong if the data is void, or how good the data is if the data is not void. @cvar ACTIVE: The data is okay. @cvar VOID: The data is void, and should not be used. AVN)rrrrrACTIVEVOIDr&r'r(r*r*Ns 3 F  Dr'r*c@eZdZdZedZedZedZy) GPGSAFixTypesa  The possible fix types of a GPGSA sentence. @cvar GSA_NO_FIX: The sentence reports no fix at all. @cvar GSA_2D_FIX: The sentence reports a 2D fix: position but no altitude. @cvar GSA_3D_FIX: The sentence reports a 3D fix: position with altitude. rrrN)rrrrr GSA_NO_FIX GSA_2D_FIX GSA_3D_FIXr&r'r(r0r0^s's#Js#Js#Jr'r0c|dddk(r|ddjdS|dddk(r|ddjdStjd|) z Returns the split version of an NMEA sentence, minus header and checksum. >>> _split(b"$GPGGA,spam,eggs*00") [b'GPGGA', b'spam', b'eggs'] @param sentence: The NMEA sentence to split. @type sentence: C{bytes} *,Nzmalformed sentence )splitrInvalidSentence)sentences r(_splitr>lsg2$"~##D)) "#$ "~##D))""%8 #CDDr'c |dddk(rpt|ddd|dd}}ttjt |Dcgc] }t |c}}||k7rt j|dd|dyycc}w) a7 Validates the checksum of an NMEA sentence. @param sentence: The NMEA sentence to check the checksum of. @type sentence: C{bytes} @raise ValueError: If the sentence has an invalid checksum. Simply returns on sentences that either don't have a checksum, or have a valid checksum. r5r6r7Nr802xz != )introperatorxorr ordrInvalidChecksum)r= referencesourcexcomputeds r(_validateChecksumrKs2$ r2HQrN6 (,,69J(KAQ(KL y &&(3tIc?'KL L !(KsA: cLeZdZdZd dZdZgdgdgdgdd ggd gd d Zy) NMEAProtocola A protocol that parses and verifies the checksum of an NMEA sentence (in string form, not L{NMEASentence}), and delegates to a receiver. It receives lines and verifies these lines are NMEA sentences. If they are, verifies their checksum and unpacks them into their components. It then wraps them in L{NMEASentence} objects and calls the appropriate receiver method with them. @cvar _SENTENCE_CONTENTS: Has the field names in an NMEA sentence for each sentence type (in order, obviously). @type _SENTENCE_CONTENTS: C{dict} of bytestrings to C{list}s of C{str} @param receiver: A receiver for NMEAProtocol sentence objects. @type receiver: L{INMEAReceiver} @param sentenceCallback: A function that will be called with a new L{NMEASentence} when it is created. Useful for massaging data from particularly misbehaving NMEA receivers. @type sentenceCallback: unary callable Nc ||_||_y)a Initializes an NMEAProtocol. @param receiver: A receiver for NMEAProtocol sentence objects. @type receiver: L{INMEAReceiver} @param sentenceCallback: A function that will be called with a new L{NMEASentence} when it is created. Useful for massaging data from particularly misbehaving NMEA receivers. @type sentenceCallback: unary callable N) _receiver_sentenceCallback)selfreceiversentenceCallbacks r(__init__zNMEAProtocol.__init__s"!1r'c|j}t|t|}t|d}|ddDcgc] }t|}} |j|}d|i}t||D]\} } |  | dk7s| || <t|}|j|j||jj|ycc}w#t $rt d|zwxYw)z Parses the data from the sentence and validates the checksum. @param rawSentence: The NMEA positioning sentence. @type rawSentence: C{bytes} rr8Nzunknown sentence type %stype) striprKr>r _SENTENCE_CONTENTSKeyError ValueErrorzip NMEASentencerPrOsentenceReceived) rQ rawSentencer= splitSentence sentenceTyperIcontentskeys sentenceDatakeyvalues r( lineReceivedzNMEAProtocol.lineReceiveds$$&(#x( #M!$45 -:12->?LO?? H**<8D - dH- *JC5B;$) S! * -  ! ! -  " "8 , ''1#@ H7,FG G HsC CC') timestamp latitudeFloatlatitudeHemispherelongitudeFloatlongitudeHemisphere fixQualitynumberOfSatellitesSeenhorizontalDilutionOfPrecisionaltitude altitudeUnitsheightOfGeoidAboveWGS84heightOfGeoidAboveWGS84UnitsNN) rhdataModerirjrkrl speedInKnots trueHeading datestampmagneticVariationmagneticVariationDirection)numberOfGSVSentencesGSVSentenceIndexrnsatellitePRN_0 elevation_0 azimuth_0signalToNoiseRatio_0satellitePRN_1 elevation_1 azimuth_1signalToNoiseRatio_1satellitePRN_2 elevation_2 azimuth_2signalToNoiseRatio_2satellitePRN_3 elevation_3 azimuth_3signalToNoiseRatio_3)rirjrkrlrhrtrv) rwrhrirjrkrl elevationnumberOfIterationsnumberOfDopplerIntervalsupdateDistanceInNauticalMiles satellitePRN)rtfixTypeusedSatellitePRN_0usedSatellitePRN_1usedSatellitePRN_2usedSatellitePRN_3usedSatellitePRN_4usedSatellitePRN_5usedSatellitePRN_6usedSatellitePRN_7usedSatellitePRN_8usedSatellitePRN_9usedSatellitePRN_10usedSatellitePRN_11positionDilutionOfPrecisionroverticalDilutionOfPrecision)GPGGAGPRMCGPGSVGPGLLGPHDTGPTRFGPGSAN)rrrrrTrgrYr&r'r(rMrMsD( 22B "   *      Y_r'rMc<eZdZdZej ZdZdZy)r]a An object representing an NMEA sentence. The attributes of this objects are raw NMEA protocol data, which are all ASCII bytestrings. This object contains all the raw NMEA protocol data in a single sentence. Not all of these necessarily have to be present in the sentence. Missing attributes are L{None} when accessed. @ivar type: The sentence type (C{"GPGGA"}, C{"GPGSV"}...). @ivar numberOfGSVSentences: The total number of GSV sentences in a sequence. @ivar GSVSentenceIndex: The index of this GSV sentence in the GSV sequence. @ivar timestamp: A timestamp. (C{"123456"} -> 12:34:56Z) @ivar datestamp: A datestamp. (C{"230394"} -> 23 Mar 1994) @ivar latitudeFloat: Latitude value. (for example: C{"1234.567"} -> 12 degrees, 34.567 minutes). @ivar latitudeHemisphere: Latitudinal hemisphere (C{"N"} or C{"S"}). @ivar longitudeFloat: Longitude value. See C{latitudeFloat} for an example. @ivar longitudeHemisphere: Longitudinal hemisphere (C{"E"} or C{"W"}). @ivar altitude: The altitude above mean sea level. @ivar altitudeUnits: Units in which altitude is expressed. (Always C{"M"} for meters.) @ivar heightOfGeoidAboveWGS84: The local height of the geoid above the WGS84 ellipsoid model. @ivar heightOfGeoidAboveWGS84Units: The units in which the height above the geoid is expressed. (Always C{"M"} for meters.) @ivar trueHeading: The true heading. @ivar magneticVariation: The magnetic variation. @ivar magneticVariationDirection: The direction of the magnetic variation. One of C{"E"} or C{"W"}. @ivar speedInKnots: The ground speed, expressed in knots. @ivar fixQuality: The quality of the fix. @type fixQuality: One of L{GPGGAFixQualities}. @ivar dataMode: Signals if the data is usable or not. @type dataMode: One of L{GPGLLGPRMCFixQualities}. @ivar numberOfSatellitesSeen: The number of satellites seen by the receiver. @ivar numberOfSatellitesUsed: The number of satellites used in computing the fix. @ivar horizontalDilutionOfPrecision: The dilution of the precision of the position on a plane tangential to the geoid. (HDOP) @ivar verticalDilutionOfPrecision: As C{horizontalDilutionOfPrecision}, but for a position on a plane perpendicular to the geoid. (VDOP) @ivar positionDilutionOfPrecision: Euclidean norm of HDOP and VDOP. @ivar satellitePRN: The unique identifcation number of a particular satellite. Optionally suffixed with C{_N} if multiple satellites are referenced in a sentence, where C{N in range(4)}. @ivar elevation: The elevation of a satellite in decimal degrees. Optionally suffixed with C{_N}, as with C{satellitePRN}. @ivar azimuth: The azimuth of a satellite in decimal degrees. Optionally suffixed with C{_N}, as with C{satellitePRN}. @ivar signalToNoiseRatio: The SNR of a satellite signal, in decibels. Optionally suffixed with C{_N}, as with C{satellitePRN}. @ivar usedSatellitePRN_N: Where C{int(N) in range(12)}. The PRN of a satellite used in computing the fix. c |jdk(S)z Tests if this current GSV sentence is the first one in a sequence. @return: C{True} if this is the first GSV sentence. @rtype: C{bool} r)r{rQs r(_isFirstGSVSentencez NMEASentence._isFirstGSVSentencews$$++r'c4|j|jk(S)z Tests if this current GSV sentence is the final one in a sequence. @return: C{True} if this is the last GSV sentence. @rtype: C{bool} )r{rzrs r(_isLastGSVSentencezNMEASentence._isLastGSVSentences$$(A(AAAr'N) rrrrrMgetSentenceAttributesALLOWED_ATTRIBUTESrrr&r'r(r]r]7s$;z&;;=,Br'r]ceZdZdZdZdZdZdZdZdLdZ d Z d Z d e jd efd e jd dfde jdefde jdefde jdefdZdZedgZdddZdMdZdZdZeedZdZiddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAiZdBZdCZdDZdEZdFZdGZ dHZ!dIZ"dJZ#dKZ$y)N NMEAAdaptera An adapter from NMEAProtocol receivers to positioning receivers. @cvar _STATEFUL_UPDATE: Information on how to update partial information in the sentence data or internal adapter state. For more information, see C{_statefulUpdate}'s docstring. @type _STATEFUL_UPDATE: See C{_statefulUpdate}'s docstring @cvar _ACCEPTABLE_UNITS: A set of NMEA notations of units that are already acceptable (metric), and therefore don't need to be converted. @type _ACCEPTABLE_UNITS: C{frozenset} of bytestrings @cvar _UNIT_CONVERTERS: Mapping of NMEA notations of units that are not acceptable (not metric) to converters that take a quantity in that unit and produce a metric quantity. @type _UNIT_CONVERTERS: C{dict} of bytestrings to unary callables @cvar _SPECIFIC_SENTENCE_FIXES: A mapping of sentece types to specific fixes that are required to extract useful information from data from those sentences. @type _SPECIFIC_SENTENCE_FIXES: C{dict} of sentence types to callables that take self and modify it in-place @cvar _FIXERS: Set of unary callables that take an NMEAAdapter instance and extract useful data from the sentence data, usually modifying the adapter's sentence data in-place. @type _FIXERS: C{dict} of native strings to unary callables @ivar yearThreshold: The earliest possible year that data will be interpreted as. For example, if this value is C{1990}, an NMEA 0183 two-digit year of "96" will be interpreted as 1996, and a two-digit year of "13" will be interpreted as 2013. @type yearThreshold: L{int} @ivar _state: The current internal state of the receiver. @type _state: C{dict} @ivar _sentenceData: The data present in the sentence currently being processed. Starts empty, is filled as the sentence is parsed. @type _sentenceData: C{dict} @ivar _receiver: The positioning receiver that will receive parsed data. @type _receiver: L{ipositioning.IPositioningReceiver} c.i|_i|_||_y)z Initializes a new NMEA adapter. @param receiver: The receiver for positioning sentences. @type receiver: L{ipositioning.IPositioningReceiver} N)_state _sentenceDatarO)rQrRs r(rTzNMEAAdapter.__init__s !r'c|jjjdd}tjj |dj }||j d<y)z Turns the NMEAProtocol timestamp notation into a datetime.time object. The time in this object is expressed as Zulu time. .rz%H%M%S_timeN)currentSentencerhr;datetimestrptimetimer)rQrh timeObjects r( _fixTimestampzNMEAAdapter._fixTimestampsV ((2288=a@ &&// 8DIIK &07#r'ic|jj}tt|dd|dd|ddg\}}}||j|jdzz z }||jkr|dz }t j ||||jd<y)z Turns an NMEA datestamp format into a C{datetime.date} object. @raise ValueError: When the day or month value was invalid, e.g. 32nd day, or 13th month, or 0th day or month. rd_dateN)rrwmaprB yearThresholdrdater)rQrdaymonthyears r( _fixDatestampzNMEAAdapter._fixDatestamps##--sT!AYQq 4!9$EFUD ""d&8&83&>?? $$$ $ CKD&.mmD%&E7#r'c(|tjurd}nd}t|j|dz}|j d\}}t |ddt |ddd|}}||dz z}tj||} | |j|<y)z Turns the NMEAProtocol coordinate format into Python float. @param coordinateType: The coordinate type. @type coordinateType: One of L{Angles.LATITUDE} or L{Angles.LONGITUDE}. latitude longitudeFloatrNr6<) r LATITUDEgetattrrr;rBfloatr Coordinater) rQcoordinateTypecoordinateNamenmeaCoordinateleftrightdegreesminutesangle coordinates r(_fixCoordinateFloatzNMEAAdapter._fixCoordinateFloats V__ ,'N(N !5!5~7OP$**3/ etCRy>5DI;aw1G+H'B,&__UN; -7>*r'Ncn|xs|}|j|}|j|j|y)a Fixes the sign for a hemisphere. This method must be called after the magnitude for the thing it determines the sign of has been set. This is done by the following functions: - C{self.FIXERS['magneticVariation']} - C{self.FIXERS['latitudeFloat']} - C{self.FIXERS['longitudeFloat']} @param coordinateType: Coordinate type. One of L{Angles.LATITUDE}, L{Angles.LONGITUDE} or L{Angles.VARIATION}. @param sentenceDataKey: The key name of the hemisphere sign being fixed in the sentence data. If unspecified, C{coordinateType} is used. @type sentenceDataKey: C{str} (unless L{None}) N)_getHemisphereSignrsetSign)rQrsentenceDataKeysigns r(_fixHemisphereSignzNMEAAdapter._fixHemisphereSigns7&*;^&&~6 ?+33D9r'c|tjurd}n8|tjurd}n#|tjurd}nt d|t |j |j}|dvry|dvryt d |) aS Returns the hemisphere sign for a given coordinate type. @param coordinateType: The coordinate type to find the hemisphere for. @type coordinateType: L{Angles.LATITUDE}, L{Angles.LONGITUDE} or L{Angles.VARIATION}. @return: The sign of that hemisphere (-1 or 1). @rtype: C{int} rjrlryzunknown coordinate type NEr8SWr:zbad hemisphere/direction: )r r LONGITUDE VARIATIONr[rrupper)rQr hemisphereKey hemispheres r(rzNMEAAdapter._getHemisphereSigns V__ ,0M v// /1M v// /8M77GHI IT11=AGGI   4 9*FG Gr'cZt|j|}|||j|<y)a A simple conversion fix. @param key: The attribute name of the value to fix. @type key: native string (Python identifier) @param converter: The function that converts the value. @type converter: unary callable N)rrr)rQre converter currentValues r(_convertzNMEAAdapter._converts+t33S9 "+L"93r'heading_angle variationc\tjt|tjSr)rAnglerr r)rs r(zNMEAAdapter.2s$**U5\63C3CDr' positionErrorhdopvdoppdop)rvrxrorrc4|j|\}}}}||jvr |j||j|<|t |j |}t |j|||y#t$r||j|<YVwxYw)a Does a stateful update of a particular positioning attribute. Specifically, this will mutate an object in the current sentence data. Using the C{sentenceKey}, this will get a tuple containing, in order, the key name in the current state and sentence data, a factory for new values, the attribute to update, and a converter from sentence data (in NMEA notation) to something useful. If the sentence data doesn't have this data yet, it is grabbed from the state. If that doesn't have anything useful yet either, the factory is called to produce a new, empty object. Either way, the object ends up in the sentence data. @param sentenceKey: The name of the key in the sentence attributes, C{NMEAAdapter._STATEFUL_UPDATE} dictionary and the adapter state. @type sentenceKey: C{str} N)_STATEFUL_UPDATErrrZrrsetattr)rQ sentenceKeyrefactoryattrrnewValues r(_statefulUpdatezNMEAAdapter._statefulUpdateHs&)-(=(=k(J%WdI d(( ( 4*.++c*:""3'WT%9%9;GH""3'x8  4*1)""3' 4sA77BBMc`tjt|tjzSr)rSpeedr MPS_PER_KNOT)inKnotss r(rzNMEAAdapter.hsTZZg9J9J(JKr'c`tjt|tjzSr)rrr MPS_PER_KPH)inKPHs r(rzNMEAAdapter.is4::eElT5E5E&EFr')NKc|t|j|}|$||jdr|dd}n td||}||jvr;|j |}t|j|}|||j |<yy)a Fixes the units of a certain value. If the units are already acceptable (metric), does nothing. None of the keys are allowed to be the empty string. @param unit: The unit that is being converted I{from}. If unspecified or L{None}, asks the current sentence for the C{unitKey}. If that also fails, raises C{AttributeError}. @type unit: C{str} @param unitKey: The name of the key/attribute under which the unit can be found in the current sentence. If the C{unit} parameter is set, this parameter is not used. @type unitKey: C{str} @param sourceKey: The name of the key/attribute that contains the current value to be converted (expressed in units as defined according to the C{unit} parameter). If unset, will use the same key as the value key. @type sourceKey: C{str} @param valueKey: The key name in which the data will be stored in the C{_sentenceData} instance attribute. If unset, attempts to remove "Units" from the end of the C{unitKey} parameter. If that fails, raises C{ValueError}. @type valueKey: C{str} NUnitsz,valueKey unspecified and couldn't be guessed)rrendswithr[_ACCEPTABLE_UNITS_UNIT_CONVERTERSr)rQunitKeyvalueKey sourceKeyunitrrs r( _fixUnitszNMEAAdapter._fixUnitsls4 <4//9D  "w'7'7'@"3B< !OPP   I t-- ---d3I"4#7#7CL+4\+BD  x ( .r'ctj}|jd<d}tdD]Sfdfd|DD\}}}}||!tj||||}|j j |Uy)zS Parses partial visible satellite information from a GSV sentence. _partialBeaconInformation)razimuthrsignalToNoiseRatiorc3JK|]}tj|ywr)rr).0rrQs r( z&NMEAAdapter._fixGSV..s&,,,d3,s #c3,K|] }d|fz yw)z%s_%iNr&)rreindexs r(rz&NMEAAdapter._fixGSV..sDWU|3DsN)rBeaconInformationrrange Satellite seenBeaconsadd) rQbeaconInformationrcprnrrsnr satelliters ` @r(_fixGSVzNMEAAdapter._fixGSVs !224:K67K1X 9E,DtD, (C)S {ck sGYDI  ) ) - -i 8 9r'ct|jd<dtdDD]C}t|j|d}||jdj t |Ey)aQ Extracts the information regarding which satellites were used in obtaining the GPS fix from a GSA sentence. Precondition: A GSA sentence was fired. Postcondition: The current sentence data (C{self._sentenceData} will contain a set of the currently used PRNs (under the key C{_usedPRNs}. _usedPRNsc3(K|] }d|fz yw)zusedSatellitePRN_%dNr&)rrIs r(rz&NMEAAdapter._fixGSA..sDQ)QD0Ds N)setrr!rrr$rB)rQrer&s r(_fixGSAzNMEAAdapter._fixGSAsd+.%;'D%)D >C$..T:C"";/33CH= >r')rrcx|jj|jj}| ||yy)zA Executes a fix for a specific type of sentence. N)_SPECIFIC_SENTENCE_FIXESgetrrV)rQfixers r(_sentenceSpecificFixz NMEAAdapter._sentenceSpecificFixs8--11$2F2F2K2KL   $K r'rVc"|jSr)r4rs r(rzNMEAAdapter.sT668r'rhc"|jSr)rrs r(rzNMEAAdapter.$"4"4"6r'rwc"|jSr)rrs r(rzNMEAAdapter.r7r'ric@|jtjSr)rr rrs r(rzNMEAAdapter.sd&>&>v&Or'rjcB|jtjdS)Nr)rr rrs r(rzNMEAAdapter.s4+B+B OOZ, r'rkc@|jtjSr)rr rrs r(rzNMEAAdapter.st'?'?@P@P'Qr'rlcB|jtjdS)Nr)rr rrs r(rzNMEAAdapter.sD,C,C   k- r'rpc*|jddS)Nrpc>tjt|SrrAltituderstrReprs r(rz&NMEAAdapter...s$--g2Or'rrrs r(rzNMEAAdapter.s "O"/" r'rqc&|jdS)Nrqrrrs r(rzNMEAAdapter.sdnn_n&Mr'rrc*|jddS)Nrrc>tjt|Srr?rAs r(rz&NMEAAdapter...sdmmE'N&Cr'rCrDrs r(rzNMEAAdapter.s %C1>1 r'rsc&|jdS)NrsrFrGrs r(rzNMEAAdapter.sT^^26D6 r'rvc$|jdS)Nrvrrs r(rzNMEAAdapter.sD$8$8$Gr'rxc$|jdS)NrxrLrs r(rzNMEAAdapter.s$*>*>?R*Sr'rycB|jtjdS)Nr)rr rrs r(rzNMEAAdapter.s43J3J   i4 r'ruc*|jdddS)Nspeedrur )rrrrGrs r(rzNMEAAdapter.sT^^S&4& r'rc$|jdS)NrrLrs r(rzNMEAAdapter.D4H4H )5 r'roc$|jdS)NrorLrs r(rzNMEAAdapter.sd6J6J +7 r'rc$|jdS)NrrLrs r(rzNMEAAdapter.rRr'c i|_i|_y)zp Resets this adapter. This will empty the adapter state and the current sentence data. N)rrrs r(clearzNMEAAdapter.clears  r'c||_i|_ |j|j|j|jy#tj $r|j YFwxYw)aj Called when a sentence is received. Will clean the received NMEAProtocol sentence up, and then update the adapter's state, followed by firing the callbacks. If the received sentence was invalid, the state will be cleared. @param sentence: The sentence that is received. @type sentence: L{NMEASentence} N) rr_validateCurrentSentence_cleanCurrentSentencerr<rV _updateState_fireSentenceCallbacks)rQr=s r(r^zNMEAAdapter.sentenceReceivedsk (   ) ) +  & & (  ##% ##  JJL s A#A76A7c|jjtjusL|jjt j us&|jjtjurtjdy)z; Tests if a sentence contains a valid fix. z bad sentenceN) rrmrrrtr*r.rr0r1rr<rs r(rXz$NMEAAdapter._validateCurrentSentencesk  + +/@/L/L L##,,0F0K0KK##++}/G/GG&&~6 6Hr'ct|jjD])}|jj |d}|"||+y)z. Cleans the current sentence. N)sortedrpresentAttributes_FIXERSr2)rQrer3s r(rYz!NMEAAdapter._cleanCurrentSentence"sG$..@@A CLL$$S$/E d  r'c|j|j|jj|jy)zW Updates the current state with the new information from the sentence. N)_updateBeaconInformation_combineDateAndTimerupdaterrs r(rZzNMEAAdapter._updateState,s4 %%'   " 4--.r'c\|jjd}|y|j||j||jj rR|jj s |jd=|jjd}||jd<yy)zJ Updates existing beacon information state with new data. rNr%) rr2_updateUsedBeacons_mergeBeaconInformationrrrrpop)rQnewbis r(rbz$NMEAAdapter._updateBeaconInformation4s  $$%@A ;  $ $$S)    2 2 4'';;=KK ;<##''(CDB68D  2 3 5r'c|j|jfD]}|jd}|ny|jD],}|j|vs|j j |.y)a Searches the adapter state and sentence data for information about which beacons where used, then adds it to the provided beacon information object. If no new beacon usage information is available, does nothing. @param beaconInformation: The beacon information object that beacon usage information will be added to (if necessary). @type beaconInformation: L{twisted.positioning.base.BeaconInformation} r+N)rrr2r# identifier usedBeaconsr$)rQr%rHusedPRNsbeacons r(rfzNMEAAdapter._updateUsedBeaconsFsu{{D$6$67 Fzz+.H#  '33 :F  H,!--11&9 :r'c|jjd}|ydD]'}t||jt||)y)a Merges beacon information in the adapter state (if it exists) into the provided beacon information. Specifically, this merges used and seen beacons. If the adapter state has no beacon information, does nothing. @param newBeaconInformation: The beacon information object that beacon information will be merged into (if necessary). @type newBeaconInformation: L{twisted.positioning.base.BeaconInformation} rN)r#rm)rr2rrd)rQnewBeaconInformationoldrs r(rgz#NMEAAdapter._mergeBeaconInformation]sMkkoo9: ; 2 KD ($ / 6 6wsD7I J Kr'ctfddDsyfddD\}}||ytjj||}|jd<y)z Combines a C{datetime.date} object and a C{datetime.time} object, collected from one or more NMEA sentences, into a single C{datetime.datetime} object suitable for sending to the L{IPositioningReceiver}. c3:K|]}|jvywr)r)rkrQs r(rz2NMEAAdapter._combineDateAndTime..wsGq1***Gs)rrNc3K|]<}jj|xsjj|>ywr)rr2r)rrerQs r(rz2NMEAAdapter._combineDateAndTime..|s?     " "3 ' ?4;;??3+? ? sAAr)anyrcombiner)rQrrdts` r(rczNMEAAdapter._combineDateAndTimepsbG4FGG  ) d <4<     & &tT 2%'6"r'c&tj}|jD]_\}}t|j|}i}d} |j D]$}||j vrd}|j|||<& |sX|di|ay#t$rYnwxYw)a< Fires sentence callbacks for the current sentence. A callback will only fire if all of the keys it requires are present in the current state and at least one such field was altered in the current sentence. The callbacks will only be fired with data from L{_state}. FTNr&) r IPositioningReceivernamesAndDescriptionsrrO positionalrrrZ)rQifacenamemethodcallbackkwargsatLeastOnePresentInSentencefields r(r[z"NMEAAdapter._fireSentenceCallbackss11!668 #LD&t~~t4HF*/ ' #..7E 2 226:3$(KK$6F5M7+"6" #  s3B BBr)NNNN)%rrrrrTrrrrrrrrHeadingr PositionErrorrr frozensetrrrr)r/r1r4r`rVr^rXrYrZrbrfrgrcr[r&r'r(rrs/#J "1MF 8(:.H8 :"4<<5A  LL  D         *        (        ( +:9<"3%( K F 'CR96 >   (8(6( 6( O (  ( Q(  (  ( M( "$ !(( ') )(. G/(0 S1(2 %' 3(8  9(> &( ?(D (* E(J &( K(GT &0 7/9$:.K&(.#r'r)rMr]r)!rrrC functoolsrzope.interfacer constantlyrrtwisted.positioningrrr twisted.positioning.baser twisted.protocols.basicr twisted.python.compatr r rr*r0r>rK!_PositioningSentenceProducerMixinrM _BaseSentencer] INMEAReceiverr__all__r&r'r(rs&&,==+09&&R V  $F $E&M&b<!L!LbJPB9**PBf \ ' '(V#V#)V#r :r'