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()
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)
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)
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()