Example #1
0
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:
        ...
Example #2
0
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
Example #3
0
            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)
Example #4
0
            # 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)
Example #5
0
        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)
Example #6
0
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)

Example #7
0
            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)
Example #8
0
                            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)
Example #9
0
        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)
Example #10
0
        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)
Example #11
0
    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)
Example #12
0
            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()
Example #13
0
            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,
    )
Example #14
0
            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)
Example #15
0
        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)