Skip to content

Commit

Permalink
add properties and setters, better instance management and better tes…
Browse files Browse the repository at this point in the history
…ting
  • Loading branch information
Mickael committed Nov 10, 2021
1 parent 93eb19d commit a0696e5
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 88 deletions.
157 changes: 77 additions & 80 deletions GreenPonik_Thermistor10k/Thermistor10k.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,29 @@ class Thermistor10k:
DEFAULT_BUS = 1
THERMISTOR_OFFSET = 2000

"""The ADS1015 and ADS1115 both have the same gain options.
GAIN RANGE (V)
---- ---------
2/3 +/- 6.144
1 +/- 4.096
2 +/- 2.048
4 +/- 1.024
8 +/- 0.512
16 +/- 0.256
"""

def __init__(self, bus=DEFAULT_BUS, addr=DEFAULT_ADDR):
self._bus = bus
self._addr = addr
self._debug = False
self._gains = [g for g in _ADS1X15_CONFIG_GAIN.keys()]
self._gain = self._gains[1] # defautl gain to 1: 512 => 4.096V
self._i2c = I2C(self._bus)
self._ads = ADS_1115.ADS1115(
i2c=self._i2c, gain=self._gain, address=self._addr
) # Create the ADS object # ads = ADS_1015.ADS1015()
self._ads_chan_selector = ADS_1115.P2
self._ads_chan = AnalogIn(self._ads, self._ads_chan_selector) # AnalogIn(ads, ADS_1015.P2)

def __enter__(self):
"""Context manager enter function."""
Expand All @@ -44,14 +63,56 @@ def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit function, ensures resources are cleaned up."""
return False # Don't suppress exceptions.

@property
def i2c(self):
return self._i2c

@property
def ads_instance(self):
return self._ads

@property
def ads_channel_selector(self):
return self._ads_chan_selector

@ads_channel_selector.setter
def ads_channel_selector(self, c):
assert(c in [ADS_1115.P0, ADS_1115.P1, ADS_1115.P2, ADS_1115.P3])
self._ads_chan_selector = c

@property
def ads_channel_read(self):
return self._ads_chan

@property
def bus(self):
return self._bus

@bus.setter
def bus(self, b):
self._bus = b

@property
def address(self):
return self._addr

@address.setter
def address(self, a):
self._addr = a

@property
def gains(self):
return self._gains

@property
def gain(self):
return self._gain

@gain.setter
def gain(self, g):
assert(g in self._gains)
self._gain = g

@property
def debug(self):
return self._debug
Expand All @@ -60,24 +121,6 @@ def debug(self):
def debug(self, d):
self._debug = d

"""
# DEPRECATED ####
# def slope_calculator(self, x_list, y_list):
#
# slope m = DY/DX
#
# slope = (y_list[1] - y_list[0]) / (x_list[1] - x_list[0])
# return slope
# def intercept_calculator(self, slope, x, y):
#
# b = y -mx
#
# intercept = y - slope * x
# return intercept
# DEPRECATED ####
"""

def steinhart_temperature(self, r, ro=10000.0, to=25.0, beta=3950.0):
"""
@brief steinhart formula for thermistor resistance conversion to celcius degrees
Expand All @@ -104,67 +147,21 @@ def read_temp(self):
# init temp value to default error code (convension GreenPonik)
temp = 9999.999
try:
with I2C(self._bus) as i2c:
"""
# DEPRECATED ####
# these points are determinated by lab test with both ec probe and manual thermometer
# # x1 = 12272
# # y1 = 25.9
# # x2 = 10752
# # y2 = 34.5
# # SLOPE = self.slope_calculator([x1, x2], [y1, y2])
# # INTERCEPT = self.intercept_calculator(SLOPE, x1, y1)
# # if self._debug is True:
# # print("slope: ", SLOPE)
# # print("intercept: ", INTERCEPT)
# DEPRECATED ####
"""

"""The ADS1015 and ADS1115 both have the same gain options.
GAIN RANGE (V)
---- ---------
2/3 +/- 6.144
1 +/- 4.096
2 +/- 2.048
4 +/- 1.024
8 +/- 0.512
16 +/- 0.256
"""
gains = [g for g in _ADS1X15_CONFIG_GAIN.keys()]
# Create the ADS object
# ads = ADS_1015.ADS1015(
ads = ADS_1115.ADS1115(
i2c,
gain=gains[0],
address=self._addr,
)
# adc2 = AnalogIn(ads, ADS_1015.P2)
adc2 = AnalogIn(ads, ADS_1115.P2)
value = adc2.value
resistance = (10000 * value / (32767 - value)) - self.THERMISTOR_OFFSET

temp = self.steinhart_temperature(resistance)

# temp = (adc2.value * SLOPE) + INTERCEPT
if self._debug is True:
print("adc2 analog: ", adc2.value)
print("adc2 voltage: ", adc2.voltage)
print("thermistor resistance: ", resistance)
print("Thermistor 10k temperature: %s" % (temp))

"""
# DEPRECATED ####
# if adc2.value >= 17500 or adc2.voltage >= 3.25:
# return 9999.999 # return error code can allow user to know if thermistor doesn't connected
# else:
# return temp
# DEPRECATED ####
"""
if temp >= 100 or temp <= 0:
return 9999.999
else:
return temp
adc_channel = self._ads_chan
value = adc_channel.value
resistance = (10000 * value / (32767 - value)) - self.THERMISTOR_OFFSET

temp = self.steinhart_temperature(resistance)

if self._debug is True:
print("adc2 analog: ", adc_channel.value)
print("adc2 voltage: ", adc_channel.voltage)
print("thermistor resistance: ", resistance)
print("Thermistor 10k temperature: %s" % (temp))

if temp >= 100 or temp <= 0:
return 9999.999
else:
return temp
except Exception as e:
print("An exception occurred in read_temp(): {}".format(e))
6 changes: 3 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx-press-theme',
# 'sphinx_press_theme',
'sphinx_rtd_theme',
'recommonmark'
]
Expand All @@ -50,9 +50,9 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = 'alabaster'
html_theme = 'alabaster'
# html_theme = 'sphinx_rtd_theme'
html_theme = 'press'
# html_theme = 'press'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Welcome to GreenPonik Thermistor 10k's documentation!
:caption: Contents:

modules

Index <readme_link.rst>

Indices and tables
==================
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ flake8>=3.8.3
check-manifest>=0.42
Sphinx==4.2.0
sphinx-rtd-theme>=1.0.0
sphinx-press-theme>=0.8.0
sphinx_press_theme==0.8.0
recommonmark>=0.7.1
91 changes: 88 additions & 3 deletions tests/test_Thermistor10k.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,109 @@
import unittest
import sys
from unittest.mock import patch
# from functools import wraps

# PRINT_ON = True


# def toggle_print(p):
# global PRINT_ON
# PRINT_ON = p


# def printf(f):
# @wraps(f)
# def wrapped(*args, **kwargs):
# r = f(*args, **kwargs)

# if len(args):
# c = str(args[0].__class__).split("'")[1] # grab self from the class method
# else:
# c = "" # no class

# if PRINT_ON:
# if r:
# print("{}.{}{}: {}".format(c, f.__name__, args[1:], r))
# else:
# print("{}.{}{}".format(c, f.__name__, args[1:]))
# return r

# return wrapped


# class Base(object):
# def __init__(self, name=None):
# print("<<< WARNING: using fake waterbrain >>>")
# if name:
# print("<<< Using: {} >>>".format(name))


class SmbusMock():
# simultate the smbus method just for tests
# simultate the smbus class just for tests
pass


class FCNTLMock:
class FcntlMock():
# simultate the fcntl class just for tests
def ioctl(self):
# simultate the FCNTL.ioctl method just for tests
pass


sys.modules["fcntl"] = FCNTLMock()
class AdafruitExtendedBusMock:
# simultate the adafruit_extended_bus class just for tests
def init():
pass

class ExtendedI2C():
# simultate the ExtendedI2C class just for tests
# @printf
# def __init__(self, bus_id=1, frequency=0):
# Base.__init__(self, self.__class__)
# pass

pass

pass


sys.modules["fcntl"] = FcntlMock()
sys.modules["smbus"] = SmbusMock()
sys.modules["adafruit_extended_bus"] = AdafruitExtendedBusMock()


class TestThermistor10k(unittest.TestCase):
@patch("adafruit_extended_bus.ExtendedI2C")
def test_properies(self, mock_i2c):
from adafruit_ads1x15.ads1x15 import _ADS1X15_CONFIG_GAIN

fixtures = {
"bus": 1,
"gain": [g for g in _ADS1X15_CONFIG_GAIN.keys()][1],
"address": 12,
"debug": True,
"ads_channel_selector": 2,
}
from GreenPonik_Thermistor10k.Thermistor10k import Thermistor10k
th = Thermistor10k()

th.bus = fixtures["bus"]
th.gain = fixtures["gain"]
th.address = fixtures["address"]
th.debug = fixtures["debug"]
th.ads_channel_selector = fixtures["ads_channel_selector"]

self.assertIsNotNone(th.bus)
self.assertIsNotNone(th.gain)
self.assertIsNotNone(th.address)
self.assertIsNotNone(th.debug)
self.assertIsNotNone(th.ads_channel_selector)
self.assertTrue(th.bus, fixtures["bus"])
self.assertTrue(th.gain, fixtures["gain"])
self.assertTrue(th.address, fixtures["address"])
self.assertTrue(th.debug, fixtures["debug"])
self.assertTrue(th.ads_channel_selector, fixtures["ads_channel_selector"])

@patch("GreenPonik_Thermistor10k.Thermistor10k.Thermistor10k")
def test_read_temp(self, mock_th):
th = mock_th()
Expand Down

0 comments on commit a0696e5

Please sign in to comment.