from gattlib import GATTRequester, GATTResponse address = "B8:27:EB:AA:82:FA" requester = GATTRequester(address) data = requester.read_by_handle(0x000c) print(data[0])
def ReadFlowerCare(address): try: requester = GATTRequester(address) except: return 'error', 0, 0, 0, 0, 0 try: # Read battery and firmware version attribute data = requester.read_by_handle(0x0038)[0] battery, version = unpack('<B6s', data) version = filter(lambda x: x in string.printable, version) except: return 'error', 0, 0, 0, 0, 0 try: # Enable real-time data reading requester.write_by_handle(0x0033, str(bytearray([0xa0, 0x1f]))) except: return 'error', 0, 0, 0, 0, 0 try: # Read plant data data = requester.read_by_handle(0x0035)[0] except: return 'error', 0, 0, 0, 0, 0 try: temperature, sunlight, moisture, fertility = unpack( '<hxIBHxxxxxx', data) return version, battery, temperature, sunlight, moisture, fertility except: return 'error', 0, 0, 0, 0, 0
class Reader: def __init__(self, address): self.requester = GATTRequester(address, False) self.connect() self.request_name() characteristics = self.requester.discover_characteristics() for ch in characteristics: print(ch) data = self.requester.read_by_handle(0x000e) print(data) def connect(self): print("Connecting...", end=" ") sys.stdout.flush() self.requester.connect(True, channel_type="random") print("OK.") def request_name(self): data = self.requester.read_by_uuid( "00002a00-0000-1000-8000-00805f9b34fb")[0] try: print("Device name:", data.decode("utf-8")) except AttributeError: print("Device name:", data) def onNotification(self, args): pass
def OnBPButtonClick(self): f = open("bp.csv", 'wt') writer = csv.writer(f) writer.writerow( ('sys', 'dia','pulse') ) req = GATTRequester("98:4F:EE:0F:59:D6") req.write_by_handle(0x000e,str(bytearray([02]))) tt = req.read_by_handle(0x0010)[0] pp = [] for c in tt: pp.append(ord(c)) print pp if(pp[1] == 2): while(1): try: tt = req.read_by_handle(0x0010)[0] pp = [] for c in tt: pp.append(ord(c)) if(pp[0] == 3): break except Exception,e: print e try: name = req.read_by_uuid("2A40")[0] #steps = (req.read_by_handle(0x0009)[0]) print type(name) value = [] for c in name: value.append((c)) print value print "sys :"+value[1]+value[2]+value[3]+"\n" print "dia :"+value[6]+value[7]+value[8]+"\n" print "sys :"+value[11]+value[12]+value[13]+"\n" writer.writerow((value[1]+value[2]+value[3],value[6]+value[7]+value[8],value[11]+value[12]+value[13])) except Exception,e: #name = False print e
def OnGSRButtonClick(self): req = GATTRequester("98:4F:EE:0F:59:D6") temp = [] f = open("gsr.csv", 'a') writer = csv.writer(f) writer.writerow( ('timestamp', 'gsr') ) flagTemp = 0; flagBP = 1; flagGSR = 0; req.write_by_handle(0x000e,str(bytearray([01]))) tt = req.read_by_handle(0x0010)[0]
class Reader(object): def __init__(self, address): self.requester = GATTRequester(address, False) self.connect() self.request_data() 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(0x1)[0] print("bytes received:", end=' ') for b in data: print(hex(ord(b)), end=' ') print("")
class MoveHub: address = "" controller = "" req = GATTRequester def __init__(self, address, controller): self.address = address self.controller = controller self.req = GATTRequester(self.address, False, self.controller) self.connect() def connect(self): if self.req.is_connected(): print("Already connected") else: print("Connecting...") sys.stdout.flush() self.req.connect(True) def is_connected(self): return self.req.is_connected() def getaddress(self): return self.address def getname(self): self.connect() devicename = self.req.read_by_handle(0x07) return devicename[0] def set_led_color(self, color): if color in LED_COLORS: self.connect() self.req.write_by_handle(HANDLE, SET_LED_COLOR[LED_COLORS.index(color)]) def motor_timed(self, motor, time_ms, dutycycle_pct): if motor in MOTORS: if dutycycle_pct in range(-100, 101): command = MOTOR_TIMED_INI command += motor command += MOTOR_TIMED_MID t = time_ms.to_bytes(2, byteorder='little') command += t if dutycycle_pct < 0: dutycycle_pct += 255 command += bytes(bytes(chr(dutycycle_pct), 'latin-1')) command += MOTOR_TIMED_END self.req.write_by_handle(HANDLE, command) def motors_timed(self, motor, time_ms, dutycycle_pct_A, dutycycle_pct_B): if motor in MOTOR_PAIRS: if dutycycle_pct_A in range(-100, 101) and dutycycle_pct_B in range(-100, 101): command = MOTORS_TIMED_INI command += motor command += MOTORS_TIMED_MID t = time_ms.to_bytes(2, byteorder='little') command += t if dutycycle_pct_A < 0: dutycycle_pct_A += 255 command += bytes(bytes(chr(dutycycle_pct_A), 'latin-1')) if dutycycle_pct_B < 0: dutycycle_pct_B += 255 command += bytes(bytes(chr(dutycycle_pct_B), 'latin-1')) command += MOTORS_TIMED_END self.req.write_by_handle(HANDLE, command)
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, DiscoveryService service = DiscoveryService() devices = service.discover(2) address = None for addr, name in devices.items(): if "CA" in addr: address = addr print(address) req = GATTRequester(address) try: name = req.read_by_uuid('8888')[0] print("uuid name ", name) except: print("not uuid") try: name = req.read_by_handle('8888')[0] print("handle name ", name) except: print("not handle") print(req) print(name)
def read_data_job(): address = mac_address global g_sun global g_moi global g_tem global g_fer now = datetime.datetime.now() test_min = int(now.strftime("%M")) time = now.strftime("%Y-%m-%d %H:%M:%S") try: requester = GATTRequester(address) #Read battery and firmware version attribute data=requester.read_by_handle(0x0038)[0] battery, version = unpack('<B6s',data) #Enable real-time data reading requester.write_by_handle(0x0033, str(bytearray([0xa0, 0x1f]))) #Read plant data data=requester.read_by_handle(0x0035)[0] temperature, sunlight, moisture, fertility = unpack('<hxIBHxxxxxx',data) temperature=float(temperature/10) min = int(test_min/10) #g_sun[min] = sunlight #g_moi[min] = moisture #g_fer[min] = fertility #g_tem[min] = temperature #conn = mysql.connect() #cursor = conn.cursor() #sql = "INSERT INTO sensor_data_test (sunlight,moisture,temperature,fertility,time) VALUES ('%d','%d','%f','%d','%s')" % (sunlight,moisture,temperature,fertility,time) #cursor.execute(sql) #conn.commit() #cursor.close() #conn.close() print "get data at %s" % time except: print "can not get data at %s" % time finally: if int(test_min/10) == 5: sum_sun = 0 sum_tem = 0 sum_fer = 0 sum_moi = 0 check_sun = 0 check_tem = 0 check_fer = 0 check_moi = 0 for i in range(0,6): if g_sun[i] != -1: sum_sun += g_sun[i] check_sun += 1 if g_moi[i] != -1: sum_moi += g_moi[i] check_moi += 1 if g_tem[i] != -1.0: sum_tem += g_tem[i] check_tem += 1 if g_fer[i] != -1: sum_fer += g_fer[i] check_fer += 1 if check_sun != 0: sum_sun = int(sum_sun/check_sun) if check_moi != 0: sum_moi = int(sum_moi/check_moi) if check_tem != 0: sum_tem = float(sum_tem/check_tem) if check_fer != 0: sum_fer = int(sum_fer/check_fer) conn = mysql.connect() cursor = conn.cursor() print "STORE DATA AFTER 1 HOUR at %s" % time sql = "INSERT INTO sensor_data (sunlight,moisture,temperature,fertility,time) VALUES ('%d','%d','%f','%d','%s')" % (sum_sun,sum_moi,sum_tem,sum_fer,time) cursor.execute(sql) conn.commit() cursor.close() conn.close() for i in range(0,6): g_sun[i] = -1 g_moi[i] = -1 g_tem[i] = -1.0 g_fer[i] = -1
def main(): conn = mysql.connect() cursor = conn.cursor() sql = "SELECT * FROM plants_info WHERE id = 1" cursor.execute(sql) results = cursor.fetchall() for row in results: plants_name = row[1] sun_b = row[2] sun_t = row[3] moi_b = row[4] moi_t = row[5] tem_b = row[6] tem_t = row[7] fer_b = row[8] fer_t = row[9] sql = "SELECT * FROM sensor_data_hour WHERE id = 2" cursor.execute(sql) results = cursor.fetchall() for row in results: status_led = row[7] status_water = row[8] status_fan = row[9] cursor.close() conn.close() sun_b = int(sun_b*10.76/(0.71*24)) sun_t = int(sun_t*10.76/(0.71*2)) status_sun = 1 status_moi = 1 status_tem = 1 status_fer = 1 if request.method == 'POST': if not session.get('mac'): conn = mysql.connect() cursor = conn.cursor() sql = "SELECT * FROM plants_info WHERE id = 1" cursor.execute(sql) results = cursor.fetchall() for row in results: address_x = row[0] cursor.close() conn.close() address = str(address_x) session['mac'] = address_x else: address = str(session['mac']) try: requester = GATTRequester(address) #Read battery and firmware version attribute data=requester.read_by_handle(0x0038)[0] battery, version = unpack('<B6s',data) #Enable real-time data reading requester.write_by_handle(0x0033, str(bytearray([0xa0, 0x1f]))) #Read plant data data=requester.read_by_handle(0x0035)[0] temperature, sunlight, moisture, fertility = unpack('<hxIBHxxxxxx',data) temperature=float(temperature/10) data_time=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") conn = mysql.connect() cursor = conn.cursor() sql = "UPDATE plants_info SET baterry = %d, firmware = '%s' WHERE id = 1" % (battery,version) cursor.execute(sql) conn.commit() sql = "UPDATE sensor_data_hour SET sunlight = %d, moisture = %d,temperature=%0.1f,fertility=%d,time='%s' WHERE id = 2" % (sunlight,moisture,temperature,fertility,data_time) cursor.execute(sql) conn.commit() cursor.close() conn.close() flash('Data updated successfully','success') except: flash('Could not update sensor value, please try again','danger') conn = mysql.connect() cursor = conn.cursor() sql = "SELECT * FROM sensor_data_hour WHERE id = 2" cursor.execute(sql) results = cursor.fetchall() for row in results: sunlight = row[1] moisture = row[2] fertility = row[4] temperature = row[3] data_time = row[5] cursor.close() conn.close() if sunlight < sun_b: status_sun = 0 elif sunlight > sun_t: status_sun = 2 if moisture < moi_b: status_moi = 0 elif moisture > moi_t: status_moi = 2 if temperature < tem_b: status_tem = 0 elif temperature > tem_t: status_tem = 2 if fertility < fer_b: status_fer = 0 elif fertility > fer_t: status_fer = 2 string_time = str(data_time) string_time = string_time[11:-6] check_hour = int(string_time) if check_hour >= 18 or check_hour <=5: status_sun = 3 return render_template('index.html',status_fan=status_fan,status_led=status_led,status_water=status_water,status_sun=status_sun,status_moi=status_moi,status_tem=status_tem,status_fer=status_fer,sun=sunlight,moi=moisture,tem=temperature,fer=fertility,time=data_time,plants_name=plants_name,sun_b=sun_b,sun_t=sun_t,moi_b=moi_b,moi_t=moi_t,tem_b=tem_b,tem_t=tem_t,fer_b=fer_b,fer_t=fer_t) else: conn = mysql.connect() cursor = conn.cursor() sql = "SELECT * FROM sensor_data_hour WHERE id = 2" cursor.execute(sql) results = cursor.fetchall() for row in results: data_sun = row[1] data_moi = row[2] data_fer = row[4] data_tem = row[3] data_time = row[5] cursor.close() conn.close() if data_sun < sun_b: status_sun = 0 elif data_sun > sun_t: status_sun = 2 if data_moi < moi_b: status_moi = 0 elif data_moi > moi_t: status_moi = 2 if data_tem < tem_b: status_tem = 0 elif data_tem > tem_t: status_tem = 2 if data_fer < fer_b: status_fer = 0 elif data_fer > fer_t: status_fer = 2 string_time = str(data_time) string_time = string_time[11:-6] check_hour = int(string_time) if check_hour >= 18 or check_hour <=5: status_sun = 3 return render_template('index.html',status_fan=status_fan,status_led=status_led,status_water=status_water,status_sun=status_sun,status_moi=status_moi,status_tem=status_tem,status_fer=status_fer,plants_name=plants_name,sun=data_sun,moi=data_moi,tem=data_tem,fer=data_fer,time=data_time,sun_b=sun_b,sun_t=sun_t,moi_b=moi_b,moi_t=moi_t,tem_b=tem_b,tem_t=tem_t,fer_b=fer_b,fer_t=fer_t)
from gattConversions import getCharacteristicDescription, getServiceDescription from scanner import getAdvAFromScan if __name__ == '__main__': AdvA = getAdvAFromScan() requester = GATTRequester(AdvA) invalidHandles = list() for x in range(0x00, 0xffff): if x % 1000 == 0: print "................................................Handle Counter at: " + str( hex(x)) try: val = requester.read_by_handle(x)[0] hexval = binascii.hexlify(val) # example service value (sv): 0018 # service uuid = sv[2:][0:2] # example characteristic declarator value (cdv): 020300002a # cdv[0:2] = permissions # cdv[4:6]+cdv[2:4] = characteristic value # cdv[8:10]+cdv[6:8] = characteristic UUID (short form) # parse service descriptor if len(hexval) == 4: lookup = getServiceDescription("0000" + hexval[2:] + hexval[0:2] + "-0000-1000-8000-00805F9B34FB") if lookup != "Service description not found.":
class Koshian: """ Koshian.pyの基本クラス """ def __init__(self, mac=""): if mac == "": self.mac = find() else: self.mac = mac self.startup() def startup(self): self.connect() delay(500) self.pin = 0 self.pin_mode = 0 self.pwm_mode = 0 #self.hardwareReset() # このシーケンスを経ると一発目の入力が正しく機能する(?) self.writePinMode(0xFF) self.writePIO(0xFF) self.writePinMode(0x00) self.I2C_read_length = 1 # ------------------------------------------- # Digital I/O Functions # ------------------------------------------- def pinMode(self, pin, mode): """ PIOを入出力指定します。 pin: ピン番号。PIO0などのように指定します。 mode: INPUT/OUTPUT で指定します。 """ self.setPWMmode(pin, DISABLE) r = self.readPinMode() if mode == OUTPUT: r |= (1 << pin) & 0xFF else: r &= (~((1 << pin)) & 0xFF) self.writePinMode(r) def digitalWrite(self, pin, value): """ PIOにデジタル出力します。 pin: ピン番号。PIO0などのように指定します。 value: HIGH/LOW で指定します。 """ self.setPWMmode(pin, DISABLE) if value == HIGH: self.pin |= (1 << pin) & 0xFF else: self.pin &= (~((1 << pin)) & 0xFF) self.writePIO(self.pin) def digitalRead(self, pin): """ PIOからデジタル入力します。 pin: ピン番号。PIO0などのように指定します。 戻り値は HIGH/LOW です。 """ if (self.pwm_mode & (1 << pin)) != 0: self.setPWMmode(pin, DISABLE) dat = self.readPIO() mask = (1 << pin) & 0xFF if (dat & mask) == 0: return LOW else: return HIGH # ------------------------------------------- # Analog I/O Functions # ------------------------------------------- def analogRead(self, pin): """ AIOからデジタル入力します。 pin: ピン番号。AIO0などのように指定します。 戻り値は mV単位です """ return self.ANALOG_read(pin) def analogWrite(self, pin, value): """ DACは未対応のようなので、PWMのみです。 pin: PIO0,1,2のみ。 value: 0-255 value/255*VCC が出力されます。 """ self.setPWMmode(pin, ENABLE) self.writePWMperiod(pin, 255 * 20) self.writePWMduty(pin, value * 20) # ------------------------------------------- # Others # ------------------------------------------- # ------------------------------------------- # PWM Functions # ------------------------------------------- def setPWMmode(self, pin, mode): """ pin: PIO0,1,2を指定。 mode: ENABLE/DISABLE """ new_mode = self.pwm_mode if mode == ENABLE: new_mode |= (1 << pin) & 0xFF else: new_mode &= (~((1 << pin)) & 0xFF) if new_mode != self.pwm_mode: self.writePWMmode(new_mode) # ------------------------------------------- # konashi PIO functions # ------------------------------------------- def writePinMode(self, value): """ value bit0-5: PIO0-5 0: INPUT 1: OUTPUT """ return self.write_command("PIO_setting", [value]) def readPinMode(self): return self.read_command("PIO_setting") def writePIOpullup(self, value): """ value bit0-5: PIO0-5 0: DISABLE 1: ENABLE """ return self.write_command("PIO_pullup", [value]) def readPIOpullup(self): return self.read_command("PIO_pullup") def writePIO(self, value): """ value bit0-5: PIO0-5 0: LOW 1: HIGH """ return self.write_command("PIO_output", [value]) def readPIO(self): return self.read_command("PIO_notification") # ------------------------------------------- # konashi Analog IO functions # ------------------------------------------- #def ANALOG_drive(self,pin): def ANALOG_read(self, pin): handle_string = "" if pin == AIO0: handle_string = "ANALOG_read_0" elif pin == AIO1: handle_string = "ANALOG_read_1" elif pin == AIO2: handle_string = "ANALOG_read_2" dat = self.read_async_command(handle_string, length=2) adat = (dat[0] << 8) + dat[1] return adat # ------------------------------------------- # konashi UART functions # ------------------------------------------- def UART_config(self, mode): """ mode 0: UART DISABLE 1: UART ENABLE """ self.write_command("UART_config", [mode]) def UART_baud_rate(self, bit_rate): """ bit_rate: bps(2400/9600 is supported) """ dat = [0, 0] bit_rate /= 240 dat[0] = (bit_rate & 0xFF00) >> 8 dat[1] = (bit_rate & 0x00FF) self.write_command("UART_baud_rate", dat) def UART_tx(self, data): """ data: max 18bytes strings """ dat = (map(lambda n: ord(n), data)) self.write_command("UART_tx", dat) def UART_rx(self): """ read 1 byte strings """ return chr(self.read_command("UART_rx", dat)[0]) # ------------------------------------------- # konashi I2C functions # ------------------------------------------- def I2C_config(self, mode): """ mode 0: I2C DISABLE 1: I2C ENABLE(100kHz) 2: I2C ENABLE(400kHz) """ self.write_command("I2C_config", [mode]) def I2C_start_stop(self, mode): """ mode 0: STOP CONDITION 1: START CONDITION 2: REPEATED START CONDITION """ self.write_command("I2C_start_stop", [mode]) def I2C_write(self, slave_address, data): """ slave_address: I2C slave address(8bit) data: data array (max 16 bytes) """ dat = [0] * 2 dat[0] = len(data) + 2 dat[1] = (slave_address << 1) & 0xfe if isinstance(data, list): dat += data if isinstance(data, str): dat += map(lambda n: ord(n), data) self.write_command("I2C_write", dat) def I2C_read_parameter(self, slave_address, length): """ Send Read Request slave_address: I2C slave address(7bit) """ self.I2C_read_length = length dat = [0] * 2 dat[0] = self.I2C_read_length dat[1] = (slave_address << 1) | 0x01 self.write_command("I2C_read_parameter", dat) def I2C_read(self): return self.read_async_command("I2C_read", length=self.I2C_read_length) # ------------------------------------------- # konashi PWM functions # ------------------------------------------- def readPWMmode(self): return self.read_command("PWM_config") def writePWMmode(self, mode): self.mode = mode self.write_command("PWM_config", [self.mode]) def writePWMperiod(self, pin, period): """ period: 1000-20480[usec] """ param = [pin, 0, 0, 0, 0] param[1] = (period & 0xFF000000) >> 24 param[2] = (period & 0x00FF0000) >> 16 param[3] = (period & 0x0000FF00) >> 8 param[4] = (period & 0x000000FF) self.write_command("PWM_parameter", param) def writePWMduty(self, pin, duty): param = [pin, 0, 0, 0, 0] param[1] = (duty & 0xFF000000) >> 24 param[2] = (duty & 0x00FF0000) >> 16 param[3] = (duty & 0x0000FF00) >> 8 param[4] = (duty & 0x000000FF) self.write_command("PWM_duty", param) # ------------------------------------------- # konashi other functions # ------------------------------------------- def hardwareReset(self): self.write_command("hardware_reset", [0xff]) # ------------------------------------------- # Bluetooth functions (depend on pygattlib) # ------------------------------------------- def connect(self): self.req = GATTRequester(self.mac) def write_command(self, handle_id, parameter): """ parameter: 配列 """ handle = HANDLE[handle_id] self.req.write_by_handle(handle, str(bytearray(parameter))) def read_async_command(self, handle_id, length=1): """ 1バイトリードのときはintで、 2バイト以上リードするときは配列で返します。 """ response = GATTResponse() handle = HANDLE[handle_id] self.req.read_by_handle_async(handle, response) while not response.received(): time.sleep(0.1) ans = response.received()[0] ans = map(lambda n: ord(n), ans) if length == 1: return ans[0] else: return ans def read_command(self, handle_id, length=1): """ 同期リード。 1バイトリードのときはintで、 2バイト以上リードするときは配列で返します。 """ handle = HANDLE[handle_id] ans = self.req.read_by_handle(handle)[0] ans = map(lambda n: ord(n), ans) if length == 1: return ans[0] else: return ans # ------------------------------------------- # Main Routine # ------------------------------------------- def setup(self): pass def loop(self): pass def run(self): self.setup() while 1: self.loop()
response = GATTResponse() req.connect() req.read_by_handle_async(0x3A, response) while not response.received(): time.sleep(0.1) steps = response.received()[0] #print "steps..." #print type(steps) #print steps #for b in steps: # print hex(ord(b)),' ' req.write_by_handle(0x3C, str(bytearray([0xff, 0xff]))) req.write_by_handle(0x3E, str(bytearray([0x64]))) data = req.read_by_handle(0x3C)[0] #for d in data: # print hex(ord(d)),' ' #print("") req.write_by_handle(0x3A, str(bytearray([0x0, 0x0]))) for i in range(1000): data = req.read_by_handle(0x39)[0] for d in data: print hex(ord(d)), print("") i = 0 axl = 0x00 axh = 0x00 for d in data: if i > 5 and i <= 11: if i == 6: # get axl and axh
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))
#!bin/python from gattlib import GATTRequester req = GATTRequester("E0:14:88:54:3D:51") name = req.read_by_uuid("00002a01-0000-1000-8000-00805f9b34fb")[0] steps = req.read_by_handle(0x15)[0]
from gattlib import GATTRequester, GATTResponse import sys address = sys.argv[1] requester = GATTRequester(address) data = requester.read_by_handle(0x000c) print(data[0])
#Read data from Xiaomi flower monitor, tested on firmware version 2.6.6 import sys from gattlib import GATTRequester, GATTResponse from struct import * import paho.mqtt.client as mqtt from farmware_tools import device address = "c4:7c:8d:66:35:49" #sys.argv[1] requester = GATTRequester(address) #Read battery and firmware version attribute data = requester.read_by_handle(0x0038)[0] battery, version = unpack('<B6s', data) device.log("Battery level:", battery, "%") device.log("Firmware version:", version) #Enable real-time data reading requester.write_by_handle(0x0033, str(bytearray([0xa0, 0x1f]))) #Read plant data data = requester.read_by_handle(0x0035)[0] temperature, sunlight, moisture, fertility = unpack('<hxIBHxxxxxx', data) device.log("Light intensity:", sunlight, "lux") print "Temperature:", temperature / 10., "C" print "Soil moisture:", moisture, "%" print "Soil fertility:", fertility, "uS/cm" #Sometimes the version contains some funny charcters which throws off the JSON processing. Cleaning string temp = version version = " " for x in temp: if x == ".":