#!/usr/bin/env python

import smbus
import time


class TSL2561:
    def __init__(self, address, channel, gain=0x00, integration_time=0x02):
        self.address = address
        self.channel = channel
        self.bus = smbus.SMBus(self.channel)
        self.gain = gain             # 0x00=normal, 0x10=0x16
        # 0x02=402ms, 0x01=101ms, 0x00=13.7ms
        self.integration_time = integration_time

        self.set_gain(self.gain)
        self.set_integration_time(self.integration_time)
        self._calc_scale()

    def enable(self):
        self.bus.write_i2c_block_data(self.address, 0x80, [0x03])
        time.sleep(0.5)

    def disable(self):
        self.bus.write_i2c_block_data(self.address, 0x80, [0x00])

    def set_gain(self, gain):
        self.gain = gain

        self.enable()
        data = self.gain | self.integration_time
        self.bus.write_i2c_block_data(self.address,
                                      0x81,
                                      [data])
        self.disable()

    def set_integration_time(self, integration_time):
        self.integration_time

        self.enable()
        data = self.gain | self.integration_time
        self.bus.write_i2c_block_data(self.address,
                                      0x81,
                                      [data])
        self.disable()

    def _calc_scale(self):
        _scale = 1.0

        if self.integration_time == 0x01:
            _scale = _scale / 0.252
        elif self.integration_time == 0x00:
            _scale = _scale / 0.034

        if self.gain == 0x00:
            _scale = _scale * 16.0

        self.scale = _scale

    def _get_raw_data(self):
        self.enable()
        data = self.bus.read_i2c_block_data(self.address, 0xAC, 4)
        vl = data[1] << 8 | data[0]
        ir = data[3] << 8 | data[2]
        self.disable()

        return (vl, ir)

    def get_lux(self):
        ch0, ch1 = self._get_raw_data()
        ch0 = ch0 * self.scale
        ch1 = ch1 * self.scale

        if ch0 == 0:
            ratio = 99999
        else:
            ratio = ch1 / float(ch0)

        if (0 < ratio) & (ratio <= 0.52):
            lux = (0.0315 * ch0) - (0.0593 * ch0 * (ratio ** 1.4))
        elif (0.52 < ratio) & (ratio <= 0.65):
            lux = (0.0229 * ch0) - (0.0291 * ch1)
        elif (0.65 < ratio) & (ratio <= 0.80):
            lux = (0.0157 * ch0) - (0.0180 * ch1)
        elif (0.80 < ratio) & (ratio <= 1.30):
            lux = (0.00338 * ch0) - (0.00260 * ch1)
        else:
            lux = 0

        return lux

if __name__ == '__main__':
    # gain: 1x, integration time: 402ms
    sensor = TSL2561(0x39, 1)
    print "Lux:", str(sensor.get_lux())

    # gain: 16x, integration time: 13.7ms
    sensor = TSL2561(0x39, 1, 0x10, 0x00)
    print "Lux:", str(sensor.get_lux())