Channel Devices
Some simple implementations of Device
. See classes
- class pymoa.device.port.Channel(name='', **kwargs)
Bases:
pymoa.device.port.ChannelBase
Represents a device containing a single channel. E.g. a single analog i/o switch, a button, etc.
For example a simple switch which does nothing:
>>> from kivy.properties import BooleanProperty >>> class SimpleSwitch(Channel): ... state = BooleanProperty(False, allownone=True) ... async def set_state(self, state): ... self.state = state >>> switch = SimpleSwitch() >>> switch.state False >>> switch.activate(switch) True >>> print(switch.state) None >>> switch.set_state(True) >>> switch.state True
- class pymoa.device.port.ChannelBase(name='', **kwargs)
Bases:
pymoa.device.Device
A somewhat more concrete than
Device
base class for general input/output devices.Following is the typical expected structure of these devices. Each channel represents some kind of interaction with the world. E.g. it might represent digital input lines and output switches, multi-channel ADCs, or analog output channels. It might event represent the graphical state of buttons.
For each of these channels in the device, the instance should contain a property representing the channel state. For example, a single digital channel,
DigitalChannel
, contains a state variable indicating the state of the switch.From the outside, the property should be treated as read only. That is, if the channel controls a switch, one does not change
state
to cause a change in the state, rather one callsset_state()
. Onceset_state()
changes the state, it is its responsibility to update the state variable and e.g.timestamp
and then emit a on_data_update event.Consequently, the pattern is for the device to update the state variables with every change to the device. From the outside, one calls
set_state()
to change the state and then reads (or listens to) the property or on_data_update to get the current state, including after a call toset_state()
.See
analog
anddigital
for example devices.- await read_state()
A abstract method causing a read of the state. This method should not return the state, but rather cause the device to read the state and update the appropriate instance property with the current state.
Note
If supported, the method needs to be overwritten by a base class otherwise, it raises a NotImplementedError.
- await write_state(**kwargs)
A abstract method for setting the state. See
ChannelBase
for details.Note
If supported, the method needs to be overwritten by a base class otherwise, it raises a NotImplementedError.
- class pymoa.device.port.Port(name='', **kwargs)
Bases:
pymoa.device.port.ChannelBase
Device similar to
Channel
, except this device represents one or more channels. E.g. a port with multiple digital lines, or a port of multiple buttons.Similar to
Channel.state
, the expectation is that each channel or line will have a property associated with it. The name of the property is any valid name representing whatever is connected. For example, if there are 2 digital lines connected to a light and IR beam break, the two properties might be named light, and ir_beam. This allows checking their state simply with e.g. x.light.Although a port is commonly represented by e.g. a list of the state of each channel, in this implementation each channel gets an individual property.
Warning
If
ChannelBase.reset_state
is True, then each of the channel properties must have allownone=True.For example:
from kivy.properties import BooleanProperty >>> class DigitalPort(Port): ... photobeam = BooleanProperty(False, allownone=True) ... light = BooleanProperty(False, allownone=True) ... ... def set_state(self, name, value): ... print('Setting line {} to {}'.format(self.attr_map[name], value)) ... setattr(self, name, value) ... >>> # photobeam controls physical line 2 and the light line 5 >>> port = DigitalPort(attr_map={'photobeam': 2, 'light': 5}) >>> print(port.photobeam) False >>> port.chan_attr_map {2: 'photobeam', 5: 'light'} >>> port.activate(port) True >>> # already active so it won't be activated again >>> port.activate(port) False >>> # reset_state is True, so the property is set None when activated >>> print(port.photobeam) None >>> port.set_state('photobeam', False) Setting line 2 to False >>> print(port.photobeam) False >>> port.deactivate(port) True
- channel_names: List[str] = []
List of name of the channels of the port.