# Path: concert/base.py
# class HardLimitError(StateError):
# 
#     """Raised when device goes into hardlimit error state."""
# 
#     def __init__(self, error_state='hard-limit', msg=None):
#         super(HardLimitError, self).__init__(error_state, msg)
# 
# class Quantity(Parameter):
# 
#     """A :class:`.Parameter` associated with a unit."""
# 
#     def __init__(self, unit, fget=None, fset=None, fget_target=None, lower=None, upper=None,
#                  data=None, check=None, external_lower_getter=None, external_upper_getter=None,
#                  user_lower_getter=None, user_lower_setter=None, user_upper_getter=None,
#                  user_upper_setter=None, help=None):
#         """
#         *fget*, *fset*, *data*, *check* and *help* are identical to the
#         :class:`.Parameter` constructor arguments.
# 
#         *unit* is a Pint quantity. *lower* and *upper* denote soft limits
#         between the :class:`.Quantity` values can lie.
#         """
#         super(Quantity, self).__init__(fget=fget, fset=fset, fget_target=fget_target, data=data,
#                                        check=check, help=help)
#         self.unit = unit
# 
#         self.upper = upper
#         self.lower = lower
#         self.external_lower_getter = external_lower_getter
#         self.external_upper_getter = external_upper_getter
#         self.user_lower_getter = user_lower_getter
#         self.user_lower_setter = user_lower_setter
#         self.user_upper_getter = user_upper_getter
#         self.user_upper_setter = user_upper_setter
# 
#     def convert(self, value):
#         return value.to(self.unit)
# 
# Path: concert/coroutines/base.py
# def start(coroutine):
#     """Wrap *coroutine* into a task and start its execution right away. The returned task will also
#     be cancellable by ctrl-k.
#     """
#     task = asyncio.ensure_future(coroutine)
#     task._is_concert_task = True
# 
#     return task
# 
# Path: concert/quantities.py

# 
# Path: concert/devices/motors/base.py
# LOG = logging.getLogger(__name__)
# class _PositionMixin(Device):
# class LinearMotor(_PositionMixin):
# class _VelocityMixin(object):
# class ContinuousLinearMotor(LinearMotor, _VelocityMixin):
# class RotationMotor(_PositionMixin):
# class ContinuousRotationMotor(RotationMotor, _VelocityMixin):
#     def __init__(self):
#     async def move(self, delta):
#     async def stop(self):
#     async def home(self):
#     async def enable(self):
#     async def disable(self):
#     async def _enable(self):
#     async def _disable(self):
#     async def _home(self):
#     async def _stop(self):
#     async def _emergency_stop(self):
#     def __init__(self):
#     async def _get_state(self):
#     async def _get_velocity(self):
#     def __init__(self):
#     async def _get_state(self):
#     async def _get_state(self):
#     def __init__(self):
#     def __init__(self):
#     async def _get_state(self):


import asyncio
import logging
import numpy as np
from concert.base import HardLimitError, Quantity
from concert.coroutines.base import start
from concert.quantities import q
from concert.devices.motors import base

    """A continuous linear motor dummy."""

    def __init__(self, position=None, upper_hard_limit=None, lower_hard_limit=None):
        base.ContinuousLinearMotor.__init__(self)
        LinearMotor.__init__(self)
        if position:
            self._position = position
        if upper_hard_limit:
            self._upper_hard_limit = upper_hard_limit
        if lower_hard_limit:
            self._lower_hard_limit = lower_hard_limit

    async def _set_velocity(self, vel):
        if vel.magnitude > 0:
            await self.set_motion_velocity(vel)
            if await self['position'].get_upper():
                start(self.set_position(await self['position'].get_upper()))
            else:
                start(self.set_position(np.inf * q.mm))
        if vel.magnitude < 0:
            await self.set_motion_velocity(vel)
            if await self['position'].get_lower():
                start(self.set_position(await self['position'].get_lower()))
            else:
                start(self.set_position(-np.inf * q.mm))
        if vel.magnitude == 0:
            start(self.stop())



# Path: concert/base.py
# class HardLimitError(StateError):
# 
#     """Raised when device goes into hardlimit error state."""
# 
#     def __init__(self, error_state='hard-limit', msg=None):
#         super(HardLimitError, self).__init__(error_state, msg)
# 
# class Quantity(Parameter):
# 
#     """A :class:`.Parameter` associated with a unit."""
# 
#     def __init__(self, unit, fget=None, fset=None, fget_target=None, lower=None, upper=None,
#                  data=None, check=None, external_lower_getter=None, external_upper_getter=None,
#                  user_lower_getter=None, user_lower_setter=None, user_upper_getter=None,
#                  user_upper_setter=None, help=None):
#         """
#         *fget*, *fset*, *data*, *check* and *help* are identical to the
#         :class:`.Parameter` constructor arguments.
# 
#         *unit* is a Pint quantity. *lower* and *upper* denote soft limits
#         between the :class:`.Quantity` values can lie.
#         """
#         super(Quantity, self).__init__(fget=fget, fset=fset, fget_target=fget_target, data=data,
#                                        check=check, help=help)
#         self.unit = unit
# 
#         self.upper = upper
#         self.lower = lower
#         self.external_lower_getter = external_lower_getter
#         self.external_upper_getter = external_upper_getter
#         self.user_lower_getter = user_lower_getter
#         self.user_lower_setter = user_lower_setter
#         self.user_upper_getter = user_upper_getter
#         self.user_upper_setter = user_upper_setter
# 
#     def convert(self, value):
#         return value.to(self.unit)
# 
# Path: concert/coroutines/base.py
# def start(coroutine):
#     """Wrap *coroutine* into a task and start its execution right away. The returned task will also
#     be cancellable by ctrl-k.
#     """
#     task = asyncio.ensure_future(coroutine)
#     task._is_concert_task = True
# 
#     return task
# 
# Path: concert/quantities.py

# 
# Path: concert/devices/motors/base.py
# LOG = logging.getLogger(__name__)
# class _PositionMixin(Device):
# class LinearMotor(_PositionMixin):
# class _VelocityMixin(object):
# class ContinuousLinearMotor(LinearMotor, _VelocityMixin):
# class RotationMotor(_PositionMixin):
# class ContinuousRotationMotor(RotationMotor, _VelocityMixin):
#     def __init__(self):
#     async def move(self, delta):
#     async def stop(self):
#     async def home(self):
#     async def enable(self):
#     async def disable(self):
#     async def _enable(self):
#     async def _disable(self):
#     async def _home(self):
#     async def _stop(self):
#     async def _emergency_stop(self):
#     def __init__(self):
#     async def _get_state(self):
#     async def _get_velocity(self):
#     def __init__(self):
#     async def _get_state(self):
#     async def _get_state(self):
#     def __init__(self):
#     def __init__(self):
#     async def _get_state(self):


# Path: concert/devices/motors/dummy.py
import asyncio
import logging
import numpy as np
from concert.base import HardLimitError, Quantity
from concert.coroutines.base import start
from concert.quantities import q
from concert.devices.motors import base


    """A continuous linear motor dummy."""

    def __init__(self, position=None, upper_hard_limit=None, lower_hard_limit=None):
        base.ContinuousLinearMotor.__init__(self)
        LinearMotor.__init__(self)
        if position:
            self._position = position
        if upper_hard_limit:
            self._upper_hard_limit = upper_hard_limit
        if lower_hard_limit:
            self._lower_hard_limit = lower_hard_limit

    async def _set_velocity(self, vel):
        if vel.magnitude > 0:
            await self.set_motion_velocity(vel)
            if await self['position'].get_upper():
                start(self.set_position(await self['position'].get_upper()))
            else:
                start(self.set_position(np.inf * q.mm))
        if vel.magnitude < 0:
            await self.set_motion_velocity(vel)
            if await self['position'].get_lower():
                start(self.set_position(await self['position'].get_lower()))
            else:
                start(self.set_position(-np.inf * q.mm))
        if vel.magnitude == 0:
            start(self.stop())



class RotationMotor(_PositionMixin, base.RotationMotor):