Skip to content

Instantly share code, notes, and snippets.

@prietopa
Created April 11, 2020 18:34
Show Gist options
  • Save prietopa/1eb2d8c47eb6222223b5a9583e77fbe5 to your computer and use it in GitHub Desktop.
Save prietopa/1eb2d8c47eb6222223b5a9583e77fbe5 to your computer and use it in GitHub Desktop.
Switch on light when lumens down from 100lx
#!/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