Created
April 11, 2020 18:34
-
-
Save prietopa/1eb2d8c47eb6222223b5a9583e77fbe5 to your computer and use it in GitHub Desktop.
Switch on light when lumens down from 100lx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import sys | |
import time | |
import smbus | |
import gpiozero | |
class BH1750(): | |
""" Implement BH1750 communication. """ | |
# Define some constants from the datasheet | |
POWER_DOWN = 0x00 # No active state | |
POWER_ON = 0x01 # Power on | |
RESET = 0x07 # Reset data register value | |
# Start measurement at 4lx resolution. Time typically 16ms. | |
CONTINUOUS_LOW_RES_MODE = 0x13 | |
# Start measurement at 1lx resolution. Time typically 120ms | |
CONTINUOUS_HIGH_RES_MODE_1 = 0x10 | |
# Start measurement at 0.5lx resolution. Time typically 120ms | |
CONTINUOUS_HIGH_RES_MODE_2 = 0x11 | |
# Start measurement at 1lx resolution. Time typically 120ms | |
# Device is automatically set to Power Down after measurement. | |
ONE_TIME_HIGH_RES_MODE_1 = 0x20 | |
# Start measurement at 0.5lx resolution. Time typically 120ms | |
# Device is automatically set to Power Down after measurement. | |
ONE_TIME_HIGH_RES_MODE_2 = 0x21 | |
# Start measurement at 1lx resolution. Time typically 120ms | |
# Device is automatically set to Power Down after measurement. | |
ONE_TIME_LOW_RES_MODE = 0x23 | |
def __init__(self, bus, addr=0x23): | |
self.bus = bus | |
self.addr = addr | |
self.power_down() | |
self.set_sensitivity() | |
def _set_mode(self, mode): | |
self.mode = mode | |
self.bus.write_byte(self.addr, self.mode) | |
def power_down(self): | |
self._set_mode(self.POWER_DOWN) | |
def power_on(self): | |
self._set_mode(self.POWER_ON) | |
def reset(self): | |
self.power_on() #It has to be powered on before resetting | |
self._set_mode(self.RESET) | |
def cont_low_res(self): | |
self._set_mode(self.CONTINUOUS_LOW_RES_MODE) | |
def cont_high_res(self): | |
self._set_mode(self.CONTINUOUS_HIGH_RES_MODE_1) | |
def cont_high_res2(self): | |
self._set_mode(self.CONTINUOUS_HIGH_RES_MODE_2) | |
def oneshot_low_res(self): | |
self._set_mode(self.ONE_TIME_LOW_RES_MODE) | |
def oneshot_high_res(self): | |
self._set_mode(self.ONE_TIME_HIGH_RES_MODE_1) | |
def oneshot_high_res2(self): | |
self._set_mode(self.ONE_TIME_HIGH_RES_MODE_2) | |
def set_sensitivity(self, sensitivity=69): | |
""" Set the sensor sensitivity. | |
Valid values are 31 (lowest) to 254 (highest), default is 69. | |
""" | |
if sensitivity < 31: | |
self.mtreg = 31 | |
elif sensitivity > 254: | |
self.mtreg = 254 | |
else: | |
self.mtreg = sensitivity | |
self.power_on() | |
self._set_mode(0x40 | (self.mtreg >> 5)) | |
self._set_mode(0x60 | (self.mtreg & 0x1f)) | |
self.power_down() | |
def get_result(self): | |
""" Return current measurement result in lx. """ | |
data = self.bus.read_word_data(self.addr, self.mode) | |
count = data >> 8 | (data&0xff)<<8 | |
mode2coeff = 2 if (self.mode & 0x03) == 0x01 else 1 | |
ratio = 1/(1.2 * (self.mtreg/69.0) * mode2coeff) | |
return ratio*count | |
def wait_for_result(self, additional=0): | |
basetime = 0.018 if (self.mode & 0x03) == 0x03 else 0.128 | |
time.sleep(basetime * (self.mtreg/69.0) + additional) | |
def do_measurement(self, mode, additional_delay=0): | |
""" | |
Perform complete measurement using command | |
specified by parameter mode with additional | |
delay specified in parameter additional_delay. | |
Return output value in Lx. | |
""" | |
self.reset() | |
self._set_mode(mode) | |
self.wait_for_result(additional=additional_delay) | |
return self.get_result() | |
def measure_low_res(self, additional_delay=0): | |
return self.do_measurement(self.ONE_TIME_LOW_RES_MODE, additional_delay) | |
def measure_high_res(self, additional_delay=0): | |
return self.do_measurement(self.ONE_TIME_HIGH_RES_MODE_1, additional_delay) | |
def measure_high_res2(self, additional_delay=0): | |
return self.do_measurement(self.ONE_TIME_HIGH_RES_MODE_2, additional_delay) | |
class Relay: | |
""" Implement Relay communication. """ | |
def __init__(self, relay_pin = 26): | |
self.on = False | |
self.relay_pin = relay_pin | |
self._relay = gpiozero.OutputDevice(self.relay_pin, active_high=False, initial_value=False) | |
def set_on(self): | |
print("Setting relay: ON") | |
self._relay.on() | |
def set_off(self): | |
print("Setting relay: OFF") | |
self._relay.off() | |
def set_toggle(self): | |
print("toggling relay") | |
self._relay.toggle() | |
def main_loop(): | |
# start by turning the relay off | |
set_relay(False) | |
while 1: | |
# then toggle the relay every second until the app closes | |
toggle_relay() | |
# wait a second | |
time.sleep(1) | |
if __name__ == "__main__": | |
relay = Relay() | |
try: | |
#bus = smbus.SMBus(0) # Rev 1 Pi uses 0 | |
bus = smbus.SMBus(1) # Rev 2 Pi uses 1 | |
sensor = BH1750(bus) | |
while True: | |
lx = sensor.measure_low_res() | |
print(f'{lx:4.2f}') | |
if lx < 100: | |
relay.set_on() | |
else: | |
relay.set_off() | |
time.sleep(1) | |
except KeyboardInterrupt: | |
# turn the relay off | |
relay.set_off() | |
print("\nExiting application\n") | |
# exit the application | |
sys.exit(0) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment