diff --git a/sense_hat/sense_hat.py b/sense_hat/sense_hat.py index a639dc6..9e051e5 100644 --- a/sense_hat/sense_hat.py +++ b/sense_hat/sense_hat.py @@ -12,6 +12,7 @@ import pwd import array import fcntl +import threading from PIL import Image # pillow from copy import deepcopy @@ -20,7 +21,10 @@ from .exceptions import ColourSensorInitialisationError class SenseHat(object): - + # singleton registration variables + _instance = None + _lock = threading.Lock() + SENSE_HAT_FB_NAME = 'RPi-Sense FB' SENSE_HAT_FB_FBIOGET_GAMMA = 61696 SENSE_HAT_FB_FBIOSET_GAMMA = 61697 @@ -30,6 +34,14 @@ class SenseHat(object): SENSE_HAT_FB_GAMMA_USER = 2 SETTINGS_HOME_PATH = '.config/sense_hat' + # Ensure that there is only a single SenseHat object running to prevent sensor read issues + def __new__(cls): + if cls._instance is None: + with cls._lock: + if not cls._instance: + cls._instance = super().__new__(cls) + return cls._instance + def __init__( self, imu_settings_file='RTIMULib', diff --git a/tests/test_singleton.py b/tests/test_singleton.py new file mode 100644 index 0000000..22e6ea6 --- /dev/null +++ b/tests/test_singleton.py @@ -0,0 +1,33 @@ +from sense_hat import SenseHat +import unittest +import time +import concurrent.futures + + +def get_temp(dummy): + sense = SenseHat() + time.sleep(5) + print(dummy) + return round(sense.get_temperature()) + +class TestSingleton(unittest.TestCase): + def test_singleton(self): + sense1 = SenseHat() + sense2 = SenseHat() + self.assertEqual(sense1.get_temperature(), sense2.get_temperature()) + self.assertEqual(sense1, sense2) + + @unittest.expectedFailure + def test_multiprocess(self): + executions = ["run1", "run2", "run3", "run4", "run5"] + prev_temp = None + with concurrent.futures.ProcessPoolExecutor() as executor: + for temp in executor.map(get_temp,executions): + if prev_temp: + print(prev_temp, temp) + self.assertEqual(temp, prev_temp) + prev_temp = temp + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file