Browse Source

set freq_tune variable from rds table block, integrate EON data,lock in station frequencies, chart.py in build path, piechart min size, decoder freq label, RDS data recorded

master
Clemens Richter 10 years ago
parent
commit
4157ba2520
  1. 8
      grc/crfa_rds_parser_table_qt.xml
  2. 3
      python/CMakeLists.txt
  3. 1
      python/__init__.py
  4. 6
      python/chart.py
  5. 12
      python/max_freq.py
  6. 143
      python/rds_parser_table_qt.py

8
grc/crfa_rds_parser_table_qt.xml

@ -12,9 +12,15 @@
#set $label = '"%s"'%$id
#end if
$(signals) = rds_parser_table_qt_Signals()
self.$(id) = crfa.rds_parser_table_qt($(signals),$nPorts)
self.$(id) = crfa.rds_parser_table_qt($(signals),$nPorts,self.set_$(freq_tune),$freq_tune)
$(win) = rds_parser_table_qt_Widget($signals, $label,self.$(id))
$(gui_hint()($win))</make>
<param>
<name>tuned frequency</name>
<key>freq_tune</key>
<value></value>
<type>float</type>
</param>
<param>
<name>Label</name>
<key>label</key>

3
python/CMakeLists.txt

@ -36,7 +36,8 @@ GR_PYTHON_INSTALL(
rds_table_qt.py
rds_parser_table_qt.py
max_freq.py
smooth_vectors.py DESTINATION ${GR_PYTHON_DIR}/crfa
smooth_vectors.py
chart.py DESTINATION ${GR_PYTHON_DIR}/crfa
)
########################################################################

1
python/__init__.py

@ -37,4 +37,5 @@ from rds_table_qt import rds_table_qt
from rds_parser_table_qt import rds_parser_table_qt
from max_freq import max_freq
from smooth_vectors import smooth_vectors
from chart import Chart
#

6
python/chart.py

@ -1,3 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gnuradio import gr
from itertools import cycle
from PyQt4.Qt import *
@ -353,6 +356,9 @@ class DialogViewer(QDialog):
def __init__(self):
QDialog.__init__(self)
self.viewer = Viewer()
#self.viewer.resize(360, 240)
self.viewer.setMinimumSize(360,240)
#self.setMinimumSize(100,100)
self.setLayout(QVBoxLayout())
self.layout().setContentsMargins(0, 0, 0, 0)
self.layout().addWidget(self.viewer)

12
python/max_freq.py

@ -49,12 +49,15 @@ class max_freq(gr.sync_block):
#ii=input_items
carrier_width=2
carrier=self.fft_len/2
numbers=np.delete(input_items[0][0],range(carrier-carrier_width,carrier+carrier_width+1))#reads input and disregards center
#threshold=100 uni
numbers=np.delete(input_items[0][0],range(carrier-carrier_width,carrier+carrier_width+1))#read input and disregard center (hackrf LO)
#threshold=100# uni
threshold=80#home
#minimum number of consecutive maximums (in fft domain) to consider signal as station:
# min_consec_max_threshold=1#uni
#min_consec_max_threshold=1#uni
min_consec_max_threshold=5#home
#fuzzyness=2#uni
fuzzyness=10#home
#TODO: what if no numbers over threshold?
#TODO auto threshold
#max_indices=[[421, 428, 429, 430, 431, 432, 433, 434, 436, 437, 438, 831, 832, 837, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851,852, 853, 854, 855, 856, 857]]
@ -65,8 +68,7 @@ class max_freq(gr.sync_block):
#last_index=0
count=1#counts number of consecutive maximums
threshold_reached=False
#fuzzyness=2#uni
fuzzyness=10#home
# max_indices[0].append(0)#to detect last station
max_indices=np.append(max_indices,0)#to detect last station
#try:

143
python/rds_parser_table_qt.py

@ -23,7 +23,8 @@ import numpy
from gnuradio import gr
import pmt,functools,csv,md5,collections
from datetime import datetime
import chart#local file
import crfa.chart as chart
from PyQt4 import Qt, QtCore, QtGui
import pprint,code#for easier testing
pp = pprint.PrettyPrinter()
@ -39,7 +40,7 @@ class rds_parser_table_qt(gr.sync_block):
"""
docstring for block qtguitest
"""
def __init__(self,signals,nPorts):
def __init__(self,signals,nPorts,slot,freq):
#QObject.__init__()
gr.sync_block.__init__(self,
name="RDS Table",
@ -52,6 +53,8 @@ class rds_parser_table_qt(gr.sync_block):
self.set_msg_handler(pmt.intern('freq'), self.set_freq)
self.signals=signals
self.RDS_data={}
self.change_freq_tune=slot
self.tuning_frequency=int(freq)
self.printcounter=0
self.ODA_application_names={}
self.TMC_data={}
@ -91,9 +94,27 @@ class rds_parser_table_qt(gr.sync_block):
freq_str="%i:%0.1fM"% (decoder_num,freq/1e6)
except ValueError:
pass#leave string as is
message_string="decoder frequencies:"
for num in self.decoder_frequencies:
freq=self.decoder_frequencies[num]
message_string+="\t %i:%0.1fM"% (num,freq/1e6)
message_string+="\t tuned frequency:%0.1fM"%(self.tuning_frequency/1e6)
self.signals.DataUpdateEvent.emit({'decoder_frequencies':message_string})
#self.signals.DataUpdateEvent.emit({'row':decoder_num,'freq':freq_str})
#print("nr:%i freq:%s"%(tgtnum,freq_str))
def init_data_for_PI(self,PI):
self.RDS_data[PI]={}
self.RDS_data[PI]["blockcounts"]={}
self.RDS_data[PI]["blockcounts"]["any"]=0
self.RDS_data[PI]["AID_list"]={}
self.RDS_data[PI]["PSN"]="_"*8
self.RDS_data[PI]["PSN_valid"]=[False]*8
self.RDS_data[PI]["AF"]={}
self.RDS_data[PI]["TP"]=-1
self.RDS_data[PI]["TA"]=-1
self.RDS_data[PI]["PTY"]=""
self.RDS_data[PI]["DI"]=[2,2,2,2]
self.RDS_data[PI]["internals"]={"last_rt_tooltip":""}
def handle_msg(self, msg, port):#port from 0 to 3
#code.interact(local=locals())
array=pmt.to_python(msg)[1]
@ -108,26 +129,22 @@ class rds_parser_table_qt(gr.sync_block):
block2=(array[2]<<8)|(array[3]) #block2
PTY=(block2>>5)&0x1F
wrong_blocks=int(array[12])
if self.decoder_frequencies.has_key(port):
freq=self.decoder_frequencies[port]
freq_str="%i:%0.1fM"% (port,freq/1e6)
self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str})
#initialize dict 1st packet from station:
if not self.RDS_data.has_key(PI):
self.RDS_data[PI]={}
self.RDS_data[PI]["blockcounts"]={}
self.RDS_data[PI]["blockcounts"]["any"]=0
self.RDS_data[PI]["AID_list"]={}
self.RDS_data[PI]["PSN"]="_"*8
self.RDS_data[PI]["PSN_valid"]=[False]*8
self.RDS_data[PI]["AF"]={}
self.RDS_data[PI]["DI"]=[2,2,2,2]
self.RDS_data[PI]["internals"]={"last_rt_tooltip":""}
self.init_data_for_PI(PI)
print("found station %s"%PI)
if self.decoder_frequencies.has_key(port):
freq=self.decoder_frequencies[port]
freq_str="%i:%0.1fM"% (port,freq/1e6)
self.RDS_data[PI]["tuned_freq"]=freq
#self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str})
self.RDS_data[PI]["blockcounts"]["any"]+=1
if self.RDS_data[PI]["blockcounts"]["any"]==5:
self.RDS_data[PI]["blockcounts"]["any"]=0
dots="."*self.RDS_data[PI]["blockcounts"]["any"]
self.RDS_data[PI]["TP"]=TP
self.RDS_data[PI]["PTY"]=self.pty_dict[PTY]
self.signals.DataUpdateEvent.emit({'row':port,'PI':PI,'PTY':self.pty_dict[PTY],'TP':TP,'wrong_blocks':wrong_blocks,'dots':dots})
if (groupType == "0A"):#AF PSN
adr=array[3]&0b00000011
@ -140,6 +157,7 @@ class rds_parser_table_qt(gr.sync_block):
#d3 Static PTY Dynamic PTY
TA=(array[3]>>4)&0x1
MS=(array[3]>>3)&0x1
self.RDS_data[PI]["TA"]=TA
flag_string="TP:%i, TA:%i, MS:%i, DI:%s"%(TP,TA,MS,str(self.RDS_data[PI]["DI"]))
self.signals.DataUpdateEvent.emit({'row':port,'PI':PI,'flags':flag_string})
@ -147,10 +165,23 @@ class rds_parser_table_qt(gr.sync_block):
#225 1110 0001 = 1AF
#249 1111 1001 = 25AF
fillercode=205#1100 1101
if not self.RDS_data[PI]["AF"].has_key("main") and self.RDS_data[PI].has_key("tuned_freq"):
freq=self.decode_AF_freq(array[4])
if freq==self.RDS_data[PI]["tuned_freq"]:
self.RDS_data[PI]["AF"]["main"]=freq
print("main frequency found in 0A: station:%s, freq:%0.1fM"% (self.RDS_data[PI]["PSN"],freq/1e6))
freq_str="0A:%0.1fM"% (freq/1e6)
self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str})
freq=self.decode_AF_freq(array[5])
if freq==self.RDS_data[PI]["tuned_freq"]:
self.RDS_data[PI]["AF"]["main"]=freq
print("main frequency found in 0A: station:%s, freq:%0.1fM"% (self.RDS_data[PI]["PSN"],freq/1e6))
freq_str="0A:%0.1fM"% (freq/1e6)
self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str})
if(array[4]>= 224 and array[4]<= 249):
#print("AF1 detected")
self.RDS_data[PI]["AF"]['number']=array[4]-224
#self.RDS_data[PI]["AF"]['main']=self.decode_AF_freq(array[5])
self.signals.DataUpdateEvent.emit({'row':port,'PI':PI,'AF':self.RDS_data[PI]["AF"]})
if(array[5]>= 224 and array[5]<= 249):
print("AF2 detected (shouldn't happen)")
@ -435,19 +466,73 @@ class rds_parser_table_qt(gr.sync_block):
TP_ON=(array[3]>>4)&0x1
PI_ON="%02X%02X" %(array[6],array[7])
variant=array[3]&0xf
self.signals.DataUpdateEvent.emit({'PI':PI_ON,'TP':TP_ON})
if not self.RDS_data.has_key(PI_ON):
self.init_data_for_PI(PI_ON)
self.RDS_data[PI_ON]["TP"]=TP_ON
print("found station %s via EON on station %s"%(PI_ON,PI))
if not self.RDS_data[PI]["EON"].has_key(PI_ON):
self.RDS_data[PI]["EON"][PI_ON]={}
self.RDS_data[PI]["EON"][PI_ON]["PSN"]="_"*8
if variant in range(4):#variant 0..3 -> PS_ON
segment=self.decode_chars(chr(array[4])+chr(array[5]))
name_list=list(self.RDS_data[PI]["EON"][PI_ON]["PSN"])
name_list=list(self.RDS_data[PI_ON]["PSN"])
#name_list=list(self.RDS_data[PI]["EON"][PI_ON]["PSN"])
name_list[variant*2:variant*2+2]=segment
self.RDS_data[PI]["EON"][PI_ON]["PSN"]="".join(name_list)
if (name_list[variant*2:variant*2+2]==list(segment)):#segment already there
segmentcolor="purple"
elif(name_list[variant*2:variant*2+2]==['_']*2): #segment new
segmentcolor="purple"
name_list[variant*2:variant*2+2]=segment
else:#name changed (böse)
segmentcolor="red"
name_list=['_']*8 #reset name
name_list[variant*2:variant*2+2]=segment
#reset stored text:
self.RDS_data[PI_ON]["PSN"]="_"*8
self.RDS_data[PI_ON]["PSN_valid"]=[False]*8
self.RDS_data[PI_ON]["PSN_valid"][variant*2:variant*2+2]=[True] *2
PS_ON_str="".join(name_list)
self.RDS_data[PI_ON]["PSN"]=PS_ON_str
self.RDS_data[PI]["EON"][PI_ON]["PSN"]=PS_ON_str
#determine if text is valid
valid=True
for i in range(0,8):
if (not self.RDS_data[PI_ON]["PSN_valid"][i]):
valid = False
if(valid):
textcolor="black"
else:
textcolor="gray"
formatted_text=self.color_text(self.RDS_data[PI_ON]["PSN"],variant*2,variant*2+2,textcolor,segmentcolor)
self.RDS_data[PI]["EON"][PI_ON]["PSN"]=PS_ON_str
self.RDS_data[PI_ON]["PSN"]=PS_ON_str
#formatted_text="<font face='Courier New' color='%s'>%s</font>"%("purple",PS_ON_str)
self.signals.DataUpdateEvent.emit({'PI':PI_ON,'PSN':formatted_text})
if variant==4:#AF_ON
print("AF_ON method A")#TODO
if variant in range(5,10):#variant 5..9 -> mapped freqs
freq_TN=self.decode_AF_freq(array[4])
freq_ON=self.decode_AF_freq(array[5])
#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")):
print("main frequency found: station:%s, freq:%0.1fM"% (self.RDS_data[PI]["PSN"],freq_TN/1e6))
self.RDS_data[PI]["AF"]["main"]=freq_TN
#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")):
print("mapped frequency found: station:%s, freq:%0.1fM"% (self.RDS_data[PI_ON]["PSN"],freq_ON/1e6))
self.RDS_data[PI_ON]["AF"]["main"]=freq_ON
freq_str="EON:%0.1fM"% (freq_ON/1e6)
self.signals.DataUpdateEvent.emit({'PI':PI_ON,'freq':freq_str})
#print("mapped freq in variant %i:, %i->%i"%(variant,freq_TN,freq_ON))
if variant==13:#PTY and TA of ON
PTY_ON=array[4]>>3
TA_ON=array[5]&0x1
self.RDS_data[PI]["EON"][PI_ON]["TA_ON"]=TA_ON
self.RDS_data[PI]["EON"][PI_ON]["PTY_ON"]=PTY_ON
self.RDS_data[PI_ON]["TA"]=TA_ON
self.RDS_data[PI_ON]["PTY"]=self.pty_dict[PTY_ON]
self.signals.DataUpdateEvent.emit({'PI':PI_ON,'PTY':self.pty_dict[PTY_ON],'TA':TA_ON})
#rest is reserved
if variant==14:#programme item number of ON
PIN_ON=(array[4]<<8)|(array[5])
@ -475,6 +560,12 @@ class rds_parser_table_qt(gr.sync_block):
pp.pprint(self.RDS_data[key]["RT+"])
self.printcounter=0
#print("group of type %s not decoded on station %s"% (groupType,PI))
def decode_AF_freq(self,freq_raw):
if freq_raw in range(1,205):#1..204
return(87500000+freq_raw*100000)#returns int
#return(87.5e6+freq_raw*0.1e6)#returns float
else:
return(0)
def ref_locs(self,loc,name_string):
if(loc==34196):#europe
return(name_string)
@ -570,7 +661,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
layout.addWidget(self.table)
self.table.setHorizontalHeaderLabels(horHeaders)
self.table.setMaximumHeight(250)#TODO use dynamic value
#self.table.setMaximumHeight(300)#TODO use dynamic value
self.tmc_message_label=QtGui.QLabel("TMC messages:")
@ -581,7 +672,8 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
button = QtGui.QPushButton("code.interact")
button.clicked.connect(self.onCLick)
layout.addWidget(button)
self.freq_label=QtGui.QLabel("decoder frequencies:")
layout.addWidget(self.freq_label)
filter_layout = Qt.QHBoxLayout()
filter_layout.addWidget(QtGui.QLabel("event filter:"))
filter_layout.addWidget(self.event_filter)
@ -593,7 +685,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
self.logOutput = Qt.QTextEdit()
self.logOutput.setReadOnly(True)
self.logOutput.setLineWrapMode(Qt.QTextEdit.NoWrap)
#self.logOutput.setMaximumHeight(100)
self.logOutput.setMaximumHeight(150)
font = self.logOutput.font()
font.setFamily("Courier")
font.setPointSize(10)
@ -608,7 +700,8 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
button.clicked.connect(functools.partial(self.getDetails, row=rowPosition))
def display_data(self, event):
#pp.pprint(event)
if type(event)==dict and event.has_key('decoder_frequencies'):
self.freq_label.setText(event['decoder_frequencies'])
if type(event)==dict and event.has_key('TMC_log'):
ef=unicode(self.event_filter.text().toUtf8(), encoding="UTF-8").lower()
lf=unicode(self.location_filter.text().toUtf8(), encoding="UTF-8").lower()
@ -686,7 +779,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
view = chart.DialogViewer()
view.setGraph(mychart)
#view.resize(360, 240)
view.resize(380, 500)
#view.resize(380, 550)
rds_data=self.tableobj.RDS_data[PI].copy()
try:
del rds_data['blockcounts']
@ -699,10 +792,12 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
l.setWordWrap(True)
#l=QtGui.QLabel("Data:")
view.layout().addWidget(l)
#code.interact(local=locals())
view.exec_()
def onCLick(self):
print("button clicked")
code.interact(local=locals())
#self.logOutput.clear()
#self.reset_color()
#pp.pprint(event)
if __name__ == "__main__":

Loading…
Cancel
Save