Пример #1
0
    def __init__(self, arduino_wait=2, sleep_tune=0.0001, log_output=False,com_port=None, 
                 ip_address=None, ip_port=2000,
                 ip_handshake='*HELLO*'):
        PymataCore.__init__(self, arduino_wait, sleep_tune, log_output, com_port, ip_address, ip_port,ip_handshake)

        # report query results are stored in this dictionary
        self.query_reply_data[BoardConstants.DHT11_DATA] = None
        self.command_dictionary[BoardConstants.DHT11_DATA] = self._dht_data
        self.command_dictionary[BoardConstants.PING_DATA] = self._ping_data
        self.dht_map = {}
        self.ping_map = {}
Пример #2
0
    async def open(self) -> Transport:
        """Establish and return a transport-layer connection to the device.

        Establishes a connection session with a mutual handshake specified by
        the transport-layer protocol. Once the connection is established,
        messages can be sent over the transport layer.

        Blocks until the connection is established.
        """
        # Connect board
        logger.info('Please plug in the device now...')
        self._board = PymataCore(**self._board_kwargs)
        self.transport = Transport(self._board, **self.transport_kwargs)
        self.transport.register_message_listener(self._on_sysex_message)
        await self._board.start_aio()
        logger.debug('Established datalink-layer connection!')
        self._handshake_started = False
        self._connected = False
        # Establish mutual handshake
        logger.debug('Initiating handshake for transport-layer connection...')
        while self.transport is not None and not self._connected:
            if self._handshake_started:
                await self.transport.send_serialized_message('')
            await asyncio.sleep(self._handshake_attempt_interval)
        # Set up event handling
        self.transport.start_receiving_serialized_messages()
        logger.info('Established transport-layer connection!')
        return self.transport
Пример #3
0
    def __init__(self, port='', pwmMax=100):
        board = None

        try:
            #Board init
            if len(port) > 0:
                board = PymataCore(com_port=port)
            else:
                board = PymataCore()

        except Exception as excObj:
            print("Something is wrong: {0}".format(excObj))
            raise excObj

        self.__board = board
        self.__board.start()

        #Led init
        self.leds = {
            1: Led(board, 10, False, Constants.PWM, pwmMax),
            2: Led(board, 9, False, Constants.PWM, pwmMax),
            3: Led(board, 5, False, Constants.PWM, pwmMax),
            4: Led(board, 4, False, Constants.OUTPUT, 1),
            5: Led(board, 8, True, Constants.OUTPUT, 1)
        }
        #Buzzer init

        #Keyboard init
        self.keys = {
            1: Key(board, 13),
            2: Key(board, 12),
            3: Key(board, 7),
            4: Key(board, 8)
        }
        #Sensors init
        self.sensorLight = AnalogSensor(board, 0)
        self.sensorTemperature = AnalogSensor(board, 1)
        self.sensorAlcohol = AnalogSensor(board, 2)
        self.sensorAxisX = AnalogSensor(board, 3)
        self.sensorAxisY = AnalogSensor(board, 4)
        self.sensorAxisZ = AnalogSensor(board, 5)
    async def kick_off(self, my_loop):
        """
        After s2aio is instantiated, this method must be called to start the HTTP server,
        instantiate tye pymata_core interface to the arduino board, open Scratch and start
        the polling watchdog timer to detect when Scratch stops polling.

        :param my_loop: The asyncio event loop
        :return: A reference to this server
        """
        self.loop = my_loop
        # noinspection PyBroadException
        try:
            # instantiate the arduino interface
            self.board = PymataCore(com_port=self.com_port)
            await self.board.start_aio()

            # populate the arduino pin capability lists
            await self.get_pin_capabilities()

            # start up the HTTP server
            app = web.Application(loop=my_loop)
            srv = await my_loop.create_server(app.make_handler(), '127.0.0.1', 50209)

            # start scratch if specified
            # open to a specified project

            if self.client == 'scratch':
                if self.scratch_executable and self.scratch_project:
                    # noinspection PyPep8
                    if sys.platform.startswith('win32'):
                        os_string = "start /b " + self.scratch_executable + ' ' + self.scratch_project
                        await asyncio.sleep(self.windows_wait_time)
                        os.system(os_string)
                    else:
                        # noinspection PyPep8
                        os_string = 'nohup ' + self.scratch_executable + ' ' + self.scratch_project + ' ' + ' > /dev/null 2>&1 &'
                        os.system(os_string)
                elif self.scratch_executable and not self.scratch_project:
                    os_string = 'nohup ' + self.scratch_executable + '> /dev/null 2>&1 &'
                    os.system(os_string)
                else:
                    print('You must provide scratch excutable information')
            elif self.client == 'snap':
                new = 2
                webbrowser.open(self.snap_url, new=new)
                await asyncio.sleep(self.windows_wait_time)
            else:
                # no client specified, just start s2aio and wait for the user to start the client of choice
                pass

            # Scratch command handlers
            app.router.add_route('GET', '/digital_pin_mode/{enable}/{pin}/{mode}', self.setup_digital_pin)
            app.router.add_route('GET', '/analog_pin_mode/{enable}/{pin}', self.setup_analog_pin)
            app.router.add_route('GET', '/poll', self.poll)
            app.router.add_route('GET', '/digital_write/{pin}/{value}', self.digital_write)
            app.router.add_route('GET', '/analog_write/{pin}/{value}', self.analog_write)
            app.router.add_route('GET', '/play_tone/{pin}/{frequency}/{duration}', self.play_tone)
            app.router.add_route('GET', '/set_servo_position/{pin}/{position}', self.set_servo_position)
            app.router.add_route('GET', '/tone_off/{pin}', self.tone_off)

            # Snap requires reporters to be supported
            app.router.add_route('GET', '/digital_read/{pin}', self.digital_read)
            app.router.add_route('GET', '/analog_read/{pin}', self.analog_read)
            app.router.add_route('GET', '/problem', self.problem)

            if self.client == 'scratch':
                await self.poll_watchdog()
            else:
                await self.keep_alive()
            return srv
        except:
            pass
Пример #5
0
    print(
        '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
        + str(data))


async def latching(my_board):
    """
    Set digital pin 6 as a PWM output and set its output value to 128
    @param my_board: A PymataCore instance
    @return: No Return Value
    """
    # set the pin mode
    # await my_board.set_pin_mode(2, Constants.ANALOG, pin_callback, Constants.CB_TYPE_ASYNCIO)
    await my_board.set_pin_mode(2, Constants.ANALOG)

    await my_board.set_analog_latch(2, Constants.LATCH_GT, 500, latch_callback,
                                    Constants.CB_TYPE_ASYNCIO)

    while True:
        await asyncio.sleep(1)
        #value = await my_board.analog_read(2)
        #print(value)


# create a PyMataCore instance and complete the initialization with a call to start()
board = PymataCore()
board.start()

# get the loop, and execute pin6_pwm_128
loop = asyncio.get_event_loop()
loop.run_until_complete(latching(board))
Пример #6
0
# your code goes here
async def blink(my_board):
    """
    Blink LED 13
    @return: No Return Value
    """
    # set the pin mode
    await my_board.set_pin_mode(13, Constants.OUTPUT)

    for i in range(0, 5):
        await my_board.digital_write(13, 1)
        await asyncio.sleep(1)
        await my_board.digital_write(13, 0)
        await asyncio.sleep(1)


if __name__ == "__main__":
    # create a PyMataCore instance and complete the initialization with a call to start_aio()
    board = PymataCore()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(board.start_aio())

    # now execute your code on the loop and shutdown when done
    try:
        loop.run_until_complete(blink(board))
        loop.run_until_complete(board.shutdown())
    except RuntimeError:
        loop.run_until_complete(board.shutdown())
        exit(0)
Пример #7
0
if args.com == 'None':
    comport = None
else:
    comport = args.com

if args.log == 'True':
    log = True
else:
    log = False

ard_ip_addr = args.aIPaddr
ard_ip_port = args.aIPport
ard_handshake = args.handshake

core = PymataCore(int(args.wait), float(args.sleep), log, comport,
                  ard_ip_addr, ard_ip_port, ard_handshake)

# core = PymataCore()
core.start()


# Signal handler to trap control C
# noinspection PyUnusedLocal,PyUnusedLocal
def _signal_handler(sig, frame):
    if core is not None:
        print('\nYou pressed Ctrl+C')
        task = asyncio.ensure_future(core.shutdown())
        asyncio.get_event_loop().run_until_complete(task)
        sys.exit(1)

Пример #8
0
        return [xa, ya, za, cx, cy, cz]

    async def wait_for_read_result(self):
        """
        This is a utility function to wait for return data call back
        @return: Returns resultant data from callback
        """
        while not self.callback_data:
            await asyncio.sleep(.001)
        rval = self.callback_data
        self.callback_data = []
        return rval


if __name__ == "__main__":
    my_board = PymataCore(2)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(my_board.start_aio())
    accel = RedBotAccel(my_board, 0x1d, 2, 0)
    loop.run_until_complete(accel.start())
    while True:
        availb = loop.run_until_complete(accel.available())
        if availb:
            axis = loop.run_until_complete(accel.read())

            x = axis[3]
            y = axis[4]
            z = axis[5]

            tap = loop.run_until_complete(accel.read_tap())
            if tap:
Пример #9
0
        return [xa, ya, za, cx, cy, cz]

    async def wait_for_read_result(self):
        """
        This is a utility function to wait for return data call back
        @return: Returns resultant data from callback
        """
        while not self.callback_data:
            await asyncio.sleep(.001)
        rval = self.callback_data
        self.callback_data = []
        return rval


if __name__ == "__main__":
    my_board = PymataCore(2)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(my_board.start_aio())
    accel = RedBotAccel(my_board, 0x1d, 2, 0)
    loop.run_until_complete(accel.start())
    while True:
        availb = loop.run_until_complete(accel.available())
        if availb:
            axis = loop.run_until_complete(accel.read())

            x = axis[3]
            y = axis[4]
            z = axis[5]

            tap = loop.run_until_complete(accel.read_tap())
            if tap:
if args.com == 'None':
    comport = None
else:
    comport = args.com

if args.log == 'True':
    log = True
else:
    log = False

ard_ip_addr = args.aIPaddr
ard_ip_port = args.aIPport
ard_handshake = args.handshake

core = PymataCore(int(args.wait), float(args.sleep), log, comport,
                  ard_ip_addr, ard_ip_port, ard_handshake)

# core = PymataCore()
core.start()


# Signal handler to trap control C
# noinspection PyUnusedLocal,PyUnusedLocal
def _signal_handler(sig, frame):
    if core is not None:
        print('\nYou pressed Ctrl+C')
        task = asyncio.ensure_future(core.shutdown())
        asyncio.get_event_loop().run_until_complete(task)
        sys.exit(1)

Пример #11
0
class PymataIOT(WebSocketServerProtocol):
    """
    This class implements the PyMata Websocket interface. JSON command messages are received via Websocket connection,
    decoded and mapped to an associated PyMata method to be executed
    operation.

    The methods below are not intended to be called directly. The JSON message format is documented as part of the
    method description. All JSON reply messages (to be handled by the client)  will also be documented for
    within the description.

    usage: pymata_iot.py [-h] [-host HOSTNAME] [-port PORT] [-wait WAIT]
                     [-comport COM] [-sleep SLEEP] [-log LOG]

        optional arguments:
          -h, --help      show this help message and exit
          -host HOSTNAME  Server name or IP address
          -port PORT      Server port number
          -wait WAIT      Arduino wait time
          -comport COM    Arduino COM port
          -sleep SLEEP    sleep tune in ms.
          -log LOG        True = send output to file, False = send output to console
    """
    parser = argparse.ArgumentParser()
    parser.add_argument("-host",
                        dest="hostname",
                        default="localhost",
                        help="Server name or IP address")
    parser.add_argument("-port",
                        dest="port",
                        default="9000",
                        help="Server port number")
    parser.add_argument("-wait",
                        dest="wait",
                        default="2",
                        help="Arduino wait time")
    parser.add_argument("-comport",
                        dest="com",
                        default="None",
                        help="Arduino COM port")
    parser.add_argument("-sleep",
                        dest="sleep",
                        default=".001",
                        help="sleep tune in ms.")
    parser.add_argument("-log",
                        dest="log",
                        default="False",
                        help="redirect console output to log file")
    args = parser.parse_args()

    ip_addr = args.hostname
    ip_port = args.port

    if args.com == 'None':
        comport = None
    else:
        comport = args.com

    if args.log == 'True':
        log = True
    else:
        log = False

    core = PymataCore(int(args.wait), float(args.sleep), log, comport)
    core.start()

    def __init__(self):
        """
        This is the "constructor" for PymataIOT. It sets up a translation dictionary using incoming JSON commands
        and maps them to command methods.
        @return: No Return.
        """

        self.command_map = {
            "analog_read": self.analog_read,
            "analog_write": self.analog_write,
            "digital_read": self.digital_read,
            "digital_write": self.digital_write,
            "disable_analog_reporting": self.disable_analog_reporting,
            "disable_digital_reporting": self.disable_digital_reporting,
            "enable_analog_reporting": self.disable_analog_reporting,
            "enable_digital_reporting": self.disable_digital_reporting,
            "encoder_config": self.encoder_config,
            "encoder_read": self.encoder_read,
            "get_analog_latch_data": self.get_analog_latch_data,
            "get_analog_map": self.get_analog_map,
            "get_capability_report": self.get_capability_report,
            "get_digital_latch_data": self.get_digital_latch_data,
            "get_firmware_version": self.get_firmware_version,
            "get_pin_state": self.get_pinstate_report,
            "get_protocol_version": self.get_protocol_version,
            "get_pymata_version": self.get_pymata_version,
            "i2c_config": self.i2c_config,
            "i2c_read_data": self.i2c_read_data,
            "i2c_read_request": self.i2c_read_request,
            "i2c_write_request": self.i2c_write_request,
            "play_tone": self.play_tone,
            "set_analog_latch": self.set_analog_latch,
            "set_digital_latch": self.set_digital_latch,
            "set_pin_mode": self.set_pin_mode,
            "set_sampling_interval": self.set_sampling_interval,
            "sonar_config": self.sonar_config,
            "sonar_read": self.sonar_read,
            "servo_config": self.servo_config,
            "stepper_config": self.stepper_config,
            "stepper_step": self.stepper_step
        }

    @asyncio.coroutine
    def analog_read(self, command):
        """
        This method reads and returns the last reported value for an analog pin.
        Normally not used since analog pin updates will be provided automatically
        as they occur with the analog_message_reply being sent to the client after set_pin_mode is called.
        (see enable_analog_reporting for message format).

        @param command: {"method": "analog_read", "params": [ANALOG_PIN]}
        @return: {"method": "analog_read_reply", "params": [PIN, ANALOG_DATA_VALUE]}
        """
        pin = int(command[0])
        data_val = yield from self.core.analog_read(pin)
        reply = json.dumps({
            "method": "analog_read_reply",
            "params": [pin, data_val]
        })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def analog_write(self, command):
        """
        This method writes a value to an analog pin.

        It is used to set the output of a PWM pin or the angle of a Servo.
        @param command: {"method": "analog_write", "params": [PIN, WRITE_VALUE]}
        @return: No return message.
        """
        pin = int(command[0])
        value = int(command[1])
        yield from self.core.analog_write(pin, value)

    @asyncio.coroutine
    def digital_read(self, command):
        """
        This method reads and returns the last reported value for a digital pin.
        Normally not used since digital pin updates will be provided automatically
        as they occur with the digital_message_reply being sent to the client after set_pin_mode is called..
        (see enable_digital_reporting for message format)

        @param command: {"method": "digital_read", "params": [PIN]}
        @return: {"method": "digital_read_reply", "params": [PIN, DIGITAL_DATA_VALUE]}
        """
        pin = int(command[0])
        data_val = yield from self.core.digital_read(pin)
        reply = json.dumps({
            "method": "digital_read_reply",
            "params": [pin, data_val]
        })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def digital_write(self, command):
        """
        This method writes a zero or one to a digital pin.
        @param command: {"method": "digital_write", "params": [PIN, DIGITAL_DATA_VALUE]}
        @return: No return message..
        """
        pin = int(command[0])
        value = int(command[1])
        yield from self.core.digital_write(pin, value)

    @asyncio.coroutine
    def disable_analog_reporting(self, command):
        """
        Disable Firmata reporting for an analog pin.
        @param command: {"method": "disable_analog_reporting", "params": [PIN]}
        @return: No return message..
        """
        pin = int(command[0])
        yield from self.core.disable_analog_reporting(pin)

    @asyncio.coroutine
    def disable_digital_reporting(self, command):
        """
        Disable Firmata reporting for a digital pin.
        @param command: {"method": "disable_digital_reporting", "params": [PIN]}
        @return: No return message.
        """
        pin = int(command[0])
        yield from self.core.disable_digital_reporting(pin)

    @asyncio.coroutine
    def enable_analog_reporting(self, command):
        """
        Enable Firmata reporting for an analog pin.
        @param command: {"method": "enable_analog_reporting", "params": [PIN]}
        @return: {"method": "analog_message_reply", "params": [PIN, ANALOG_DATA_VALUE]}
        """
        pin = int(command[0])
        yield from self.core.enable_analog_reporting(pin)

    @asyncio.coroutine
    def enable_digital_reporting(self, command):
        """
        Enable Firmata reporting for a digital pin.

        @param command: {"method": "enable_digital_reporting", "params": [PIN]}
        @return: {"method": "digital_message_reply", "params": [PIN, DIGITAL_DATA_VALUE]}
        """
        pin = int(command[0])
        yield from self.core.enable_digital_reporting(pin)

    @asyncio.coroutine
    def encoder_config(self, command):
        """
        Configure 2 pins for FirmataPlus encoder operation.

        @param command: {"method": "encoder_config", "params": [PIN_A, PIN_B]}
        @return: {"method": "encoder_data_reply", "params": [ENCODER_DATA]}
        """
        pin_a = int(command[0])
        pin_b = int(command[1])
        yield from self.core.encoder_config(pin_a, pin_b,
                                            self.encoder_callback)

    @asyncio.coroutine
    def encoder_read(self, command):
        """
        This is a polling method to read the last cached FirmataPlus encoder value.
        Normally not used. See encoder config for the asynchronous report message format.

        @param command: {"method": "encoder_read", "params": [PIN_A]}
        @return: {"method": "encoder_read_reply", "params": [PIN_A, ENCODER_VALUE]}
        """
        pin = int(command[0])
        val = yield from self.core.encoder_read(pin)
        reply = json.dumps({
            "method": "encoder_read_reply",
            "params": [pin, val]
        })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_analog_latch_data(self, command):
        """
        This method retrieves a latch table entry for an analog pin.

        See constants.py for definition of reply message parameters.

        @param command:  {"method": "get_analog_latch_data", "params": [ANALOG_PIN]}
        @return: {"method": "get_analog_latch_data_reply", "params": [ANALOG_PIN, LATCHED_STATE, THRESHOLD_TYPE,\
         THRESHOLD_TARGET, DATA_VALUE, TIME_STAMP ]}
        """
        pin = int(command[0])
        data_val = yield from self.core.get_analog_latch_data(pin)
        if data_val:
            data_val = data_val[0:-1]
        reply = json.dumps({
            "method": "get_analog_latch_data_reply",
            "params": [pin, data_val]
        })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_analog_map(self):
        """
        This method retrieves the Firmata analog map.

        Refer to: http://firmata.org/wiki/Protocol#Analog_Mapping_Query to interpret the reply

        The command JSON format is: {"method":"get_analog_map","params":["null"]}
        @return: {"method": "analog_map_reply", "params": [ANALOG_MAP]}
        """
        value = yield from self.core.get_analog_map()
        if value:
            reply = json.dumps({"method": "analog_map_reply", "params": value})
        else:
            reply = json.dumps({
                "method": "analog_map_reply",
                "params": "None"
            })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_capability_report(self):
        """
        This method retrieves the Firmata capability report.

        Refer to http://firmata.org/wiki/Protocol#Capability_Query

        The command format is: {"method":"get_capability_report","params":["null"]}

        @return: {"method": "capability_report_reply", "params": [RAW_CAPABILITY_REPORT]}
        """
        value = yield from self.core.get_capability_report()
        asyncio.sleep(.1)
        if value:
            reply = json.dumps({
                "method": "capability_report_reply",
                "params": value
            })
        else:
            reply = json.dumps({
                "method": "capability_report_reply",
                "params": "None"
            })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_digital_latch_data(self, command):
        """
        This method retrieves a latch table entry for a digital pin.

        See constants.py for definition of reply message parameters.

        @param command:  {"method": "get_digital_latch_data", "params": [ANALOG_PIN]}
        @return: {"method": "get_digital_latch_data_reply", "params": [DIGITAL_PIN, LATCHED_STATE, THRESHOLD_TYPE,\
         THRESHOLD_TARGET, DATA_VALUE, TIME_STAMP ]}
        """
        pin = int(command[0])
        data_val = yield from self.core.get_digital_latch_data(pin)
        if data_val:
            data_val = data_val[0:-1]
        reply = json.dumps({
            "method": "get_digital_latch_data_reply",
            "params": [pin, data_val]
        })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_firmware_version(self):
        """
        This method retrieves the Firmata firmware version.

        See: http://firmata.org/wiki/Protocol#Query_Firmware_Name_and_Version


        JSON command: {"method": "get_firmware_version", "params": ["null"]}

        @return: {"method": "firmware_version_reply", "params": [FIRMWARE_VERSION]}
        """
        value = yield from self.core.get_firmware_version()
        if value:
            reply = json.dumps({
                "method": "firmware_version_reply",
                "params": value
            })
        else:
            reply = json.dumps({
                "method": "firmware_version_reply",
                "params": "Unknown"
            })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_pinstate_report(self, command):
        """
        This method retrieves a Firmata pin_state report for a pin..

        See: http://firmata.org/wiki/Protocol#Pin_State_Query

        @param command: {"method": "get_pin_state", "params": [PIN]}
        @return: {"method": "get_pin_state_reply", "params": [PIN_NUMBER, PIN_MODE, PIN_STATE]}
        """
        pin = int(command[0])
        value = yield from self.core.get_pin_state(pin)
        if value:
            reply = json.dumps({"method": "pin_state_reply", "params": value})
        else:
            reply = json.dumps({
                "method": "pin_state_reply",
                "params": "Unknown"
            })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_protocol_version(self):
        """
        This method retrieves the Firmata protocol version.

        JSON command: {"method": "get_protocol_version", "params": ["null"]}

        @return: {"method": "protocol_version_reply", "params": [PROTOCOL_VERSION]}
        """
        value = yield from self.core.get_protocol_version()
        if value:
            reply = json.dumps({
                "method": "protocol_version_reply",
                "params": value
            })
        else:
            reply = json.dumps({
                "method": "protocol_version_reply",
                "params": "Unknown"
            })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def get_pymata_version(self):
        """
         This method retrieves the PyMata release version number.

         JSON command: {"method": "get_pymata_version", "params": ["null"]}

         @return:  {"method": "pymata_version_reply", "params":[PYMATA_VERSION]}
        """
        value = yield from self.core.get_pymata_version()
        if value:
            reply = json.dumps({
                "method": "pymata_version_reply",
                "params": value
            })
        else:
            reply = json.dumps({
                "method": "pymata_version_reply",
                "params": "Unknown"
            })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def i2c_config(self, command):
        """
        This method initializes the I2c and sets the optional read delay (in microseconds).

        It must be called before doing any other i2c operations for a given device.
        @param command: {"method": "i2c_config", "params": [DELAY]}
        @return: No Return message.
        """
        delay = int(command[0])
        yield from self.core.i2c_config(delay)

    @asyncio.coroutine
    def i2c_read_data(self, command):
        """
        This method retrieves the last value read for an i2c device identified by address.
        This is a polling implementation and i2c_read_request and i2c_read_request_reply may be
        a better alternative.
        @param command: {"method": "i2c_read_data", "params": [I2C_ADDRESS ]}
        @return:{"method": "i2c_read_data_reply", "params": i2c_data}
        """
        address = int(command[0])
        i2c_data = yield from self.core.i2c_read_data(address)
        reply = json.dumps({
            "method": "i2c_read_data_reply",
            "params": i2c_data
        })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def i2c_read_request(self, command):
        """
        This method sends an I2C read request to Firmata. It is qualified by a single shot, continuous
        read, or stop reading command.
        Special Note: for the read type supply one of the following string values:

         "0" = I2C_READ

         "1" = I2C_READ | I2C_END_TX_MASK"

         "2" = I2C_READ_CONTINUOUSLY

         "3" = I2C_READ_CONTINUOUSLY | I2C_END_TX_MASK

         "4" = I2C_STOP_READING

        @param command: {"method": "i2c_read_request", "params": [I2C_ADDRESS, I2C_REGISTER,
                NUMBER_OF_BYTES, I2C_READ_TYPE ]}
        @return: {"method": "i2c_read_request_reply", "params": [DATA]}
        """
        device_address = int(command[0])
        register = int(command[1])
        number_of_bytes = int(command[2])

        if command[3] == "0":
            read_type = Constants.I2C_READ_CONTINUOUSLY
        elif command[3] == "1":
            read_type = Constants.I2C_READ
        elif command[3] == "2":
            read_type = Constants.I2C_READ | Constants.I2C_END_TX_MASK
        elif command[3] == "3":
            read_type = Constants.I2C_READ_CONTINUOUSLY | Constants.I2C_END_TX_MASK
        else:  # the default case stop reading valid request or invalid request
            read_type = Constants.I2C_STOP_READING

        yield from self.core.i2c_read_request(device_address, register,
                                              number_of_bytes, read_type,
                                              self.i2c_read_request_callback)
        yield from asyncio.sleep(1)

    @asyncio.coroutine
    def i2c_write_request(self, command):
        """
        This method performs an I2C write at a given I2C address,
        @param command: {"method": "i2c_write_request", "params": [I2C_DEVICE_ADDRESS, [DATA_TO_WRITE]]}
        @return:No return message.
        """
        device_address = int(command[0])
        params = command[1]
        params = [int(i) for i in params]
        yield from self.core.i2c_write_request(device_address, params)

    @asyncio.coroutine
    def play_tone(self, command):
        """
        This method controls a piezo device to play a tone. It is a FirmataPlus feature.
        Tone command is TONE_TONE to play, TONE_NO_TONE to stop playing.
        @param command: {"method": "play_tone", "params": [PIN, TONE_COMMAND, FREQUENCY(Hz), DURATION(MS)]}
        @return:No return message.
        """
        pin = int(command[0])
        if command[1] == "TONE_TONE":
            tone_command = Constants.TONE_TONE
        else:
            tone_command = Constants.TONE_NO_TONE
        frequency = int(command[2])
        duration = int(command[3])
        yield from self.core.play_tone(pin, tone_command, frequency, duration)

    @asyncio.coroutine
    def set_analog_latch(self, command):
        """
        This method sets the an analog latch for a given analog pin, providing the threshold type, and
        latching threshold.
        @param command: {"method": "set_analog_latch", "params": [PIN, THRESHOLD_TYPE, THRESHOLD_VALUE]}
        @return:{"method": "analog_latch_data_reply", "params": [PIN, DATA_VALUE_LATCHED, TIMESTAMP_STRING]}
        """
        pin = int(command[0])
        threshold_type = int(command[1])
        threshold_value = int(command[2])
        yield from self.core.set_analog_latch(pin, threshold_type,
                                              threshold_value,
                                              self.analog_latch_callback)

    @asyncio.coroutine
    def set_digital_latch(self, command):
        """
        This method sets the a digital latch for a given digital pin, the threshold type, and latching threshold.
        @param command:{"method": "set_digital_latch", "params": [PIN, THRESHOLD (0 or 1)]}
        @return:{"method": digital_latch_data_reply", "params": [PIN, DATA_VALUE_LATCHED, TIMESTAMP_STRING]}
        """
        pin = int(command[0])
        threshold_value = int(command[1])
        yield from self.core.set_digital_latch(pin, threshold_value,
                                               self.digital_latch_callback)

    @asyncio.coroutine
    def set_pin_mode(self, command):
        """
        This method sets the pin mode for the selected pin. It handles: Input, Analog(Input) PWM, and OUTPUT. Servo
        is handled by servo_config().
        @param command: {"method": "set_pin_mode", "params": [PIN, MODE]}
        @return:No return message.
        """
        pin = int(command[0])
        mode = int(command[1])
        if mode == Constants.INPUT:
            cb = self.digital_callback
        elif mode == Constants.ANALOG:
            cb = self.analog_callback
        else:
            cb = None

        yield from self.core.set_pin_mode(pin, mode, cb)

    def set_sampling_interval(self, command):
        """
        This method sets the Firmata sampling interval in ms.
        @param command:{"method": "set_sampling_interval", "params": [INTERVAL]}
        @return:No return message.
        """
        sample_interval = int(command[0])
        yield from self.core.set_sampling_interval(sample_interval)

    @asyncio.coroutine
    def sonar_config(self, command):
        """
        This method configures 2 pins to support HC-SR04 Ping devices.
        This is a FirmataPlus feature.
        @param command: {"method": "sonar_config", "params": [TRIGGER_PIN, ECHO_PIN, PING_INTERVAL(default=50),
         MAX_DISTANCE(default= 200 cm]}
        @return:{"method": "sonar_data_reply", "params": [DISTANCE_IN_CM]}
        """
        trigger = int(command[0])
        echo = int(command[1])
        interval = int(command[2])
        max_dist = int(command[3])
        yield from self.core.sonar_config(trigger, echo, self.sonar_callback,
                                          interval, max_dist)

    @asyncio.coroutine
    def sonar_read(self, command):
        """
        This method retrieves the last sonar data value that was cached.
        This is a polling method. After sonar config, sonar_data_reply messages will be sent automatically.
        @param command: {"method": "sonar_read", "params": [TRIGGER_PIN]}
        @return:{"method": "sonar_read_reply", "params": [TRIGGER_PIN, DATA_VALUE]}
        """
        pin = int(command[0])
        val = yield from self.core.sonar_data_retrieve(pin)

        reply = json.dumps({
            "method": "sonar_read_reply",
            "params": [pin, val]
        })
        self.sendMessage(reply.encode('utf8'))

    @asyncio.coroutine
    def servo_config(self, command):
        """
        This method configures a pin for servo operation. The servo angle is set by using analog_write().
        @param command: {"method": "servo_config", "params": [PIN, MINIMUM_PULSE(ms), MAXIMUM_PULSE(ms)]}
        @return:No message returned.
        """
        pin = int(command[0])
        min_pulse = int(command[1])
        max_pulse = int(command[2])
        yield from self.core.servo_config(pin, min_pulse, max_pulse)

    @asyncio.coroutine
    def stepper_config(self, command):
        """
        This method configures 4 pins for stepper motor operation.
        This is a FirmataPlus feature.
        @param command: {"method": "stepper_config", "params": [STEPS_PER_REVOLUTION, [PIN1, PIN2, PIN3, PIN4]]}
        @return:No message returned.
        """
        steps_per_revs = int(command[0])
        pins = command[1]
        pin1 = int(pins[0])
        pin2 = int(pins[1])
        pin3 = int(pins[2])
        pin4 = int(pins[3])
        yield from self.core.stepper_config(steps_per_revs,
                                            [pin1, pin2, pin3, pin4])

    @asyncio.coroutine
    def stepper_step(self, command):
        """
        This method activates a stepper motor motion.
        This is a FirmataPlus feature.
        @param command: {"method": "stepper_step", "params": [SPEED, NUMBER_OF_STEPS]}
        @return:No message returned.
        """
        speed = int(command[0])
        num_steps = int(command[1])
        yield from self.core.stepper_step(speed, num_steps)

    def onClose(self, was_clean, code, reason):
        """
        Websocket management message.
        This message is received when the client closes the connection. A console status message is printed and
        and the interface is shutdown before exiting.
        @param was_clean: Autobahn provided flag
        @param code:Autobahn provided flag
        @param reason:Autobahn provided flag
        @return:Console message is generated.
        """
        print("WebSocket connection closed: {0}".format(reason))
        yield from self.core.shutdown()

    def onConnect(self, request):
        """
        WebSocket management method.
        This method issues a console status message for Websocket connection establishment.
        @param request: Websocket request
        @return: No return value.
        """
        print("Client connecting: {0}".format(request.peer))

    def onMessage(self, payload, is_binary):
        """
        Websocket management method.
        This method receives JSON messages from the Websocket client. All messages are assumed to be text.
        If a binary message is sent, a console status message is generated.
    
        The JSON command is interpreted and translated to a method call to handle the command request.
        @param payload: JSON command
        @param is_binary: True if message is binary. Assumed to always be False
        @return: No value is returned.
        """
        if is_binary:
            print("Binary message received: {0} bytes".format(len(payload)))
            print('Expected text and not binary')
        else:
            cmd_dict = json.loads(payload.decode('utf8'))
            client_cmd = cmd_dict.get("method")

            if client_cmd in self.command_map:
                cmd = self.command_map.get(client_cmd)
                params = cmd_dict.get("params")
                if params[0] != "null":
                    yield from cmd(params)
                else:
                    yield from cmd()

    def onOpen(self):
        """
        WebSocket management method.
        This method issues a console status message for the opening of a Websocket connection. It sends a Firmata
        reset command to the Arduino.
        @return:  No return value.
        """
        print("WebSocket connection open.")
        yield from self.core.send_reset()

    def analog_callback(self, data):
        """
        This method handles the analog message received from pymata_core
        @param data: analog callback message
        @return:{"method": "analog_message_reply", "params": [PIN, DATA_VALUE}
        """
        reply = json.dumps({
            "method": "analog_message_reply",
            "params": [data[0], data[1]]
        })
        self.sendMessage(reply.encode('utf8'))

    def analog_latch_callback(self, data):
        """
        This method handles analog_latch data received from pymata_core
        @param data: analog latch callback message
        @return:{"method": "analog_latch_data_reply", "params": [ANALOG_PIN, VALUE_AT_TRIGGER, TIME_STAMP_STRING]}
        """
        ts = data[2]
        st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
        reply = json.dumps({
            "method": "analog_latch_data_reply",
            "params": [data[0], data[1], st]
        })
        self.sendMessage(reply.encode('utf8'))

    def digital_callback(self, data):
        """
        This method handles the digital message received from pymata_core
        @param data: digital callback message
        @return:{"method": "digital_message_reply", "params": [PIN, DATA_VALUE]}
        """
        reply = json.dumps({
            "method": "digital_message_reply",
            "params": [data[0], data[1]]
        })
        self.sendMessage(reply.encode('utf8'))
        # yield from self.core.sleep(.001)

    def digital_latch_callback(self, data):
        """
        This method handles the digital latch data message received from pymata_core
        @param data: digital latch callback message
        @return:s{"method": "digital_latch_data_reply", "params": [PIN, DATA_VALUE_AT_TRIGGER, TIME_STAMP_STRING]}
        """
        ts = data[2]
        st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
        reply = json.dumps({
            "method": "digital_latch_data_reply",
            "params": [data[0], data[1], st]
        })
        self.sendMessage(reply.encode('utf8'))

    def encoder_callback(self, data):
        """
        This method handles the encoder data message received from pymata_core
        @param data: encoder data callback message
        @return:{"method": "encoder_data_reply", "params": [ENCODER VALUE]}
        """
        reply = json.dumps({"method": "encoder_data_reply", "params": data})
        self.sendMessage(reply.encode('utf8'))

    def i2c_read_request_callback(self, data):
        """
        This method handles the i2c read data message received from pymata_core.
        @param data: i2c read data callback message
        @return:{"method": "i2c_read_request_reply", "params": [DATA_VALUE]}
        """
        reply = json.dumps({
            "method": "i2c_read_request_reply",
            "params": data
        })
        # print(reply);
        self.sendMessage(reply.encode('utf8'))

    def i2c_read_data_callback(self, data):
        """
        This method handles the i2c cached read data received from pymata_core.
        @param data: i2c read cached data callback message
        @return:{"method": "i2c_read_data_reply", "params": [DATA_VALUE]}
        """
        reply = json.dumps({"method": "i2c_read_data_reply", "params": data})
        self.sendMessage(reply.encode('utf8'))

    def sonar_callback(self, data):
        """
        This method handles sonar data received from pymata_core.
        @param data: sonar data callback message
        @return:{"method": "sonar_data_reply", "params": [DATA_VALUE]}
        """
        reply = json.dumps({"method": "sonar_data_reply", "params": data})

        self.sendMessage(reply.encode('utf8'))
Пример #12
0
currentBrightness = 0
requestedBrightness = 0
lastBrightness = 255
currentMode = MODE_OFF
requestedMode = MODE_OFF
switchModeAt = time.time()

logger = logging.getLogger(__name__)

mqttClient = MQTTClient(config={
    'keep_alive': 5,
    'ping_delay': 1,
    'auto_reconnect': True
})

board = PymataCore()


async def init_firmata():
    """ Initialize Firmata connection """

    await board.start_aio()

    await board.set_pin_mode(FAN_PIN, FirmataConstants.OUTPUT)
    await board.set_pin_mode(FIRE_PIN, FirmataConstants.OUTPUT)
    await board.set_pin_mode(HEATER_LOW_PIN, FirmataConstants.OUTPUT)
    await board.set_pin_mode(HEATER_HIGH_PIN, FirmataConstants.OUTPUT)
    await board.set_pin_mode(LIGHT_PIN, FirmataConstants.PWM)

    await board.digital_write(FAN_PIN, 0)
    await board.digital_write(FIRE_PIN, 0)
Пример #13
0
    async def left_encoder_callback(self, data):
        if self.socket:
            if data[0] != 0 or data[1] != 0:
                msg = json.dumps({
                    "info": "encoders",
                    "left": data[0],
                    "right": data[1]
                })
                self.socket.sendMessage(msg.encode('utf8'))
            asyncio.sleep(.1)

    def establish_socket(self, socket):
        self.socket = socket


if __name__ == "__main__":

    loop = asyncio.get_event_loop()
    my_core = PymataCore()

    rbc = RedBotController(my_core)
    loop.run_until_complete(rbc.init_red_board())
    asyncio.ensure_future(rbc.motor_control(0, 1, 60))
    asyncio.ensure_future(rbc.motor_control(1, 1, 60))

    while True:
        loop.run_until_complete(rbc.get_accel_data())
        loop.run_until_complete(asyncio.sleep(.1))

    loop.run_forever()
Пример #14
0
    Blink LED 13
    @return: No Return Value
    """
    # set the pin mode
    await my_board.set_pin_mode(13, Constants.OUTPUT)

    for i in range(0, 5):
        await my_board.digital_write(13, 1)
        await asyncio.sleep(1)
        await my_board.digital_write(13, 0)
        await asyncio.sleep(1)


if __name__ == "__main__":
    # create a PyMataCore instance and complete the initialization with a call to start_aio()
    board = PymataCore()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(board.start_aio())

    # now execute your code on the loop and shutdown when done
    try:
        loop.run_until_complete(blink(board))
        loop.run_until_complete(board.shutdown())
    except RuntimeError:
        loop.run_until_complete(board.shutdown())
        exit(0)



Пример #15
0
from pymata_aio.constants import Constants


@asyncio.coroutine
def pin_6_pwm_128(my_board):
    """
    Set digital pin 6 as a PWM output and set its output value to 128
    @param my_board: A PymataCore instance
    @return: No Return Value
    """
    # set the pin mode
    yield from my_board.set_pin_mode(6, Constants.PWM)

    # set the pin to 128
    yield from my_board.analog_write(6, 128)

    # let the led stay lit for 3 seconds
    yield from asyncio.sleep(3)

    # shutdown
    yield from my_board.shutdown()


# create a PyMataCore instance and complete the initialization with a call to start()
board = PymataCore()
board.start()

# get the loop, and execute pin6_pwm_128
loop = asyncio.get_event_loop()
loop.run_until_complete(pin_6_pwm_128(board))
Пример #16
0
    async def kick_off(self, my_loop):
        """
        After s2aios is instantiated, this method must be called to start the HTTP server,
        instantiate tye pymata_core interface to the arduino board

        :param my_loop: The asyncio event loop
        :return: A reference to this server
        """
        self.loop = my_loop

        # noinspection PyBroadException
        try:
            # instantiate the arduino interface
            self.board = PymataCore(arduino_wait=5, com_port=self.com_port, ip_address=self.ip_address,
                                    ip_port=self.ip_port)
            await self.board.start_aio()

            # populate the arduino pin capability lists
            await self.get_pin_capabilities()

            # start up the HTTP server
            app = web.Application(loop=my_loop)
            srv = await my_loop.create_server(app.make_handler(), self.server_ip_address, self.server_ip__port)

            # Scratch command handlers
            # multi-board
            app.router.add_route('GET', '/multi_board_connect/{board}/{addr}/{port}', self.multi_board_connect)
            app.router.add_route('GET', '/digital_pin_mode/{board}/{enable}/{pin}/{mode}', self.setup_digital_pin)
            app.router.add_route('GET', '/analog_pin_mode/{board}/{enable}/{pin}', self.setup_analog_pin)
            app.router.add_route('GET', '/digital_write/{board}/{pin}/{value}', self.digital_write)
            app.router.add_route('GET', '/analog_write/{board}/{pin}/{value}', self.analog_write)
            app.router.add_route('GET', '/play_tone/{pin}/{board}/{frequency}/{duration}', self.play_tone)
            app.router.add_route('GET', '/set_servo_position/{board}/{pin}/{position}', self.set_servo_position)
            app.router.add_route('GET', '/tone_off/{board}/{pin}', self.tone_off)

            # Snap requires reporters to be supported
            app.router.add_route('GET', '/digital_read/{board}/{pin}', self.digital_read)
            app.router.add_route('GET', '/analog_read/{board}/{pin}', self.analog_read)

            # single board interface

            app.router.add_route('GET', '/digital_read/{pin}', self.digital_read)
            app.router.add_route('GET', '/analog_read/{pin}', self.analog_read)

            app.router.add_route('GET', '/digital_pin_mode/{enable}/{pin}/{mode}', self.setup_digital_pin)
            app.router.add_route('GET', '/analog_pin_mode/{enable}/{pin}', self.setup_analog_pin)
            app.router.add_route('GET', '/poll', self.poll)
            app.router.add_route('GET', '/digital_write/{pin}/{value}', self.digital_write)
            app.router.add_route('GET', '/analog_write/{pin}/{value}', self.analog_write)
            app.router.add_route('GET', '/play_tone/{pin}/{frequency}/{duration}', self.play_tone)
            app.router.add_route('GET', '/set_servo_position/{pin}/{position}', self.set_servo_position)
            app.router.add_route('GET', '/tone_off/{pin}', self.tone_off)

            # Snap requires reporters to be supported
            app.router.add_route('GET', '/digital_read/{pin}', self.digital_read)
            app.router.add_route('GET', '/analog_read/{pin}', self.analog_read)
            app.router.add_route('GET', '/problem', self.problem)
            await self.board.keep_alive()

            await self.keep_alive()
            # self.client = aiohttp.ClientSession(loop=loop)
            return srv
        except:
            pass