class IoTDevice(object): """ IoTDevice represents a single EyeoT IoT (Arduino 101) BLE device, initialized by one of several authorized MAC addresses. Input: MAC address of the EyeoT device to control Output: Initialized EyeoT device containing the proper MAC address, service UUID, tx_command and rx_response characteristic UUIDs, tx_handle, and GATTRequester """ def __init__(self, address): self.address = address self.service_uuid = arduino.service_uuid self.tx_command = arduino.tx_command self.rx_response = arduino.rx_response self.tx_handle = arduino.tx_handle self.rx_handle = arduino self.req = GATTRequester(address, False) # initialize req but don't connect self.response = ble_consts.not_ready def connect(self): print("Connecting...\n") self.req.connect(True) print("Connection Successful! \n") def send_command(self, command): self.req.write_by_handle(arduino.tx_handle, command) print("Sent '{0}' command\n".format(ble_consts.commands[command])) def receive_response(self): self.response = int( self.req.read_by_handle(arduino.rx_handle)[0].encode('hex')) / 100 print("Response '{0}' received!\n".format( ble_consts.responses[self.response]))
class Driver(object): handle = 0x16 commands = { 'press': '\x57\x01\x00', 'on': '\x57\x01\x01', 'off': '\x57\x01\x02', } def __init__(self, device, bt_interface=None, timeout_secs=None): self.device = device self.bt_interface = bt_interface self.timeout_secs = timeout_secs if timeout_secs else 5 self.req = None def connect(self): if self.bt_interface: self.req = GATTRequester(self.device, False, self.bt_interface) else: self.req = GATTRequester(self.device, False) self.req.connect(True, 'random') connect_start_time = time.time() while not self.req.is_connected(): if time.time() - connect_start_time >= self.timeout_secs: raise RuntimeError('Connection to {} timed out after {} seconds' .format(self.device, self.timeout_secs)) def run_command(self, command): self.req.write_by_handle(self.handle, self.commands[command]) data = self.req.read_by_handle(self.handle) return data
class Cloudpets(object): def __init__(self, address): self._requester = GATTRequester(address, False) self.led = Led(self) self.speaker = Speaker(self) self.microphone = Microphone(self) self.state = None self.name = None self.setup_datetime = None def connect(self): self._requester.connect(True) self._retrieve_config() def disconnect(self): self._requester.disconnect() def _read_value(self, handle): return self._requester.read_by_handle(handle) def _send_command(self, handle, cmd): self._requester.write_by_handle(handle, str(bytearray(cmd))) def _retrieve_config(self): response = self._read_value(HANDLES['config'])[0] self.name = MODELS[int(response[:2])] self.setup_datetime = datetime.strptime(response[2:], "%m_%d_%H_%M_%S")
class Toio(object): HANDLER = {'motor': "TBU"} DIRECTION = {'fwd': 1, 'bck': 2} MOTOR = {'1st': 1, '2nd': 2} SPEED_MAX = 100 def __init__(self, addr): self.req = "" if not addr: return self.req = GATTRequester(addr, False) print("Connecting...: {}".format(addr)) self.req.connect(wait=True, channel_type="random") print("Connected: {}".format(addr)) def request_data(self, uuid): return self.req.read_by_uuid(uuid)[0] def write_data(self, handler, data): self.req.write_by_handle(handler, data) def disconnect(self): self.req.disconnect() def is_connected(self): if not self.req: return False return self.req.is_connected() def _move(self, motor_1st_dir, motor_1st_speed, motor_2nd_dir, motor_2nd_speed, duration_sec): self.write_data(self.HANDLER['motor'], str( bytearray([2, self.MOTOR['1st'], motor_1st_dir, motor_1st_speed, self.MOTOR['2nd'], motor_2nd_dir, motor_2nd_speed, int(duration_sec * 100)]))) import time time.sleep(duration_sec) def straight(self): self._move(self.DIRECTION['fwd'], self.SPEED_MAX, self.DIRECTION['fwd'], self.SPEED_MAX, 1) def turn_left(self): self._move(self.DIRECTION['fwd'], self.SPEED_MAX / 2, self.DIRECTION['fwd'], self.SPEED_MAX, 1) def turn_right(self): self._move(self.DIRECTION['fwd'], self.SPEED_MAX, self.DIRECTION['fwd'], self.SPEED_MAX / 2, 1) def back(self): self._move(self.DIRECTION['bck'], self.SPEED_MAX, self.DIRECTION['bck'], self.SPEED_MAX, 1) def spin_turn_180(self): self._move(self.DIRECTION['bck'], self.SPEED_MAX, self.DIRECTION['fwd'], self.SPEED_MAX, 0.5) def spin_turn_360(self): self._move(self.DIRECTION['bck'], self.SPEED_MAX, self.DIRECTION['fwd'], self.SPEED_MAX, 1)
class BluezBleInterface(BleInterface): def __init__(self, *args, **kwargs): super(BluezBleInterface, self).__init__(*args, **kwargs) self._addr = kwargs.get('addr') self._log.info("Started interface {0}.".format(self)) def __del__(self): self._disconnect() def _connect(self, addr): self._log.info("BLE %s connecting ..." % addr) self.requester = GATTRequester(addr, False) self.requester.connect(True) chars = self.requester.discover_characteristics() self.characteristic = {} for char in chars: self.characteristic[char['uuid']] = char['value_handle'] self._log.info("BLE %s connected OK" % self._addr) def _disconnect(self): self.requester.disconnect() def _read_uuid(self, reg, type='float'): value = self.requester.read_by_uuid(reg)[0] if type == 'float': return struct.unpack('H', value)[0] * 1.0 elif type == 'string': try: value = value.decode("utf-8") except AttributeError: pass return value else: return value def _write_uuid(self, reg, value, type='float'): if type == 'string': value = struct.pack('B', value) self.requester.write_by_handle(self.characteristic[reg], value)
class Reader(): def __init__(self, address): self.requester = GATTRequester(address, False) self.connect() self.request_data() self.turn() def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") def request_data(self): data = self.requester.read_by_handle(0x03) print("Device name: " + str(data)) candle = self.requester.read_by_handle(0x23) print("Candle: " + str(candle)) def turn(self): self.requester.write_by_handle(0x0016, str(bytearray([0, 0, 0, 0])))
class Blimp: def __init__(self, mac="C4:C3:00:01:07:3F"): # Check for empty arg and correct MAC address format # Default MAC address is given otherwise if not re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", mac.lower()): print("Using default MAC: C4:C3:00:01:07:3F") self.mac = "C4:C3:00:01:07:3F" else: self.mac = mac self.service = DiscoveryService() self.devices = self.service.discover(2) self.requester = GATTRequester(self.mac, False) def find_blimp(self, blimp_name): self.devices = self.service.discover(2) for address, name in self.devices: if name == blimp_name: self.mac = address print(blimp_name + " found with MAC Address " + address) break def connect(self): try: self.requester.connect(True) except: print("Failed to connect; Make sure target is turned on and correct MAC address is provided") def disconnect(self): try: self.requester.disconnect(True) except: print("Failed to disconnect; try again") def is_connected(self): return self.requester.is_connected() # Enter value between -32767 to 32767 # Negative value commands backward thrust, and vice versa with positive value, for left propeller def left(self, value): if self.is_connected(): if -32768 < value < 32768: if value < 0: command = '{:04x}'.format(-1*int(value)) else: command = '{:04x}'.format(65535 - int(value)) self.requester.write_by_handle(34, command.decode('hex')) else: print("Command value is must be integer between -32767 & 32767") else: print("First connect to target before commanding thrust") # Enter value between -32767 to 32767 # Negative value commands backward thrust, and vice versa with positive value, for right propeller def right(self, value): if self.is_connected(): if -32768 < value < 32768: if value < 0: command = '{:04x}'.format(-1*int(value)) else: command = '{:04x}'.format(65535 - int(value)) self.requester.write_by_handle(36, command.decode('hex')) else: print("Command value is must be integer between -32767 & 32767") else: print("First connect to target before commanding thrust") # Enter value between -32767 to 32767 # Negative value commands backward thrust, and vice versa with positive value, for down propeller def down(self, value): if self.is_connected(): if -32768 < value < 32768: if value < 0: command = '{:04x}'.format(-1*int(value)) else: command = '{:04x}'.format(65535 - int(value)) self.requester.write_by_handle(38, command.decode('hex')) else: print("Command value is must be integer between -32767 & 32767") else: print("First connect to target before commanding thrust") # Function to stop all actuators def stop(self): if self.is_connected(): command = '{:04x}'.format(65535) self.requester.write_by_handle(34, command.decode('hex')) self.requester.write_by_handle(36, command.decode('hex')) self.requester.write_by_handle(38, command.decode('hex')) else: print("Command failed; not connected to target")
print("Characteristic value handle is %d." % vh_light) break assert(vh_light is not None) # Use the handle to set the LED brightness to a specific intensity, # one command every 10 microseconds. The data sent to the characteristic # is a UTF-8 string that describes a pair of four-byte hexadecimal numbers. # These two numbers specify the on-off intervals of a PWM signal to the LED. # # The full range for each number is 65536 (2^16), but we are # only altering one number, and only using an 8-bit range for it. # The first number is fixed at '00ff'. # The second number is ranging up and down like so: # # 0000,0010,0020...00dc,00e6,00f0,00fa,00f0,00e6,00dc...0020,0010,0000 (repeat) print("Fading remote LED now. Press ctrl-c to stop.") fade_in_out = range(0,255,10) + range(255,0,-10) try: while True: for vol in fade_in_out: str_vol="%02x"%vol grq.write_by_handle(vh_light, '00ff,00' + str_vol) time.sleep(.01) except KeyboardInterrupt: grq.write_by_handle(vh_light, '00ff,0000') print("\nDisconnecting...") grq.disconnect() print("Done.")
characteristics = grq.discover_characteristics() # # the UUID of the service on the BLE device. # light_ctrl_uuid = '59c889e0-5364-11e7-b114-b2f933d5fe66' # find the handle for the characteristic. vh_light = None for c12c in characteristics: if c12c['uuid'] == light_ctrl_uuid: vh_light = c12c['value_handle'] print("Characteristic value handle is %d." % vh_light) break assert(vh_light is not None) # use the handle to command the LED on and off, at a one-second interval print("Flashing remote LED now. Press ctrl-c to stop.") try: while True: grq.write_by_handle(vh_light, str(bytearray([8]))) time.sleep(1) grq.write_by_handle(vh_light, str(bytearray([0]))) time.sleep(1) except KeyboardInterrupt: print("\nDisconnecting...") grq.disconnect() print("Done.")
class Reader: def __init__(self, address): self.requester1 = GATTRequester("40:06:A0:97:74:A9", False) self.requester2 = GATTRequester("40:06:A0:94:FE:F7", False) self.connect() self.send_data() #self.request_data() def connect(self): print("Connecting...", end=" ") sys.stdout.flush() self.requester1.connect(True) self.requester2.connect(True) print("OK.") def request_data(self): data1 = self.requester1.read_by_uuid( "00001800-0000-1000-8000-00805f9b34fb")[0] data2 = self.requester2.read_by_uuid( "00001800-0000-1000-8000-00805f9b34fb")[0] try: print("Device name:", data1.decode("utf-8")) except AttributeError: print("Device name:", data1) def send_data(self): #data = str(bytearray("TTWU")) #print("Send Ok ,"+data) print("sidong off") self.requester1.write_by_handle(0x12, b'\x54\x52\x46\x68\x0D\x0A') self.requester2.write_by_handle(0x12, b'\x54\x52\x46\x68\x0D\x0A') #print("brake") #self.requester1.write_by_handle(0x12, b'\x54\x53\x53\x5A\x0D\x0A') #self.requester2.write_by_handle(0x12, b'\x54\x53\x53\x5A\x0D\x0A') print("Sidong ON") self.requester1.write_by_handle(0x12, b'\x54\x52\x4E\x60\x0D\x0A') self.requester2.write_by_handle(0x12, b'\x54\x52\x4E\x60\x0D\x0A') print("SPEED SLOW") #self.requester1.write_by_handle(0x12, b'\x54\x57\x32\x77\x0D\x0A') #self.requester2.write_by_handle(0x12, b'\x54\x57\x32\x77\x0D\x0A') print("SPEED FULL") self.requester1.write_by_handle(0x12, b'\x54\x57\x82\x27\x0D\x0A') self.requester2.write_by_handle(0x12, b'\x54\x57\x82\x27\x0D\x0A')