transition_width=25) @exported_value(type=BandShape, changes='never') def get_band_shape(self): """implement IDemodulator""" return BandShape.bandpass_transition( low=-self.__cutoff, high=self.__cutoff, transition=self.__transition_width, ) def get_output_type(self): """implement IDemodulator""" return SignalType(kind='MONO', sample_rate=self.__demod_rate) @exported_value(type=unicode, changes='continuous') def get_text(self): message = safe_delete_head_nowait(self.__char_queue) if message: textstring = self.__text textstring += message.to_string().decode('us-ascii') # TODO: Make the buffer longer and arrange so partial updates rather than the entire buffer can be sent to clients. self.__text = textstring[-100:] return self.__text pluginMode = ModeDef(mode='PSK31', info='PSK31', demod_class=PSK31Demodulator, available=_available)
def get_angle(self): return self.__angle @setter def set_angle(self, value): value = float(value) compensation = math.pi / 180 * -6.5 # empirical, calibrated against VOR receiver (and therefore probably wrong) value = value + compensation value = value % (2 * math.pi) phase_shift = int(self.__rf_rate / self.__vor_sig_freq * (value / (2 * math.pi))) self.__delay.set_dly(phase_shift) self.__angle = value def get_input_type(self): return SignalType(kind='MONO', sample_rate=self.__audio_rate) def get_output_type(self): return SignalType(kind='IQ', sample_rate=self.__rf_rate) # Twisted plugin exports pluginMode = ModeDef(mode='VOR', info='VOR', demod_class=VOR, mod_class=VORModulator) pluginClient = ClientResourceDef( key=__name__, resource=static.File(os.path.join(os.path.split(__file__)[0], 'client')), load_js_path='vor.js')
def __lineReceived(self, line): if line == '': # observed glitch in output pass elif line.startswith('Enabled demodulators:'): pass elif line.startswith( '$ULTW' ) and self.__last_line is not None: # observed glitch in output; need to glue to previous line, I think? ll = self.__last_line self.__last_line = None self.__target(ll + line) elif line.startswith('APRS: '): line = line[len('APRS: '):] self.__last_line = line self.__target(line) else: # TODO: Log these properly print 'Not APRS line: %r' % line # TODO: Arrange for a way for the user to see why it is unavailable. _multimon_available = test_subprocess('multimon-ng -h; exit 0', 'available demodulators:', shell=True) pluginDef_APRS = ModeDef( mode='APRS', # TODO: Rename mode to be more accurate info='APRS', demod_class=FMAPRSDemodulator, available=_multimon_available)
self.state_changed() if shape_changed: self.state_shape_changed() def is_interesting(self): """Implements ITelemetryObject.""" return True def get_object_expiry(self): """implement ITelemetryObject""" return self.__last_heard_time + drop_unheard_timeout_seconds @exported_value(type=TimestampT(), changes='explicit', label='Last heard') def get_last_heard_time(self): return self.__last_heard_time # TODO: Arrange for a way for the user to see why it is unavailable. _rtl_433_available = test_subprocess(['rtl_433', '-r', '/dev/null'], 'Reading samples from file', shell=False) plugin_mode = ModeDef( mode='433', info=EnumRow( label='rtl_433', description='OOK telemetry decoded by rtl_433 mostly found at 433 MHz' ), demod_class=RTL433Demodulator, available=_rtl_433_available)
# # ShinySDR is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with ShinySDR. If not, see <http://www.gnu.org/licenses/>. from __future__ import absolute_import, division, print_function, unicode_literals from twisted.python.util import sibpath from twisted.web import static from shinysdr.interfaces import ModeDef, ClientResourceDef from .demodulator import WSPRDemodulator, find_wsprd plugin_mode = ModeDef( mode='WSPR', info='WSPR', demod_class=WSPRDemodulator, unavailability=None if find_wsprd() else 'wsprd not found.') plugin_client = ClientResourceDef(key=__name__, resource=static.File( sibpath(__file__, 'client')), load_js_path='wspr.js') __all__ = []
Output has frequencies from -250 to +250. ''' return MultistageChannelFilter(input_rate=self.__input_rate, output_rate=self.__demod_rate, cutoff_freq=250 - 25, transition_width=25) def state_def(self): for d in super(PSK31Demodulator, self).state_def(): yield d # TODO make this possible to be decorator style yield 'text', self.__text_cell @exported_value(type=BandShape, changes='never') def get_band_shape(self): """implement IDemodulator""" return BandShape.bandpass_transition( low=-self.__cutoff, high=self.__cutoff, transition=self.__transition_width) def get_output_type(self): """implement IDemodulator""" return SignalType(kind='MONO', sample_rate=self.__demod_rate) pluginMode = ModeDef(mode='PSK31', info='PSK31', demod_class=PSK31Demodulator, unavailability=_unavailability)
@exported_value(type=_uvquality_range, changes='this_setter', label='Unvoiced speech quality', parameter='uvquality') def get_uvquality(self): return self.__uvquality @setter def set_uvquality(self, value): value = _uvquality_range(value) if self.__uvquality != value: self.__uvquality = value self.__do_connect() def get_output_type(self): return self.__output_type @exported_value(type=BandShape, changes='never') def get_band_shape(self): return self.__fm_demod.get_band_shape() _modeDef = ModeDef( mode= u'DSD', # TODO: Ought to declare all the individual modes that DSD can decode -- once we have a way to not spam the mode selector with that. info=EnumRow( label=u'DSD', description=u'All modes DSD can decode (P25, DMR, D-STAR, …)'), demod_class=DSDDemodulator, available=bool(_available_version))
from shinysdr.interfaces import ModeDef from shinysdr.types import EnumRow plugin_available = ModeDef(mode='available', info=EnumRow(label='expected available'), demod_class=object(), unavailability=None) plugin_unavailable = ModeDef(mode='unavailable', info=EnumRow(label='expected unavailable'), demod_class=object(), unavailability='For testing.')
@exported_value(type=int, changes='explicit', sort_key='050', label='Ident') # TODO naming may be wrong def get_ident(self): return self.__ident @exported_value(type=six.text_type, changes='explicit', sort_key='020', label='Aircraft type') def get_aircraft_type(self): return self.__aircraft_type @exported_value(type=Track, changes='explicit', sort_key='010', label='') def get_track(self): return self.__track plugin_mode = ModeDef(mode='MODE-S', info=EnumRow( label='Mode S', description='Aviation telemetry found at 1090 MHz'), demod_class=ModeSDemodulator, unavailability=_unavailability) plugin_client = ClientResourceDef( key=__name__, resource=static.File(os.path.join(os.path.split(__file__)[0], 'client')), load_js_path='mode_s.js')
changes='this_setter', label='Unvoiced speech quality', parameter='uvquality') def get_uvquality(self): return self.__uvquality @setter def set_uvquality(self, value): value = _uvquality_range(value) if self.__uvquality != value: self.__uvquality = value self.__do_connect(True) def get_output_type(self): return self.__output_type @exported_value(type=BandShape, changes='never') def get_band_shape(self): return self.__fm_demod.get_band_shape() _modeDef = ModeDef( mode= u'DSD', # TODO: Ought to declare all the individual modes that DSD can decode -- once we have a way to not spam the mode selector with that. info=EnumRow( label=u'DSD', description=u'All modes DSD can decode (P25, DMR, D-STAR, …)'), demod_class=DSDDemodulator, unavailability=None if _available_version else 'dsd.dsd_block_ff not found.')
# Not usable because python blocks have bad interactions with reconfiguration or something. # class RTTYEncoder(gr.basic_block): # """ # Convert ASCII to a bit-stream with 2 bits per symbol (except for stop bits which are 3). # """ # def __init__(self): # gr.basic_block.__init__(self, # name=type(self).__name__, # in_sig=[numpy.uint8], # out_sig=[numpy.float32]) # # def forecast(self, noutput_items, ninput_items_required): # ninput_items_required[0] = int(math.ceil(noutput_items / _HALF_BITS_PER_CODE)) # # def general_work(self, input_items, output_items): # char_in = input_items[0] # bits_out = output_items[0] # count_in, count_out = _encode_rtty(char_in, bits_out) # self.consume_each(count_in) # return count_out # Plugin exports pluginMode = ModeDef(mode='RTTY', info='RTTY', demod_class=RTTYDemodulator, mod_class=RTTYModulator, unavailability=_unavailability)
mode=mode, stereo=True, audio_rate=audio_rate, demod_rate=audio_rate, band_filter=audio_rate * 0.5, band_filter_transition=audio_rate * 0.2, **kwargs) self.split_block = blocks.complex_to_float(1) self.connect(self, self.band_filter_block, self.rf_squelch_block, self) self.connect(self.band_filter_block, self.rf_probe_block) pluginDef_iq = ModeDef(mode='IQ', info='Raw I/Q', demod_class=IQDemodulator) _am_lower_cutoff_freq = 40 _am_audio_bandwidth = 7500 _am_demod_method_type = EnumT({ u'async': u'Asynchronous', u'lsb': u'Lower sideband', u'usb': u'Upper sideband', u'stereo': u'ISB stereo', }) class AMDemodulator(SimpleAudioDemodulator): """Amplitude modulation (AM) demodulator.""" __demod_rate = 16000
return out[:count_out] # Not usable because python blocks have bad interactions with reconfiguration or something. # class RTTYEncoder(gr.basic_block): # """ # Convert ASCII to a bit-stream with 2 bits per symbol (except for stop bits which are 3). # """ # def __init__(self): # gr.basic_block.__init__(self, # name=type(self).__name__, # in_sig=[numpy.uint8], # out_sig=[numpy.float32]) # # def forecast(self, noutput_items, ninput_items_required): # ninput_items_required[0] = int(math.ceil(noutput_items / _HALF_BITS_PER_CODE)) # # def general_work(self, input_items, output_items): # char_in = input_items[0] # bits_out = output_items[0] # count_in, count_out = _encode_rtty(char_in, bits_out) # self.consume_each(count_in) # return count_out # Plugin exports pluginMode = ModeDef(mode='RTTY', info='RTTY', demod_class=RTTYDemodulator, mod_class=RTTYModulator, available=_available)
# (at your option) any later version. # # ShinySDR is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with ShinySDR. If not, see <http://www.gnu.org/licenses/>. from __future__ import absolute_import, division, unicode_literals from twisted.python.util import sibpath from twisted.web import static from shinysdr.interfaces import ModeDef, ClientResourceDef from .demodulator import WSPRDemodulator, find_wsprd plugin_mode = ModeDef(mode='WSPR', info='WSPR', demod_class=WSPRDemodulator, available=find_wsprd() is not None) plugin_client = ClientResourceDef(key=__name__, resource=static.File( sibpath(__file__, 'client')), load_js_path='wspr.js') __all__ = []
# Not usable because python blocks have bad interactions with reconfiguration or something. # class RTTYEncoder(gr.basic_block): # """ # Convert ASCII to a bit-stream with 2 bits per symbol (except for stop bits which are 3). # """ # def __init__(self): # gr.basic_block.__init__(self, # name=type(self).__name__, # in_sig=[numpy.uint8], # out_sig=[numpy.float32]) # # def forecast(self, noutput_items, ninput_items_required): # ninput_items_required[0] = int(math.ceil(noutput_items / _HALF_BITS_PER_CODE)) # # def general_work(self, input_items, output_items): # char_in = input_items[0] # bits_out = output_items[0] # count_in, count_out = _encode_rtty(char_in, bits_out) # self.consume_each(count_in) # return count_out # Plugin exports pluginMode = ModeDef(mode='RTTY', info='RTTY', demod_class=RTTYDemodulator, mod_class=RTTYModulator, available=_available and False) # disabled until it works better