Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
NSLog0 committed Sep 4, 2020
0 parents commit 4b9eee2
Show file tree
Hide file tree
Showing 6 changed files with 342 additions and 0 deletions.
138 changes: 138 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@

# Created by https://www.gitignore.io/api/python
# Edit at https://www.gitignore.io/?templates=python

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

### Python Patch ###
.venv/

### Python.VirtualEnv Stack ###
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
pip-selfcheck.json

# End of https://www.gitignore.io/api/python

data.log
Empty file added __init__.py
Empty file.
50 changes: 50 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import logging
from bluepy.btle import DefaultDelegate, Peripheral, Scanner
import requests
import json

from scanner import ScanDelegate
from parser import BLEParser

try:
s = ScanDelegate()
scanner = Scanner().withDelegate(s)
value = {}
headers = {'Content-type': 'application/json'}
logging.basicConfig(filename='data.log', level=logging.INFO)

mapping_value = {
'oximiter':
{
'char': '2A5F',
'serv': '1822'
},
'bloodpressure':
{
'char': '2A35',
'serv': '1810'
},
'glucose': {
'char': '2A18',
'serv': '1808'
}
}

mapping_name = {
'nonin3230': 'oximiter',
'blesmart': 'bloodpressure',
'mi band 2': 'heart_rate'
}

while True:
devices = scanner.scan(5.0)
if s.knowdevice:
connector = Peripheral(s.UUID, "public")
_type = mapping_name[s.name]
value = BLEParser(connector, _type=_type, servUUID=mapping_value[_type]['serv'],
charactUUID=mapping_value[_type]['char']).notify()
requests.post('http://localhost:5000/devices/scan',
data=json.dumps(value), headers=headers)
connector.disconnect()
except Exception as e:
print(str(e))
89 changes: 89 additions & 0 deletions parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import logging
import binascii
import time
import sys
import time

from bluepy.btle import DefaultDelegate, Peripheral, Scanner
from sfloat import to_int

try:
import queue
except ImportError:
import Queue as queue


class BLEParser():
__device = None
__serv = None
__charact = None
__buffer_holder = queue.Queue()

class NotificationDelegate(DefaultDelegate):
def __init__(self, buffer_holder):
DefaultDelegate.__init__(self)
self.buffer_holder = buffer_holder

def handleNotification(self, cHandle, data):
decoded = binascii.b2a_hex(data).decode('utf-8')
self.buffer_holder.put(decoded)

def __init__(self, device, _type, connect_type="public", servUUID="1822", charactUUID="2a5f", sending_pkg=b"\x01\x00"):
self.__device = device
self.__device.setDelegate(
BLEParser.NotificationDelegate(self.__buffer_holder))
self.connect_type = connect_type
self.servUUID = servUUID
self.charactUUID = charactUUID
self.sending_pkg = sending_pkg
self._type = _type

def set_up(self):
self.get_service()
self.get_characteristics()
self.sending()

def get_service(self):
self.__serv = self.__device.getServiceByUUID(self.servUUID)

def get_characteristics(self):
self.__charact = self.__serv.getCharacteristics(self.charactUUID)[0]

def sending(self):
self.__device.writeCharacteristic(
self.__charact.getHandle() + 1, self.sending_pkg, withResponse=True)

def notify(self):
self.set_up()
counter = 0
while counter <= 5:
if self.__device.waitForNotifications(1.0):
counter += 1

continue

self.__device.disconnect()
return self.parser()

def parser(self):
data = self.__buffer_holder.get_nowait()
return self.template(data)

def template(self, data):
result = ''
if self._type is 'oximiter':
oxi = int(to_int(int(data[4:6] + data[2:4], 16)))
h_rate = int(to_int(int(data[8:10] + data[6:8], 16)))
result = {'device': 'oximiter', 'value': {
'heart_rate': int(h_rate), 'spo2': int(oxi)}}

if self._type is 'glucose':
lv = int(to_int(int(data[4:6] + data[2:4], 16)))
result = {'device': 'glucose', 'value': int(lv)}

if self._type is 'bloodpressure':
normal = int(to_int(int(data[4:6] + data[2:4], 16)))
result = {'device': 'bloodPressure', 'value': {
normal: int(normal), low: int(normal)}}

return result
28 changes: 28 additions & 0 deletions scanner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import sys
import time
import binascii
import logging
from bluepy.btle import DefaultDelegate, Peripheral, Scanner


class ScanDelegate(DefaultDelegate):

UUID = ''
knowdevice = False
name = ''

def __init__(self):
DefaultDelegate.__init__(self)

def handleDiscovery(self, dev, isNewDev, isNewData):
for (adtype, desc, value) in dev.getScanData():
self.knowdevice = False
self.name = ''
if ("nonin3230" in value.lower()):
self.name = 'nonin3230'
self.knowdevice = True

if self.knowdevice == True:
self.UUID = dev.addr

break
37 changes: 37 additions & 0 deletions sfloat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
def twos_complement(value, bitWidth):
if value >= 2**bitWidth:
raise ValueError(
"Value: {} out of range of {}-bit value.". format(value, bitWidth))
else:
return value - int((value << 1) & 2**bitWidth)


def getExponent(value):
exponent = twos_complement(((value >> 12) & 0xF), 4)
return int(exponent)


def getMantissa(value):
mantissa = twos_complement((value & 0x0FFF), 12)
return int(mantissa)


def to_int(value):
# NaN
if (value == 0x07FF):
return float('nan')
# NRes (not at this resolution)
elif (value == 0x0800):
return float('nan')
# Positive infinity
elif (value == 0x07FE):
return float("inf")
# Negative infinity
elif (value == 0x0802):
return float("-inf")
# Reserved
elif (value == 0x0801):
return float("nan")
else:
return float(getMantissa(value) * pow(10, getExponent(value)))

0 comments on commit 4b9eee2

Please sign in to comment.