Ejemplo n.º 1
0
class CO2_stat(object):
    """Code associated with the thermostat controller"""
    def __init__(self):
        self.logger = Logger("CO2_stat")
        self.logger.debug("initialize CO2 controller object")
        self._co2 = SCD30(self.logger)
        self._fan = Fan(self.logger)

    def check(self, co2=None, test=False):
        """Adjust the fan depending upon the CO2
               Args:
                   temp: optional test CO2
               Returns:
                   None
               Raises:
                   None
        """
        target_co2 = TARGET_CO2
        if co2 == None:
            co2, temp, rh = self._co2.get_data()
        msg = "{} {} {} {}".format("CO2:", co2, " Target CO2:", target_co2)
        # Get target temperature from file

        self.logger.info(msg)
        if co2 > target_co2:
            self._fan.set(Fan.ON)
        else:
            self._fan.set(Fan.OFF)
Ejemplo n.º 2
0
class RF_Sender:
    def __init__(self, logger=None, pin=11):
        self._pin = pin
        self._protocol = 1
        self._length = 444
        self._logger = logger
        if self._logger == None:
            self._logger = Logger('RF_Send', Logger.INFO)
        self._logger.debug("Initialize RF Sender on channel {}".format(pin))
        self._rfdevice = RFDevice(pin)
        self._rfdevice.enable_tx()

    def send(self, code, protocol, length):
        self._rfdevice.tx_code(code, protocol, length)
        print("TX Pin: {}, Code: {}, Protocol: {}, Length: {}".format(
            self._pin, code, protocol, length))

    def set_on(self, pin):
        self.send(code[pin]['On'], protocol, length)

    def set_off(self, pin):
        self.send(code[pin]['Off'], protocol, length)

    def cleanup(self):
        self._rfdevice.cleanup()
Ejemplo n.º 3
0
class Humidistat(object):
    """Code associated with the thermostat controller"""
    def __init__(self):
        self._logger = Logger("Humidistat")
        self._logger.setLevel(Logger.INFO)
        self._logger.debug("initialize Humidistat object")
        self._co2 = SCD30()
        self._humidifier = Humidifier()
        self._target_rh = 80

    def check(self, rh=None, test=False):
        """Adjust the fhumidifier depending upon the rh
               Args:
                   temp: optional test rh
               Returns:
                   None
               Raises:
                   None
        """
        if rh == None:
            co2, temp, rh = self._co2.get_data()
            msg = "{} {} {} {}".format("Humidity:", rh, " Target Humidity:",
                                       self._target_rh)
            self._logger.info(msg)
        if rh > self._target_rh:
            self._humidifier.set(Humidifier.OFF)
        else:
            self._humidifier.set(Humidifier.ON)
Ejemplo n.º 4
0
class Thermostat(object):
    """Code associated with the thermostat controller"""
    def __init__(self):
        self._logger = Logger("Thermostat",
                              lvl=Logger.INFO,
                              file="/home/pi/MVP/logs/state.log")
        self._logger.debug("initialize Thermostat object")
        self._temp = SI7021(self._logger)
        self._fan = Fan(self._logger)

    def check(self, temp=None):
        """Adjust the fan depending upon the temperature
               Args:
                   temp: optional test temperature
               Returns:
                   None
               Raises:
                   None
        """
        if temp == None:
            temp = self._temp.get_tempC()
        # Get target temperature from file
        target_temp = env['thermostat']['targetTemp']
        msg = "{} {} {} {}".format("Temp:", temp, " Target Temp:", target_temp)
        self._logger.debug(msg)
        if temp > target_temp:
            self._fan.set(Fan.ON)
        else:
            self._fan.set(Fan.OFF)
Ejemplo n.º 5
0
class Template(object):

   def __init__(self, logger=None):
      """Initialize the object
           Args:
               logger: existing logger to use
           Returns:
               rh: calculated relative humidity
           Raises:
               None
      """
      if logger == None:
          self._logger = Logger("Template", Logger.INFO, "/home/pi/MVP/logs/template.log")
          
    def doSomething(self):
      """Function to do something
           Args:
               none:
           Returns:
               thing:
           Raises:
               None
      """
        self._logger.debug("In doSomething")
        thing = True
        self._logger.debug("{}: {}".format("thing", thing))
        return thing
Ejemplo n.º 6
0
class OneWireTemp(object):

    one_temp = {0: "Ambient", 1: "Reservoir", 2: "Box", 3: "Top"}

    def __init__(self, logger=None):
        """Create sensor object
           Args:
               None
           Returns:
               None
           Raises:
               None
        """
        self._logger = logger
        if logger == None:
            self._logger = Logger("OneWireTemp", Logger.INFO)
        self._logger.debug("Initialize OneWireTemp")
        # flag for testing
        self._test = False

    def read_temp_raw(self, x):
        """Read sensor buffer
           Args:
               x: number of the sensor
           Returns:
               lines: lines read
           Raises:
               None
        """
        device_folder = glob.glob(base_dir + '28*')[x]
        device_file = device_folder + '/w1_slave'
        self._logger.debug("{} {}, {} {}, {} {}".format(
            "In read temp raw-Device:", x, "Device Folder:", device_folder,
            "Device File:", device_file))
        f = open(device_file, 'r')
        lines = f.readlines()
        f.close()
        return lines

    def getTempC(self, x):
        """Read sensor buffer
           Args:
               x: number of the sensor
           Returns:
               temp_c: temperature reading
           Raises:
               None
        """
        lines = self.read_temp_raw(x)
        while lines[0].strip()[-3:] != 'YES':
            time.sleep(0.2)
            lines = read_temp_raw()
        equals_pos = lines[1].find('t=')
        if equals_pos != -1:
            temp_string = lines[1][equals_pos + 2:]
            temp_c = float(temp_string) / 1000.0
            #        temp_f = temp_c * 9.0 / 5.0 + 32.0
            #        return temp_c, temp_f
            return temp_c
Ejemplo n.º 7
0
class Pump(object):
    def __init__(self, logger=None):
        self._rf = RF_Sender()
        self._logger = logger
        if self._logger == None:
            self._logger = Logger('Pump', Logger.INFO,
                                  "/home/pi/MVP/logs/obsv.log")
        self._persist = Persistence(self._logger)

    def __del__(self):
        '''
        Don't call GPIO.cleanup() as need to leave pin state as is
        '''
        pass

    def on(self, test=False):
        "Check state and turn on if needed"
        self._rf.set_on(pumpPin, )
        self.log_state("On", test)
        self._logger.debug('Pump turned ON')

    def off(self, test=False):
        '''Check state and turn off if needed'''
        self._rf.set_off(pumpPin)
        self.log_state("Off", test)
        self._logger.debug('Pump turned Off')

    def log_state(self, value, test=False):
        """
        Create Environment Observation
    """
        status_qualifier = 'Success'
        if test:
            status_qualifier = 'Test'
        self._persist.save([
            'State_Change', '', 'Reservoir', 'Pump', 'State', value, 'Pump',
            'state', status_qualifier, ''
        ])
Ejemplo n.º 8
0
class Pump:

    def __init__(self, logger=None):
        '''Initialize the object'''
        self.solenoidPin = Relay4
        if logger==None:
            self._logger = Logger('Solenoid', Logger.INFO)
        else:
            self._logger = logger
        self._relay=Relay(self._logger)
        self._couch=CouchUtil(self._logger)
        self._test = False
        
        self.activity_type = 'State_Change'

    def on(self):
        self._relay.set_off(self.solenoidPin)
        self._logger.debug("{}".format("Open Solenoid"))            
        self.logState("Open")
        
    def off(self):
        self._relay.set_on(self.solenoidPin)
        self._logger.debug("{}".format("Close Solenoid"))            
        self.logState("Closed")

    def getState(self):
        state=self._relay.get_state(self.solenoidPin)
        if state==0:
            return "On"
        else:
            return "Off"

    def logState(self, value):
        status_qualifier='Success'
        if self._test:
            status_qualifier='Test'
        self._couch.saveList(['State_Change', '', 'Pump', 'Reservoir', 'State', value, 'state', 'Solenoid', status_qualifier, ''])
Ejemplo n.º 9
0
class AppendUtil(object):
    def __init__(self, logger=None):
        """Record optional sensor data
        Args:
            lvl: Logging level
        Returns:
            None
        Raises:
            None
        """
        if logger == None:
            self._logger = Logger("AppendUtil", Logger.DETAIL)
        else:
            self._logger = logger
        self._sheet_name = '1Mtlr_-yqwdEwXFEcaLoEP01aDN7vvOosDOEerFpDkaI'
        self._scope = ['https://www.googleapis.com/auth/spreadsheets']
        self._l_util = ListUtil(self._logger)
        self._s_util = SheetUtil(self._sheet_name, self._scope, self._logger)
        self._logger.debug("Initialized AppendUtil")

    def append(self, rec, append_range):
        #print(rec)
        self._s_util.append(append_range, rec)

    def save(self, doc):
        '''
        This is the entry function into the object
        Lookup the range in the dictionary before appending
        Save list to Google Sheet
        Args:
            self
            doc - formatted list to save (append)
        Returns:
            None
        Throws:
            None

        '''
        self._logger.detail("In save")
        name = doc[0]
        self._logger.debug('%s: %s' % ('Rec Type', name))
        rec = self._l_util.build(doc)
        # dictionary of sheet tabs
        range = {
            'Environment_Observation': 'Environment!A1',
            'State_Change': 'State!A1',
            'Agronomic_Activity': 'Agronomic!A1',
            'Phenotype_Observation': 'Phenotype!A1'
        }
        # Lookup range for record type - note this is a lookup on a list of lists

        append_range = range[name]
        self._logger.debug('%s: %s' % ('Range', append_range))
        self._s_util.append(append_range, rec)
Ejemplo n.º 10
0
class Light(object):
    def __init__(self, logger=None):
        self._logger = logger
        if self._logger == None:
            self._logger = Logger('Light', Logger.INFO,
                                  "/home/pi/MVP/logs/obsv.log")
            self._logger.debug("Initialize RF Light")
        self._rf = RF_Sender(self._logger)
        self._persist = Persistence(self._logger)

    def __del__(self):
        self._rf.cleanup()

    def set_on(self, test=False):
        "Check state and turn on if needed"
        self._rf.set_on(lightPin, )
        self.log_state("On", test)
        self._logger.debug('Light turned ON')

    def set_off(self, test=False):
        '''Check state and turn off if needed'''
        self._rf.set_off(lightPin)
        self.log_state("Off", test)
        self._logger.debug('Light turned Off')

    def log_state(self, value, test=False):
        """
        Create Environment Observation
    """
        status_qualifier = 'Success'
        if test:
            status_qualifier = 'Test'
        self._persist.save([
            'State_Change', '', 'Top', 'Lights', 'State', value, 'Boolean',
            'Light', status_qualifier, ''
        ])

    def check(self):
        env = Environ(self._logger)
        if env._state:
            self.set_on(test)
        else:
            self.set_off(test)
Ejemplo n.º 11
0
class StartUp(object):
    def __init__(self, logger=None):
        if logger == None:
            self._logger = Logger("StartUp", Logger.INFO)
        else:
            self._logger = logger
        self._logger.debug("StartUp Initialized")

    def check(self, test=False):
        """Main function to run what needs to be done at restart
        Args:
            test: flag for testing system
        Returns:
            None:
        Raises:
            None
        """
        light_state = "Unknown"
        try:
            light_state = self.checkLight()
        except Exception as e:
            self._logger.error(e)
        self.checkPump()

    def checkPump(self):
        """Make sure the pump is turned off
            Don't check, just turn off
            If no pump in installed, this will just flip the GPIO
        Args:
            test: flag for testing system
        Returns:
            state: (should be Off)
        Raises:
            None
        """

        self._logger.debug("In checkPump")
        pump_state = "Unknown"
        try:
            pump_state = self.pumpOff()
            self._logger.debug("{}: {}".format("Pump State", pump_state))
        except Exception as e:
            self._logger.error(e)

    def pumpOff(self):
        """Make sure the pump is turned off
        Args:
            test: flag for testing system
        Returns:
            state: (should be Off)
        Raises:
            None
        """
        from Pump import Pump
        pump = Pump()

        self._logger.debug("In pumpOff")
        p = Pump(self._logger)
        p.off()
        msg = "Pump is turned off"
        self._logger.debug(msg)
        return "Off"

    def checkLight(self):
        """Check if lights should be on or off
        Args:
            test: flag for testing system
        Returns:
            None
        Raises:
            None
        """
        # Move import here so can trap if fails
        # couchdb library does not seem to load when initially starting
        self._logger.debug("In checkLight")
        import Light
        # Get times from env and split into components
        s = env['lights']['On']
        e = env['lights']['Off']
        state = self.determineState(s, e)
        l = Light.Light(self._logger)
        if state:
            l.set_on(test)
            return "On"
        else:
            l.set_off(test)
            return "Off"

    def determineState(self, start, end):
        ''' Determine if lights should be on or off'''
        s = start.split(':')
        e = end.split(':')
        # Munge date into times
        t = datetime.now()
        st = t.replace(hour=int(s[0]), minute=int(s[1]), second=int(s[2]))
        et = t.replace(hour=int(e[0]), minute=int(e[1]), second=int(e[2]))

        if st > et:
            # Night Light - roll to next day when lights go off
            et += timedelta(days=1)

        msg = "{} {} {} {}".format("Start Time: ", st, "End Time: ", et)
        self._logger.debug(msg)

        if (st < datetime.now()) and (et > datetime.now()):
            msg = "Lights should be On"
            self._logger.debug(msg)
            return True
        else:
            msg = "Lights should be Off"
            self._logger.debug(msg)
            return False
Ejemplo n.º 12
0
class I2C(object):
    def __init__(self, path, addr, logger=None):
        self._path = path
        self._addr = addr
        self._i2c = pI2C(self._path)
        self._logger = logger
        if logger == None:
            self._logger = Logger("SCD30", Logger.INFO)
        self._logger.debug("initialize I2C object")

    def __exit__(self, exc_type, exc_value, traceback):
        self._i2c.close()

    def msg_write(self, cmds):
        """Write to sensor
           Args:
               cmds: commands to send
           Returns:
               msgs: basically returns the cmds, since nothing altered
           Raises:
               None
      """
        self._logger.debug("In Msg Write")
        for cmd in cmds:
            self._logger.detail("{}, {}".format("Cmd: ", cmd))

        msgs = [self._i2c.Message(cmds)]
        try:
            self._logger.detail("Transfer")
            self._i2c.transfer(self._addr, msgs)
            msb = msgs[0].data[0]
            self._logger.detail("{}, {}".format("MSB: ", hex(msb)))
            return msgs

        except Exception as e:
            self._logger.error(str(e))
            return None

    def msg_read(self, size, cmds=None):
        """Read existing data
           Args:
               cmds: addresses to read from - optional for some sensors (SI7021)
               size: size of byte array for receiving data
           Returns:
               msgs: message package, last one should hold data
           Raises:
               None
      """

        self._logger.detail("{}, {}, {}, {}".format("Msg Read - size: ", size,
                                                    " cmds: ", cmds))
        sz = self._i2c.Message(bytearray([0x00 for x in range(size)]),
                               read=True)
        msgs = [sz]
        #       print("C " + str(type(cmds)))
        if cmds is not None:
            #           print("Cmds " + str(cmds))
            rd = self._i2c.Message(cmds)
            msgs = [rd, sz]
        try:
            self._i2c.transfer(self._addr, msgs)
            return msgs

        except Exception as e:
            self._logger.error(str(e))
            return None

    def get_data(self, cmd, sleep, size, read=None):
        '''Combine sending of command and reading
        Some sensors default the read to the prior command and don't specify a read address
       '''
        self._logger.debug("{}, {}, {}, {}, {}, {}".format(
            "In Get Data-cmd: ", cmd, " sleep: ", sleep, " size: ", size))
        self.msg_write(cmd)
        time.sleep(sleep)
        msgs = self.msg_read(size, read)
        if msgs == None:
            return None
        else:
            for msg in msgs:
                self._logger.detail("-")
                for dt in msg.data:
                    self._logger.detail("Dt " + str(dt))
            self._logger.debug("Data " + str(msgs[0].data[0]) + " " +
                               str(msgs[0].data[1]))
            value = self.bytesToWord(msgs[0].data[0], msgs[0].data[1])
            return msgs

    def bytesToWord(self, high, low):
        """Convert two byte buffers into a single word value
           shift the first byte into the work high position
           then add the low byte
            Args:
                high: byte to move to high position of word
                low: byte to place in low position of word
            Returns:
                word: the final value
            Raises:
                None
       """
        self._logger.debug("{}, {}, {}, {}".format("In Bytes To Word-high: ",
                                                   high, " Low: ", low))
        word = (high << 8) + low
        return word
Ejemplo n.º 13
0
class Reservoir:

    FULL = 0
    EMPTY = 1
    OK = 2

    vol_per_mm = 0.3785  # estimate 1 gal per 10 mm, this is reservoir specific
    vol_per_sec = 0.3785  # estimate 100 ml per sec, this is reservoir specific

    def __init__(self):
        '''Get distances for determining reservoir levels'''
        self.res = {'full': full_ec, 'empty': empty_ec, 'timeout': timeout}
        self._activity_type = 'Agronomic_Activity'
        self._logger = Logger('LogReservoir', Logger.INFO)
        self._persist = Persistence(self._logger)
        self._logger.detail("Reservoir Initialized")
        # flag for testing
        self._test = False

    def getStatus(self):
        "Logic for calling the reservoir full"
        self._logger.detail("In getStatus")
        ec = self.getEC()
        if ec <= full_ec:
            self._logger.debug("{}, {}, {:10.1f}".format(
                "Reservoir Full", EC, ec))
            return Reservoir.FULL, ec
        elif ec >= empty_ec:
            self._logger.debug("{}, {}, {:10.1f}".format(
                "Reservoir Empty", EC, ec))
            return Reservoir.EMPTY, ec
        else:
            self._logger.debug("{}, {}, {:10.1f}".format(
                "Reservoir not Empty", EC, ec))
            return Reservoir.OK, ec

    def isFull(self):
        self._logger.detail("In isFull")
        status, ec = self.getStatus()
        if status == Reservoir.FULL:
            return True
        else:
            return False

    def getEC(self):
        '''Get EC reading'''
        self._logger.detail("In getEC")
        snsr = EC(self._logger)
        return snsr.getEC()

    def fill(self, test=False):
        ''' Routine to control re-filling of the reservoir'''
        self._logger.detail("{}".format("In Fill"))
        start_ec = self.getEC()
        start_t = time.time()
        pump = Pump()
        pump.on()
        # Loop till filled or times out
        while (not self.isFull()) and self.isFilling(start_t):
            self._logger.detail("{}".format("In Fill Loop"))
        self._logger.detail("{}".format("Exit Fill Loop, close solenoid"))
        # Close valve
        pump.off()
        # Calculate amount filled
        stop_t = time.time()
        stop_ec = self.getEC()
        dif_t = stop_t - start_t
        volume = dif_t * self.vol_per_sec
        self._logger.detail("{}".format("Exit Fill"))

        return volume

    def isFilling(self, start_time, test=False):
        '''Check that actually filling: the distance is actually changing'''
        start_ec = self.getEC()
        self._logger.detail("{} {}".format("Filling, Start EC:", start_ec))
        time.sleep(fill_time)

        # Check for level change first, else will never get to this logic till timeout
        end_ec = self.getEC()
        change = start_ec - end_ec
        if end_ec < start_ec:  # need to see at least a 5mm change
            self._logger.detail("{} {} {} {} {} {}".format(
                "Still Filling, change:", change, "Start", start_ec, "End",
                end_ec))
            return True
        else:
            self._logger.detail("{} {} {} {} {} {}".format(
                "Not Filling, no change:", change, "Start", start_ec, "End",
                end_ec))
            return False


# Check for timeout
        stop_time = time.time()
        if stop_time - start_time > self.res['timeout']:
            self._logger.detail("{}".format("Timeout"))
            return False
        else:
            return True

    def checkReservoir(self):
        '''Check condition of reservoir and fill if necessary'''
        self._logger.detail("{}".format("Check Reservoir"))
        status, ec = self.getStatus()
        self._logger.debug("{} {} {} {}".format("Status:", status, "EC", ec))

        # Is full, log state
        if status == Reservoir.FULL:
            self._logger.detail("{}".format("Status: Full"))
            self._logger.info("{} {} {} {}".format("EC:", ec, "Full level:",
                                                   self.res['full'], "Empty:",
                                                   self.res['empty']))
            return True
        else:
            # Needs filling
            self._logger.debug("{}".format("Status: Filling"))
            volume = self.fill()
            if volume > 0:
                # Filled, log volume
                self.logState(volume, 'Success')
                return True
            else:
                # Failure
                self._logger.debug("{}".format("Status: Failure"))
                level = 'Empty'
                if status == '2':
                    level = 'Ok'
                self._logger.error("{}".format("Failure to fill Reservoir"))
                self._logger.error("{} {} {} {}".format(
                    "EC:", ec, "Full level:", self.res['full'], "Empty:",
                    self.res['empty']))
                self.logState(volume, 'Failure')
                return False

    def logState(self, value, status_qualifier):

        if self._test:
            status_qualifier = 'Test'
        txt = {
            'Volume': value,
            'full_level': self.res['full'],
            'empty_level': self.res['empty'],
            'status': 'Full'
        }
        self._persist.save([
            'State_Change', '', 'Nutrient', 'Reservoir', 'Volume', value,
            'Liter', 'Solenoid', status_qualifier, ''
        ])
        self._logger.info(txt)
Ejemplo n.º 14
0
class ListUtil(object):
    def __init__(self, logger=None):
        if logger == None:
            self._logger = Logger("ListUtil", Logger.DETAIL)
        else:
            self._logger = logger
        self._logger.detail("Initialize ListUtil")

    def build(self, doc):
        '''
        Convert activity list to list of lists
        Args:
            doc: list of attributes, should be of format:
                 [activity_name, trial, plot, subject, attribute, value, units, participant, status_qualifier, comment]
                 participant may be a device string, or a list: ['person':'hmw']
        Returns:
            rec: list formatted record ready for the spreadsheet
        Throws:
            None

        '''
        # add timestamp and field_id
        timestamp = datetime.utcnow()
        ts_str = timestamp.isoformat()[:19]
        t_str = ts_str.replace('T', ' ')
        doc.insert(0, env['field']['field_id'])
        doc.insert(0, t_str)

        # append date, week of trial
        start = env['trials'][0]['start_date']
        st = datetime.strptime(start, '%Y-%m-%dT%H:%M:%S')
        dif = timestamp - st
        # Week of trial
        wk = int(math.ceil(dif.days / 7))
        # date portion
        doc.append(t_str[:10])
        # time portion
        doc.append(t_str[-8:])
        # weeks of trial
        doc.append(wk)
        # create binned timestamp - time is 20 minute group
        ts2 = timestamp.replace(minute=(int(math.floor(timestamp.minute /
                                                       20))),
                                second=0)
        ts2_str = ts2.isoformat()[:19]
        doc.append(ts2_str)
        # fix participant
        if isinstance(doc[PARTICIPANT], list):
            p_type = doc[PARTICIPANT][0]
            p_name = doc[PARTICIPANT][1]
            del doc[PARTICIPANT]
            doc.insert(PARTICIPANT, p_name)
            doc.insert(PARTICIPANT, p_type)
        else:
            doc.insert(PARTICIPANT, 'device')
        # Remove 'Field' from Environment & State
        # 'Plot' is used for Location of sensor
        self._logger.debug(doc[2])
        if doc[2] == 'Environment_Observation':
            del doc[3]
        if doc[2] == 'State_Change':
            del doc[3]
        # convert to list of lists
        doc2 = [[el] for el in doc]
        self._logger.debug(doc2)
        return doc2
Ejemplo n.º 15
0
class Fan(object):
    """Code associated with the exhaust fan"""
    ON = 1
    OFF = 0

    target_temp = 0

    def __init__(self, logger=None):
        self._logger = logger
        if logger == None:
            self._logger = Logger("Relay", Logger.INFO)
        self._logger.debug("initialize Fan object")
        self._relay = Relay(self._logger)
        self.fan_relay = FAN_PIN
        self._persist = Persistence(self._logger)
        # flag for testing
        self._test = False

    def set(self, state):
        """Set the fan to state
            Args:
                state: condition from other source
            Returns:
                None
            Raises:
                None
        """
        self._logger.debug("In set_state")
        prior = self._relay.get_state(self.fan_relay)
        self._relay.set_state(self.fan_relay, state)
        current = self._relay.get_state(self.fan_relay)
        if prior != current:
            self.log_state(state)

    def set_fan_on(self):
        """Turn the fan on
            Args:
                None
            Returns:
                None
            Raises:
                None
        """
        self._logger.debug("In set_fan_on")
        self.set(ON, test)

    def set_fan_off(self):
        """Turn the fan off
            Args:
                None
            Returns:
                None
            Raises:
                None
        """
        self._logger.debug("In set_fan_off")
        self.set(OFF, test)

    def log_state(self, value):
        """Send state change to database
           Args:
               value: state change (numeric value)
               test: flag for testing
           Returns:
               None
           Raises:
               None
        """
        state = 'Off'
        if value > 0:
            state = 'On'
        status_qualifier = 'Success'
        if self._test:
            status_qualifier = 'Test'
        self._persist.save([
            'State_Change', '', 'Side', 'Fan', 'State', state, 'Boolean',
            'Fan', status_qualifier, ''
        ])
        self._logger.debug("{}, {:1}, {} {}".format(
            "Fan State Change: Value: ", value, " Status Qualifier: ",
            status_qualifier))

    def getState(self):
        return self._relay.get_state(self.fan_relay)
Ejemplo n.º 16
0
class SheetUtil(object):
    def __init__(self, sheet_name, scope, logger=None):
        if logger == None:
            self._logger = Logger("SheetUtil", Logger.DETAIL)
        else:
            self._logger = logger
        self._logger.debug("Initialize SheetUtil")
        self._sheet_name = sheet_name
        self._scope = scope

        # The ID and range of a sample spreadsheet.
        self._sheet = self.open_sheet()
        self._logger.debug("%s: %s" % ('Opened', sheet_name))

    def open_sheet(self):
        '''
        Args:
            self
        Returns:
            sheet - sheet service
        Throws:
            None

        '''
        creds = None
        # The file token.pickle stores the user's access and refresh tokens, and is
        # created automatically when the authorization flow completes for the first
        # time.
        if os.path.exists('token.pickle'):
            with open('token.pickle', 'rb') as token:
                creds = pickle.load(token)
        # If there are no (valid) credentials available, let the user log in.
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    CRED, self._scope)
                creds = flow.run_local_server(port=0)
            # Save the credentials for the next run
            with open('token.pickle', 'wb') as token:
                pickle.dump(creds, token)

        service = build('sheets', 'v4', credentials=creds)
        # Call the Sheets API
        sheet = service.spreadsheets()
        return sheet

    def getData(self, range_name):
        '''
        Read data range from a sheet
        Args:
            self
            range: where to get data from, includes tab
        Returns:
            values: data from sheet
        Throws:
            None

        '''
        result = self._sheet.values().get(spreadsheetId=self._sheet_name,
                                          range=range_name).execute()
        values = result.get('values', [])
        return values

    def append(self, range_name, values):
        '''
        Append data to a range
        Args:
            self
            range_name - where to put the data
            values - what to add
        Returns:
            None
        Throws:
            None

        '''

        # Append Test
        resource = {"majorDimension": "COLUMNS", "values": values}

        result = self._sheet.values().append(
            spreadsheetId=self._sheet_name,
            range=range_name,
            body=resource,
            valueInputOption="USER_ENTERED").execute()
Ejemplo n.º 17
0
class LogShroom(object):
    def __init__(self, logger=None):
        """Create sensor object
           Args:
               None
           Returns:
               None
           Raises:
               None
        """
        self._logger = logger
        if logger == None:
            self._logger = Logger("LogShroom",
                                  Logger.INFO,
                                  file="/home/pi/MVP/logs/obsv.log")
        self._logger.debug("Initialize LogShroom")
        self._couch = CouchUtil(self._logger)
        # flag for testing
        self._test = False

    def log(self):
        """Routine to log all sensors
        Args:
            None
        Returns:
            None
        Raises:
            None
        """
        self.getSCD()

    def getSCD(self):
        """Record CO2 sensor (scd30)
            Generates co2, temperature and relative humidity
        Args:
            None
        Returns:
            None
        Raises:
            None
        """

        from scd30 import SCD30
        self._scd = SCD30(self._logger)
        self._logger.debug("In SCD30")
        try:
            co2, temp, rh = self._scd.get_data()

            status = 'Success'
            if self._test:
                status = 'Test'
            self._couch.saveList([
                'Environment_Observation', '', 'Top', 'Air', 'CO2',
                "{:10.1f}".format(co2), 'ppm', 'scd30', status, ''
            ])
            self._couch.saveList([
                'Environment_Observation', '', 'Top', 'Air', 'Temperature',
                "{:10.1f}".format(temp), 'Centigrade', 'scd30', status, ''
            ])
            self._couch.saveList([
                'Environment_Observation', '', 'Top', 'Air', 'Humidity',
                "{:10.1f}".format(rh), 'Percent', 'scd30', status, ''
            ])
            self._logger.info("{} {:6.1f}, {} {:3.1f}, {} {:3.1f}".format(
                "EnvObsv-CO2:", co2, "Temp", temp, "Humidity:", rh))
        except Exception as e:
            status = 'Failure'
            if self._test:
                status = 'Test'
            self._couch.saveList([
                'Environment_Observation', '', 'Top', 'Air', 'CO2', '', 'ppm',
                'scd30', status,
                str(e)
            ])
            self._couch.saveList([
                'Environment_Observation', '', 'Top', 'Air', 'Temperature', '',
                'Centigrde', 'scd30', status, ''
            ])
            self._couch.saveList([
                'Environment_Observation', '', 'Top', 'Air', 'Humidity', '',
                'Percent', 'scd30', status, ''
            ])
            self._logger.debug("{} {}".format("EnvObsv-SCD30 Error:", e))
Ejemplo n.º 18
0
class LogSensorsExtra(object):
    def __init__(self, lvl=Logger.INFO):
        """Record optional sensor data
        Args:
            lvl: Logging level
        Returns:
            None
        Raises:
            None
        """
        self._logger = Logger("LogSensor-Extra",
                              lvl,
                              file="/home/pi/MVP/logs/obsv.log")
        self._activity_type = "Environment_Observation"
        self._test = False
        self._persist = Persistence(self._logger)

    def getOneWire(self, test=False):
        """Loop OneWire temperature sensors
            Assumes there are four
        Args:
            test: flag for testing
        Returns:
            None
        Raises:
            None
        """
        self._logger.debug("In getOneWire")
        from OneWireTemp import OneWireTemp
        for sensor in OneWireTemp.one_temp:
            self.logOneWire(sensor, OneWireTemp.one_temp[sensor])

    def logOneWire(self, sensor, name, test=False):
        """Record OneWire temperature sensor
        Args:
            sensor: number of the sensor
            name: name of the sensor
            test: flag for testing
        Returns:
            None
        Raises:
            None
        """
        self._logger.debug("In logOneWire")
        from OneWireTemp import OneWireTemp
        try:
            ow = OneWireTemp()
            temp = ow.getTempC(sensor)

            status_qualifier = 'Success'
            if self._test:
                status_qualifier = 'Test'
            rec = [
                self._activity_type, '', name, 'Air', 'Temperature',
                "{:10.1f}".format(temp), 'Centigrade',
                'DS18B20-' + str(sensor), status_qualifier, ''
            ]
            self._persist.save(rec)
            self._logger.info("{}, {}, {:10.1f}".format(
                name, status_qualifier, temp))
        except Exception as e:
            status_qualifier = 'Failure'
            if test:
                status_qualifier = 'Test'
            rec = [
                self._activity_type, '', name, 'Air', 'Temperature', '',
                'Centigrade', 'DS18B20-' + str(sensor), status_qualifier,
                str(e)
            ]
            self._persist.save(rec)
            self._logger.error("{}, {}, {}".format(name, status_qualifier, e))

    def getLux(self, test=False):
        """Record LUX sensor (TSL2561)
        Args:
            test: flag for testing
        Returns:
            None
        Raises:
            None
        """
        from TSL2561 import TSL2561
        lx = TSL2561()
        self._logger.info("TSL2561 - LUX")

        try:
            lux = lx.getLux()
            status_qualifier = 'Success'
            if test:
                status_qualifier = 'Test'
            rec = [
                self._activity_type, '', 'Canopy', 'Light', 'LUX',
                "{:3.1f}".format(lux), 'lux', 'TSL2561', status_qualifier, ''
            ]
            self._persist.save(rec)
            self._logger.info("{}, {}, {:10.1f}".format(
                "LUX", status_qualifier, lux))
        except Exception as e:
            status_qualifier = 'Failure'
            if test:
                status_qualifier = 'Test'
            rec = [
                self._activity_type, '', 'Canopy', 'Light', 'LUX', '', 'lux',
                'TSL2561', status_qualifier,
                str(e)
            ]
            self._persist.save(rec)
            self._logger.error("{}, {}, {}".format("LUX", status_qualifier, e))

    def getEC(self, test=False):
        """Record EC sensor (EC - ADC reading)
        Args:
            test: flag for testing
        Returns:
            None
        Raises:
            None
        """

        from EC import EC
        self._logger.info("EC")

        try:
            s = EC()
            ec = s.getEC()

            status_qualifier = 'Success'
            if test:
                status_qualifier = 'Test'
                print("{}, {}, {:10.1f}".format("EC", status_qualifier, ec))
            rec = [
                self._activity_type, '', 'Reservoir', 'Nutrient', 'EC',
                "{:3.1f}".format(ec), 'EC', 'EC', status_qualifier, ''
            ]
            self._persist.save(rec)
            self._logger.info("{}, {}, {:10.1f}".format(
                "EC", status_qualifier, ec))
        except Exception as e:
            status_qualifier = 'Failure'
            if test:
                status_qualifier = 'Test'
                print("{}, {}, {:10.1f}".format("EC", status_qualifier, ec))
            rec = [
                self._activity_type, '', 'Reservoir', 'Nutrient', 'EC', '',
                'EC', 'EC', status_qualifier,
                str(e)
            ]
            self._persist.save(rec)
            self._logger.error("{}, {}, {}".format("EC CCS811",
                                                   status_qualifier, e))

    def getCO2_NDIR(self, test=False):
        """Record CO2 sensor (NDIR)
        Args:
            test: flag for testing
        Returns:
            None
        Raises:
            None
        """
        from NDIR import Sensor
        self._logger.info("CO2 - NDIR")
        try:
            sensor = Sensor()
            sensor.begin()
            co2 = sensor.getCO2()

            status_qualifier = 'Success'
            if test:
                status_qualifier = 'Test'
                print("{}, {}, {:10.1f}".format("CO2 Canopy", status_qualifier,
                                                co2))
            rec = [
                self._activity_type, '', 'Canopy', 'Air', 'CO2',
                "{:3.1f}".format(co2), 'ppm', 'MH-Z16-NDIR', status_qualifier,
                ''
            ]
            self._persist.save(rec)
            self._logger.debug("{}, {}, {:10.1f}".format(
                "CO2", status_qualifier, co2))
        except Exception as e:
            status_qualifier = 'Failure'
            if test:
                status_qualifier = 'Test'
                print("{}, {}, {:10.1f}".format("CO2 Canopy", status_qualifier,
                                                co2))
            rec = [
                self._activity_type, '', 'Canopy', 'Air', 'CO2', '', 'ppm',
                'MH-Z16-NDIR', status_qualifier,
                str(e)
            ]
            self._persist.save(rec)
            self._logger.error("{}, {}, {}".format("CO2 NDIR",
                                                   status_qualifier, e))

    def getCO2_CCS811(self, test=False):
        """Record CO2 sensor (CCS811)
        Args:
            test: flag for testing
        Returns:
            None
        Raises:
            None
        """
        from CCS811 import CCS811
        self._logger.info("CO2 CCS811")
        try:
            sensor = CCS811(SLAVE)
            co2 = sensor.get_co2()

            status_qualifier = 'Success'
            if test:
                status_qualifier = 'Test'
                print("{}, {}, {:10.1f}".format("CO2 Canopy", status_qualifier,
                                                co2))
            rec = [
                self._activity_type, '', 'Canopy', 'Air', 'CO2',
                "{:3.1f}".format(co2), 'ppm', 'CCS811',
                str(e)
            ]
            self._persist.save(rec)
            self._logger.debug("{}, {}, {:10.1f}".format(
                "CCS811 - CO2", status_qualifier, co2))
        except Exception as e:
            status_qualifier = 'Failure'
            if test:
                status_qualifier = 'Test'
                print("{}, {}, {:10.1f}".format("CO2 Canopy", status_qualifier,
                                                co2))
            rec = [
                self._activity_type, '', 'Canopy', 'Air', 'CO2', '', 'ppm',
                'CCS811', status_qualifier,
                str(e)
            ]
            self._persist.save(rec)
            self._logger.error("{}, {}, {}".format("CO2 CCS811",
                                                   status_qualifier, e))

    def getSCD(self):
        """Record CO2 sensor (scd30)
            Generates co2, temperature and relative humidity
        Args:
            None
        Returns:
            None
        Raises:
            None
        """

        from scd30 import SCD30
        self._scd = SCD30(self._logger)
        self._logger.debug("In SCD30")
        try:
            co2, temp, rh = self._scd.get_data()

            status = 'Success'
            if self._test:
                status = 'Test'
            c_rec = [
                'Environment_Observation', '', 'Top', 'Air', 'CO2',
                "{:10.1f}".format(co2), 'ppm', 'scd30', status, ''
            ]
            t_rec = [
                'Environment_Observation', '', 'Top', 'Air', 'Temperature',
                "{:10.1f}".format(temp), 'Centigrade', 'scd30', status, ''
            ]
            h_rec = [
                'Environment_Observation', '', 'Top', 'Air', 'Humidity',
                "{:10.1f}".format(rh), 'Percent', 'scd30', status, ''
            ]
            self._persist.save(c_rec)
            self._persist.save(t_rec)
            self._persist.save(h_rec)
            self._logger.info("{} {:6.1f}, {} {:3.1f}, {} {:3.1f}".format(
                "EnvObsv-CO2:", co2, "Temp", temp, "Humidity:", rh))
        except Exception as e:
            status = 'Failure'
            if self._test:
                status = 'Test'
            c_rec = [
                'Environment_Observation', '', 'Top', 'Air', 'CO2', '', 'ppm',
                'scd30', status,
                str(e)
            ]
            t_rec = [
                'Environment_Observation', '', 'Top', 'Air', 'Temperature', '',
                'Centigrde', 'scd30', status, ''
            ]
            h_rec = [
                'Environment_Observation', '', 'Top', 'Air', 'Humidity', '',
                'Percent', 'scd30', status, ''
            ]
            self._persist.save(c_rec)
            self._persist.save(t_rec)
            self._persist.save(h_rec)
            self._logger.debug("{} {}".format("EnvObsv-SCD30 Error:", e))

    def log(self):
        '''Log extra sensors
            Uncomment desired sensors
            Imports are in the function to avoid loading unnecessary code
        '''

        #self.getOneWire()

        self.getLux()

        self.getEC()

        self.getCO2_NDIR()

        #self.getCO2_CCS811()

        self.getSCD()
Ejemplo n.º 19
0
class SCD30:
    CMD_START_PERIODIC_MEASUREMENT = 0x0010
    CMD_STOP_PERIODIC_MEASUREMENT = 0x0104
    CMD_READ_MEASUREMENT = 0x0300
    CMD_GET_DATA_READY = 0x0202
    CMD_SET_MEASUREMENT_INTERVAL = 0x4600
    CMD_SET_TEMPERATURE_OFFSET = 0x5403
    CMD_SET_ALTITUDE = 0x5102

    WORD_LEN = 2
    COMMAND_LEN = 2
    MAX_BUFFER_WORDS = 24

    STATUS_FAIL = 1
    STATUS_OK = 0

    CO2_DATA_INDEX = 0
    TEMP_DATA_INDEX = 1
    HUMIDITY_DATA_INDEX = 2

    def __init__(self, logger=None):
        """Create sensor object
           Args:
               None
           Returns:
               None
           Raises:
               None
        """        
        self._addr = addr
        self._path = path
        self._logger = logger
        if logger == None:
           self._logger = Logger("SCD30", Logger.INFO)
        self._i2c = I2C(path, addr, self._logger)
        self._logger.debug("initialize SCD30")        
        
        self.start_periodic_measurement()
        

    
    def start_periodic_measurement(self):
        """Start sensor to generate data (about every 2 seconds
           Args:
               self:
               test: flag for test logic
           Returns:
               None
           Raises:
               None
        """        

        # command 0x0010, altitude 0x03eb, crc_check 0x87
        # altitude set to 1003 mb
        #msgs = [0x00,0x10, 0x03, 0xeb, 0x87]
        # Altitude is currently set to 0
        self._logger.debug("In Start Periodic Measurment")        
        
        msgs = [0x00,0x10, 0x00, 0x00, 0x81]
        self._i2c.msg_write(msgs)                

    # TESTE ADN WORKS!
    def stop_periodic_measurement(self):
        """Stop automatic data gathering
           Args:
               None
           Returns:
               None
           Raises:
               None
        """
        self._logger.debug("In Stop Periodic Measurment")        
        
        msgs = [0x01,0x14]
        self._i2c.msg_write(msgs)                
        
#        return self._i2c.msg_write(self.CMD_STOP_PERIODIC_MEASUREMENT
        pass


    def read_measurement(self):
        """Read data
           Args:
               self:
               test:
           Returns:
               CO2
               Temp
               Relative Humidity
           Raises:
               None
        """
        self._logger.debug("In Read Measurment")        
        
        self._i2c.msg_write([0x03, 0x00])
        msgs = self._i2c.msg_read(18)
        
        data3 = self.bytes_to_value(msgs[0].data)                    
        return data3[self.CO2_DATA_INDEX], data3[self.TEMP_DATA_INDEX], data3[self.HUMIDITY_DATA_INDEX]

    def bytes_to_value(self, byte_array):
        """Convert array of byte values into three float values
           Args:
               self
               byte_array: array of data from I2C sensor
               test
           Returns:
               data: array of float values (CO2, Temp, RH)
           Raises:
               None
        """        
        self._logger.debug("In Bytes To Value")        
        
        # Array for value bytes (exclude crc check byte)
        bytes_buf = [0]*12 # 2 words for each co2, temperature, humidity
        l = len(bytes_buf)
        ld = len(byte_array)
        # array for word conversion - two words per value
        word_buf = [0]*int(l/2)
        # final data structure - one place per value
        data = [0]*int(len(word_buf)/2)

        # Load bytes_buffer, strip crc bytes
        y = 0
        for x in range(0, ld, 6):
#            print("x: " + str(x) + " y: " + str(y))
            bytes_buf[y] = byte_array[x]
            bytes_buf[y+1] = byte_array[x+1]
            bytes_buf[y+2] = byte_array[x+3]
            bytes_buf[y+3] = byte_array[x+4]            
            y += 4
        self._logger.detail("bytes_buf: " + str(bytes_buf))        
        
        # Convert sensor data reads to physical value per Sensirion specification
        # Load buffer with values
        # Cast 4 bytes to one unsigned 32 bit integer
        # Cast unsigned 32 bit integer to 32 bit float

        # Convert bytes to words
        for i in range(len(word_buf)):
            word_buf[i] = (bytes_buf[i*2] << 8) | bytes_buf[i*2+1]
            self._logger.detail(str(hex(bytes_buf[i])) + " " + str(hex(bytes_buf[i+1])))
            self._logger.detail(hex(word_buf[i]))

        #convert words to int32
        data[self.CO2_DATA_INDEX] = (word_buf[0] << 16) | word_buf[1]
        data[self.TEMP_DATA_INDEX] = (word_buf[2] << 16) | word_buf[3]
        data[self.HUMIDITY_DATA_INDEX] = (word_buf[4] << 16) | word_buf[5]

        #Convert int32 data to float32
        floatData = numpy.array(data, dtype=numpy.int32)
        data = floatData.view('float32')

        self._logger.detail("CO2: " + str(data[self.CO2_DATA_INDEX]))
        self._logger.detail("Temp: " + str(data[self.TEMP_DATA_INDEX]))
        self._logger.detail("RH: " + str(data[self.HUMIDITY_DATA_INDEX]))

        return data
        
        

    # interval : (u16 integer)
    def set_measurement_interval(self, interval_sec):
        """Set frequency of automatic data collectoin
           Args:
               self
               interval_sec: time in seconds
               test
           Returns:
               None
           Raises:
               None
        """
        self._logger.debug("In Set Measurment Interval")
        if interval_sec < 2 or interval_sec > 1800:
            return self.STATUS_FAIL
# Need to finish this so value is 32 word split to two 16 words
# Calculate crc value for last word
        # [Cmd MSB, Cmd LSB, Interval MSB, Interval LSB, CRC]
        # msb, lsb = convert_word(interval_sec, test)
        # crc = calc_crc(msb, lsb, test)
        # msg = [0x46,0x10, msb, lsb, crc]
        msgs = [0x46,0x10, 0x00, 0x02, 0xE3]
        self._i2c.msg_write(msgs)                


    def get_data_ready(self):
        """Check if have fresh data from periodic update
           Args:
               self
               test
           Returns:
               ready flag
           Raises:
               None
        """          
        self._logger.debug("In Get Data Ready")        
        self._i2c.msg_write([0x02, 0x02])
        msgs = self._i2c.msg_read(3)        
        #for msg in msgs:
        #    self._logger.detail("Msg: " + str(msg))
        #    for d in msg.data:
        #        self._logger.detail("Data: " + str(hex(d)))
        #self._logger.detail("Data: " + str(msgs[0].data[1]))
        return msgs[0].data[1]
    
    # Strange behaviour
    def set_temperature_offset(self, temperature_offset):
        """Temperature compensation offset
           Args:
               self
               temperature offset
               test
           Returns:
               None
           Raises:
               None
        """          
        self._logger.debug("In Set Temperature Offset")                
# Need to finish this so value is 32 word split to two 16 words
# Calculate crc value for last word
        # [Cmd MSB, Cmd LSB, Interval MSB, Interval LSB, CRC]
        # msb, lsb = convert_word(interval_sec, test)
        # crc = calc_crc(msb, lsb, test)
        # msg = [0x54,0x03, msb, lsb, crc]
        msgs = [0x54,0x03, 0x00, 0x02, 0xE3]
        self._i2c.msg_write(msgs)                 


    # TESTE ADN WORKS!
    def set_altitude(self, altitude):
        """Altitude compensation 
           Args:
               self
               altitude: uint16, height over sea level in [m] above 0
               test
           Returns:
               None
           Raises:
               None
        """          
        self._logger.debug("In Set Altitude")                
# Need to finish this so value is 32 word split to two 16 words
# Calculate crc value for last word
        # [Cmd MSB, Cmd LSB, Interval MSB, Interval LSB, CRC]
        # msb, lsb = convert_word(interval_sec, test)
        # crc = calc_crc(msb, lsb, test)
        # msg = [0x51,0x02, msb, lsb, crc]
        msgs = [0x51,0x02, 0x00, 0x02, 0xE3]
        self._i2c.msg_write(msgs)                 

    # TESTE ADN WORKS!
    def get_configured_address(self, test=False):
        """Altitude compensation 
           Args:
               self
               test
           Returns:
               self._addr: address of the sensor
           Raises:
               None
        """                  
        self._logger.debug("In Get Configured Address")        
        return self._addr
    
    def get_data(self):
        """High level logic to simply get data
           Args:
               self
               test
           Returns:
               co2: co2 value
               temp: temperature value
               rh: relative humidity value
           Raises:
               NameError: if error in logic (I2C Problem)
        """
        self._logger.debug("In Get Data")                
        for x in range(0, 4): # Only give four reste tries before giving up
            try:
                while True:
                    # Test if data is ready
                    if self.get_data_ready():
                       # fetch data 
                       co2, temp, rh = self.read_measurement()
                       self._logger.detail("CO2: " + str(co2))
                       self._logger.detail("Temp: " + str(temp))
                       self._logger.detail("RH: " + str(rh))
                       return co2, temp, rh
                    time.sleep(1)
            # try reset to see if can recover from errors
            except Exception as e:
                self._logger.error("{}, {}".format("Data Ready Err: ", e))
                self.__init__()
                time.sleep(2)
        # Give up if cannot fix the problems
        raise NameError("Too Many Failures")                        
Ejemplo n.º 20
0
class Relay(object):
    def __init__(self, logger=None):
        self._logger = logger
        if logger == None:
            self._logger = Logger("Relay", Logger.INFO)
        self._logger.debug("Initialize Relay")
        GPIO.setwarnings(False)
        if not GPIO.getmode() == GPIO.BOARD:
            GPIO.setmode(GPIO.BOARD)
        GPIO.setup(Relay1, GPIO.OUT)
        GPIO.setup(Relay2, GPIO.OUT)
        GPIO.setup(Relay3, GPIO.OUT)
        GPIO.setup(Relay4, GPIO.OUT)

    def __del__(self):
        '''
        Don't GPIO.cleanup() as need to leave pin state alone 
        '''
        pass

    def set_state(self, pin, state):
        '''Change state if different'''
        msg = "{}, {}, {}".format("Current ", state, GPIO.input(pin))
        self._logger.debug(msg)
        if state == ON and not GPIO.input(pin):
            self.set_on(pin)
            msg = "{} {} {}".format("Pin:", pin, " On")
            self._logger.debug(msg)
        elif state == OFF and GPIO.input(pin):
            self.set_off(pin)
            msg = "{} {} {}".format("Pin:", pin, " Off")
            self._logger.debug(msg)
        else:
            msg = "{} {} {}".format("Pin:", pin, " No Change")
            self._logger.debug(msg)

    def get_state(self, pin):
        '''Get the current state of the pin'''
        state = GPIO.input(pin)
        self._logger.debug("State: " + str(state))
        return state

    def set_off(self, pin):
        GPIO.setup(pin, GPIO.OUT)
        GPIO.output(pin, GPIO.LOW)
        self._logger.debug("Set Off")

    def set_on(self, pin):
        GPIO.setup(pin, GPIO.OUT)
        GPIO.output(pin, GPIO.HIGH)
        self._logger.debug("Set On")

    def watch_change(self, pin, callback):
        GPIO.setup(pin, GPIO.IN)
        # only react to going high
        GPIO.add_event_detect(pin, GPIO.RISING, callback)
Ejemplo n.º 21
0
class Humidifier(object):
    """Code associated with the Humidifier"""

    ON = 1
    OFF = 0
    target_rh = 0

    def __init__(self, logger=None):
        self._logger = logger
        if logger == None:
            self._logger = Logger("Humidifier", Logger.INFO)
        self._logger.debug("initialize Fan object")
        self._relay = Relay(self._logger)
        self._pin = 29
        self._couch = CouchUtil(self._logger)
        # flag for if in testing
        self._test = False

    def set(self, state):
        """Set the humidifier to state
            Args:
                state: condition from other source
            Returns:
                None
            Raises:
                None
        """
        self._logger.debug("In set_state")
        self._relay.set_state(self._pin, state)

    def set_on(self):
        """Turn the humidifier on
            Args:
                None
            Returns:
                None
            Raises:
                None
        """
        self._logger.debug("In set_on")
        self.set(ON, test)

    def set_off(self):
        """Turn the fan off
            Args:
                None
            Returns:
                None
            Raises:
                None
        """
        self._logger.debug("In set_off")
        self.set(OFF, test)

    def get_state(self):
        return self._relay.get_state(self._pin)

    def log_state(self, value):
        """Send state change to database
           Args:
               value: state change
               test: flag for testing
           Returns:
               None
           Raises:
               None
        """
        status_qualifier = 'Success'
        if self._test:
            status_qualifier = 'Test'
        self._couch.saveList([
            'State_Change', '', 'Side', 'Fan', 'State', value, 'state', 'Fan',
            status_qualifier, ''
        ])