class Reconnect(object): def __init__(self, address): self.requester = GATTRequester(address, False) times = 3 print("I will connect & disconnect {} times...".format(times)) for i in range(times): self.connect() self.disconnect() def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") time.sleep(1) def disconnect(self): print("Disconnecting...", end=' ') sys.stdout.flush() self.requester.disconnect() print("OK!") time.sleep(1)
class ActiveDisconnect(object): def __init__(self, address): self.requester = GATTRequester(address, False) self.connect() self.check_status() self.disconnect() self.check_status() def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") def check_status(self): status = "connected" if self.requester.is_connected() else "not connected" print("Checking current status: {}".format(status)) time.sleep(1) def disconnect(self): print("Disconnecting...", end=' ') sys.stdout.flush() self.requester.disconnect() print("OK!")
class SensorTag(object): def __init__(self, address): self.requester = GATTRequester(address, False) def connect(self): print("Connecting...") self.requester.connect(True) print("Succeed.") def check_status(self): status = "connected" if self.requester.is_connected() else "not connected" print("Checking current status: {}".format(status)) def disconnect(self): print("Disconnecting...") self.requester.disconnect() print("Succeed.") def show_primary(self): print("Discover Primary...") primary = self.requester.discover_primary() for prim in primary: print(prim) print("Done.") def show_characteristic(self): print("Discover Characteristic...") characteristic = self.requester.discover_characteristics() for char in characteristic: print(char) print("Done.")
class MagicBlue: def __init__(self, mac_address): self.mac_address = mac_address self._connection = None def connect(self): """ Connect to device :return: True if connection succeed, False otherwise """ self._connection = GATTRequester(self.mac_address, False) try: self._connection.connect(True, "random") except RuntimeError as e: logger.error('Connection failed : {}'.format(e)) return False return True def disconnect(self): """ Disconnect from device """ self._connection.disconnect() def is_connected(self): """ :return: True if connection succeed, False otherwise """ return self._connection.is_connected() def set_color(self, rgb_color): """ Change bulb's color :param rgb_color: color as a list of 3 values between 0 and 255 """ self._connection.write_by_handle(HANDLE_CHANGE_COLOR, bytes(bytearray([MAGIC_CHANGE_COLOR] + list(rgb_color)))) def set_random_color(self): """ Change bulb's color with a random color """ self.set_color([random.randint(1, 255) for i in range(3)]) def turn_off(self): """ Turn off the light by setting color to black (rgb(0,0,0)) """ self.set_color([0, 0, 0]) def turn_on(self, brightness=1.0): """ Set white color on the light :param brightness: a float value between 0.0 and 1.0 defining the brightness """ self.set_color([int(255 * brightness) for i in range(3)])
class BleClient: def __init__(self, address): self.requester = GATTRequester(address, False) self.connect() self.request_data() def connect(self): print("~ BLE ~ Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("~ BLE ~ OK!") time.sleep(1) def disconnect(self): print("~ BLE ~ Disconnecting...", end=' ') sys.stdout.flush() self.requester.disconnect() print("~ BLE ~ OK!") time.sleep(1) def request_data(self, uuid="00002a00-0000-1000-8000-00805f9b34fb"): data = self.requester.read_by_uuid(uuid)[0] try: print("~ BLE ~ Device name:", data.decode("utf-8")) except AttributeError: print("~ BLE ~ Device name:", data) else: return data def wait_disconnection(self): status = "connected" if self.requester.is_connected( ) else "not connected" print("~ BLE ~ Checking current status: {}".format(status)) print( "\n~ BLE ~Now, force a hardware disconnect. To do so, please switch off,\n" "reboot or move away your device. Don't worry, I'll wait...") while self.requester.is_connected(): time.sleep(1) print("\n~ BLE ~OK. Current state is disconnected. Congratulations ;)")
class Reader(object): def __init__(self, address): writeResponse = False try: self.requester = GATTRequester(address, False) self.connect() self.send_data() except: print("Connection failed") self.requester.connect(False) def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") def send_data(self): status = True profile = self.requester.read_by_handle(0x61) time.sleep(2) print(profile) #Checks the profile loaded by the FPGA, if it's 12, then stop loop while ("\x0c" not in profile): #Attempt to set profile to 12 try: self.requester.write_by_handle(0x61, str(bytearray([12]))) except RuntimeError: status = False break #Delay time to allow for successful transfer time.sleep(2) print("Currently in profile loop") try: profile = self.requester.read_by_handle(0x61) except RuntimeError: status = False break time.sleep(2) #time.sleep(3) while status: #Write the button press to reset data try: writeResponse = GATTResponse() self.requester.write_by_handle_async(0x72, str(bytearray([1])), writeResponse) counter = 0 time.sleep(0.4) information_taken = self.requester.read_by_handle(0xa2)[0] counter = 0 time.sleep(0.5) print("bytes received:", end=' ') print(int(ord(information_taken[0]))) #first array containing value data = {} data[fields[0]] = 0 #send to bpressure array data[fields[1]] = int(ord(information_taken[0])) params = urllib.urlencode(data) data = urllib.urlencode(data) headers = {} headers["Content-Type"] = 'application/x-www-form-urlencoded' headers["Connection"] = "close" headers["Content-Length"] = len(params) headers["Phant-Private-Key"] = private_hash c = httplib.HTTPConnection(base_url) c.request("POST", "/input/" + public_hash + ".txt", params, headers) #send to website https://data.sparkfun.com/streams/7JYarO9dElfVn7vnlG5q r = c.getresponse() #print (r.status,r.reason) #time.sleep(2) except: break try: self.requester.disconnect() except: print("disconnect failed")
from gattlib import GATTRequester req = GATTRequester("C9:E8:56:3B:4D:B1", False) req.connect(True, "random") req.is_connected() print(req.discover_primary()) req.disconnect()
class BLEConnectionManager(object): """BLEConnectionManager is used to manage a connection to a Bluetooth Low Energy device. This class allows us to connect, create a requester, create a response, and disconnect from a BLE device. :param address: MAC address (BD_ADDR) of target BTLE device :param adapter: BTLE adapter on host machine to use for connection (defaults to first found adapter). If an empty string is submitted, we connect to the host's default adapter. :param addressType: Type of address you want to connect to [public | random] :param securityLevel: Security level [low | medium | high] :param createRequester: When creating the connection manager, we can choose to create the requester or not. It can be helpful to set this to False when overriding methods in the GATTRequester class. :param psm: Specific PSM (default: 0) :param mtu: Specific MTU (default: 0) :type address: str :type adapter: str :type addressType: str :type securityLevel: str :type createRequester: bool :type psm: int :type mtu: int :ivar address: initial value: address :ivar adapter: initial value: adapter :ivar createRequester: initial value: createRequester :ivar requester: initial value: GATTRequester(address, False, adapter) if createRequester == True, else None :ivar responses: initial value: [] """ def __init__(self, address, adapter, addressType, securityLevel, createRequester=True, psm=0, mtu=0): self.address = address self.adapter = adapter self.requester = None self.responses = [] self.responseCounter = 0 self.addressType = addressType self.securityLevel = securityLevel self.psm = psm self.mtu = mtu if createRequester: self.createRequester() def __del__(self): if self.requester is not None and self.requester.is_connected(): self.disconnect() def createRequester(self): """Create a GATTRequester for the BLEConnectionManager :return: Returns the newly created requester :rtype: GATTRequester """ if self.adapter == "": self.requester = GATTRequester(self.address, False) else: self.requester = GATTRequester(self.address, False, self.adapter) return self.requester def setRequester(self, requester): """Sets the BLEConnectionManager's requester to the user-supplied GATTRequester :param requester: Custom GATTRequester :type requester: GATTRequester :return: None """ self.requester = requester def setResponse(self, response): """Sets the BLEConnectionManager's response to the user-supplied GATTResponse :param response: Custom GATTResponse :type response: GATTResponse :return: None """ self.response = response def createResponse(self, responseFunction=None): """Create a GATTResponse for the BLEConnectionManager. If a responseFunction is supplied, then the GATTResponse created will have an overridden on_response function. The responseFunction most only accept one parameter, which is the data contained in the response. The response is assigned an ID and stored in the response list. :param responseFunction: Function pointer called with a single parameter (data in response) when data is received. If not supplied, the GATTResponse function .received() can be called to access data (note: this function is not available if the responseFunction is specified) :type responseFunction: function pointer :return: Tuple with the response ID and response object :rtype: tuple (int, GATTResponse) """ class BLECustomResponse(GATTResponse): def __init__(self, responseFunction): super(BLECustomResponse, self).__init__() self.responseFunction = responseFunction def on_response(self, data): if self.responseFunction is not None: self.responseFunction(data) if responseFunction is not None: response = (self.responseCounter + 1, BLECustomResponse(responseFunction)) else: response = (self.responseCounter + 1, GATTResponse()) self.responses.append(response) self.responseCounter += 1 return response def isConnected(self): """ Return whether the connection manager's requester is still connected to a device :return: Return requester connection status :rtype: bool """ return self.requester.is_connected() def connect(self): """Connect to BLE device using BLEConnectionManager's requester :return: """ if not self.requester.is_connected(): self.requester.connect(True, self.addressType, self.securityLevel, self.psm, self.mtu) def disconnect(self): """Disconnect from BLE device using BLEConnectionManager's requester :return: """ self.requester.disconnect()
class SensorTag(object): def __init__(self, address): self.requester = GATTRequester(address, False) self.humidity = float(0.0) self.temperature = float(0.0) self.object_temperature = float(0.0) self.barometer = float(0.0) self.gyrometer = {"x": float(0.0), "y": float(0.0), "z": float(0.0)} self.acceleration = {"x": float(0.0), "y": float(0.0), "z": float(0.0)} self.geomagnetism = {"x": float(0.0), "y": float(0.0), "z": float(0.0)} self.lux = float(0.0) def connect(self): print("Connecting...") self.requester.connect(True) print("Succeed.") def check_status(self): status = "connected" if self.requester.is_connected( ) else "not connected" print("Checking current status: {}".format(status)) def disconnect(self): print(str("Disconnecting...")) self.requester.disconnect() print("Succeed.") def enable_humidity(self, enable): status = '\x01' if enable else '\x00' self.requester.write_by_handle(0x2f, status) def check_humidity(self): time.sleep(3) raw_data = self.requester.read_by_handle(0x2c)[0] raw_temp = (ord(raw_data[1]) << 8) + ord(raw_data[0]) raw_humi = (ord(raw_data[3]) << 8) + ord(raw_data[2]) self.temperature = round((float(raw_temp) / float(65536)) * 165 - 40, 1) self.humidity = round((float(raw_humi) / float(65536)) * 100, 1) def enable_IRtemperature(self, enable): status = '\x01' if enable else '\x00' self.requester.write_by_handle(0x27, status) def check_IRtemperature(self): time.sleep(3) raw_data = self.requester.read_by_handle(0x24)[0] raw_obj = (ord(raw_data[1]) << 8) + ord(raw_data[0]) raw_amb = (ord(raw_data[3]) << 8) + ord(raw_data[2]) self.object_temperature = round((float(raw_obj) / 4.0) * 0.03125, 1) self.temperature = round((float(raw_amb) / 4.0) * 0.03125, 1) def enable_Barometer(self, enable): status = '\x01' if enable else '\x00' self.requester.write_by_handle(0x37, status) def check_Barometer(self): time.sleep(3) raw_data = self.requester.read_by_handle(0x34)[0] raw_temp = (ord(raw_data[2]) << 16) + (ord(raw_data[1]) << 8) + ord( raw_data[0]) raw_baro = (ord(raw_data[5]) << 16) + (ord(raw_data[4]) << 8) + ord( raw_data[3]) self.temperature = round(float(raw_temp) / 100.0, 1) self.barometer = round(float(raw_baro) / 100.0, 1) def enable_9AxisSensor(self, enable): status = '\x7f\x00' if enable else '\x00\x00' self.requester.write_by_handle(0x3f, status) def check_9AxisSensor(self): time.sleep(3) raw_data = self.requester.read_by_handle(0x3c)[0] raw_gyro_x = struct.unpack('h', raw_data[0] + raw_data[1])[0] raw_gyro_y = struct.unpack('h', raw_data[2] + raw_data[3])[0] raw_gyro_z = struct.unpack('h', raw_data[4] + raw_data[5])[0] raw_acce_x = struct.unpack('h', raw_data[8] + raw_data[7])[0] raw_acce_y = struct.unpack('h', raw_data[10] + raw_data[9])[0] raw_acce_z = struct.unpack('h', raw_data[10] + raw_data[11])[0] raw_geom_x = struct.unpack('h', raw_data[12] + raw_data[13])[0] raw_geom_y = struct.unpack('h', raw_data[14] + raw_data[15])[0] raw_geom_z = struct.unpack('h', raw_data[16] + raw_data[17])[0] self.gyrometer["x"] = round(float(raw_gyro_x) / (65536 / 500), 2) self.gyrometer["y"] = round(float(raw_gyro_y) / (65536 / 500), 2) self.gyrometer["z"] = round(float(raw_gyro_z) / (65536 / 500), 2) #/2.0 ? /8.0 ? self.acceleration["x"] = float(raw_acce_x) / (32768.0 / 8.0) self.acceleration["y"] = float(raw_acce_y) / (32768.0 / 8.0) self.acceleration["z"] = float(raw_acce_z) / (32768.0 / 8.0) self.geomagnetism["x"] = float(raw_geom_x) self.geomagnetism["y"] = float(raw_geom_y) self.geomagnetism["z"] = float(raw_geom_z) def enable_Optical(self, enable): status = '\x01' if enable else '\x00' self.requester.write_by_handle(0x47, status) def check_Optical(self): raw_data = self.requester.read_by_handle(0x44)[0] raw_lux = (ord(raw_data[1]) << 8) + ord(raw_data[0]) raw_lux_m = raw_lux & 0b0000111111111111 raw_lux_e = (raw_lux & 0b1111000000000000) >> 12 self.lux = raw_lux_m * (0.01 * pow(2.0, raw_lux_e))