@ -394,13 +394,13 @@ class tmc_message:
#datetime.timedelta(hours=0.25)
#datetime.timedelta(hours=0.25)
def getDuration ( self ) : #returns string
def getDuration ( self ) : #returns string
if " D " in self . event . durationType and not self . event . nature == " F " :
if " D " in self . event . durationType and not self . event . nature == " F " :
return tmc_message . duration_dict [ " Info_dyn " ] [ self . tmc_DP ]
return " , " + tmc_message . duration_dict [ " Info_dyn " ] [ self . tmc_DP ]
elif " L " in self . event . durationType and not self . event . nature == " F " :
elif " L " in self . event . durationType and not self . event . nature == " F " :
return tmc_message . duration_dict [ " Info_long " ] [ self . tmc_DP ]
return " , " + tmc_message . duration_dict [ " Info_long " ] [ self . tmc_DP ]
elif " D " in self . event . durationType and self . event . nature == " F " :
elif " D " in self . event . durationType and self . event . nature == " F " :
return tmc_message . duration_dict [ " Forecast_dyn " ] [ self . tmc_DP ]
return " , " + tmc_message . duration_dict [ " Forecast_dyn " ] [ self . tmc_DP ]
elif " L " in self . event . durationType and self . event . nature == " F " :
elif " L " in self . event . durationType and self . event . nature == " F " :
return tmc_message . duration_dict [ " Forecast_long " ] [ self . tmc_DP ]
return " , " + tmc_message . duration_dict [ " Forecast_long " ] [ self . tmc_DP ]
else :
else :
return " "
return " "
#self.event.durationType #D,(D),L,(L)
#self.event.durationType #D,(D),L,(L)
@ -429,28 +429,27 @@ class tmc_message:
else :
else :
try :
try :
multi = " %i : %s " % ( self . length , str ( self . mgm_list ) )
multi = " %i : %s " % ( self . length , str ( self . mgm_list ) )
#multi+=";events:"
#for i,event in enumerate(self.events):
#if not i==0:
#multi+=str(event)+","
except AttributeError :
except AttributeError :
multi = " [multi incomplete] "
multi = " [multi incomplete] "
return str ( multi )
def info_str ( self ) :
info = " "
info + = self . getDuration ( )
if not self . cancellation_time == None :
if not self . cancellation_time == None :
if language == " de " :
if language == " de " :
multi + = " (aufgehoben um %s ) " % self . cancellation_time
info + = " (aufgehoben um %s ) " % self . cancellation_time
else :
else :
multi + = " (cancelled at %s ) " % self . cancellation_time
info + = " (cancelled at %s ) " % self . cancellation_time
multi + = " ; " + self . getDuration ( )
return info
return str ( multi )
def events_string ( self ) :
def events_string ( self ) :
str_list = [ str ( elem ) for elem in self . events ]
str_list = [ str ( elem ) for elem in self . events ]
return str ( " , " . join ( str_list ) )
return str ( " , " . join ( str_list ) )
def log_string ( self ) :
def log_string ( self ) :
return str ( self . event . updateClass ) + " : " + self . getTime ( ) + " : " + self . location_text ( ) + " : " + self . events_string ( ) + " ; " + self . psn
return str ( self . event . updateClass ) + " : " + self . getTime ( ) + " : " + self . location_text ( ) + " : " + self . events_string ( ) + " ; " + self . info_str ( ) + " ; " + self . psn
def db_string ( self ) :
def db_string ( self ) :
return str ( self . location ) + " : " + str ( self . event . updateClass ) + " : " + self . events_string ( )
return str ( self . location ) + " : " + str ( self . event . updateClass ) + " : " + self . events_string ( ) + " ; " + self . info_str ( )
def map_string ( self ) :
def map_string ( self ) :
return str ( self . event . updateClass ) + " : " + self . getTime ( ) + " : " + self . events_string ( ) + " ; " + self . multi _str( ) + " ; " + self . psn
return ' <span title= " %s " > ' % self . multi_str ( ) + str ( self . event . updateClass ) + " : " + self . getTime ( ) + " : " + self . events_string ( ) + self . info _str( ) + " ; " + self . psn + " </span> "
def end_loc ( self ) :
def end_loc ( self ) :
return self . location . get_extent_location ( self . location , self . tmc_extent , self . tmc_dir )
return self . location . get_extent_location ( self . location , self . tmc_extent , self . tmc_dir )
def location_text ( self ) :
def location_text ( self ) :
@ -508,8 +507,8 @@ class tmc_message:
try :
try :
msg_ltn = tableobj . RDS_data [ PI ] [ " AID_list " ] [ 52550 ] [ " LTN " ]
msg_ltn = tableobj . RDS_data [ PI ] [ " AID_list " ] [ 52550 ] [ " LTN " ]
table_ltn = 1 #german table
table_ltn = 1 #german table
if msg_ltn != table_ltn and tableobj . debug :
if msg_ltn != table_ltn and tableobj . debug and False : #disabled, spams log
print ( " msg_ltn: %i does not match given table (1) on station: %s " % ( msg_ltn , self . psn ) )
print ( " msg_ltn: %i does not match expected table (1) on station: %s " % ( msg_ltn , self . psn ) )
except KeyError :
except KeyError :
if tableobj . debug :
if tableobj . debug :
print ( " no LTN found " )
print ( " no LTN found " )
@ -648,6 +647,14 @@ class mgm_tag:#mgm=multi group message
, 5 : " Equivalent of diversion bit set to ' 1 ' . "
, 5 : " Equivalent of diversion bit set to ' 1 ' . "
, 6 : " Increase the number of steps in the problem extent by 8. "
, 6 : " Increase the number of steps in the problem extent by 8. "
, 7 : " Increase the number of steps in the problem extent by 16. " }
, 7 : " Increase the number of steps in the problem extent by 16. " }
control_codes_short = { 0 : " urgency+=1 "
, 1 : " urgency-=1 "
, 2 : " directionality changed "
, 3 : " dynamic/longer-lasting changed "
, 4 : " spoken/unspoken duration changed "
, 5 : " diversion=1 "
, 6 : " extent+=8 "
, 7 : " extent+=16 " }
@staticmethod
@staticmethod
def decode_time_date ( raw ) : #label7/8 raw to datestring
def decode_time_date ( raw ) : #label7/8 raw to datestring
if raw < = 95 :
if raw < = 95 :
@ -680,7 +687,7 @@ class mgm_tag:#mgm=multi group message
if ( self . label == 0 ) :
if ( self . label == 0 ) :
return " duration: %i " % self . data . uint
return " duration: %i " % self . data . uint
elif ( self . label == 1 ) :
elif ( self . label == 1 ) :
return " control code: %i " % self . data . uint
return " control code %i : %s "% ( self . data . uint , mgm_tag . control_codes_short [ self . data . uint ] )
elif ( self . label == 2 ) :
elif ( self . label == 2 ) :
return " length affected: %i km " % self . length_to_km ( self . data . uint )
return " length affected: %i km " % self . length_to_km ( self . data . uint )
elif ( self . label == 3 ) :
elif ( self . label == 3 ) :
@ -923,11 +930,12 @@ class rds_parser_table_qt(gr.sync_block):#START
if time . time ( ) - self . minute_count_timer > 3 : #every 3 second
if time . time ( ) - self . minute_count_timer > 3 : #every 3 second
self . minute_count_max = self . minute_count
self . minute_count_max = self . minute_count
self . signals . DataUpdateEvent . emit ( { ' group_count ' : self . minute_count , ' group_count_max ' : self . minute_count_max } )
self . minute_count = 0
self . minute_count = 0
self . minute_count_timer = time . time ( )
self . minute_count_timer = time . time ( )
pr . enable ( ) #disabled-internal-profiling
#pr.enable() #disabled-internal-profiling
self . minute_count + = 1
self . minute_count + = 1
self . signals . DataUpdateEvent . emit ( { ' group_count ' : self . minute_count , ' group_count_max ' : self . minute_count_max } )
#self.signals.DataUpdateEvent.emit({'group_count':self.minute_count,'group_count_max':self.minute_count_max} )
if self . writeDB :
if self . writeDB :
#db=sqlite3.connect(self.db_name)
#db=sqlite3.connect(self.db_name)
db = self . db
db = self . db
@ -1135,7 +1143,8 @@ class rds_parser_table_qt(gr.sync_block):#START
paging = array [ 4 ] & 0xf
paging = array [ 4 ] & 0xf
extended_country_code = array [ 5 ]
extended_country_code = array [ 5 ]
self . RDS_data [ PI ] [ " ECC " ] = extended_country_code
self . RDS_data [ PI ] [ " ECC " ] = extended_country_code
#print("ECC:%s"%hex(extended_country_code))
if self . debug :
print ( " PI: %s PSN: %s ,ECC: %s " % ( PI , self . RDS_data [ PI ] [ " PSN " ] , hex ( extended_country_code ) ) )
elif variant == 1 :
elif variant == 1 :
TMC_info = SLC
TMC_info = SLC
elif variant == 2 :
elif variant == 2 :
@ -1143,7 +1152,7 @@ class rds_parser_table_qt(gr.sync_block):#START
elif variant == 3 :
elif variant == 3 :
language_codes = SLC
language_codes = SLC
if self . debug :
if self . debug :
print ( " language_codes: %s " % hex ( language_codes ) )
print ( " PI: %s PSN: %s , language_codes:%s " % ( PI , self . RDS_data [ PI ] [ " PSN " ] , hex ( language_codes ) ) )
elif variant == 6 :
elif variant == 6 :
#for use by broadcasters
#for use by broadcasters
if self . debug :
if self . debug :
@ -1214,7 +1223,7 @@ class rds_parser_table_qt(gr.sync_block):#START
textcolor = " " #use default color (white if background is black)
textcolor = " " #use default color (white if background is black)
l = list ( self . RDS_data [ PI ] [ " RT_ " + str ( ab_flag ) ] [ " RT " ] )
l = list ( self . RDS_data [ PI ] [ " RT_ " + str ( ab_flag ) ] [ " RT " ] )
rt = " " . join ( l [ 0 : text_end ] ) #remove underscores(default symbol) after line end marker
rt = " " . join ( l [ 0 : text_end ] ) #remove underscores(default symbol) after line end marker
if not self . RDS_data [ PI ] [ " internals " ] [ " last_valid_rt " ] == rt : #ignore duplicates
if not self . RDS_data [ PI ] [ " internals " ] [ " last_valid_rt " ] == rt : #ignore duplicates #TODO add 2nd order duplicates ABAB
self . RDS_data [ PI ] [ " internals " ] [ " RT_history " ] . append ( l )
self . RDS_data [ PI ] [ " internals " ] [ " RT_history " ] . append ( l )
if len ( self . RDS_data [ PI ] [ " internals " ] [ " RT_history " ] ) > 10 : #only store last 10 RTs
if len ( self . RDS_data [ PI ] [ " internals " ] [ " RT_history " ] ) > 10 : #only store last 10 RTs
self . RDS_data [ PI ] [ " internals " ] [ " RT_history " ] . pop ( 0 )
self . RDS_data [ PI ] [ " internals " ] [ " RT_history " ] . pop ( 0 )
@ -1254,20 +1263,31 @@ class rds_parser_table_qt(gr.sync_block):#START
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " groupType " ] = app_group
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " groupType " ] = app_group
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " app_name " ] = app_name
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " app_name " ] = app_name
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " app_data " ] = app_data
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " app_data " ] = app_data
if AID == 52550 : #TMC alert-c initialize
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " provider name " ] = " ________ "
if self . log :
if self . log :
print ( " new ODA: AID: %i , name: %s , app_group: %s , station: %s " % ( AID , app_name , app_group , PI ) )
print ( " new ODA: AID: %i , name: ' %s ' , app_group: %s , station: %s " % ( AID , app_name , app_group , PI ) )
#decode 3A group of TMC
#decode 3A group of TMC
if AID == 52550 : #TMC alert-c
if AID == 52550 : #TMC alert-c (continuously update)
variant = app_data >> 14
variant = app_data >> 14
if variant == 0 :
if variant == 0 :
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " LTN " ] = ( app_data >> 6 ) & 0x3f #location table number
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " LTN " ] = ( app_data >> 6 ) & 0x3f #location table number (6 bits)
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " AFI " ] = ( app_data >> 5 ) & 0x1 #alternative frequency indicator
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " AFI " ] = ( app_data >> 5 ) & 0x1 #alternative frequency indicator
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " M " ] = ( app_data >> 4 ) & 0x1 #transmission mode indicator
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " M " ] = ( app_data >> 4 ) & 0x1 #transmission mode indicator
#Message Geographical Scope:
#Message Geographical Scope:
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " I " ] = ( app_data >> 3 ) & 0x1 #international (EUROROAD)
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " scope " ] = " "
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " N " ] = ( app_data >> 2 ) & 0x1 #national
if ( app_data >> 3 ) & 0x1 == 1 :
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " R " ] = ( app_data >> 1 ) & 0x1 #regional
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " scope " ] + = " I " #international (EUROROAD)
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " U " ] = ( app_data >> 0 ) & 0x1 #urban
if ( app_data >> 2 ) & 0x1 == 1 :
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " scope " ] + = " N " #national
if ( app_data >> 1 ) & 0x1 == 1 :
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " scope " ] + = " R " #regional
if ( app_data >> 0 ) & 0x1 == 1 :
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " scope " ] + = " U " #urban
#self.RDS_data[PI]["AID_list"][AID]["I"]=(app_data>>3)&0x1#international (EUROROAD)
#self.RDS_data[PI]["AID_list"][AID]["N"]=(app_data>>2)&0x1#national
#self.RDS_data[PI]["AID_list"][AID]["R"]=(app_data>>1)&0x1#regional
#self.RDS_data[PI]["AID_list"][AID]["U"]=(app_data>>0)&0x1#urban
elif variant == 1 :
elif variant == 1 :
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " SID " ] = ( app_data >> 6 ) & 0x3f #service identifier
self . RDS_data [ PI ] [ " AID_list " ] [ AID ] [ " SID " ] = ( app_data >> 6 ) & 0x3f #service identifier
#timing parameters (used to switch away from TMC station without missing messages):
#timing parameters (used to switch away from TMC station without missing messages):
@ -1373,18 +1393,23 @@ class rds_parser_table_qt(gr.sync_block):#START
if adr == 4 or adr == 5 : #service provider name
if adr == 4 or adr == 5 : #service provider name
segment = self . decode_chars ( chr ( array [ 4 ] ) + chr ( array [ 5 ] ) + chr ( array [ 6 ] ) + chr ( array [ 7 ] ) )
segment = self . decode_chars ( chr ( array [ 4 ] ) + chr ( array [ 5 ] ) + chr ( array [ 6 ] ) + chr ( array [ 7 ] ) )
if self . debug :
if self . debug :
print ( " TMC-info adr: %i (provider name), segment: %s " % ( adr , segment ) )
print ( " TMC-info adr: %i (provider name), segment: %s , station: %s " % ( adr , segment , self . RDS_data [ PI ] [ " PSN " ] ) )
if self . RDS_data [ PI ] [ " AID_list " ] . has_key ( 52550 ) :
text_list = list ( self . RDS_data [ PI ] [ " AID_list " ] [ 52550 ] [ " provider name " ] )
seg_adr_start = ( adr - 4 ) * 4 #start of segment
text_list [ seg_adr_start : seg_adr_start + 4 ] = segment
self . RDS_data [ PI ] [ " AID_list " ] [ 52550 ] [ " provider name " ] = " " . join ( text_list )
if adr == 7 : #freq of tuned an mapped station (not seen yet)
if adr == 7 : #freq of tuned an mapped station (not seen yet)
freq_TN = tmc_y >> 8
freq_TN = tmc_y >> 8
freq_ON = tmc_y & 0xff #mapped frequency
freq_ON = tmc_y & 0xff #mapped frequency
if self . debug :
if self . debug :
print ( " TMC-info: TN: %i " % freq_TN )
print ( " TMC-info: TN: %i , station: %s "% ( freq_TN , self . RDS_data [ PI ] [ " PSN " ] ) )
self . RDS_data [ PI ] [ " TMC_TN " ] = freq_TN
self . RDS_data [ PI ] [ " TMC_TN " ] = freq_TN
else :
else :
if self . debug :
if self . debug :
print ( " alert plus " ) #(not seen yet)
print ( " alert plus on station %s ( %s ) " % ( PI , self . RDS_data [ PI ] [ " PSN " ] ) ) #(not seen yet)
#self.tableobj.RDS_data["D301"]["AID_list"][52550]["provider name"]="test____"
#RadioText+ (grouptype mostly 12A):
#RadioText+ (grouptype mostly 12A):
elif self . RDS_data [ PI ] [ " AID_list " ] . has_key ( 19415 ) and self . RDS_data [ PI ] [ " AID_list " ] [ 19415 ] [ " groupType " ] == groupType : #RT+
elif self . RDS_data [ PI ] [ " AID_list " ] . has_key ( 19415 ) and self . RDS_data [ PI ] [ " AID_list " ] [ 19415 ] [ " groupType " ] == groupType : #RT+
if not self . RDS_data [ PI ] . has_key ( " RT+ " ) :
if not self . RDS_data [ PI ] . has_key ( " RT+ " ) :
@ -1528,12 +1553,14 @@ class rds_parser_table_qt(gr.sync_block):#START
#lock in tuned network if freq_TN matches decoder frequency
#lock in tuned network if freq_TN matches decoder frequency
if ( self . RDS_data [ PI ] . has_key ( " tuned_freq " ) and freq_TN == self . RDS_data [ PI ] [ " tuned_freq " ] and not self . RDS_data [ PI ] [ " AF " ] . has_key ( " main " ) ) :
if ( self . RDS_data [ PI ] . has_key ( " tuned_freq " ) and freq_TN == self . RDS_data [ PI ] [ " tuned_freq " ] and not self . RDS_data [ PI ] [ " AF " ] . has_key ( " main " ) ) :
if self . log :
if self . log :
print ( " main frequency found: station: %s , freq: %0.1f M " % ( self . RDS_data [ PI ] [ " PSN " ] , freq_TN / 1e6 ) )
print ( " main frequency found in 14A : station: %s , freq: %0.1f M " % ( self . RDS_data [ PI ] [ " PSN " ] , freq_TN / 1e6 ) )
self . RDS_data [ PI ] [ " AF " ] [ " main " ] = freq_TN
self . RDS_data [ PI ] [ " AF " ] [ " main " ] = freq_TN
freq_str = " EON_TN: %0.1f M " % ( freq_TN / 1e6 )
self . signals . DataUpdateEvent . emit ( { ' PI ' : PI , ' freq ' : freq_str } )
#lock in ON if TN is locked in
#lock in ON if TN is locked in
if ( self . RDS_data [ PI ] [ " AF " ] . has_key ( " main " ) and self . RDS_data [ PI ] [ " AF " ] [ " main " ] == freq_TN and not self . RDS_data [ PI_ON ] [ " AF " ] . has_key ( " main " ) ) :
if ( self . RDS_data [ PI ] [ " AF " ] . has_key ( " main " ) and self . RDS_data [ PI ] [ " AF " ] [ " main " ] == freq_TN and not self . RDS_data [ PI_ON ] [ " AF " ] . has_key ( " main " ) ) :
if self . log :
if self . log :
print ( " mapped frequency found: station: %s , freq: %0.1f M " % ( self . RDS_data [ PI_ON ] [ " PSN " ] , freq_ON / 1e6 ) )
print ( " mapped frequency found in 14A : station: %s , freq: %0.1f M " % ( self . RDS_data [ PI_ON ] [ " PSN " ] , freq_ON / 1e6 ) )
self . RDS_data [ PI_ON ] [ " AF " ] [ " main " ] = freq_ON
self . RDS_data [ PI_ON ] [ " AF " ] [ " main " ] = freq_ON
freq_str = " EON: %0.1f M " % ( freq_ON / 1e6 )
freq_str = " EON: %0.1f M " % ( freq_ON / 1e6 )
self . signals . DataUpdateEvent . emit ( { ' PI ' : PI_ON , ' freq ' : freq_str } )
self . signals . DataUpdateEvent . emit ( { ' PI ' : PI_ON , ' freq ' : freq_str } )
@ -1651,6 +1678,7 @@ class rds_parser_table_qt(gr.sync_block):#START
return_string + = alphabet [ alnr ] [ index ]
return_string + = alphabet [ alnr ] [ index ]
except KeyError :
except KeyError :
return_string + = " ? %02X ? " % ord ( char )
return_string + = " ? %02X ? " % ord ( char )
print ( " symbol not decoded: " + " ? %02X ? " % ord ( char ) + " in string: " + return_string )
#charlist[i]='?'#symbol not decoded #TODO
#charlist[i]='?'#symbol not decoded #TODO
pass
pass
#return "".join(charlist)
#return "".join(charlist)
@ -1716,7 +1744,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
label_layout . addWidget ( self . count_label )
label_layout . addWidget ( self . count_label )
layout . addLayout ( label_layout )
layout . addLayout ( label_layout )
#TODO set different minsize if TMC is shown
#TODO set different minsize if TMC is shown
self . setMinimumSize ( Qt . QSize ( 500 , 5 0* self . tableobj . nPorts ) )
self . setMinimumSize ( Qt . QSize ( 500 , 4 0* self . tableobj . nPorts ) )
if self . showTMC :
if self . showTMC :
self . tmc_message_label = QtGui . QLabel ( " TMC messages: " )
self . tmc_message_label = QtGui . QLabel ( " TMC messages: " )
self . event_filter = QtGui . QLineEdit ( ) #QPlainTextEdit ?
self . event_filter = QtGui . QLineEdit ( ) #QPlainTextEdit ?
@ -1933,6 +1961,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
scrollArea . setWidgetResizable ( True )
scrollArea . setWidgetResizable ( True )
scrollArea . setWidget ( l )
scrollArea . setWidget ( l )
view . layout ( ) . addWidget ( scrollArea )
view . layout ( ) . addWidget ( scrollArea )
view . setWindowTitle ( self . tableobj . RDS_data [ PI ] [ " PSN " ] )
view . exec_ ( )
view . exec_ ( )
def onCLick ( self ) :
def onCLick ( self ) :
print ( " button clicked " )
print ( " button clicked " )