예제 #1
0
 def __init__(self, opt):
     self.opt = opt
     self.gpio_pins = {
         #pin:{
         #  id:<one/two word name>
         #  mode:time, sun, man
         #  prio:if overlaping happens this should order the run(not implemented)
         #  on:when to switch on
         #  duration:<runtime in minutes>
         #  sun_delay=offset to sunset (negative value is possible)
         #  state:0/1 (will be read)
         #}
     }
     self.gpio_test = {
          'gpio4':{
             'id':'Front',
             'mode':'time',
             'prio':'0',
             'on':"18:00",
             'duration':"30",
             'sun_delay':'10',
             'state':0,
             'dow':'Mon,Tue,Wed,Thu,Fr,Sat,Sun',
          },
     }
     # since the /tmp/ directory is trashed
     # the webserver is only running once
     self.lock_dir = "/tmp/raspi_gpio_lockdir"
     if self.opt.get("dry_run"):
         self.gpio_path = "."
     else:
         self.gpio_path = "/sys/class/gpio"
     self.config()
     self.sun = SunRise()
예제 #2
0
 def run_cronjob(self):
     """ runs a cronjob to update the sunset-times and
         flips the pins if needed
     """
     self.gpio_pins = self.lese_config()
     self.read_init_pins()
     self.sun = SunRise()
     for gpio in self.gpio_pins.keys():
         self.time_trigger(gpio)
예제 #3
0
 def run_cronjob(self):
     """ runs a cronjob to update the sunset-times and
         flips the pins if needed
     """
     self.gpio_pins = self.lese_config()
     self.read_init_pins()
     sys.path.append(self.opt.get("root")+"lib/")
     from sunrise import SunRise
     self.sun = SunRise()
     for gpio in self.gpio_pins.keys():
         self.time_trigger(gpio)
예제 #4
0
class GpioCtrl(object):
    """ webpy server
    """
    def __init__(self, opt):
        self.opt = opt
        self.gpio_pins = {
            #pin:{
            #  id:<one/two word name>
            #  mode:time, sun, man
            #  prio:if overlaping happens this should order the run(not implemented)
            #  on:when to switch on
            #  duration:<runtime in minutes>
            #  sun_delay=offset to sunset (negative value is possible)
            #  state:0/1 (will be read)
            #}
        }
        self.gpio_test = {
             'gpio4':{
                'id':'Front',
                'mode':'time',
                'prio':'0',
                'on':"18:00",
                'duration':"30",
                'sun_delay':'10',
                'state':0,
                'dow':'Mon,Tue,Wed,Thu,Fr,Sat,Sun',
             },
        }
        # since the /tmp/ directory is trashed
        # the webserver is only running once
        self.lock_dir = "/tmp/raspi_gpio_lockdir"
        if self.opt.get("dry_run"):
            self.gpio_path = self.opt.get("root")+"/sys/class/gpio"
        else:
            self.gpio_path = "/sys/class/gpio"
        self.cfg_file = self.opt.get("root")+"/etc/raspi_gpio.cfg"
        self.config()
        sys.path.append(self.opt.get("root")+"lib/")
        from sunrise import SunRise
        self.sun = SunRise()

    def run_webserver(self):
        """ bringt die Sache ans Laufen
        """
        if self.aquire_lock():
            self.urls = (
                "/(.*)", "Dashboard",
                )
            app = web.application(self.urls, globals())
            app.run()

    def aquire_lock(self, force=False):
        """ try to obtain lock file, return True if ok
            False otherwise. If forced, renew lock.
        """
        if not os.path.exists(self.lock_dir):
            os.mkdir(self.lock_dir)
            return True
        if force:
            os.remove(self.lock_dir)
            os.mkdir(self.lock_dir)
            return True
        return False

    def config(self):
        """ Lese Config ein
        """
        # default values
        config = ConfigParser()
        config.read(self.cfg_file)
        if self.opt.get("create_cfg"):
            for gpio in self.gpio_test.keys():
                if gpio not in config.sections():
                    # Ansonsten legen wir die cfg an
                    config.add_section(gpio)
                    for key, val in self.gpio_test[gpio].items():
                        config.set(gpio, key, val)
                    filed = open(self.cfg_file, "wb")
                    config.write(filed)
                    filed.close()
            config.read(self.cfg_file)
        for gpio in config.sections():
            
            self.gpio_pins[gpio] = {}
            for option in config.options(gpio):
                self.gpio_pins[gpio][option] = config.get(gpio, option)
        self.read_init_pins()
    
    def read_init_pins(self):
        ## init pins
        for gpio in self.gpio_pins.keys():
            pfad = "%s/%s/value" % (self.gpio_path, gpio)
            if not os.path.exists(pfad):
                self.init_gpio(gpio)
            else:
                self.read_gpiopin(gpio)

    def now_gt(self, clock):
        """ Checks whether the current time is greater then the given
            clock == datetime.object
        """
        mat = re.match("(?P<h>\d+):(?P<m>\d+)", clock)
        assert mat, "'%s' has to match H+:M+!" % clock
        cdic = mat.groupdict()
        now = datetime.datetime.now()
        clock_dt = datetime.datetime(
                    year=now.year, month=now.month, day=now.day,
                    hour=int(cdic['h']), minute=int(cdic['m']))
        # this check fails if a day 
        return now > clock_dt

    def run_cronjob(self):
        """ runs a cronjob to update the sunset-times and
            flips the pins if needed
        """
        self.gpio_pins = self.lese_config()
        self.read_init_pins()
        sys.path.append(self.opt.get("root")+"lib/")
        from sunrise import SunRise
        self.sun = SunRise()
        for gpio in self.gpio_pins.keys():
            self.time_trigger(gpio)
    
    def time_trigger(self, gpio):
        """ reacts if the time should trigger something
        """
        if self.gpio_pins[gpio]['mode'] == 'man':
            # nothing to be done
            print "man ", self.gpio_pins[gpio]
            pass 
        else:
            if self.gpio_pins[gpio]['mode'] == 'sonne':
                # check the sunset-time
                self.set_sunset(gpio)
            # Now we check if there is something to do
            now = datetime.datetime.now()
            dow = time.strftime("%a")
            dow_go = True
            if 'dow' in self.gpio_pins[gpio].keys() and \
                        self.gpio_pins[gpio]['dow'] != "":
                dow_set = self.gpio_pins[gpio]['dow'].split(",")
                if dow not in dow_set:
                    dow_go = False
            gpio_on = self.get_dt_on(gpio)
            gpio_off = self.get_dt_off(gpio)
            if dow_go and gpio_on <= now <= gpio_off:
                if int(self.gpio_pins[gpio]['state']) != 1:
                    print "flip! %s" % gpio
                    self.wechsel(gpio)
                print "ON: ", gpio, self.gpio_pins[gpio]
            else:
                if int(self.gpio_pins[gpio]['state']) == 1:
                    print "flip! %s" % gpio
                    self.wechsel(gpio)
                print "OFF ", gpio, self.gpio_pins[gpio]
    
    def get_dt_on(self, gpio):
        """ returns a datetime instance with the date to switch on
        """
        (std, minute) = self.gpio_pins[gpio]['on'].split(":")
        now = datetime.datetime.now()
        temp_on = datetime.datetime(year=now.year,
                        month=now.month,
                        day=now.day,
                        hour=int(std),
                        minute=int(minute))
        return temp_on
    
    def get_dt_off(self, gpio):
        """ returns a datetime instance with the date to switch on + duration
        """
        (std, minute) = self.gpio_pins[gpio]['on'].split(":")
        now = datetime.datetime.now()
        temp_on = datetime.datetime(year=now.year,
                        month=now.month,
                        day=now.day,
                        hour=int(std),
                        minute=int(minute))
        offset = datetime.timedelta(0,
                        minutes=int(self.gpio_pins[gpio]['duration']))
        return temp_on + offset
    
    def set_sunset(self, gpio):
        """ set the sunset value
        """
        values = self.gpio_pins[gpio]
        untergang = self.sun.sunset()
        now = datetime.datetime.now()
        temp_on = datetime.datetime(year=now.year,
                        month=now.month,
                        day=now.day,
                        hour=untergang.hour,
                        minute=untergang.minute)
        offset = datetime.timedelta(0, minutes=int(values['sun_delay']))
        neue_on = temp_on + offset
        self.change_cfg(gpio, 'on',
                        neue_on.strftime("%H:%M"))
    
    def lese_config(self):
        """ Lese Config ein
        """
        config = ConfigParser()
        config.read(self.cfg_file)
        gpio_pins = {}
        for gpio in config.sections():
            gpio_pins[gpio] = {}
            for option in config.options(gpio):
                gpio_pins[gpio][option] = config.get(gpio, option)
        return gpio_pins

    def init_gpio(self, gpio):
        """ Initiere gpio-pin
        """
        reg = "gpio(\d+)"
        mat = re.match(reg, gpio)
        assert mat, "gpiopin '%s' ist nicht koscher!" % gpio
        gpio_nr =  mat.group(1)
        if not self.opt.get("dry_run"):
            pfad = "%s/export" % (self.gpio_path)
            os.system("echo %s > %s" % (gpio_nr, pfad))
            pfad = "%s/%s/direction" % (self.gpio_path, gpio)
            os.system("echo out > %s" % (pfad))
            pfad = "%s/%s/value" % (self.gpio_path, gpio)
            os.system("echo 0 > %s" % (pfad))
        else:
            pfad = "%s/%s" % (self.gpio_path, gpio)
            os.system("mkdir %s" % pfad)
            pfad = "%s/%s/value" % (self.gpio_path, gpio)
            os.system("echo 0 > %s" % (pfad))
    
    def schalten(self, wert, gpiopin):
        """ Schaltet pin gpiopin auf wert 
        """ 
        assert (wert == 0) or (wert == 1), \
                " Ungueltiger Wert, Wert muss 0 (aus) oder 1 (ein) sein!"
        cmd = "echo %s > %s/%s/value" % (wert, self.gpio_path, gpiopin)
        os.system(cmd)
        self.read_gpiopin(gpiopin)
    
    def read_gpiopin(self, gpiopin):
        """ read current status and updates gpio_pins dictonary
        """
        pin_path = "%s/%s/value" % (self.gpio_path, gpiopin)
        fobj = open(pin_path, "r")
        new_state = fobj.read().strip()
        # Ugly quick fix, should be fixed in a better way
        if gpiopin not in self.gpio_pins.keys():
            self.gpio_pins[gpiopin] = {}
            self.gpio_pins[gpiopin]['state'] = 0
        if self.gpio_pins[gpiopin]['state'] != new_state:
            self.gpio_pins[gpiopin]['state'] = new_state
            self.change_cfg(gpiopin, 'state', new_state)
        fobj.close()
    
    def wechsel(self, gpiopin):
        """ liest gpiopin aus und wechselt den Zustand
        """
        fobj = open("%s/%s/value" % (self.gpio_path, gpiopin), "r")
        wert = fobj.read().strip()
        fobj.close()
        assert int(wert) in [0, 1], "Wertebereich verlassen '%s'" % wert
        if int(wert) == 1:
            self.schalten(0, gpiopin)
        else:
            self.schalten(1, gpiopin)
    
    def change_cfg(self, gpio, key, val):
        """ Update cfg und gpio_pins
        """
        print "change_cfg [%s][%s] = %s" % (gpio, key, val)
        self.gpio_pins[gpio][key] = val
        config = ConfigParser()
        config.read(self.cfg_file)
        if gpio not in config.sections():
            config.add_section(gpio)
        config.set(gpio, key, val)
        filed = open(self.cfg_file, "wb")
        config.write(filed)
        filed.close()