Skip to content

Commit

Permalink
Prep for v0.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Gadgetoid committed Oct 28, 2020
1 parent e96d952 commit 4fe091a
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 131 deletions.
9 changes: 5 additions & 4 deletions Makefile
@@ -1,5 +1,6 @@
LIBRARY_VERSION=$(shell grep version library/setup.cfg | awk -F" = " '{print $$2}')
LIBRARY_NAME=$(shell grep name library/setup.cfg | awk -F" = " '{print $$2}')
PACKAGE_NAME="sgp30"

.PHONY: usage install uninstall
usage:
Expand All @@ -25,13 +26,13 @@ uninstall:

check:
@echo "Checking for trailing whitespace"
@! grep -IUrn --color "[[:blank:]]$$" --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=PKG-INFO
@! grep -IlUrn --color "[[:blank:]]$$" --exclude-dir=.vscode --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=PKG-INFO
@echo "Checking for DOS line-endings"
@! grep -IUrn --color "" --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=Makefile
@! grep -IlUrn --color "" --exclude-dir=.vscode --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=Makefile
@echo "Checking library/CHANGELOG.txt"
@cat library/CHANGELOG.txt | grep ^${LIBRARY_VERSION}
@echo "Checking library/${LIBRARY_NAME}/__init__.py"
@cat library/${LIBRARY_NAME}/__init__.py | grep "^__version__ = '${LIBRARY_VERSION}'"
@echo "Checking library/${PACKAGE_NAME}/__init__.py"
@cat library/${PACKAGE_NAME}/__init__.py | grep "^__version__ = '${LIBRARY_VERSION}'"

tag:
git tag -a "v${LIBRARY_VERSION}" -m "Version ${LIBRARY_VERSION}"
Expand Down
44 changes: 22 additions & 22 deletions examples/test.py
@@ -1,22 +1,22 @@
from sgp30 import SGP30
import time
import sys

sgp30 = SGP30()

# result = sgp30.command('set_baseline', (0xFECA, 0xBEBA))
# result = sgp30.command('get_baseline')
# print(["{:02x}".format(n) for n in result])

print("Sensor warming up, please wait...")
def crude_progress_bar():
sys.stdout.write('.')
sys.stdout.flush()

sgp30.start_measurement(crude_progress_bar)
sys.stdout.write('\n')

while True:
result = sgp30.get_air_quality()
print(result)
time.sleep(1.0)
from sgp30 import SGP30
import time
import sys

sgp30 = SGP30()

# result = sgp30.command('set_baseline', (0xFECA, 0xBEBA))
# result = sgp30.command('get_baseline')
# print(["{:02x}".format(n) for n in result])

print("Sensor warming up, please wait...")
def crude_progress_bar():
sys.stdout.write('.')
sys.stdout.flush()

sgp30.start_measurement(crude_progress_bar)
sys.stdout.write('\n')

while True:
result = sgp30.get_air_quality()
print(result)
time.sleep(1.0)
7 changes: 7 additions & 0 deletions library/CHANGELOG.txt
@@ -1,3 +1,10 @@
0.0.2
-----

* BugFix: avoid infinite loop during start_measurement (thanks @millerdq2038)
* BugFix: corrected parameter order for set_baseline (thanks @phooey)
* Improvement: close i2c file handle to avoid leak (https://github.com/pimoroni/sgp30-python/issues/5)

0.0.1
-----

Expand Down
7 changes: 7 additions & 0 deletions library/README.md
Expand Up @@ -19,6 +19,13 @@ Latest/development library from GitHub:


# Changelog
0.0.2
-----

* BugFix: avoid infinite loop during start_measurement (thanks @millerdq2038)
* BugFix: corrected parameter order for set_baseline (thanks @phooey)
* Improvement: close i2c file handle to avoid leak (https://github.com/pimoroni/sgp30-python/issues/5)

0.0.1
-----

Expand Down
2 changes: 1 addition & 1 deletion library/setup.cfg
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
[metadata]
name = pimoroni-sgp30
version = 0.0.1
version = 0.0.2
author = Philip Howard
author_email = phil@pimoroni.com
description = Driver for the SGP30 Gas Sensor
Expand Down
2 changes: 1 addition & 1 deletion library/sgp30/__init__.py
Expand Up @@ -2,7 +2,7 @@
import time


__version__ = '0.0.1'
__version__ = '0.0.2'

SGP30_I2C_ADDR = 0x58

Expand Down
44 changes: 22 additions & 22 deletions library/tests/test_setup.py
@@ -1,22 +1,22 @@
from tools import MockI2CDev, MockI2CMsg


def test_setup():
from sgp30 import SGP30
dev = MockI2CDev()
assert dev._open is True
sgp30 = SGP30(i2c_dev=dev, i2c_msg=MockI2CMsg())
del sgp30
assert dev._open is False


def test_get_unique_id():
from sgp30 import SGP30
sgp30 = SGP30(i2c_dev=MockI2CDev(), i2c_msg=MockI2CMsg())
assert sgp30.get_unique_id() == 0xffffffffffff


def test_get_feature_set_version():
from sgp30 import SGP30
sgp30 = SGP30(i2c_dev=MockI2CDev(), i2c_msg=MockI2CMsg())
assert sgp30.get_feature_set_version() == (0xc, 0xfe)
from tools import MockI2CDev, MockI2CMsg


def test_setup():
from sgp30 import SGP30
dev = MockI2CDev()
assert dev._open is True
sgp30 = SGP30(i2c_dev=dev, i2c_msg=MockI2CMsg())
del sgp30
assert dev._open is False


def test_get_unique_id():
from sgp30 import SGP30
sgp30 = SGP30(i2c_dev=MockI2CDev(), i2c_msg=MockI2CMsg())
assert sgp30.get_unique_id() == 0xffffffffffff


def test_get_feature_set_version():
from sgp30 import SGP30
sgp30 = SGP30(i2c_dev=MockI2CDev(), i2c_msg=MockI2CMsg())
assert sgp30.get_feature_set_version() == (0xc, 0xfe)
162 changes: 81 additions & 81 deletions library/tests/tools.py
@@ -1,81 +1,81 @@
import struct


class MockI2CDev():
def __init__(self):
self._open = True
self._last_write = None

def i2c_rdwr(self, a, b=None):
if isinstance(a, MockI2CMsgW):
self._last_write = a.process()
if isinstance(a, MockI2CMsgR):
a.process(self._last_write)
if b is not None:
b.process(self._last_write)

def close(self):
self._open = False


class MockI2CMsg():
def write(self, i2c_addr, data):
return MockI2CMsgW(i2c_addr, data)

def read(self, i2c_addr, response_len):
return MockI2CMsgR(i2c_addr, response_len)


class MockI2CMsgR():
def __init__(self, i2c_addr, response_len):
self._num_words = response_len // 3
self.buf = None

def process(self, last_command):
result = [0, 0, 0]
if last_command[0] == 0x3682: # get_serial_id
result = [0xffff, 0xffff, 0xffff]
if last_command[0] == 0x202f: # get_feature_set_version
result = [0xCAFE, 0x0000, 0x0000]

buf = []

for i in range(self._num_words):
word = result[i]
packed = bytearray(struct.pack('>H', word))
buf.append(packed[0])
buf.append(packed[1])
buf.append(self.calculate_crc(word))

self.buf = bytearray(buf)

def calculate_crc(self, data):
"""Calculate an 8-bit CRC from a 16-bit word
Defined in section 6.6 of the SGP30 datasheet.
Polynominal: 0x31 (x8 + x5 + x4 + x1)
Initialization: 0xFF
Reflect input/output: False
Final XOR: 0x00
"""
crc = 0xff # Initialization value
# calculates 8-Bit checksum with given polynomial
for byte in [(data & 0xff00) >> 8, data & 0x00ff]:
crc ^= byte
for _ in range(8):
if crc & 0x80:
crc = (crc << 1) ^ 0x31 # XOR with polynominal
else:
crc <<= 1
return crc & 0xff


class MockI2CMsgW():
def __init__(self, i2c_addr, data):
self._data = data

def process(self):
command_len = (len(self._data) - 2) // 3
return struct.unpack('>H' + ('Hx' * command_len), self._data)
import struct


class MockI2CDev():
def __init__(self):
self._open = True
self._last_write = None

def i2c_rdwr(self, a, b=None):
if isinstance(a, MockI2CMsgW):
self._last_write = a.process()
if isinstance(a, MockI2CMsgR):
a.process(self._last_write)
if b is not None:
b.process(self._last_write)

def close(self):
self._open = False


class MockI2CMsg():
def write(self, i2c_addr, data):
return MockI2CMsgW(i2c_addr, data)

def read(self, i2c_addr, response_len):
return MockI2CMsgR(i2c_addr, response_len)


class MockI2CMsgR():
def __init__(self, i2c_addr, response_len):
self._num_words = response_len // 3
self.buf = None

def process(self, last_command):
result = [0, 0, 0]
if last_command[0] == 0x3682: # get_serial_id
result = [0xffff, 0xffff, 0xffff]
if last_command[0] == 0x202f: # get_feature_set_version
result = [0xCAFE, 0x0000, 0x0000]

buf = []

for i in range(self._num_words):
word = result[i]
packed = bytearray(struct.pack('>H', word))
buf.append(packed[0])
buf.append(packed[1])
buf.append(self.calculate_crc(word))

self.buf = bytearray(buf)

def calculate_crc(self, data):
"""Calculate an 8-bit CRC from a 16-bit word
Defined in section 6.6 of the SGP30 datasheet.
Polynominal: 0x31 (x8 + x5 + x4 + x1)
Initialization: 0xFF
Reflect input/output: False
Final XOR: 0x00
"""
crc = 0xff # Initialization value
# calculates 8-Bit checksum with given polynomial
for byte in [(data & 0xff00) >> 8, data & 0x00ff]:
crc ^= byte
for _ in range(8):
if crc & 0x80:
crc = (crc << 1) ^ 0x31 # XOR with polynominal
else:
crc <<= 1
return crc & 0xff


class MockI2CMsgW():
def __init__(self, i2c_addr, data):
self._data = data

def process(self):
command_len = (len(self._data) - 2) // 3
return struct.unpack('>H' + ('Hx' * command_len), self._data)

0 comments on commit 4fe091a

Please sign in to comment.