def main(project, *, plcs=None, include=None, exclude=None, macro=None): macros = util.split_macros(macro or []) include = include or [] exclude = exclude or [] solution_path, projects = util.get_tsprojects_from_filename(project.name) ioc_classes = [] for tsproj_project in projects: parsed_tsproj = pytmc.parser.parse(tsproj_project) for plc_name, plc_project in parsed_tsproj.plcs_by_name.items(): logger.debug('Project: %s PLC: %s', tsproj_project, plc_name) if plcs and plc_name not in plcs: logger.debug('Skipping; not in valid list: %s', plcs) continue try: ioc = caproto_ioc_from_plc( plc_name, plc_project, macros, includes=include, excludes=exclude) except Exception: logger.exception('Failed to create IOC for plc %s', plc_name) else: ioc_classes.append(ioc) parser, split_args = template_arg_parser( desc='Auto-generated mock PLC IOC', default_prefix='', argv=['--list-pvs'], macros={}, supported_async_libs=['asyncio'] ) def start_ioc(ioc_class): import asyncio asyncio.set_event_loop(asyncio.new_event_loop()) ioc_options, run_options = split_args( parser.parse_args(['--list-pvs'])) ioc = ioc_class(**ioc_options) caproto_run(ioc.pvdb, **run_options) # if len(ioc_classes) == 1: # start_ioc(ioc_classes[0]) # else: threads = [] for ioc_class in ioc_classes: thread = threading.Thread(target=start_ioc, kwargs=dict(ioc_class=ioc_class), daemon=True) thread.start() threads.append(thread) try: while any(thread.is_alive() for thread in threads): time.sleep(1) except KeyboardInterrupt: ...
def create_parser(): parser, split_args = template_arg_parser( default_prefix='TEST:FLUKE:985:', desc='Fluke 985 particle counter IOC', supported_async_libs=('asyncio', )) parser.add_argument('--host', help='Hostname or IP of the Fluke 985', required=True, type=str) parser.add_argument('--port', help='Port to connect to (mostly for debugging)', default=80, type=int) parser.add_argument('--autosave', help='Path to the autosave file', default='autosave.json', type=str) return parser, split_args
if ev.type not in (1, 3): continue try: # TODO also yield the event timestamp if ev.type == 1: key = digital_mapping[ev.code] yield key, ev.value elif ev.type == 3: key = analog_mapping[ev.code] yield key, ev.value except KeyError: print((ev.type, ev.code, ev.value)) if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='gp:', desc='Run an IOC that updates when gamepad buttons are pressed.', supported_async_libs=('asyncio', )) parser.add_argument('--event', help='The file descriptor in /dev/input to use', required=True, type=str) args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = GampadIOC(event_path=args.event, **ioc_options) run(ioc.pvdb, **run_options)
# Calculate new attenuator state using selected method if self.ATT_CALC_METHOD.value == att_calc_strings[0]: curr_att = self.current_att() new_att = UpDownByOne(peak_status, curr_att) else: # no other calculation methods supported right now new_att = self.current_att() preatt, posatt = EvenAttenuation(new_att) await self.write_att(preatt, posatt) if bi_strings.index(self.ENABLE_PEAK_SHARPEN.value): sig = PeakSharpen(sig, self.SHARPEN_K2.value) # self.SHARPEN_K4.value) ret = sig await instance.write(ret) if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='EM1K0:GMD:', desc='Simulate the data stream of the GMD.', supported_async_libs=('asyncio', )) parser.add_argument('--datafile', help='The .csv file the data is stored in', required=True, type=str) args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = GmdSimIoc(datafile=args.datafile, **ioc_options) ioc = GmdSimIoc(datafile=args.datafile, **ioc_options) run(ioc.pvdb, **run_options)
for pwm in self.pwm.values(): pwm.start(0) @color.shutdown async def color(self, instance, async_lib): for pwm in self.pwm.values(): pwm.ChangeDutyCycle(0) for pwm in self.pwm.values(): pwm.stop(0) for pin in self.pins.values(): GPIO.output(pin, GPIO.LOW) # Turn off all leds GPIO.cleanup() if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='rpi:', desc='Run an IOC that colors RGB LEDs.', supported_async_libs=('asyncio', )) for channel in ('red', 'green', 'blue'): parser.add_argument(f'--{channel}', help=f'The BOARD pin for the {channel} channel', required=True, type=str) args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = IOC(red=args.red, green=args.green, blue=args.blue, **ioc_options) run(ioc.pvdb, **run_options)
REFRESH_PERIOD = 1 class Sensor(pvproperty): def __init__(self, measure_func, *args, **kwargs): super(Sensor, self).__init__(*args, **kwargs) self.measure_func = measure_func self.startup(self.measure) async def measure(self, group, instance, async_lib): while True: await instance.write(value=self.measure_func()) await async_lib.library.sleep(REFRESH_PERIOD) class Sense(PVGroup): def __init__(self, *args, **kwargs): super(Sense, self).__init__(*args, **kwargs) Gas = Sensor(lambda : sense.gas, value=0, dtype=float, read_only=True) if __name__ == "__main__": parser, split_args = template_arg_parser(default_prefix='Sense:', desc='Raspberry Pi BME680 Air Quality') args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = Sense(**ioc_options) run(ioc.pvdb, **run_options)
ev = categorize(ev) if ev.keycode == 'KEY_ENTER': read = ''.join([ ev.keycode.split('_')[1] for ev in local if (ev.keystate and 'SHIFT' not in ev.keycode) ]) if not read: continue yield read local.clear() else: local.append(ev) if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='bc:', desc='Run an IOC that updates when a barcode is read.', supported_async_libs=('asyncio',)) parser.add_argument('--event', help='The file descriptor in /dev/input to use', required=True, type=str) args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = BarcodeIOC(event_path=args.event, **ioc_options) run(ioc.pvdb, **run_options)
value=0, dtype=float, read_only=True) Compass = Sensor(sense.get_compass, value=0, dtype=float, read_only=True) Text = pvproperty(value='', dtype=str) @Text.startup async def Text(self, instance, async_lib): instance.loop = async_lib.library.get_event_loop() @Text.putter async def Text(self, instance, value): await instance.loop.run_in_executor(None, sense.show_message, value, self.scroll_speed, self.text_colour, self.back_colour) return value # TODO: why is this value not set? # TODO: check with put completion # caput -c <- if __name__ == "__main__": parser, split_args = template_arg_parser(default_prefix='Sense:', desc='Raspberry Pi SenseHat') args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = Sense(**ioc_options) run(ioc.pvdb, **run_options)
The compiled code object. names : set of str Node / variable names. """ output_name, _, expr = map(lambda x: x.strip(), code_string.partition('=')) ast_node = ast.parse(expr) code_object = compile(expr, '', 'eval') return (output_name, expr, code_object, set(node.id for node in ast.walk(ast_node) if isinstance(node, ast.Name) and node.id not in NP_NAMES)) if __name__ == '__main__': parser, split_args = template_arg_parser(default_prefix='Formula:', desc=dedent(FormulaIOC.__doc__)) # add our own CLI argument parser.add_argument( '--formula', help='The formula to evaluate. Must be a python expression.', required=True, type=str, ) args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = create_ioc(args.formula)(**ioc_options) run(ioc.pvdb, **run_options)
if(self._hw_error_val == 'True'): # if hw error -> fail await fail_to_state.write(value='True') return self._cmd_states[1] else: await fail_to_state.write(value='False') if(self._sts_error_val == 'True'): # if sts error -> don't change sts return self._cmd_states[1] await self.pos_sts.write(value=state_val) self._pos_sts_val = state_val return self._cmd_states[0] if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='eps2state:', desc='EPS Two State IOC.') retries_help = 'Number of attempts required for changing state' enable_help = 'State change is enabled' hwerror_help = 'HW error is activated' stserror_help = 'Pos-Sts error is activated' parser.add_argument('--retries', help=retries_help, required=False, default=2, type=int) parser.add_argument('--enable', help=enable_help, required=False, default='True', type=str) parser.add_argument('--hwerror', help=hwerror_help, required=False, default='False', type=str) parser.add_argument('--stserror', help=stserror_help, required=False, default='False', type=str)
class RecordMockingIOC(PVGroup): A = pvproperty(**rec_kwargs) ioc = RecordMockingIOC(**ioc_options) prefix = ioc_options['prefix'] print( f'{prefix}A is mocking {record_type!r} record with default value ' f'{default_value!r} ({val_dtype}) and fields:', ', '.join(ioc.A.fields)) run(ioc.pvdb, **run_options) if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='any:record:', desc='Run an IOC that mocks an arbitrary record type') record_options = ', '.join(sorted(records)) parser.add_argument( '--record-type', help=f'The record type to use for `A`. Options are: {record_options}', type=str, default='ai') args = parser.parse_args() ioc_options, run_options = split_args(args) start_ioc(args.record_type, ioc_options=ioc_options, run_options=run_options)
if period < 10e-15: period = 0.5 j = 0 @steady.startup async def steady(self, instance, async_lib): period = .1 for j in itertools.count(): await instance.write(value=j % 1000) await async_lib.library.sleep(period) if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='chirp:', desc= 'One PV updates at a steady rate; another "chirps" (accelerating updates).' ) def in_range(v): v = float(v) if not (0 < v < 1): raise argparse.ArguementTypeError(f" {v} not in range [0, 1]") return v parser.add_argument('--ramprate', help='The multiplicative factor to apply to the', type=in_range, default=0.75) args = parser.parse_args()
await instance.write(value=chirp_value) await async_lib.sleep(update_period) update_period *= self.ramp_rate chirp_value += 1 if update_period < 10e-15: update_period = 0.5 chirp_value = 0 @steady.scan(period=0.1) async def steady(self, instance, async_lib): await instance.write(value=(self.steady.value + 1) % 1000) if __name__ == "__main__": parser, split_args = template_arg_parser( default_prefix="chirp:", desc=textwrap.dedent(Chirp.__doc__), ) def in_range(v): v = float(v) if not (0 < v < 1): raise argparse.ArgumentTypeError(f" {v} not in range [0, 1]") return v parser.add_argument( "--ramprate", help="The multiplicative factor to apply when chirping.", type=in_range, default=0.75, )
response.data, # We can even make the timestamp the same: timestamp=response.metadata.timestamp, ) @value.startup async def value(self, instance, async_lib): # Note that the asyncio context must be created here so that it knows # which asyncio loop to use: self.client_context = Context() self.pv, = await self.client_context.get_pvs(self.target) # Subscribe to the target PV and register self._callback. self.subscription = self.pv.subscribe(data_type='time') self.subscription.add_callback(self._callback) if __name__ == '__main__': parser, split_args = template_arg_parser( default_prefix='mirror:', desc='Mirror the value of another floating-point PV.', supported_async_libs=('asyncio',) ) parser.add_argument('--target', help='The PV to mirror', required=True, type=str) args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = Mirror(target=args.target, **ioc_options) run(ioc.pvdb, **run_options)
return self.pantilthat.get_pan() @Pan.putter async def Pan(self, instance, value): self.pantilthat.pan(value) Tilt = pvproperty(dtype=float) @Tilt.getter async def Tilt(self, instance): return self.pantilthat.get_tilt() @Tilt.putter async def Tilt(self, instance, value): self.pantilthat.tilt(value) # Another option is to implement devices directly with ophyd objects. This will cut out one step of IPC, however fewer # tools support ophyd objects directly. # https://gist.github.com/danielballan/84484f940aea836ac997d3873c88d762 if __name__ == "__main__": parser, split_args = template_arg_parser( default_prefix='Camera:', desc='Raspberry Pi HQ Camera with tilt-pan control') args = parser.parse_args() ioc_options, run_options = split_args(args) ioc = Camera(**ioc_options) run(ioc.pvdb, **run_options)