Adding and logging to csv files to the subscription service
This commit is contained in:
@@ -1 +0,0 @@
|
||||
etwy
|
||||
@@ -1,37 +0,0 @@
|
||||
import gatt
|
||||
|
||||
manager = gatt.DeviceManager(adapter_name='hci0')
|
||||
|
||||
class KanoWand(gatt.Device):
|
||||
def services_resolved(self):
|
||||
super().services_resolved()
|
||||
print("Grabbing services")
|
||||
print(self.is_connected())
|
||||
print(self.services)
|
||||
|
||||
for service in self.services:
|
||||
print("FOUND SERVICE")
|
||||
# print(service)
|
||||
# print(service.device)
|
||||
print(service.uuid)
|
||||
print(service.characteristics)
|
||||
for char in service.characteristics:
|
||||
print("FOUND CHARACTERISTIC")
|
||||
print(char.uuid)
|
||||
print(char.read_value())
|
||||
# device_information_service = next(s for s in self.services if s.uuid == '0000180a-0000-1000-8000-00805f9b34fb')
|
||||
#
|
||||
# firmware_version_characteristic = next(
|
||||
# c for c in device_information_service.characteristics
|
||||
# if c.uuid == '00002a26-0000-1000 -8000-00805f9b34fb')
|
||||
#
|
||||
# firmware_version_characteristic.read_value()
|
||||
|
||||
def characteristic_value_updated(self, characteristic, value):
|
||||
print("Firmware version:", value.decode("utf-8"))
|
||||
|
||||
|
||||
device = KanoWand(mac_address='e3:ae:cd:af:28:e2', manager=manager)
|
||||
device.connect()
|
||||
manager.run()
|
||||
manager.stop()
|
||||
@@ -0,0 +1,56 @@
|
||||
import asyncio
|
||||
from bleak import discover
|
||||
from pprint import pprint
|
||||
|
||||
async def run():
|
||||
devices = await discover()
|
||||
for d in devices:
|
||||
print(d)
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(run())
|
||||
|
||||
import asyncio
|
||||
from bleak import BleakClient
|
||||
|
||||
address = "D8:9B:12:D1:08:80"
|
||||
MODEL_NBR_UUID = "64a7000f-f691-4b93-a6f4-0968f5b648f8"
|
||||
|
||||
async def run(address, loop):
|
||||
async with BleakClient(address, loop=loop) as client:
|
||||
# await client.connect()
|
||||
print(await client.is_connected())
|
||||
print(await client.get_services())
|
||||
services = await client.get_services()
|
||||
pprint(services.descriptors)
|
||||
pprint(services.characteristics)
|
||||
pprint(services.services)
|
||||
# print(services.descriptors)
|
||||
# for key, val in services.descriptors.items():
|
||||
# print(f"{key} + {val}")
|
||||
#
|
||||
# print(services.characteristics)
|
||||
# for key, val in services.characteristics.items():
|
||||
# print(f"{key} + {val}")
|
||||
|
||||
print(services)
|
||||
for x in services:
|
||||
print(x)
|
||||
for characteristic in x.characteristics:
|
||||
print("")
|
||||
print(characteristic)
|
||||
print(characteristic.properties)
|
||||
for descriptor in characteristic.descriptors:
|
||||
print(descriptor)
|
||||
print(x.description)
|
||||
# for i in range(10):
|
||||
# x = await client.read_gatt_descriptor(i)
|
||||
# print(x)
|
||||
|
||||
# model_number = await client.read_gatt_char()
|
||||
# print(model_number)
|
||||
# print("Model Number: {0}".format("".join(map(chr, model_number))))
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(run(address, loop))
|
||||
+151
-32
@@ -1,62 +1,152 @@
|
||||
"""
|
||||
Notifications
|
||||
-------------
|
||||
Example showing how to add notifications to a characteristic and handle the responses.
|
||||
Updated on 2019-07-03 by hbldh <henrik.blidh@gmail.com>
|
||||
"""
|
||||
|
||||
import logging
|
||||
import asyncio
|
||||
import platform
|
||||
import struct
|
||||
import time
|
||||
import pandas as pd
|
||||
|
||||
from bleak import BleakClient
|
||||
from bleak import _logger as logger
|
||||
from converters import BinToInt
|
||||
from converters import BinToInt, BinToFloat
|
||||
|
||||
"""
|
||||
This is used for reading and decoding values from t he Kano Harry Potter Coding Wand
|
||||
- Wand sends 25 updates to gyro and accel every second
|
||||
- Wand sends 3 Dimensional data as 48 bit reverse marshalled integers
|
||||
- Wand seems to send smaller single dimensional data in 16bit unsigned integers
|
||||
"""
|
||||
|
||||
BUTTON = 1
|
||||
GYROSCOPE = 2
|
||||
NINE_AXIS = 2
|
||||
ACCELEROMETER = 3
|
||||
BATTERY = 4
|
||||
TEMPERATURE = 5
|
||||
MAGNETOMETER = 6
|
||||
|
||||
INT_DECODER = BinToInt(48)
|
||||
FLOAT_DECODER = BinToFloat(16, 31)
|
||||
BUTTON_STATUS = None
|
||||
|
||||
CHARACTERISTIC_UUIDS = {
|
||||
# ("64a7000d-f691-4b93-a6f4-0968f5b648f8"):BUTTON,#Button
|
||||
# ("64a7000a-f691-4b93-a6f4-0968f5b648f8"):GYROSCOPE,#9 axis
|
||||
("64a7000d-f691-4b93-a6f4-0968f5b648f8"): BUTTON, # Button
|
||||
("64a7000a-f691-4b93-a6f4-0968f5b648f8"): NINE_AXIS, # 9 axis
|
||||
("64a7000c-f691-4b93-a6f4-0968f5b648f8"): ACCELEROMETER, # Accel
|
||||
# ("64a70007-f691-4b93-a6f4-0968f5b648f8"):BATTERY,
|
||||
# ("64a70014-f691-4b93-a6f4-0968f5b648f8"):TEMPERATURE
|
||||
# ("64a70014-f691-4b93-a6f4-0968f5b648f8"):TEMPERATURE,
|
||||
# ("64a70014-f691-4b93-a6f4-0968f5b648f8"):MAGNETOMETER
|
||||
} # <--- Change to the characteristic you want to enable notifications from.
|
||||
|
||||
# TODO: RUMBLE
|
||||
# TODO: RGB
|
||||
# TODO: MAGNETOMETER??
|
||||
#
|
||||
|
||||
|
||||
# device_address = "e3:ae:cd:af:28:e2"
|
||||
device_address = "D8:9B:12:D1:08:80"
|
||||
|
||||
|
||||
class Gyro(object):
|
||||
def __init__(self):
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.z = 0
|
||||
|
||||
def __str__(self):
|
||||
print(self.x, self.y, self.z)
|
||||
|
||||
|
||||
class Accel(object):
|
||||
def __init__(self):
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.z = 0
|
||||
|
||||
def __str__(self):
|
||||
print(self.x, self.y, self.z)
|
||||
|
||||
|
||||
class Sensors(object):
|
||||
def __init__(self):
|
||||
self.gyro = None
|
||||
self.gyro_updates = 0
|
||||
|
||||
self.accel = None
|
||||
self.accel_updates = 0
|
||||
self.dataframe = pd.DataFrame(columns=["gyro_x", "gyro_y", "gyro_z", "accel_x", "accel_y", "accel_z"])
|
||||
|
||||
def append_to_dataframe(self):
|
||||
# print("Printing the gyro and accel", self.gyro, self.accel)
|
||||
# print(self.dataframe)
|
||||
# print(self.gyro_updates, self.accel_updates)
|
||||
if self.gyro_updates == self.accel_updates:
|
||||
# print({
|
||||
# "gyro_x": self.gyro.x,
|
||||
# "gyro_y": self.gyro.y,
|
||||
# "gyro_z": self.gyro.z,
|
||||
# "accel_x": self.accel.x,
|
||||
# "accel_y": self.accel.y,
|
||||
# "accel_z": self.accel.z,
|
||||
# })
|
||||
# try:
|
||||
#
|
||||
# except Exception as e:
|
||||
# print("ERROR HAS OCCURRED")
|
||||
# print(e)
|
||||
self.dataframe = self.dataframe.append(
|
||||
pd.DataFrame({
|
||||
"gyro_x": self.gyro.x,
|
||||
"gyro_y": self.gyro.y,
|
||||
"gyro_z": self.gyro.z,
|
||||
"accel_x": self.accel.x,
|
||||
"accel_y": self.accel.y,
|
||||
"accel_z": self.accel.z,
|
||||
}, index=[0])
|
||||
)
|
||||
|
||||
def save_df_to_file(self, filename):
|
||||
self.dataframe.to_csv(filename, index=False)
|
||||
|
||||
def set_gyro(self, gyro):
|
||||
self.gyro = gyro
|
||||
self.gyro_updates += 1
|
||||
|
||||
def set_accel(self, accel):
|
||||
self.accel = accel
|
||||
self.accel_updates += 1
|
||||
|
||||
|
||||
def chunker(seq, size):
|
||||
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
|
||||
|
||||
def decode_button(data):
|
||||
print(data)
|
||||
print(int.from_bytes(data, byteorder='big'))
|
||||
|
||||
def decode_gyroscope(data):
|
||||
decode_accelerometer(data)
|
||||
count = 0
|
||||
|
||||
|
||||
def decode_button(data):
|
||||
global sensors, count
|
||||
if int.from_bytes(data, byteorder='big'):
|
||||
print("Button Pressed")
|
||||
sensors = Sensors()
|
||||
count += 1
|
||||
else:
|
||||
print("Button Released")
|
||||
sensors.save_df_to_file(f"dataset{count}.csv")
|
||||
|
||||
|
||||
def decode_nine_axis(data):
|
||||
converted = [INT_DECODER.process(x, True) / 10 ** 14 for x in chunker(data, 6)]
|
||||
|
||||
# print(converted, sum(converted))
|
||||
return converted
|
||||
|
||||
|
||||
def decode_accelerometer(data):
|
||||
converted = [INT_DECODER.process(x, True)/10**14 for x in chunker(data, 6)]
|
||||
print(converted,sum(converted))
|
||||
converted = [INT_DECODER.process(x, True) / 10 ** 14 for x in chunker(data, 6)]
|
||||
# print(converted, sum(converted))
|
||||
return converted
|
||||
|
||||
|
||||
def decode_battery(data):
|
||||
print(len(data))
|
||||
print(data)
|
||||
print(int.from_bytes(data, byteorder='big'))
|
||||
global BUTTON_STATUS
|
||||
BUTTON_STATUS = int.from_bytes(data, byteorder='big')
|
||||
|
||||
|
||||
def decode_temp(data):
|
||||
print(len(data))
|
||||
@@ -64,30 +154,56 @@ def decode_temp(data):
|
||||
print(struct.unpack("h", data))
|
||||
|
||||
|
||||
def decode_magnet(data):
|
||||
print(data)
|
||||
print(len(data))
|
||||
|
||||
|
||||
count = 0
|
||||
|
||||
sensors = Sensors()
|
||||
|
||||
|
||||
def notification_handler(sender, data):
|
||||
global count, sensors
|
||||
"""Simple notification handler which prints the data received."""
|
||||
#TODO: Convert to a dictionary and a single decode command
|
||||
# TODO: Convert to a dictionary and a single decode command
|
||||
sender = CHARACTERISTIC_UUIDS[sender]
|
||||
if sender == BUTTON:
|
||||
decode_button(data)
|
||||
elif sender == GYROSCOPE:
|
||||
decode_gyroscope(data)
|
||||
elif sender == NINE_AXIS:
|
||||
gyro = Gyro()
|
||||
# print("getting gyro values")
|
||||
|
||||
gyro.x, gyro.y, gyro.z = decode_nine_axis(data)
|
||||
# print("got gyro values")
|
||||
# print(gyro)
|
||||
sensors.set_gyro(gyro)
|
||||
sensors.append_to_dataframe()
|
||||
elif sender == ACCELEROMETER:
|
||||
decode_accelerometer(data)
|
||||
accel = Accel()
|
||||
accel.x, accel.y, accel.z = decode_nine_axis(data)
|
||||
sensors.set_accel(accel)
|
||||
sensors.append_to_dataframe()
|
||||
# decode_accelerometer(data)
|
||||
elif sender == BATTERY:
|
||||
decode_battery(data)
|
||||
elif sender == TEMPERATURE:
|
||||
decode_temp(data)
|
||||
elif sender == MAGNETOMETER:
|
||||
decode_magnet(data)
|
||||
|
||||
|
||||
async def start_notify(client):
|
||||
for char in CHARACTERISTIC_UUIDS.keys():
|
||||
await client.start_notify(char, notification_handler)
|
||||
|
||||
|
||||
async def stop_notify(client):
|
||||
for char in CHARACTERISTIC_UUIDS.keys():
|
||||
await client.stop_notify(char)
|
||||
|
||||
|
||||
async def run(address, loop, debug=False):
|
||||
if debug:
|
||||
import sys
|
||||
@@ -105,13 +221,16 @@ async def run(address, loop, debug=False):
|
||||
logger.info("Connected: {0}".format(x))
|
||||
await start_notify(client)
|
||||
|
||||
await asyncio.sleep(60.0, loop=loop)
|
||||
# await asyncio.sleep(60.0, loop=loop)
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
await stop_notify(client)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
|
||||
os.environ["PYTHONASYNCIODEBUG"] = str(1)
|
||||
address = (
|
||||
device_address # <--- Change to your device's address here if you are using Windows or Linux
|
||||
@@ -119,4 +238,4 @@ if __name__ == "__main__":
|
||||
else "243E23AE-4A99-406C-B317-18F1BD7B4CBE" # <--- Change to your device's address here if you are using macOS
|
||||
)
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(run(address, loop, True))
|
||||
loop.run_until_complete(run(address, loop, True))
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import asyncio
|
||||
from bleak import discover
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
|
||||
async def run():
|
||||
devices = await discover()
|
||||
for d in devices:
|
||||
print(d)
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(run())
|
||||
|
||||
# import asyncio
|
||||
# from bleak import BleakClient
|
||||
#
|
||||
# address = "e3:ae:cd:af:28:e2"
|
||||
# MODEL_NBR_UUID = "64a7000f-f691-4b93-a6f4-0968f5b648f8"
|
||||
#
|
||||
# async def run(address, loop):
|
||||
# async with BleakClient(address, loop=loop) as client:
|
||||
# # await client.connect()
|
||||
# print(await client.is_connected())
|
||||
# print(await client.get_services())
|
||||
# services = await client.get_services()
|
||||
# pprint(services.descriptors)
|
||||
# pprint(services.characteristics)
|
||||
# pprint(services.services)
|
||||
# # print(services.descriptors)
|
||||
# # for key, val in services.descriptors.items():
|
||||
# # print(f"{key} + {val}")
|
||||
# #
|
||||
# # print(services.characteristics)
|
||||
# # for key, val in services.characteristics.items():
|
||||
# # print(f"{key} + {val}")
|
||||
#
|
||||
# print(services)
|
||||
# for x in services:
|
||||
# print(x)
|
||||
# for characteristic in x.characteristics:
|
||||
# print("")
|
||||
# print(characteristic)
|
||||
# print(characteristic.properties)
|
||||
# for descriptor in characteristic.descriptors:
|
||||
# print(descriptor)
|
||||
# print(x.description)
|
||||
# # for i in range(10):
|
||||
# # x = await client.read_gatt_descriptor(i)
|
||||
# # print(x)
|
||||
#
|
||||
# # model_number = await client.read_gatt_char()
|
||||
# # print(model_number)
|
||||
# # print("Model Number: {0}".format("".join(map(chr, model_number))))
|
||||
#
|
||||
#
|
||||
# loop = asyncio.get_event_loop()
|
||||
# loop.run_until_complete(run(address, loop))
|
||||
Reference in New Issue
Block a user