Module swarm.swarm
Expand source code
import logging
from enum import IntEnum
class Sensor(IntEnum):
"""All Sensor types known by the ftSwarm"""
UNDEFINED = -1
DIGITAL = 0
ANALOG = 1
SWITCH = 2
REEDSWITCH = 3
LIGHTBARRIER = 4
VOLTMETER = 5
OHMMETER = 6
THERMOMETER = 7
LDR = 8
TRAILSENSOR = 9
COLORSENSOR = 10
ULTRASONIC = 11
BUTTON = 12
class Actor(IntEnum):
"""All Actor types known by the ftSwarm"""
UNDEFINDED = -1
XMOTOR = 0
XMMOTOR = 1
TRACTOR = 2
ENCODER = 3
LAMP = 4
VALVE = 5
COMPRESSOR = 6
BUZZER = 7
class MotionType(IntEnum):
"""How to move a motor"""
COAST = 0
BRAKE = 1
ON = 2
class Toggle(IntEnum):
"""Toggle states"""
NOTOGGLE = 0
TOGGLEUP = 1
TOGGLEDOWN = 2
class Align(IntEnum):
"""Text alignment for display"""
ALIGNLEFT = 0
ALIGNCENTER = 1
ALIGNRIGHT = 2
class Trigger(IntEnum):
"""Trigger events"""
TRIGGERUP = 0
TRIGGERDOWN = 1
TRIGGERVALUE = 2
TRIGGERI2CREAD = 3
TRIGGERI2CWRITE = 4
class FtSwarmBase:
"""Base class for all ftSwarm implementations"""
def __init__(self) -> None:
self.logger = logging.getLogger("swarm-base")
async def send(self, port_name: str, command: str, *args: str | int | float) -> int | str | None:
pass
class FtSwarmIO:
"""
Base class for all ftSwarm interfaces
Don't use this class at all
"""
def __init__(self, swarm: FtSwarmBase, port_name: str) -> None:
self._port_name = port_name
self._swarm = swarm
async def post_init(self) -> None:
pass
async def get_port_name(self) -> str:
return self._port_name
async def set_value(self, value: str) -> None:
self._swarm.logger.warning(f"Received unexpected write to {self._port_name}: {value}")
class FtSwarmActorShim(FtSwarmIO):
"""
Shim class for all ftSwarm actors for type annotations
Don't use this class at all
"""
def get_port_name(self) -> str:
pass
class FtSwarmInput(FtSwarmIO):
"""
Base class for all ftSwarm inputs
Don't use this class at all
"""
def __init__(self, swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0):
super().__init__(swarm, name)
self._normallyOpen = normally_open
self._value = 0
self._hysteresis = hysteresis
async def post_init(self) -> None:
await self._swarm.send(self._port_name, "setSensorType", await self.get_sensor_type(), self._normallyOpen)
await self._swarm.send(self._port_name, "subscribe", self._hysteresis)
self._value = await self._swarm.send(self._port_name, "getValue")
async def get_sensor_type(self) -> Sensor:
return Sensor.UNDEFINED
async def on_trigger(self, trigger_event: Trigger, actor: FtSwarmActorShim, value: int | None = None) -> None:
# The last parameter is optional, so we need to check if it is None
await self._swarm.send(self._port_name, "onTrigger", trigger_event, actor.get_port_name(), *([value] or []))
async def set_value(self, str_value: str) -> None:
self._value = int(str_value)
class FtSwarmDigitalInput(FtSwarmInput):
"""
Digital input
Maps to ports A1...A4 on all controller types
"""
def __init__(self, swarm: FtSwarmBase, name: str) -> None:
super().__init__(swarm, name, True, 0)
async def get_sensor_type(self) -> Sensor:
return Sensor.DIGITAL
async def get_toggle(self) -> Toggle:
return Toggle(await self._swarm.send(self._port_name, "getToggle"))
async def get_state(self) -> bool:
return self._value != 0
async def is_pressed(self) -> bool:
return await self.get_state()
async def is_released(self) -> bool:
return not (await self.get_state())
async def has_toggled_up(self) -> bool:
return (await self.get_toggle()) == Toggle.TOGGLEUP
async def has_toggled_down(self) -> bool:
return (await self.get_toggle()) == Toggle.TOGGLEDOWN
class FtSwarmSwitch(FtSwarmDigitalInput):
"""
Mechanical switch
Maps to ports A1...A4 on all controller types
Wiring for fischertechnik switches: 1-3 is normally open, 1-2 is normally closed
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.SWITCH
class FtSwarmReedSwitch(FtSwarmDigitalInput):
"""
Reed switch
Maps to ports A1...A4 on all controller types
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.REEDSWITCH
class FtSwarmLightBarrier(FtSwarmDigitalInput):
"""
Light barrier
Maps to ports A1...A4 on all controller types
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.LIGHTBARRIER
class FtSwarmButton(FtSwarmDigitalInput):
"""
Onboard button
This input is only available on the ftSwarmControl
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.BUTTON
class FtSwarmAnalogInput(FtSwarmInput):
"""
General analog input
Maps to ports A1...A6 on the ftSwarm specifically
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.ANALOG
async def get_value(self) -> int:
return self._value
class FtSwarmVoltmeter(FtSwarmAnalogInput):
"""
Voltmeter
Maps to port A2 on the ftSwarm specifically
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.VOLTMETER
async def get_voltage(self) -> int:
return await self._swarm.send(self._port_name, "getVoltage")
class FtSwarmOhmmeter(FtSwarmAnalogInput):
"""
Ohmmeter
Maps to ports A1...A6 on the ftSwarm specifically
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.OHMMETER
async def get_resistance(self) -> int:
return await self._swarm.send(self._port_name, "getResistance")
class FtSwarmThermometer(FtSwarmAnalogInput):
"""
Thermometer based on 1.5kOhm NTC
Maps to ports A1...A6 on the ftSwarm specifically
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.THERMOMETER
async def get_celcius(self) -> int:
return await self._swarm.send(self._port_name, "getCelcius")
async def get_kelvin(self) -> int:
return await self._swarm.send(self._port_name, "getKelvin")
async def get_fahrenheit(self) -> int:
return await self._swarm.send(self._port_name, "getFahrenheit")
class FtSwarmLDR(FtSwarmAnalogInput):
"""
LDR
Maps to ports A1...A6 on the ftSwarm specifically
At FtSwarmControl you could use a LDR with a FtSwarmDigitalInput as well
"""
async def get_sensor_type(self) -> Sensor:
return Sensor.LDR
class FtSwarmActor(FtSwarmIO):
"""
Base class for all actors
Don't use this class directly, use one of the derived classes instead
"""
def __init__(self, swarm: FtSwarmBase, port_name: str, high_precision: bool = False) -> None:
super().__init__(swarm, port_name)
self._high_precision = high_precision
async def post_init(self) -> None:
await self._swarm.send(self._port_name, "setActorType", await self.get_actor_type(), self._high_precision)
async def get_actor_type(self) -> Actor:
return Actor.UNDEFINDED
class FtSwarmMotor(FtSwarmActor):
"""
General motor class, use this class for (old) gray motors, mini motors, XS motors
M1..M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.XMOTOR
async def set_speed(self, speed) -> None:
await self._swarm.send(self._port_name, "setSpeed", speed)
async def get_speed(self) -> int:
return await self._swarm.send(self._port_name, "getSpeed")
class FtSwarmTractorMotor(FtSwarmMotor):
"""
Tractor & XM motor
M1..M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.TRACTOR
async def set_motion_type(self, motion_type) -> None:
"""
Set motion type of motor
FtSwarmTractor has different options for stopping motor:
:return: None
"""
await self._swarm.send(self._port_name, "setMotionType", motion_type)
async def get_motion_type(self) -> MotionType:
return MotionType(await self._swarm.send(self._port_name, "getMotionType"))
async def coast(self) -> None:
await self.set_motion_type(MotionType.COAST)
async def brake(self) -> None:
await self.set_motion_type(MotionType.BRAKE)
async def run(self) -> None:
await self.set_motion_type(MotionType.ON)
class FtSwarmXMMotor(FtSwarmTractorMotor):
"""
XM motor
M1...M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.XMMOTOR
# TODO: implement encoder input
class FtSwarmEncoderMotor(FtSwarmTractorMotor):
"""
Encoder motor
M1...M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.ENCODER
class FtSwarmLamp(FtSwarmActor):
"""
Classic lamp or LED
M1...M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.LAMP
async def on(self, power=255) -> None:
await self._swarm.send(self._port_name, "setSpeed", power)
async def off(self) -> None:
await self._swarm.send(self._port_name, "setSpeed", 0)
class FtSwarmBinaryActor(FtSwarmActor):
"""
Base class for all binary actors
Don't use this class directly, use one of the derived classes instead
"""
async def on(self) -> None:
await self._swarm.send(self._port_name, "setSpeed", 255)
async def off(self) -> None:
await self._swarm.send(self._port_name, "setSpeed", 0)
class FtSwarmValve(FtSwarmBinaryActor):
"""
Electromagnetic Valve
M1...M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.VALVE
class FtSwarmCompressor(FtSwarmBinaryActor):
"""
Compressor
M1...M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.COMPRESSOR
class FtSwarmBuzzer(FtSwarmBinaryActor):
"""
Buzzer
M1...M2 all contollers - keep power budget in mind!
"""
async def get_actor_type(self) -> Actor:
return Actor.BUZZER
class FtSwarmServo(FtSwarmIO):
"""
Servo
ftSwarm only
A servo has 150mA typically, higher values with load. Keep power budget in mind!
"""
def __init__(self, swarm, port_name) -> None:
super().__init__(swarm, port_name)
self._position = 0
self._offset = 0
async def post_init(self) -> None:
self._offset = self._swarm.send(self._port_name, "getOffset")
self._position = self._swarm.send(self._port_name, "getPositon")
async def get_position(self) -> int:
return self._position
async def set_position(self, position) -> None:
self._position = position
await self._swarm.send(self._port_name, "setPosition", position)
async def get_offset(self) -> int:
return self._offset
async def set_offset(self, offset) -> None:
self._offset = offset
await self._swarm.send(self._port_name, "setOffset", offset)
class FtSwarmJoystick(FtSwarmIO):
"""
Joystick
ftSwarmControl only
"""
def __init__(self, swarm, port_name, hysteresis) -> None:
super().__init__(swarm, port_name)
self._lr = 0
self._fb = 0
self._hysteresis = hysteresis
async def post_init(self) -> None:
await self._swarm.send(self._port_name, "subscribe", self._hysteresis)
async def get_fb(self) -> int:
return self._fb
async def get_lr(self) -> int:
return self._lr
async def on_trigger_lr(self, trigger_event, actor, p1=None) -> None:
await self._swarm.send(self._port_name, "onTriggerLR", trigger_event, actor, *(p1 or []))
async def on_trigger_fb(self, trigger_event, actor, p1=None) -> None:
await self._swarm.send(self._port_name, "onTriggerFB", trigger_event, actor, *(p1 or []))
class FtSwarmPixel(FtSwarmIO):
"""
RGB LED
ftSwarm only
One LED takes up to 60mA, keep power budget in mind!
"""
def __init__(self, swarm, port_name) -> None:
super().__init__(swarm, port_name)
self._brightness = 0
self._color = 0
async def post_init(self) -> None:
self._brightness = await self._swarm.send(self._port_name, "getBrightness")
self._color = await self._swarm.send(self._port_name, "getColor")
async def get_brightness(self) -> int:
"""
Get the brightness of the LED
:return: brightness 0..255
"""
return self._brightness
async def set_brightness(self, brightness) -> None:
self._brightness = brightness
await self._swarm.send(self._port_name, "setBrightness", brightness)
async def get_color(self) -> int:
return self._color
async def set_color(self, color) -> None:
# If color is a tuple, reformat it as hex
if isinstance(color, tuple) or isinstance(color, list):
color = (color[0] << 16) + (color[1] << 8) + color[2]
self._color = color
await self._swarm.send(self._port_name, "setColor", color)
class FtSwarmI2C(FtSwarmIO):
"""
I2C slave with 4 registers
"""
def __init__(self, swarm, port_name) -> None:
super().__init__(swarm, port_name)
self.__register = [0, 0, 0, 0, 0, 0, 0, 0]
async def post_init(self) -> None:
for i in range(8):
self.__register[i] = await self._swarm.send(self._port_name, "getRegister", i)
await self._swarm.send(self._port_name, "subscribe")
async def get_register(self, reg) -> int:
return self.__register[reg]
async def set_register(self, reg, value) -> None:
self.__register[reg] = value
await self._swarm.send(self._port_name, "setRegister", reg, value)
async def on_trigger(self, trigger_event, actor, p1) -> None:
await self._swarm.send(self._port_name, "onTrigger", trigger_event, actor.get_port_name(), p1)
Classes
class Actor (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
All Actor types known by the ftSwarm
Expand source code
class Actor(IntEnum): """All Actor types known by the ftSwarm""" UNDEFINDED = -1 XMOTOR = 0 XMMOTOR = 1 TRACTOR = 2 ENCODER = 3 LAMP = 4 VALVE = 5 COMPRESSOR = 6 BUZZER = 7
Ancestors
- enum.IntEnum
- builtins.int
- enum.Enum
Class variables
var BUZZER
var COMPRESSOR
var ENCODER
var LAMP
var TRACTOR
var UNDEFINDED
var VALVE
var XMMOTOR
var XMOTOR
class Align (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
Text alignment for display
Expand source code
class Align(IntEnum): """Text alignment for display""" ALIGNLEFT = 0 ALIGNCENTER = 1 ALIGNRIGHT = 2
Ancestors
- enum.IntEnum
- builtins.int
- enum.Enum
Class variables
var ALIGNCENTER
var ALIGNLEFT
var ALIGNRIGHT
class FtSwarmActor (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Base class for all actors
Don't use this class directly, use one of the derived classes instead
Expand source code
class FtSwarmActor(FtSwarmIO): """ Base class for all actors Don't use this class directly, use one of the derived classes instead """ def __init__(self, swarm: FtSwarmBase, port_name: str, high_precision: bool = False) -> None: super().__init__(swarm, port_name) self._high_precision = high_precision async def post_init(self) -> None: await self._swarm.send(self._port_name, "setActorType", await self.get_actor_type(), self._high_precision) async def get_actor_type(self) -> Actor: return Actor.UNDEFINDED
Ancestors
Subclasses
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.UNDEFINDED
async def post_init(self) ‑> NoneType
-
Expand source code
async def post_init(self) -> None: await self._swarm.send(self._port_name, "setActorType", await self.get_actor_type(), self._high_precision)
class FtSwarmActorShim (swarm: FtSwarmBase, port_name: str)
-
Shim class for all ftSwarm actors for type annotations
Don't use this class at all
Expand source code
class FtSwarmActorShim(FtSwarmIO): """ Shim class for all ftSwarm actors for type annotations Don't use this class at all """ def get_port_name(self) -> str: pass
Ancestors
Methods
def get_port_name(self) ‑> str
-
Expand source code
def get_port_name(self) -> str: pass
class FtSwarmAnalogInput (swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0)
-
General analog input
Maps to ports A1…A6 on the ftSwarm specifically
Expand source code
class FtSwarmAnalogInput(FtSwarmInput): """ General analog input Maps to ports A1...A6 on the ftSwarm specifically """ async def get_sensor_type(self) -> Sensor: return Sensor.ANALOG async def get_value(self) -> int: return self._value
Ancestors
Subclasses
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.ANALOG
async def get_value(self) ‑> int
-
Expand source code
async def get_value(self) -> int: return self._value
class FtSwarmBase
-
Base class for all ftSwarm implementations
Expand source code
class FtSwarmBase: """Base class for all ftSwarm implementations""" def __init__(self) -> None: self.logger = logging.getLogger("swarm-base") async def send(self, port_name: str, command: str, *args: str | int | float) -> int | str | None: pass
Subclasses
Methods
async def send(self, port_name: str, command: str, *args: str | int | float) ‑> int | str | None
-
Expand source code
async def send(self, port_name: str, command: str, *args: str | int | float) -> int | str | None: pass
class FtSwarmBinaryActor (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Base class for all binary actors
Don't use this class directly, use one of the derived classes instead
Expand source code
class FtSwarmBinaryActor(FtSwarmActor): """ Base class for all binary actors Don't use this class directly, use one of the derived classes instead """ async def on(self) -> None: await self._swarm.send(self._port_name, "setSpeed", 255) async def off(self) -> None: await self._swarm.send(self._port_name, "setSpeed", 0)
Ancestors
Subclasses
Methods
async def off(self) ‑> NoneType
-
Expand source code
async def off(self) -> None: await self._swarm.send(self._port_name, "setSpeed", 0)
async def on(self) ‑> NoneType
-
Expand source code
async def on(self) -> None: await self._swarm.send(self._port_name, "setSpeed", 255)
class FtSwarmButton (swarm: FtSwarmBase, name: str)
-
Onboard button
This input is only available on the ftSwarmControl
Expand source code
class FtSwarmButton(FtSwarmDigitalInput): """ Onboard button This input is only available on the ftSwarmControl """ async def get_sensor_type(self) -> Sensor: return Sensor.BUTTON
Ancestors
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.BUTTON
class FtSwarmBuzzer (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Buzzer
M1…M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmBuzzer(FtSwarmBinaryActor): """ Buzzer M1...M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.BUZZER
Ancestors
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.BUZZER
class FtSwarmCompressor (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Compressor
M1…M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmCompressor(FtSwarmBinaryActor): """ Compressor M1...M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.COMPRESSOR
Ancestors
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.COMPRESSOR
class FtSwarmDigitalInput (swarm: FtSwarmBase, name: str)
-
Digital input
Maps to ports A1…A4 on all controller types
Expand source code
class FtSwarmDigitalInput(FtSwarmInput): """ Digital input Maps to ports A1...A4 on all controller types """ def __init__(self, swarm: FtSwarmBase, name: str) -> None: super().__init__(swarm, name, True, 0) async def get_sensor_type(self) -> Sensor: return Sensor.DIGITAL async def get_toggle(self) -> Toggle: return Toggle(await self._swarm.send(self._port_name, "getToggle")) async def get_state(self) -> bool: return self._value != 0 async def is_pressed(self) -> bool: return await self.get_state() async def is_released(self) -> bool: return not (await self.get_state()) async def has_toggled_up(self) -> bool: return (await self.get_toggle()) == Toggle.TOGGLEUP async def has_toggled_down(self) -> bool: return (await self.get_toggle()) == Toggle.TOGGLEDOWN
Ancestors
Subclasses
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.DIGITAL
async def get_state(self) ‑> bool
-
Expand source code
async def get_state(self) -> bool: return self._value != 0
async def get_toggle(self) ‑> Toggle
-
Expand source code
async def get_toggle(self) -> Toggle: return Toggle(await self._swarm.send(self._port_name, "getToggle"))
async def has_toggled_down(self) ‑> bool
-
Expand source code
async def has_toggled_down(self) -> bool: return (await self.get_toggle()) == Toggle.TOGGLEDOWN
async def has_toggled_up(self) ‑> bool
-
Expand source code
async def has_toggled_up(self) -> bool: return (await self.get_toggle()) == Toggle.TOGGLEUP
async def is_pressed(self) ‑> bool
-
Expand source code
async def is_pressed(self) -> bool: return await self.get_state()
async def is_released(self) ‑> bool
-
Expand source code
async def is_released(self) -> bool: return not (await self.get_state())
class FtSwarmEncoderMotor (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Encoder motor
M1…M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmEncoderMotor(FtSwarmTractorMotor): """ Encoder motor M1...M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.ENCODER
Ancestors
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.ENCODER
Inherited members
class FtSwarmI2C (swarm, port_name)
-
I2C slave with 4 registers
Expand source code
class FtSwarmI2C(FtSwarmIO): """ I2C slave with 4 registers """ def __init__(self, swarm, port_name) -> None: super().__init__(swarm, port_name) self.__register = [0, 0, 0, 0, 0, 0, 0, 0] async def post_init(self) -> None: for i in range(8): self.__register[i] = await self._swarm.send(self._port_name, "getRegister", i) await self._swarm.send(self._port_name, "subscribe") async def get_register(self, reg) -> int: return self.__register[reg] async def set_register(self, reg, value) -> None: self.__register[reg] = value await self._swarm.send(self._port_name, "setRegister", reg, value) async def on_trigger(self, trigger_event, actor, p1) -> None: await self._swarm.send(self._port_name, "onTrigger", trigger_event, actor.get_port_name(), p1)
Ancestors
Methods
async def get_register(self, reg) ‑> int
-
Expand source code
async def get_register(self, reg) -> int: return self.__register[reg]
async def on_trigger(self, trigger_event, actor, p1) ‑> NoneType
-
Expand source code
async def on_trigger(self, trigger_event, actor, p1) -> None: await self._swarm.send(self._port_name, "onTrigger", trigger_event, actor.get_port_name(), p1)
async def post_init(self) ‑> NoneType
-
Expand source code
async def post_init(self) -> None: for i in range(8): self.__register[i] = await self._swarm.send(self._port_name, "getRegister", i) await self._swarm.send(self._port_name, "subscribe")
async def set_register(self, reg, value) ‑> NoneType
-
Expand source code
async def set_register(self, reg, value) -> None: self.__register[reg] = value await self._swarm.send(self._port_name, "setRegister", reg, value)
class FtSwarmIO (swarm: FtSwarmBase, port_name: str)
-
Base class for all ftSwarm interfaces
Don't use this class at all
Expand source code
class FtSwarmIO: """ Base class for all ftSwarm interfaces Don't use this class at all """ def __init__(self, swarm: FtSwarmBase, port_name: str) -> None: self._port_name = port_name self._swarm = swarm async def post_init(self) -> None: pass async def get_port_name(self) -> str: return self._port_name async def set_value(self, value: str) -> None: self._swarm.logger.warning(f"Received unexpected write to {self._port_name}: {value}")
Subclasses
Methods
async def get_port_name(self) ‑> str
-
Expand source code
async def get_port_name(self) -> str: return self._port_name
async def post_init(self) ‑> NoneType
-
Expand source code
async def post_init(self) -> None: pass
async def set_value(self, value: str) ‑> NoneType
-
Expand source code
async def set_value(self, value: str) -> None: self._swarm.logger.warning(f"Received unexpected write to {self._port_name}: {value}")
class FtSwarmInput (swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0)
-
Base class for all ftSwarm inputs
Don't use this class at all
Expand source code
class FtSwarmInput(FtSwarmIO): """ Base class for all ftSwarm inputs Don't use this class at all """ def __init__(self, swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0): super().__init__(swarm, name) self._normallyOpen = normally_open self._value = 0 self._hysteresis = hysteresis async def post_init(self) -> None: await self._swarm.send(self._port_name, "setSensorType", await self.get_sensor_type(), self._normallyOpen) await self._swarm.send(self._port_name, "subscribe", self._hysteresis) self._value = await self._swarm.send(self._port_name, "getValue") async def get_sensor_type(self) -> Sensor: return Sensor.UNDEFINED async def on_trigger(self, trigger_event: Trigger, actor: FtSwarmActorShim, value: int | None = None) -> None: # The last parameter is optional, so we need to check if it is None await self._swarm.send(self._port_name, "onTrigger", trigger_event, actor.get_port_name(), *([value] or [])) async def set_value(self, str_value: str) -> None: self._value = int(str_value)
Ancestors
Subclasses
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.UNDEFINED
async def on_trigger(self, trigger_event: Trigger, actor: FtSwarmActorShim, value: int | None = None) ‑> NoneType
-
Expand source code
async def on_trigger(self, trigger_event: Trigger, actor: FtSwarmActorShim, value: int | None = None) -> None: # The last parameter is optional, so we need to check if it is None await self._swarm.send(self._port_name, "onTrigger", trigger_event, actor.get_port_name(), *([value] or []))
async def post_init(self) ‑> NoneType
-
Expand source code
async def post_init(self) -> None: await self._swarm.send(self._port_name, "setSensorType", await self.get_sensor_type(), self._normallyOpen) await self._swarm.send(self._port_name, "subscribe", self._hysteresis) self._value = await self._swarm.send(self._port_name, "getValue")
async def set_value(self, str_value: str) ‑> NoneType
-
Expand source code
async def set_value(self, str_value: str) -> None: self._value = int(str_value)
class FtSwarmJoystick (swarm, port_name, hysteresis)
-
Joystick
ftSwarmControl only
Expand source code
class FtSwarmJoystick(FtSwarmIO): """ Joystick ftSwarmControl only """ def __init__(self, swarm, port_name, hysteresis) -> None: super().__init__(swarm, port_name) self._lr = 0 self._fb = 0 self._hysteresis = hysteresis async def post_init(self) -> None: await self._swarm.send(self._port_name, "subscribe", self._hysteresis) async def get_fb(self) -> int: return self._fb async def get_lr(self) -> int: return self._lr async def on_trigger_lr(self, trigger_event, actor, p1=None) -> None: await self._swarm.send(self._port_name, "onTriggerLR", trigger_event, actor, *(p1 or [])) async def on_trigger_fb(self, trigger_event, actor, p1=None) -> None: await self._swarm.send(self._port_name, "onTriggerFB", trigger_event, actor, *(p1 or []))
Ancestors
Methods
async def get_fb(self) ‑> int
-
Expand source code
async def get_fb(self) -> int: return self._fb
async def get_lr(self) ‑> int
-
Expand source code
async def get_lr(self) -> int: return self._lr
async def on_trigger_fb(self, trigger_event, actor, p1=None) ‑> NoneType
-
Expand source code
async def on_trigger_fb(self, trigger_event, actor, p1=None) -> None: await self._swarm.send(self._port_name, "onTriggerFB", trigger_event, actor, *(p1 or []))
async def on_trigger_lr(self, trigger_event, actor, p1=None) ‑> NoneType
-
Expand source code
async def on_trigger_lr(self, trigger_event, actor, p1=None) -> None: await self._swarm.send(self._port_name, "onTriggerLR", trigger_event, actor, *(p1 or []))
async def post_init(self) ‑> NoneType
-
Expand source code
async def post_init(self) -> None: await self._swarm.send(self._port_name, "subscribe", self._hysteresis)
class FtSwarmLDR (swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0)
-
LDR
Maps to ports A1…A6 on the ftSwarm specifically At FtSwarmControl you could use a LDR with a FtSwarmDigitalInput as well
Expand source code
class FtSwarmLDR(FtSwarmAnalogInput): """ LDR Maps to ports A1...A6 on the ftSwarm specifically At FtSwarmControl you could use a LDR with a FtSwarmDigitalInput as well """ async def get_sensor_type(self) -> Sensor: return Sensor.LDR
Ancestors
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.LDR
class FtSwarmLamp (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Classic lamp or LED
M1…M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmLamp(FtSwarmActor): """ Classic lamp or LED M1...M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.LAMP async def on(self, power=255) -> None: await self._swarm.send(self._port_name, "setSpeed", power) async def off(self) -> None: await self._swarm.send(self._port_name, "setSpeed", 0)
Ancestors
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.LAMP
async def off(self) ‑> NoneType
-
Expand source code
async def off(self) -> None: await self._swarm.send(self._port_name, "setSpeed", 0)
async def on(self, power=255) ‑> NoneType
-
Expand source code
async def on(self, power=255) -> None: await self._swarm.send(self._port_name, "setSpeed", power)
class FtSwarmLightBarrier (swarm: FtSwarmBase, name: str)
-
Light barrier
Maps to ports A1…A4 on all controller types
Expand source code
class FtSwarmLightBarrier(FtSwarmDigitalInput): """ Light barrier Maps to ports A1...A4 on all controller types """ async def get_sensor_type(self) -> Sensor: return Sensor.LIGHTBARRIER
Ancestors
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.LIGHTBARRIER
class FtSwarmMotor (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
General motor class, use this class for (old) gray motors, mini motors, XS motors
M1..M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmMotor(FtSwarmActor): """ General motor class, use this class for (old) gray motors, mini motors, XS motors M1..M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.XMOTOR async def set_speed(self, speed) -> None: await self._swarm.send(self._port_name, "setSpeed", speed) async def get_speed(self) -> int: return await self._swarm.send(self._port_name, "getSpeed")
Ancestors
Subclasses
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.XMOTOR
async def get_speed(self) ‑> int
-
Expand source code
async def get_speed(self) -> int: return await self._swarm.send(self._port_name, "getSpeed")
async def set_speed(self, speed) ‑> NoneType
-
Expand source code
async def set_speed(self, speed) -> None: await self._swarm.send(self._port_name, "setSpeed", speed)
class FtSwarmOhmmeter (swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0)
-
Ohmmeter
Maps to ports A1…A6 on the ftSwarm specifically
Expand source code
class FtSwarmOhmmeter(FtSwarmAnalogInput): """ Ohmmeter Maps to ports A1...A6 on the ftSwarm specifically """ async def get_sensor_type(self) -> Sensor: return Sensor.OHMMETER async def get_resistance(self) -> int: return await self._swarm.send(self._port_name, "getResistance")
Ancestors
Methods
async def get_resistance(self) ‑> int
-
Expand source code
async def get_resistance(self) -> int: return await self._swarm.send(self._port_name, "getResistance")
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.OHMMETER
class FtSwarmPixel (swarm, port_name)
-
RGB LED
ftSwarm only One LED takes up to 60mA, keep power budget in mind!
Expand source code
class FtSwarmPixel(FtSwarmIO): """ RGB LED ftSwarm only One LED takes up to 60mA, keep power budget in mind! """ def __init__(self, swarm, port_name) -> None: super().__init__(swarm, port_name) self._brightness = 0 self._color = 0 async def post_init(self) -> None: self._brightness = await self._swarm.send(self._port_name, "getBrightness") self._color = await self._swarm.send(self._port_name, "getColor") async def get_brightness(self) -> int: """ Get the brightness of the LED :return: brightness 0..255 """ return self._brightness async def set_brightness(self, brightness) -> None: self._brightness = brightness await self._swarm.send(self._port_name, "setBrightness", brightness) async def get_color(self) -> int: return self._color async def set_color(self, color) -> None: # If color is a tuple, reformat it as hex if isinstance(color, tuple) or isinstance(color, list): color = (color[0] << 16) + (color[1] << 8) + color[2] self._color = color await self._swarm.send(self._port_name, "setColor", color)
Ancestors
Methods
async def get_brightness(self) ‑> int
-
Get the brightness of the LED :return: brightness 0..255
Expand source code
async def get_brightness(self) -> int: """ Get the brightness of the LED :return: brightness 0..255 """ return self._brightness
async def get_color(self) ‑> int
-
Expand source code
async def get_color(self) -> int: return self._color
async def post_init(self) ‑> NoneType
-
Expand source code
async def post_init(self) -> None: self._brightness = await self._swarm.send(self._port_name, "getBrightness") self._color = await self._swarm.send(self._port_name, "getColor")
async def set_brightness(self, brightness) ‑> NoneType
-
Expand source code
async def set_brightness(self, brightness) -> None: self._brightness = brightness await self._swarm.send(self._port_name, "setBrightness", brightness)
async def set_color(self, color) ‑> NoneType
-
Expand source code
async def set_color(self, color) -> None: # If color is a tuple, reformat it as hex if isinstance(color, tuple) or isinstance(color, list): color = (color[0] << 16) + (color[1] << 8) + color[2] self._color = color await self._swarm.send(self._port_name, "setColor", color)
class FtSwarmReedSwitch (swarm: FtSwarmBase, name: str)
-
Reed switch
Maps to ports A1…A4 on all controller types
Expand source code
class FtSwarmReedSwitch(FtSwarmDigitalInput): """ Reed switch Maps to ports A1...A4 on all controller types """ async def get_sensor_type(self) -> Sensor: return Sensor.REEDSWITCH
Ancestors
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.REEDSWITCH
class FtSwarmServo (swarm, port_name)
-
Servo
ftSwarm only
A servo has 150mA typically, higher values with load. Keep power budget in mind!
Expand source code
class FtSwarmServo(FtSwarmIO): """ Servo ftSwarm only A servo has 150mA typically, higher values with load. Keep power budget in mind! """ def __init__(self, swarm, port_name) -> None: super().__init__(swarm, port_name) self._position = 0 self._offset = 0 async def post_init(self) -> None: self._offset = self._swarm.send(self._port_name, "getOffset") self._position = self._swarm.send(self._port_name, "getPositon") async def get_position(self) -> int: return self._position async def set_position(self, position) -> None: self._position = position await self._swarm.send(self._port_name, "setPosition", position) async def get_offset(self) -> int: return self._offset async def set_offset(self, offset) -> None: self._offset = offset await self._swarm.send(self._port_name, "setOffset", offset)
Ancestors
Methods
async def get_offset(self) ‑> int
-
Expand source code
async def get_offset(self) -> int: return self._offset
async def get_position(self) ‑> int
-
Expand source code
async def get_position(self) -> int: return self._position
async def post_init(self) ‑> NoneType
-
Expand source code
async def post_init(self) -> None: self._offset = self._swarm.send(self._port_name, "getOffset") self._position = self._swarm.send(self._port_name, "getPositon")
async def set_offset(self, offset) ‑> NoneType
-
Expand source code
async def set_offset(self, offset) -> None: self._offset = offset await self._swarm.send(self._port_name, "setOffset", offset)
async def set_position(self, position) ‑> NoneType
-
Expand source code
async def set_position(self, position) -> None: self._position = position await self._swarm.send(self._port_name, "setPosition", position)
class FtSwarmSwitch (swarm: FtSwarmBase, name: str)
-
Mechanical switch Maps to ports A1…A4 on all controller types Wiring for fischertechnik switches: 1-3 is normally open, 1-2 is normally closed
Expand source code
class FtSwarmSwitch(FtSwarmDigitalInput): """ Mechanical switch Maps to ports A1...A4 on all controller types Wiring for fischertechnik switches: 1-3 is normally open, 1-2 is normally closed """ async def get_sensor_type(self) -> Sensor: return Sensor.SWITCH
Ancestors
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.SWITCH
class FtSwarmThermometer (swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0)
-
Thermometer based on 1.5kOhm NTC
Maps to ports A1…A6 on the ftSwarm specifically
Expand source code
class FtSwarmThermometer(FtSwarmAnalogInput): """ Thermometer based on 1.5kOhm NTC Maps to ports A1...A6 on the ftSwarm specifically """ async def get_sensor_type(self) -> Sensor: return Sensor.THERMOMETER async def get_celcius(self) -> int: return await self._swarm.send(self._port_name, "getCelcius") async def get_kelvin(self) -> int: return await self._swarm.send(self._port_name, "getKelvin") async def get_fahrenheit(self) -> int: return await self._swarm.send(self._port_name, "getFahrenheit")
Ancestors
Methods
async def get_celcius(self) ‑> int
-
Expand source code
async def get_celcius(self) -> int: return await self._swarm.send(self._port_name, "getCelcius")
async def get_fahrenheit(self) ‑> int
-
Expand source code
async def get_fahrenheit(self) -> int: return await self._swarm.send(self._port_name, "getFahrenheit")
async def get_kelvin(self) ‑> int
-
Expand source code
async def get_kelvin(self) -> int: return await self._swarm.send(self._port_name, "getKelvin")
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.THERMOMETER
class FtSwarmTractorMotor (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Tractor & XM motor
M1..M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmTractorMotor(FtSwarmMotor): """ Tractor & XM motor M1..M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.TRACTOR async def set_motion_type(self, motion_type) -> None: """ Set motion type of motor FtSwarmTractor has different options for stopping motor: :return: None """ await self._swarm.send(self._port_name, "setMotionType", motion_type) async def get_motion_type(self) -> MotionType: return MotionType(await self._swarm.send(self._port_name, "getMotionType")) async def coast(self) -> None: await self.set_motion_type(MotionType.COAST) async def brake(self) -> None: await self.set_motion_type(MotionType.BRAKE) async def run(self) -> None: await self.set_motion_type(MotionType.ON)
Ancestors
Subclasses
Methods
async def brake(self) ‑> NoneType
-
Expand source code
async def brake(self) -> None: await self.set_motion_type(MotionType.BRAKE)
async def coast(self) ‑> NoneType
-
Expand source code
async def coast(self) -> None: await self.set_motion_type(MotionType.COAST)
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.TRACTOR
async def get_motion_type(self) ‑> MotionType
-
Expand source code
async def get_motion_type(self) -> MotionType: return MotionType(await self._swarm.send(self._port_name, "getMotionType"))
async def run(self) ‑> NoneType
-
Expand source code
async def run(self) -> None: await self.set_motion_type(MotionType.ON)
async def set_motion_type(self, motion_type) ‑> NoneType
-
Set motion type of motor FtSwarmTractor has different options for stopping motor:
:return: None
Expand source code
async def set_motion_type(self, motion_type) -> None: """ Set motion type of motor FtSwarmTractor has different options for stopping motor: :return: None """ await self._swarm.send(self._port_name, "setMotionType", motion_type)
class FtSwarmValve (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
Electromagnetic Valve
M1…M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmValve(FtSwarmBinaryActor): """ Electromagnetic Valve M1...M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.VALVE
Ancestors
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.VALVE
class FtSwarmVoltmeter (swarm: FtSwarmBase, name: str, normally_open: bool = True, hysteresis: float = 0)
-
Voltmeter
Maps to port A2 on the ftSwarm specifically
Expand source code
class FtSwarmVoltmeter(FtSwarmAnalogInput): """ Voltmeter Maps to port A2 on the ftSwarm specifically """ async def get_sensor_type(self) -> Sensor: return Sensor.VOLTMETER async def get_voltage(self) -> int: return await self._swarm.send(self._port_name, "getVoltage")
Ancestors
Methods
async def get_sensor_type(self) ‑> Sensor
-
Expand source code
async def get_sensor_type(self) -> Sensor: return Sensor.VOLTMETER
async def get_voltage(self) ‑> int
-
Expand source code
async def get_voltage(self) -> int: return await self._swarm.send(self._port_name, "getVoltage")
class FtSwarmXMMotor (swarm: FtSwarmBase, port_name: str, high_precision: bool = False)
-
XM motor
M1…M2 all contollers - keep power budget in mind!
Expand source code
class FtSwarmXMMotor(FtSwarmTractorMotor): """ XM motor M1...M2 all contollers - keep power budget in mind! """ async def get_actor_type(self) -> Actor: return Actor.XMMOTOR
Ancestors
Methods
async def get_actor_type(self) ‑> Actor
-
Expand source code
async def get_actor_type(self) -> Actor: return Actor.XMMOTOR
Inherited members
class MotionType (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
How to move a motor
Expand source code
class MotionType(IntEnum): """How to move a motor""" COAST = 0 BRAKE = 1 ON = 2
Ancestors
- enum.IntEnum
- builtins.int
- enum.Enum
Class variables
var BRAKE
var COAST
var ON
class Sensor (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
All Sensor types known by the ftSwarm
Expand source code
class Sensor(IntEnum): """All Sensor types known by the ftSwarm""" UNDEFINED = -1 DIGITAL = 0 ANALOG = 1 SWITCH = 2 REEDSWITCH = 3 LIGHTBARRIER = 4 VOLTMETER = 5 OHMMETER = 6 THERMOMETER = 7 LDR = 8 TRAILSENSOR = 9 COLORSENSOR = 10 ULTRASONIC = 11 BUTTON = 12
Ancestors
- enum.IntEnum
- builtins.int
- enum.Enum
Class variables
var ANALOG
var BUTTON
var COLORSENSOR
var DIGITAL
var LDR
var LIGHTBARRIER
var OHMMETER
var REEDSWITCH
var SWITCH
var THERMOMETER
var TRAILSENSOR
var ULTRASONIC
var UNDEFINED
var VOLTMETER
class Toggle (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
Toggle states
Expand source code
class Toggle(IntEnum): """Toggle states""" NOTOGGLE = 0 TOGGLEUP = 1 TOGGLEDOWN = 2
Ancestors
- enum.IntEnum
- builtins.int
- enum.Enum
Class variables
var NOTOGGLE
var TOGGLEDOWN
var TOGGLEUP
class Trigger (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
Trigger events
Expand source code
class Trigger(IntEnum): """Trigger events""" TRIGGERUP = 0 TRIGGERDOWN = 1 TRIGGERVALUE = 2 TRIGGERI2CREAD = 3 TRIGGERI2CWRITE = 4
Ancestors
- enum.IntEnum
- builtins.int
- enum.Enum
Class variables
var TRIGGERDOWN
var TRIGGERI2CREAD
var TRIGGERI2CWRITE
var TRIGGERUP
var TRIGGERVALUE