Browse Source

broke long lines, removed old comments

dev
Clemens Richter 9 years ago
parent
commit
4ece95f756
  1. 146
      python/rds_parser_table_qt.py

146
python/rds_parser_table_qt.py

@ -27,7 +27,7 @@ import pmt,functools,csv,md5,collections,copy,sqlite3,atexit,time,re,sys
from datetime import datetime
from datetime import timedelta
import multirds.chart as chart
from multirds.tmc_classes import language
from multirds.tmc_classes import language#supported: de, en (both partially)
from PyQt4 import Qt, QtCore, QtGui
import pprint,code
@ -40,7 +40,6 @@ pr = cProfile.Profile()
from PyQt4.QtCore import QObject, pyqtSignal
from bitstring import BitArray
#language="de"#currently supported: de, en (both partially) #defined in tmc_classes.py
class rds_parser_table_qt_Signals(QObject):
@ -64,11 +63,13 @@ class rds_parser_table_qt(gr.sync_block):#START
out_sig=None)
if nPorts==1:
self.message_port_register_in(pmt.intern('in'))
self.set_msg_handler(pmt.intern('in'), functools.partial(self.handle_msg, port=0))
self.set_msg_handler(pmt.intern('in'),
functools.partial(self.handle_msg, port=0))
else:
for i in range(nPorts):
self.message_port_register_in(pmt.intern('in%d'%i))
self.set_msg_handler(pmt.intern('in%d'%i), functools.partial(self.handle_msg, port=i))
self.set_msg_handler(pmt.intern('in%d'%i),
functools.partial(self.handle_msg, port=i))
self.nPorts=nPorts
self.message_port_register_in(pmt.intern('freq'))
self.set_msg_handler(pmt.intern('freq'), self.set_freq)
@ -90,10 +91,12 @@ class rds_parser_table_qt(gr.sync_block):#START
self.decoder_frequencies={}
self.decoders=[]
for i in range(nPorts):
self.decoders.append({'synced':False,'freq':None,'PI':"",'pilot_SNR':0,'decim_mode':0})
self.decoders.append({'synced':False,'freq':None,'PI':"",
'pilot_SNR':0,'decim_mode':0})
#self.decoder_synced={}
#self.colorder=['ID','freq','name','PTY','AF','time','text','quality','buttons']
self.colorder=['ID','freq','name','buttons','PTY','AF','time','text','quality','pilot_SNR','RT+']
self.colorder=['ID','freq','name','buttons','PTY','AF',
'time','text','quality','pilot_SNR','RT+']
self.workdir=workdir
self.PI_dict={}#contains PI:numpackets (string:integer)
@ -121,16 +124,19 @@ class rds_parser_table_qt(gr.sync_block):#START
#self.dbc.execute('''CREATE TABLE rtp
# (time text,PI text,rtp_string text)''')
reader = csv.reader(open(self.workdir+'RDS_ODA-AIDs_names_only.csv'), delimiter=',', quotechar='"')
reader = csv.reader(open(self.workdir+'RDS_ODA-AIDs_names_only.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header
for row in reader:
self.ODA_application_names[int(row[0])]=row[1]
#read RT+ class name list:
reader = csv.reader(open(self.workdir+'RTplus_classnames.csv'), delimiter=',', quotechar='"')
reader = csv.reader(open(self.workdir+'RTplus_classnames.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header
self.rtp_classnames=dict((int(rows[0]),rows[1]) for rows in reader)
#read TMC-event list
reader = csv.reader(open(self.workdir+'event-list_with_forecast_sort.csv'), delimiter=',', quotechar='"')
reader = csv.reader(open(self.workdir+'event-list_with_forecast_sort.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header
self.ecl_dict=dict((int(rows[0]),rows[1:]) for rows in reader)
#Code,Text CEN-English,Text (German),Text (German) kein Quantifier,Text (Quantifier = 1),Text (Quantifier >1),N,Q,T,D,U,C,R ,Comment
@ -142,24 +148,31 @@ class rds_parser_table_qt(gr.sync_block):#START
#C: update class:
#read update classes
reader = csv.reader(open(self.workdir+'tmc_update_class_names.csv'), delimiter=',', quotechar='"')
reader = csv.reader(open(self.workdir+'tmc_update_class_names.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header, "code(C),english,german"
if language=="de":
self.tmc_update_class_names=dict((int(rows[0]),rows[2]) for rows in reader)#german names
self.tmc_update_class_names=dict((int(rows[0]),rows[2])
for rows in reader)#german names
else:
self.tmc_update_class_names=dict((int(rows[0]),rows[1]) for rows in reader)#english names
self.tmc_update_class_names=dict((int(rows[0]),rows[1])
for rows in reader)#english names
#read supplementary information code list
reader = csv.reader(open(self.workdir+'label6-supplementary-information-codes.csv'), delimiter=',', quotechar='"')
reader = csv.reader(open(self.workdir+'label6-supplementary-information-codes.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header, "code,english,german"
if language=="de":
self.label6_suppl_info=dict((int(rows[0]),rows[2]) for rows in reader)#german
self.label6_suppl_info=dict((int(rows[0]),rows[2])
for rows in reader)#german
else:
self.label6_suppl_info=dict((int(rows[0]),rows[1]) for rows in reader)#english
self.label6_suppl_info=dict((int(rows[0]),rows[1])
for rows in reader)#english
#read PTY list
f=open(self.workdir+'pty-list.csv')
reader = csv.reader(f, delimiter=',', quotechar='"')
reader.next()#skip header
self.pty_dict=dict((int(rows[0]),unicode(rows[1],errors='ignore')) for rows in reader)
self.pty_dict=dict((int(rows[0]),unicode(rows[1],errors='ignore'))
for rows in reader)
f.close()
self.minute_count=0
self.minute_count_max=0
@ -341,7 +354,9 @@ class rds_parser_table_qt(gr.sync_block):#START
self.RDS_data[PI]["TP"]=TP
self.RDS_data[PI]["PTY"]=self.pty_dict[PTY]
self.signals.DataUpdateEvent.emit({'PI':PI,'PTY':self.pty_dict[PTY],'TP':TP,'wrong_block_ratio':self.RDS_data[PI]["wrong_block_ratio"],'dots':dots})
self.signals.DataUpdateEvent.emit({'PI':PI,'PTY':self.pty_dict[PTY],
'wrong_block_ratio':self.RDS_data[PI]["wrong_block_ratio"],
'TP':TP,'dots':dots})
#self.signals.DataUpdateEvent.emit({'PI':PI,'PTY':self.pty_dict[PTY],'TP':TP})
@ -514,9 +529,6 @@ class rds_parser_table_qt(gr.sync_block):#START
if(not self.RDS_data[PI].has_key("RT_0")):#initialize variables
self.RDS_data[PI]["RT_0"]={"RT":"_"*64,"RT_valid":[False]*64,"RT_all_valid":False}
self.RDS_data[PI]["RT_1"]={"RT":"_"*64,"RT_valid":[False]*64,"RT_all_valid":False}
#self.RDS_data[PI]["RT"]="_"*64
#self.RDS_data[PI]["RT_valid"]=[False]*64
#self.RDS_data[PI]["RT_all_valid"]=False
self.RDS_data[PI]["RT_last_ab_flag"]=2
adr= array[3]&0b00001111
@ -527,7 +539,6 @@ class rds_parser_table_qt(gr.sync_block):#START
#segment=self.decode_chars(chr(array[4])+chr(array[5])+chr(array[6])+chr(array[7]))
segment=chr(array[4])+chr(array[5])+chr(array[6])+chr(array[7])#EDIT:latedecode
#print("RT:adress: %d, segment:%s"%(adr,segment))
#self.signals.DataUpdateEvent.emit({'col':5,'row':port,'PI':PI,'groupType':groupType,'adress':adr,'segment':segment})
text_list=list(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"])
#determine text length:
@ -574,12 +585,18 @@ class rds_parser_table_qt(gr.sync_block):#START
if len(self.RDS_data[PI]["internals"]["RT_history"])>10:#only store last 10 RTs
self.RDS_data[PI]["internals"]["RT_history"].pop(0)
if self.writeDB:
t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"RT",self.decode_chars(rt))
t=(
str(datetime.now()),PI,self.RDS_data[PI]["PSN"],
"RT",self.decode_chars(rt)
)
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
self.RDS_data[PI]["internals"]["last_valid_rt"]=rt
try:#save rt+ if it exist
if self.writeDB:
t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"RT+",self.decode_chars(str(self.RDS_data[PI]["RT+"])))
t=(str(datetime.now()),PI,
self.RDS_data[PI]["PSN"],"RT+",
self.decode_chars(str(self.RDS_data[PI]["RT+"]))
)
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
except KeyError:
pass#no rt+ -> dont save
@ -636,10 +653,7 @@ class rds_parser_table_qt(gr.sync_block):#START
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:
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):
@ -670,10 +684,6 @@ class rds_parser_table_qt(gr.sync_block):#START
if self.debug:
print("station:%s sent empty 4A group"%self.RDS_data[PI]["PSN"])
else:
#hours=((array[5] & 0x1) << 4) | ((array[6] >> 4) & 0x0f)
#minutes=((array[6] &0x0F)<<2)|((array[7] >>6)&0x3)
#offsetdir=(array[7]>>5)&0x1
#local_time_offset=0.5*((array[7])&0x1F)
if(offsetdir==1):
local_time_offset*=-1
try:
@ -712,7 +722,8 @@ class rds_parser_table_qt(gr.sync_block):#START
self.IH_data[PI][ih_data]["count"]+=1
self.IH_data[PI][ih_data]["last_time"]=str(datetime.now())
#TMC-alert-c (grouptype mostly 8A):
elif self.RDS_data[PI]["AID_list"].has_key(52550) and self.RDS_data[PI]["AID_list"][52550]["groupType"]==groupType:#TMC alert-C
elif (self.RDS_data[PI]["AID_list"].has_key(52550)
and self.RDS_data[PI]["AID_list"][52550]["groupType"]==groupType):#TMC alert-C
tmc_x=array[3]&0x1f #lower 5 bit of block2
tmc_y=(array[4]<<8)|(array[5]) #block3
tmc_z=(array[6]<<8)|(array[7])#block4
@ -744,34 +755,7 @@ class rds_parser_table_qt(gr.sync_block):#START
#~ ltn=1#assume germany TODO:add better error handling
#~ if self.log:
#~ print("no LTN (yet) for PI:%s"%PI)
#~ if tmc_T == 0:
#~ if tmc_F==1:#single group
#~ tmc_msg=tmc_message(PI,psn,ltn,tmc_x,tmc_y,tmc_z,datetime_received,self)
#~ self.print_tmc_msg(tmc_msg)
#~ elif tmc_F==0 and Y15==1:#1st group of multigroup
#~ ci=int(tmc_x&0x7)
#~ tmc_msg=tmc_message(PI,psn,ltn,tmc_x,tmc_y,tmc_z,datetime_received,self)
#~ #if self.RDS_data[PI]["internals"]["unfinished_TMC"].has_key(ci):
#~ #print("overwriting parital message")
#~ self.RDS_data[PI]["internals"]["unfinished_TMC"][ci]={"msg":tmc_msg,"time":time.time()}
#~ else:
#~ ci=int(tmc_x&0x7)
#~ if self.RDS_data[PI]["internals"]["unfinished_TMC"].has_key(ci):
#~ tmc_msg=self.RDS_data[PI]["internals"]["unfinished_TMC"][ci]["msg"]
#~ tmc_msg.add_group(tmc_y,tmc_z)
#~ age=time.time()-self.RDS_data[PI]["internals"]["unfinished_TMC"][ci]["time"]
#~ t=(time.time(),PI,age,ci,tmc_msg.is_complete)
#~ #print("%f: continuing message PI:%s,age:%f,ci:%i complete:%i"%t)
#~ self.RDS_data[PI]["internals"]["unfinished_TMC"][ci]["time"]=time.time()
#~ if tmc_msg.is_complete:
#~ self.print_tmc_msg(tmc_msg)#print and store message
#~ del self.RDS_data[PI]["internals"]["unfinished_TMC"][tmc_msg.ci]#delete finished message
#~ else:
#~ #if not ci==0:
#~ #print("ci %i not found, discarding"%ci)
#~ pass
#~ else:#alert plus or provider info
if tmc_T == 1:#rest done by tmc_parser
adr=tmc_x&0xf
@ -1020,7 +1004,8 @@ class rds_parser_table_qt(gr.sync_block):#START
0b1100:u"ÁÀÉÈÍÌÓÒÚÙŘČŠŽĐĿ",
0b1101:u"ÂÄÊËÎÏÔÖÛÜřčšžđŀ",
0b1110:u"ÃÅÆŒŷÝÕØÞŊŔĆŚŹŦð",
0b1111:u"ãåæœŵýõøþŋŕćśźŧ "}#0xff should not occur (not in standard) (but occured 2017-03-04-9:18 , probably transmission error)
0b1111:u"ãåæœŵýõøþŋŕćśźŧ "}#0xff should not occur (not in standard)
#(but occured 2017-03-04-9:18 , probably transmission error)
#charlist=list(charstring)
return_string=u""
@ -1042,15 +1027,18 @@ class rds_parser_table_qt(gr.sync_block):#START
#return_string+=unichr(ord(char))#TODO: properly decide for UTF8 or EBU charset
except KeyError:
return_string+=u"?%02X?"%ord(char)#symbol not decoded
print("symbol not decoded: "+"?%02X?"%ord(char)+"in string:"+return_string)
print("symbol not decoded: "+"?%02X?"%ord(char)+
"in string:"+return_string)
pass
if not type(return_string)==unicode:
code.interact(local=locals())
return return_string
def color_text(self, text, start,end,textcolor,segmentcolor):
#formatted_text="<font face='Courier New' color='%s'>%s</font><font face='Courier New' color='%s'>%s</font><font face='Courier New' color='%s'>%s</font>"% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:])
#formatted_text="<span style='background-color: yellow;color:%s'>%s</span><span style='color:%s'>%s</span><span style='color:%s'>%s</span>"% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:])
formatted_text=("<span style='font-family:Courier New;color:%s'>%s</span>"*3)% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:])
formatted_text=(
"<span style='font-family:Courier New;color:%s'>%s</span>"*3
)% (textcolor,text[:start],
segmentcolor,text[start:end],
textcolor,text[end:])
return formatted_text
class rds_parser_table_qt_Widget(QtGui.QWidget):
def __init__(self, signals,label,tableobj):
@ -1075,9 +1063,6 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
self.table.setColumnCount(len(self.colorder))
self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) #disallow editing
##button.clicked.connect(self.getDetails)
layout.addWidget(self.table)
self.table.setHorizontalHeaderLabels(self.colorder)
#self.table.setMaximumHeight(300)#TODO use dynamic value
@ -1102,7 +1087,8 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
label_layout = Qt.QHBoxLayout()
self.freq_label=QtGui.QLabel("decoder frequencies:")
self.freq_label.setWordWrap(True)
self.freq_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Ignored))#expand in horizontal direction and only wrap if window too small
self.freq_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Ignored))#expand in horizontal direction and only wrap if window too small
#self.freq_label.setTextFormat(QtCore.Qt.RichText)
#self.freq_label.setTextFormat(QtCore.Qt.PlainText)
self.count_label=QtGui.QLabel("count:")
@ -1242,7 +1228,8 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
def showIHdata(self):
view=Qt.QDialog()
l=QtGui.QLabel("In House Data:\n%s"%pp.pformat(self.tableobj.IH_data))
l.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse |QtCore.Qt.TextSelectableByKeyboard)
l.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse |
QtCore.Qt.TextSelectableByKeyboard)
l.setWordWrap(True)
#self.IH_data
layout=Qt.QVBoxLayout()
@ -1255,10 +1242,12 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
PI=str(self.table.cellWidget(row,PIcol).text())
freq=int(self.tableobj.RDS_data[PI]['AF']['main'])
#print("setaudio row:%i, chan:%s, PI:%s,freq:%i"%(row,audio_channel,PI,freq))
send_pmt = pmt.pmt_to_python.pmt_from_dict({"cmd":"set_audio_freq","chan":audio_channel,"freq":freq})
send_pmt = pmt.pmt_to_python.pmt_from_dict({"cmd":"set_audio_freq",
"chan":audio_channel,"freq":freq})
self.tableobj.message_port_pub(pmt.intern('ctrl'), send_pmt)
#catch:
#print("no freq, cant set decoder")#show notification? popup: too intrusive, log: maybe not visible, other possibility?
#print("no freq, cant set decoder")
#show notification? popup: too intrusive, log: maybe not visible, other possibility?
#print("freq not in RX BW")#automatically shift freq-tune?
def setAudio2(self,row,audio_channel):
@ -1278,13 +1267,15 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
PIcol=self.colorder.index('ID')
PI=str(self.table.cellWidget(row,PIcol).text())
view = chart.DialogViewer()
if self.tableobj.PI_dict.has_key(PI) and self.tableobj.PI_dict[PI]>3:#dont print piechart if no packets received (detected via EON)
if self.tableobj.PI_dict.has_key(PI) and self.tableobj.PI_dict[PI]>3:
#dont print piechart if no packets received (detected via EON)
table=chart.DataTable()
table.addColumn('groupType')
table.addColumn('numPackets')
blockcounts=copy.deepcopy(self.tableobj.RDS_data[PI]['blockcounts'])
del blockcounts['any']
#lambda function removes last character of PI string (A or B) and sorts based on integer valure of number in front
#lambda function removes last character of PI string (A or B)
#and sorts based on integer valure of number in front
for key in sorted(blockcounts,key=lambda elem: int(elem[0:-1])):
count=blockcounts[key]
table.addRow([key+": "+str(count),count])
@ -1298,11 +1289,14 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
del rds_data['PSN_valid']
del rds_data["RT_0"]['RT_valid']
del rds_data["RT_1"]['RT_valid']
rds_data['internals']['RT_history']=["".join(rt) for rt in rds_data['internals']['RT_history']]#combine char lists into strings (more compact)
rds_data['internals']['RT_history']=["".join(rt) for rt
in rds_data['internals']['RT_history']]
#combine char lists into strings (more compact)
except KeyError:
pass
l=QtGui.QLabel("Data:%s"%pp.pformat(rds_data))
l.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse |QtCore.Qt.TextSelectableByKeyboard)
l.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse |
QtCore.Qt.TextSelectableByKeyboard)
l.setWordWrap(True)
#l=QtGui.QLabel("Data:")

Loading…
Cancel
Save