11"""
22uni_handler.py
33
4- WORK IN PROGRESS - AWAITING PARSER DEVELOPMENT
5-
64Unicore GNSS Protocol handler - handles all incoming UNI messages
75
86Parses individual UNI (Unicore UM98n GNSS) messages (using pyunignss library)
1816"""
1917
2018import logging
19+ from time import time
20+
21+ from pyunigps import UNIMessage
22+
23+ from pygpsclient .helpers import fix2desc , wnotow2date
24+
25+ SATSINFO_GNSSID = {
26+ 0 : 0 , # GPS
27+ 1 : 6 , # GLONASS
28+ 2 : 1 , # SBAS
29+ 3 : 2 , # GAL
30+ 4 : 3 , # BDS
31+ 5 : 5 , # QZSS
32+ 6 : 7 , # IRNSS
33+ }
34+
35+ SATELLITE_GNSSID = {
36+ 0 : 0 , # GPS
37+ 1 : 6 , # GLONASS
38+ 2 : 1 , # SBAS
39+ 5 : 2 , # GALILEO
40+ 6 : 3 , # BEIDOU
41+ 7 : 5 , # QZSS
42+ 9 : 7 , # NAVIC
43+ }
2144
2245
2346class UNIHandler :
@@ -40,7 +63,7 @@ def __init__(self, app):
4063 self ._parsed_data = None
4164
4265 # pylint: disable=unused-argument
43- def process_data (self , raw_data : bytes , parsed_data : object ):
66+ def process_data (self , raw_data : bytes , parsed_data : UNIMessage ):
4467 """
4568 Process relevant UNI message types
4669
@@ -49,5 +72,169 @@ def process_data(self, raw_data: bytes, parsed_data: object):
4972 """
5073
5174 if raw_data is None :
52- pass
75+ return
5376 # self.logger.debug(f"data received {parsed_data.identity}")
77+ self .__app .gnss_status .utc = wnotow2date (
78+ parsed_data .wno , int (parsed_data .tow / 1000 ), parsed_data .leapsecond
79+ ) # datetime.time
80+ if parsed_data .identity in ("BESTNAV" , "BESTNAVH" ):
81+ self ._process_BESTNAV (parsed_data )
82+ elif parsed_data .identity in ("PVTSLT" ,):
83+ self ._process_PVTSLT (parsed_data )
84+ elif parsed_data .identity in (
85+ "ADRNAV" ,
86+ "ADRNAVH" ,
87+ "PPPNAV" ,
88+ "SPPNAV" ,
89+ "SPPNAVH" ,
90+ ):
91+ self ._process_ADRNAV (parsed_data )
92+ elif parsed_data .identity in ("SATSINFO" ,):
93+ self ._process_SATSINFO (parsed_data )
94+ elif parsed_data .identity in ("SATELLITE" ,):
95+ self ._process_SATELLITE (parsed_data )
96+ elif parsed_data .identity in ("STADOP" , "ADRDOP" , "PPPDOP" ):
97+ self ._process_STADOP (parsed_data )
98+
99+ def _process_pos (self , lat : float , lon : float , hmsl : float , undulation : float ):
100+ """
101+ Process lat/lon/hmsl/hae.
102+
103+ :param float lat: lat
104+ :param float lon: lon
105+ :param float hmsl: hmsl in meters
106+ :param float undulation: separation in meters
107+ """
108+
109+ self .__app .gnss_status .lat = lat
110+ self .__app .gnss_status .lon = lon
111+ self .__app .gnss_status .alt = hmsl
112+ self .__app .gnss_status .hae = hmsl + undulation
113+
114+ def _process_fix (self , postype : int ):
115+ """
116+ Process fix type.
117+
118+ :param int postype: attribute representing fix type
119+ """
120+
121+ self .__app .gnss_status .fix = fix2desc ("BESTNAV" , postype )
122+ self .__app .gnss_status .diff_corr = ("RTK" in self .__app .gnss_status .fix ) or (
123+ "PPP" in self .__app .gnss_status .fix
124+ )
125+
126+ def _process_BESTNAV (self , data : UNIMessage ):
127+ """
128+ Process BESTNAV sentence - Navigation position velocity time solution.
129+
130+ :param UNIMessage data: BESTNAV parsed message
131+ """
132+
133+ self ._process_pos (data .lat , data .lon , data .hmsl , data .undulation )
134+ self ._process_fix (data .postype )
135+ self .__app .gnss_status .sip = data .numsolnsvs
136+ self .__app .gnss_status .diff_age = data .diffage
137+ self .__app .gnss_status .speed = data .horspd
138+ self .__app .gnss_status .track = data .trkgnd
139+ self .__app .gnss_status .diff_station = data .stationid
140+
141+ def _process_PVTSLT (self , data : UNIMessage ):
142+ """
143+ Process PVTSLT sentence - Navigation position velocity time solution.
144+
145+ :param UNIMessage data: PVTSLT parsed message
146+ """
147+
148+ self ._process_pos (
149+ data .psrposlat , data .psrposlon , data .psrposhmsl , data .undulation
150+ )
151+ self ._process_fix (data .psrpostype )
152+ self .__app .gnss_status .sip = data .psrpossolnsvs
153+ self .__app .gnss_status .speed = data .psrvelground
154+ self .__app .gnss_status .track = data .headingdegree
155+ self .__app .gnss_status .pdop = data .pdop
156+ self .__app .gnss_status .hdop = data .hdop
157+ self .__app .gnss_status .diff_age = data .bestpos_diffage
158+
159+ def _process_ADRNAV (self , data : UNIMessage ):
160+ """
161+ Process ADRNAV, PPPNAV, SPPNAV sentences.
162+
163+ :param UNIMessage data: ADRNAV/PPPNAV/SPPNAV parsed message
164+ """
165+
166+ self ._process_pos (data .lat , data .lon , data .hmsl , data .undulation )
167+ self ._process_fix (data .postype )
168+
169+ def _process_SATSINFO (self , data : UNIMessage ):
170+ """
171+ Process SATSINFO sentences - Space Vehicle Information for all
172+ GNSS constellations.
173+
174+ :param UNIMessage data: SATSINFO parsed message
175+ """
176+
177+ self .__app .gnss_status .gsv_data = {}
178+ num_siv = int (data .numsat )
179+ now = time ()
180+
181+ for i in range (num_siv ):
182+ idx = f"_{ i + 1 :02d} "
183+ gnssId = SATSINFO_GNSSID [getattr (data , "sysstatus" + idx + "_01" )]
184+ svid = getattr (data , "prn" + idx )
185+ elev = getattr (data , "elev" + idx )
186+ azim = getattr (data , "azi" + idx )
187+ cno = getattr (data , "cno" + idx + "_01" )
188+ self .__app .gnss_status .gsv_data [(gnssId , svid )] = (
189+ gnssId ,
190+ svid ,
191+ elev ,
192+ azim ,
193+ cno ,
194+ now ,
195+ )
196+
197+ self .__app .gnss_status .siv = len (self .__app .gnss_status .gsv_data )
198+
199+ def _process_SATELLITE (self , data : UNIMessage ):
200+ """
201+ Process SATELLITE sentences - Space Vehicle Information for a
202+ specific GNSS constellation (7 in total).
203+
204+ :param UNIMessage data: SATSINFO parsed message
205+ """
206+
207+ gnssId = SATELLITE_GNSSID [getattr (data , "gnss" )]
208+ for gnss , prn in list (self .__app .gnss_status .gsv_data .keys ()):
209+ if gnss == gnssId :
210+ self .__app .gnss_status .gsv_data .pop ((gnss , prn ))
211+
212+ num_siv = int (data .numsat )
213+ now = time ()
214+ for i in range (num_siv ):
215+ idx = f"_{ i + 1 :02d} "
216+ svid = getattr (data , "prn" + idx )
217+ elev = getattr (data , "elv" + idx )
218+ azim = getattr (data , "azi" + idx )
219+ cno = 0 # cno not available from this message
220+ self .__app .gnss_status .gsv_data [(gnssId , svid )] = (
221+ gnssId ,
222+ svid ,
223+ elev ,
224+ azim ,
225+ cno ,
226+ now ,
227+ )
228+
229+ self .__app .gnss_status .siv = len (self .__app .gnss_status .gsv_data )
230+
231+ def _process_STADOP (self , data : UNIMessage ):
232+ """
233+ Process STADOP/ADRDOP/PPPDOP sentences - DOP Information.
234+
235+ :param UNIMessage data: STADOP/ADRDOP/PPPDOP parsed message
236+ """
237+
238+ self .__app .gnss_status .pdop = data .pdop
239+ self .__app .gnss_status .hdop = data .hdop
240+ self .__app .gnss_status .vdop = data .vdop
0 commit comments