Пример #1
0
    def __init_center_cell(self):
        base_freq_cell = self.__rx_main.state()[_FREQ_CELL_KEY]
        mode_cell = self.__rx_main.state()['MD']
        sidetone_cell = self.state()['CW']
        iq_offset_cell = LooseCell(key='iq_offset', value=0.0, type=float)

        self.__iq_center_cell = ViewCell(
            base=base_freq_cell,
            get_transform=lambda x: x + iq_offset_cell.get(),
            set_transform=lambda x: x - iq_offset_cell.get(),
            key=_FREQ_CELL_KEY,
            type=base_freq_cell.type(),  # runtime variable...
            writable=True,
            persists=base_freq_cell.metadata().persists)

        def changed_iq(_value=None):
            # TODO this is KX3-specific
            mode = mode_cell.get()
            if mode == 'CW':
                iq_offset = sidetone_cell.get()
            elif mode == 'CW-REV':
                iq_offset = -sidetone_cell.get()
            elif mode == 'AM' or mode == 'FM':
                iq_offset = 11000.0
            else:  # USB, LSB, other
                iq_offset = 0.0
            iq_offset_cell.set(iq_offset)
            self.__iq_center_cell.changed_transform()

        # TODO bad practice
        mode_cell._subscribe_immediate(changed_iq)
        sidetone_cell._subscribe_immediate(changed_iq)
        changed_iq()
Пример #2
0
 def setUp(self):
     self.lc = LooseCell(value=0, type=RangeT([(-100, 100)]))
     self.delta = 1
     self.vc = ViewCell(base=self.lc,
                        get_transform=lambda x: x + self.delta,
                        set_transform=lambda x: x - self.delta,
                        type=int)
Пример #3
0
 def setUp(self):
     self.lc = LooseCell(value=0, key='a', ctor=int)
     self.vc = ViewCell(base=self.lc,
                        get_transform=lambda x: x + 1,
                        set_transform=lambda x: x - 1,
                        key='b',
                        ctor=int)
Пример #4
0
 def setUp(self):
     self.lc = LooseCell(value=0, type=RangeT([(-100, 100)]), writable=True)
     self.delta = 1
     self.vc = ViewCell(base=self.lc,
                        get_transform=lambda x: x + self.delta,
                        set_transform=lambda x: x - self.delta,
                        type=int,
                        writable=True,
                        interest_tracker=LoopbackInterestTracker())
Пример #5
0
class TestViewCell(unittest.TestCase):
    def setUp(self):
        self.lc = LooseCell(value=0, key='a', type=int)
        self.vc = ViewCell(
            base=self.lc,
            get_transform=lambda x: x + 1,
            set_transform=lambda x: x - 1,
            key='b',
            type=int)
    
    def test_get_set(self):
        self.assertEqual(0, self.lc.get())
        self.assertEqual(1, self.vc.get())
        self.vc.set(2)
        self.assertEqual(1, self.lc.get())
        self.assertEqual(2, self.vc.get())
        self.lc.set(3)
        self.assertEqual(3, self.lc.get())
        self.assertEqual(4, self.vc.get())
    
    def test_subscription(self):
        fired = []
        
        def f():
            fired.append(self.vc.get())
        
        self.vc.subscribe(f)
        self.lc.set(1)
        self.assertEqual([2], fired)
Пример #6
0
class TestViewCell(unittest.TestCase):
    def setUp(self):
        self.lc = LooseCell(value=0, key='a', type=int)
        self.vc = ViewCell(
            base=self.lc,
            get_transform=lambda x: x + 1,
            set_transform=lambda x: x - 1,
            key='b',
            type=int)
    
    def test_get_set(self):
        self.assertEqual(0, self.lc.get())
        self.assertEqual(1, self.vc.get())
        self.vc.set(2)
        self.assertEqual(1, self.lc.get())
        self.assertEqual(2, self.vc.get())
        self.lc.set(3)
        self.assertEqual(3, self.lc.get())
        self.assertEqual(4, self.vc.get())
    
    def test_subscription(self):
        fired = []
        
        def f():
            fired.append(self.vc.get())
        
        self.vc.subscribe(f)
        self.lc.set(1)
        self.assertEqual([2], fired)
Пример #7
0
    def __init_center_cell(self):
        base_freq_cell = self.__rx_main.state()[_FREQ_CELL_KEY]
        mode_cell = self.__rx_main.state()['MD']
        sidetone_cell = self.state()['CW']
        submode_cell = self.state()['DT']
        iq_offset_cell = LooseCell(value=0.0, type=float, writable=True)

        self.__iq_center_cell = ViewCell(
            base=base_freq_cell,
            get_transform=lambda x: x + iq_offset_cell.get(),
            set_transform=lambda x: x - iq_offset_cell.get(),
            type=base_freq_cell.type(),  # runtime variable...
            writable=True,
            persists=base_freq_cell.metadata().persists)

        def changed_iq(_value=None):
            # TODO this is KX3-specific
            mode = mode_cell.get()
            if mode == 'CW':
                iq_offset = sidetone_cell.get()
            elif mode == 'CW-REV':
                iq_offset = -sidetone_cell.get()
            elif mode == 'AM' or mode == 'FM':
                iq_offset = 11000.0
            elif mode == 'DATA' or mode == 'DATA-REV':
                submode = submode_cell.get()
                if submode == 0:  # "DATA A", SSB with less processing
                    iq_offset = 0.0  # ???
                elif submode == 1:  # "AFSK A", SSB with RTTY style filter
                    iq_offset = 0.0  # ???
                elif submode == 2:  # "FSK D", RTTY
                    iq_offset = 900.0
                elif submode == 3:  # "PSK D", PSK31
                    iq_offset = 1000.0  # I think so...
                else:
                    iq_offset = 0  # fallback
                if mode == 'DATA-REV':
                    iq_offset = -iq_offset
            else:  # USB, LSB, other
                iq_offset = 0.0
            iq_offset_cell.set(iq_offset)
            self.__iq_center_cell.changed_transform()

        # TODO bad practice
        mode_cell._subscribe_immediate(changed_iq)
        sidetone_cell._subscribe_immediate(changed_iq)
        submode_cell._subscribe_immediate(changed_iq)
        changed_iq()
Пример #8
0
def _merge_vfos(vfos):
    fixed = 0.0
    variable = []
    for vfo in vfos:
        p = vfo.type().get_single_point()
        if p is not None:
            fixed += p
        else:
            variable.append(vfo)
    if len(variable) == 0:
        if fixed == 0.0:
            return None
        else:
            return _ConstantVFOCell(fixed)
    elif len(variable) == 1:
        variable_one = variable[0]
        if fixed == 0.0:
            return variable_one
        else:
            return ViewCell(
                base=variable_one,
                get_transform=lambda x: x + fixed,
                set_transform=lambda x: x - fixed,
                type=variable_one.type().shifted_by(fixed),
                writable=True,
                persists=variable_one.metadata().persists)
    else:
        raise ValueError('Multiple non-stub VFOs not yet supported.')
Пример #9
0
 def setUp(self):
     self.lc = LooseCell(value=0, key='a', type=int)
     self.vc = ViewCell(
         base=self.lc,
         get_transform=lambda x: x + 1,
         set_transform=lambda x: x - 1,
         key='b',
         type=int)
Пример #10
0
 def setUp(self):
     self.lc = LooseCell(value=0, type=RangeT([(-100, 100)]))
     self.delta = 1
     self.vc = ViewCell(
         base=self.lc,
         get_transform=lambda x: x + self.delta,
         set_transform=lambda x: x - self.delta,
         type=int)
Пример #11
0
 def setUp(self):
     self.lc = LooseCell(value=0, type=RangeT([(-100, 100)]), writable=True)
     self.delta = 1
     self.vc = ViewCell(
         base=self.lc,
         get_transform=lambda x: x + self.delta,
         set_transform=lambda x: x - self.delta,
         type=int,
         writable=True,
         interest_tracker=LoopbackInterestTracker())
Пример #12
0
 def __init_center_cell(self):
     base_freq_cell = self.__rx_main.state()[_FREQ_CELL_KEY]
     mode_cell = self.__rx_main.state()['MD']
     sidetone_cell = self.state()['CW']
     submode_cell = self.state()['DT']
     iq_offset_cell = LooseCell(key='iq_offset', value=0.0, type=float)
     
     self.__iq_center_cell = ViewCell(
             base=base_freq_cell,
             get_transform=lambda x: x + iq_offset_cell.get(),
             set_transform=lambda x: x - iq_offset_cell.get(),
             key=_FREQ_CELL_KEY,
             type=base_freq_cell.type(),  # runtime variable...
             writable=True,
             persists=base_freq_cell.metadata().persists)
     
     def changed_iq(_value=None):
         # TODO this is KX3-specific
         mode = mode_cell.get()
         if mode == 'CW':
             iq_offset = sidetone_cell.get()
         elif mode == 'CW-REV':
             iq_offset = -sidetone_cell.get()
         elif mode == 'AM' or mode == 'FM':
             iq_offset = 11000.0
         elif mode == 'DATA' or mode == 'DATA-REV':
             submode = submode_cell.get()
             if submode == 0:  # "DATA A", SSB with less processing
                 iq_offset = 0.0  # ???
             elif submode == 1:  # "AFSK A", SSB with RTTY style filter
                 iq_offset = 0.0  # ???
             elif submode == 2:  # "FSK D", RTTY
                 iq_offset = 900.0
             elif submode == 3:  # "PSK D", PSK31
                 iq_offset = 1000.0  # I think so...
             else:
                 iq_offset = 0  # fallback
             if mode == 'DATA-REV':
                 iq_offset = -iq_offset
         else:  # USB, LSB, other
             iq_offset = 0.0
         iq_offset_cell.set(iq_offset)
         self.__iq_center_cell.changed_transform()
     
     # TODO bad practice
     mode_cell._subscribe_immediate(changed_iq)
     sidetone_cell._subscribe_immediate(changed_iq)
     submode_cell._subscribe_immediate(changed_iq)
     changed_iq()
Пример #13
0
class TestViewCell(unittest.TestCase):
    def setUp(self):
        self.lc = LooseCell(value=0, type=RangeT([(-100, 100)]))
        self.delta = 1
        self.vc = ViewCell(base=self.lc,
                           get_transform=lambda x: x + self.delta,
                           set_transform=lambda x: x - self.delta,
                           type=int)

    # TODO: Add tests for behavior when the transform is not perfectly one-to-one (such as due to floating-point error).

    def test_get_set(self):
        self.assertEqual(0, self.lc.get())
        self.assertEqual(1, self.vc.get())
        self.vc.set(2)
        self.assertEqual(1, self.lc.get())
        self.assertEqual(2, self.vc.get())
        self.lc.set(3)
        self.assertEqual(3, self.lc.get())
        self.assertEqual(4, self.vc.get())

        self.delta = 10
        self.vc.changed_transform()
        self.assertEqual(3, self.lc.get())
        self.assertEqual(13, self.vc.get())

    def test_subscription(self):
        st = CellSubscriptionTester(self.vc)

        self.lc.set(1)
        st.expect_now(2)

        self.delta = 10
        self.vc.changed_transform()
        self.assertEqual(1, self.lc.get())
        st.expect_now(11)
        st.unsubscribe()
        self.lc.set(2)
        st.advance()

    def test_coerced_base_value(self):
        self.vc.set(999)  # out of base cell's range, gets clamped
        self.assertEqual(100 + self.delta, self.vc.get())
Пример #14
0
class _ElecraftRadio(ExportedState):
    # TODO: Tell protocol to do no/less polling when nobody is looking.

    def __init__(self, protocol):
        self.__protocol = protocol
        self.__rx_main = _ElecraftReceiver(protocol, False)
        self.__rx_sub = _ElecraftReceiver(protocol, True)
        self.__init_center_cell()

    def __init_center_cell(self):
        base_freq_cell = self.__rx_main.state()[_FREQ_CELL_KEY]
        mode_cell = self.__rx_main.state()['MD']
        sidetone_cell = self.state()['CW']
        submode_cell = self.state()['DT']
        iq_offset_cell = LooseCell(value=0.0, type=float, writable=True)

        self.__iq_center_cell = ViewCell(
            base=base_freq_cell,
            get_transform=lambda x: x + iq_offset_cell.get(),
            set_transform=lambda x: x - iq_offset_cell.get(),
            type=base_freq_cell.type(),  # runtime variable...
            writable=True,
            persists=base_freq_cell.metadata().persists)

        def changed_iq(_value=None):
            # TODO this is KX3-specific
            mode = mode_cell.get()
            if mode == 'CW':
                iq_offset = sidetone_cell.get()
            elif mode == 'CW-REV':
                iq_offset = -sidetone_cell.get()
            elif mode == 'AM' or mode == 'FM':
                iq_offset = 11000.0
            elif mode == 'DATA' or mode == 'DATA-REV':
                submode = submode_cell.get()
                if submode == 0:  # "DATA A", SSB with less processing
                    iq_offset = 0.0  # ???
                elif submode == 1:  # "AFSK A", SSB with RTTY style filter
                    iq_offset = 0.0  # ???
                elif submode == 2:  # "FSK D", RTTY
                    iq_offset = 900.0
                elif submode == 3:  # "PSK D", PSK31
                    iq_offset = 1000.0  # I think so...
                else:
                    iq_offset = 0  # fallback
                if mode == 'DATA-REV':
                    iq_offset = -iq_offset
            else:  # USB, LSB, other
                iq_offset = 0.0
            iq_offset_cell.set(iq_offset)
            self.__iq_center_cell.changed_transform()

        # TODO bad practice
        mode_cell._subscribe_immediate(changed_iq)
        sidetone_cell._subscribe_immediate(changed_iq)
        submode_cell._subscribe_immediate(changed_iq)
        changed_iq()

    def state_def(self):
        """overrides ExportedState"""
        for d in super(_ElecraftRadio, self).state_def():
            yield d
        for d in _st.install_cells(self, self.__protocol, is_sub=None):
            yield d

    def close(self):
        """implements IComponent"""
        self.__protocol.transport.loseConnection()

    def iq_center_cell(self):
        """Made available for Device creation; not a well-thought-out interface."""
        return self.__iq_center_cell

    def get_direct_protocol(self):
        """For experimental use only."""
        return self.__protocol

    @exported_value(type=NoticeT(always_visible=False),
                    changes='continuous')  # TODO better changes
    def get_errors(self):
        error = self.__protocol.get_communication_error()
        if not error:
            return u''
        elif error == u'not_responding':
            return u'Radio not responding.'
        elif error == u'bad_data':
            return u'Bad data from radio.'
        else:
            return six.text_type(error)

    @exported_value(type=ReferenceT(), changes='never')
    def get_rx_main(self):
        return self.__rx_main

    @exported_value(type=ReferenceT(), changes='never')
    def get_rx_sub(self):
        return self.__rx_sub
Пример #15
0
class TestViewCell(unittest.TestCase):
    def setUp(self):
        self.lc = LooseCell(value=0, type=RangeT([(-100, 100)]))
        self.delta = 1
        self.vc = ViewCell(
            base=self.lc,
            get_transform=lambda x: x + self.delta,
            set_transform=lambda x: x - self.delta,
            type=int)
    
    # TODO: Add tests for behavior when the transform is not perfectly one-to-one (such as due to floating-point error).
    
    def test_get_set(self):
        self.assertEqual(0, self.lc.get())
        self.assertEqual(1, self.vc.get())
        self.vc.set(2)
        self.assertEqual(1, self.lc.get())
        self.assertEqual(2, self.vc.get())
        self.lc.set(3)
        self.assertEqual(3, self.lc.get())
        self.assertEqual(4, self.vc.get())
        
        self.delta = 10
        self.vc.changed_transform()
        self.assertEqual(3, self.lc.get())
        self.assertEqual(13, self.vc.get())
    
    def test_subscription(self):
        st = CellSubscriptionTester(self.vc)
        
        self.lc.set(1)
        st.expect_now(2)
        
        self.delta = 10
        self.vc.changed_transform()
        self.assertEqual(1, self.lc.get())
        st.expect_now(11)
        st.unsubscribe()
        self.lc.set(2)
        st.advance()
    
    def test_coerced_base_value(self):
        self.vc.set(999)  # out of base cell's range, gets clamped
        self.assertEqual(100 + self.delta, self.vc.get())
Пример #16
0
class _ElecraftRadio(ExportedState):
    # TODO: Tell protocol to do no/less polling when nobody is looking.
    
    def __init__(self, protocol):
        self.__protocol = protocol
        self.__rx_main = _ElecraftReceiver(protocol, False)
        self.__rx_sub = _ElecraftReceiver(protocol, True)
        self.__init_center_cell()
    
    def __init_center_cell(self):
        base_freq_cell = self.__rx_main.state()[_FREQ_CELL_KEY]
        mode_cell = self.__rx_main.state()['MD']
        sidetone_cell = self.state()['CW']
        submode_cell = self.state()['DT']
        iq_offset_cell = LooseCell(value=0.0, type=float)
        
        self.__iq_center_cell = ViewCell(
                base=base_freq_cell,
                get_transform=lambda x: x + iq_offset_cell.get(),
                set_transform=lambda x: x - iq_offset_cell.get(),
                type=base_freq_cell.type(),  # runtime variable...
                writable=True,
                persists=base_freq_cell.metadata().persists)
        
        def changed_iq(_value=None):
            # TODO this is KX3-specific
            mode = mode_cell.get()
            if mode == 'CW':
                iq_offset = sidetone_cell.get()
            elif mode == 'CW-REV':
                iq_offset = -sidetone_cell.get()
            elif mode == 'AM' or mode == 'FM':
                iq_offset = 11000.0
            elif mode == 'DATA' or mode == 'DATA-REV':
                submode = submode_cell.get()
                if submode == 0:  # "DATA A", SSB with less processing
                    iq_offset = 0.0  # ???
                elif submode == 1:  # "AFSK A", SSB with RTTY style filter
                    iq_offset = 0.0  # ???
                elif submode == 2:  # "FSK D", RTTY
                    iq_offset = 900.0
                elif submode == 3:  # "PSK D", PSK31
                    iq_offset = 1000.0  # I think so...
                else:
                    iq_offset = 0  # fallback
                if mode == 'DATA-REV':
                    iq_offset = -iq_offset
            else:  # USB, LSB, other
                iq_offset = 0.0
            iq_offset_cell.set(iq_offset)
            self.__iq_center_cell.changed_transform()
        
        # TODO bad practice
        mode_cell._subscribe_immediate(changed_iq)
        sidetone_cell._subscribe_immediate(changed_iq)
        submode_cell._subscribe_immediate(changed_iq)
        changed_iq()
    
    def state_def(self):
        """overrides ExportedState"""
        for d in super(_ElecraftRadio, self).state_def():
            yield d
        for d in _st.install_cells(self, self.__protocol, is_sub=None):
            yield d
    
    def close(self):
        """implements IComponent"""
        self.__protocol.transport.loseConnection()
    
    def iq_center_cell(self):
        """Made available for Device creation; not a well-thought-out interface."""
        return self.__iq_center_cell
    
    def get_direct_protocol(self):
        """For experimental use only."""
        return self.__protocol
    
    @exported_value(type=NoticeT(always_visible=False), changes='continuous')  # TODO better changes
    def get_errors(self):
        error = self.__protocol.get_communication_error()
        if not error:
            return u''
        elif error == u'not_responding':
            return u'Radio not responding.'
        elif error == u'bad_data':
            return u'Bad data from radio.'
        else:
            return unicode(error)
    
    @exported_value(type=ReferenceT(), changes='never')
    def get_rx_main(self):
        return self.__rx_main
    
    @exported_value(type=ReferenceT(), changes='never')
    def get_rx_sub(self):
        return self.__rx_sub