Ejemplo n.º 1
0
def reboot(wait=1, block=False):
    """
    Reboots the Raspberry Pi from a new thread.
    
    @type wait: int
    @param wait: length of time to wait before rebooting
    @type block: bool
    @param block: If True, clear output and perform reboot after wait.
        Set to True at start of thread (recursive).
    """
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print _('Rebooting...')
        except Exception:
            pass
        subprocess.Popen(['reboot'])
    else:
        t = Thread(target=reboot, args=(wait, True))
        t.start()
Ejemplo n.º 2
0
Archivo: sip.py Proyecto: jfmauzey/SIP
def sip_begin():
    #########################################################
    #### Code to import all webpages and plugin webpages ####

    import plugins

    try:
        print _('plugins loaded:')
    except Exception:
        pass
    for name in plugins.__all__:
        print ' ', name

    gv.plugin_menu.sort(key=lambda entry: entry[0])

    #  Keep plugin manager at top of menu
    try:
        for i, item in enumerate(gv.plugin_menu):
            if '/plugins' in item:
                gv.plugin_menu.pop(i)
    except Exception:
        pass

    thread.start_new_thread(timing_loop, ())

    if gv.use_gpio_pins:
        set_output()

    app.notfound = lambda: web.seeother('/')

    app.run()
Ejemplo n.º 3
0
def restart(wait=1, block=False):
    """
    Restarts the software from a new thread.
    Set to True at start of thread (recursive).
    """
    if block:
        report_restart()
        from gpio_pins import set_output

        gv.srvals = [0] * (gv.sd[u"nst"])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print(_(u"Restarting..."))
        except Exception:
            pass
        gv.restarted = 0
        pid = os.getpid()
        command = u"systemctl status " + str(pid)
        output = str(subprocess.check_output(command.split()))
        unit_name = output.split()[1]
        command = u"systemctl restart " + unit_name
        subprocess.Popen(command.split())
    else:
        t = Thread(target=restart, args=(wait, True))
        t.start()
Ejemplo n.º 4
0
def poweroff(wait=1, block=False):
    """
    Powers off the Raspberry Pi from a new thread.
    
    @type wait: int or float
    @param wait: number of seconds to wait before rebooting
    @type block: bool
    @param block: If True, clear output and perform reboot after wait.
        Set to True at start of thread (recursive).
    """
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print _('Powering off...')
        except Exception:
            pass
        subprocess.Popen(['poweroff'])
    else:
        t = Thread(target=poweroff, args=(wait, True))
        t.start()
Ejemplo n.º 5
0
def poweroff(wait=1, block=False):
    """
    Powers off the Raspberry Pi from a new thread.
    
    @type wait: int or float
    @param wait: number of seconds to wait before rebooting
    @type block: bool
    @param block: If True, clear output and perform reboot after wait.
        Set to True at start of thread (recursive).
    """
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print _('Powering off...')
        except Exception:
            pass
        subprocess.Popen(['poweroff'])
    else:
        t = Thread(target=poweroff, args=(wait, True))
        t.start()
Ejemplo n.º 6
0
def set_stations(virt):
    """
    Astivate stations associated with a virtual station.
    Selected stations wil run concurrently.
    """
    global skip  #  prevent endless recursion

    if not skip:
        vid = ((gv.sd['nbrd'] - 1) * 8) + virt
        print("ready to set stations uaing stations ",
              com_stations[str(vid)])  # - test
        for b in range(gv.sd[u"nbrd"] - 1):
            stn_list = [int(i) - 1 for i in com_stations[str(vid)].split(",")]
            for sid in stn_list:
                gv.srvals[
                    sid] = 1  #  used to turn zones on or off (list of one byte per station, 1 = turn on, 0 = turn off)
                gv.sbits[
                    b] |= 1 << sid  #  station bits, used to display stations that are on in UI (list of bytes, one byte per board)
                gv.ps[sid][
                    0] = 1  #  program schedule used for UI display (list of 2 element lists i.e. [program number, duration])
                if not gv.sd[u'mm']:
                    gv.sbits[
                        b] &= 1 << vid  #  station bits, used to display stations that are on in UI (list of bytes, one byte per board)
                    gv.rs[sid][1] = gv.rs[vid][
                        1]  #  run schedule (list [scheduled start time, scheduled stop time, duration, program number])
            skip = 1
            set_output()
    else:
        skip = 0
Ejemplo n.º 7
0
def restart(wait=1, block=False):
    """
    Restarts the software from a new thread.
    
    @type wait: int
    @param wait: length of time to wait before rebooting
    @type block: bool
    @param block: If True, clear output and perform reboot after wait.
        Set to True at start of thread (recursive).
    """
    if block:
        report_restart()
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            gv.logger.info(_('Restarting...'))
        except Exception:
            pass
        subprocess.Popen('service sip restart'.split())
    else:
        t = Thread(target=restart, args=(wait, True))
        t.start()
Ejemplo n.º 8
0
def reboot(wait=1, block=False):
    """
    Reboots the Raspberry Pi from a new thread.
    
    @type wait: int
    @param wait: length of time to wait before rebooting
    @type block: bool
    @param block: If True, clear output and perform reboot after wait.
        Set to True at start of thread (recursive).
    """
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print _('Rebooting...')
        except Exception:
            pass
        subprocess.Popen(['reboot'])
    else:
        t = Thread(target=reboot, args=(wait, True))
        t.start()
Ejemplo n.º 9
0
 def GET(self):
     qdict = web.input()
     if u"rsn" in qdict and qdict[u"rsn"] == u"1":
         stop_stations()
         raise web.seeother(u"/")
     if u"en" in qdict and qdict[u"en"] == u"":
         qdict[u"en"] = u"1"  # default
     elif u"en" in qdict and qdict[u"en"] == u"0":
         gv.srvals = [0] * (gv.sd[u"nst"])  # turn off all stations
         set_output()
     if u"mm" in qdict and qdict[u"mm"] == u"0":
         clear_mm()
     if u"rd" in qdict and qdict[u"rd"] != u"0" and qdict[u"rd"] != "":
         gv.sd[u"rd"] = int(float(qdict[u"rd"]))
         gv.sd[u"rdst"] = int(
             gv.now + gv.sd[u"rd"] * 3600
         )  # + 1  # +1 adds a smidge just so after a round trip the display hasn"t already counted down by a minute.
         stop_onrain()
     elif u"rd" in qdict and qdict[u"rd"] == u"0":
         gv.sd[u"rdst"] = 0
     for key in list(qdict.keys()):
         try:
             gv.sd[key] = int(qdict[key])
         except Exception as e:
             report_error(u"change_values Exception", e)
             pass
     jsave(gv.sd, u"sd")
     report_value_change()
     raise web.seeother(u"/")  # Send browser back to home page
Ejemplo n.º 10
0
def process_actions():
    global logged_internal_error

    if len(actions) > 10 and not logged_internal_error:
        try:
            gv.plugin_data['te']['tesender'].try_mail(
                'Internal error',
                'Action list likely too long len: ' + str(len(actions)))
        except:
            log_event('action list email send failed')
        log_event('Action list likely too long len: ' + str(len(actions)))
        for a in actions:
            log_event('action time: ' + str(a['time']) + ' what: ' +
                      a['action']['what'])
        logged_internal_error = True

    for i, a in enumerate(actions[:]):
        if a['time'] > gv.now:  # actions are sorted in time
            break
        else:
            action = a['action']
            try:
                if action['what'] == 'set_heatpump_mode':
                    set_heatpump_mode(action['mode'], False)
                elif action['what'] == 'set_heatpump_pump_mode':
                    set_heatpump_pump_mode(action['mode'], False)
                elif action['what'] == 'set_boiler_mode':
                    set_boiler_mode(action['mode'], False)
                elif action['what'] == 'set_valve_change':
                    amount = action['valve_change_percent']
                    amount = min(amount, 100)
                    amount = max(amount, -100)
                    if amount == 0:  # stop valve movement
                        #                        log_event('stop valve')
                        gv.srvals[close_ret] = 0
                        gv.srvals[open_ret] = 0
                    elif amount < 0:  # more return, less buffer tank
                        # assume 100 seconds to fully move valve, so each amount request is actually a second
                        insert_action(gv.now - int(amount), {
                            'what': 'set_valve_change',
                            'valve_change_percent': 0
                        })
                        gv.srvals[close_ret] = 0
                        gv.srvals[open_ret] = 1
                        log_event('more return water: ' + str(-int(amount)) +
                                  '%')
                    else:  # less return, more buffer tank
                        insert_action(gv.now + int(amount), {
                            'what': 'set_valve_change',
                            'valve_change_percent': 0
                        })
                        gv.srvals[close_ret] = 1
                        gv.srvals[open_ret] = 0
                        log_event('more buffer tank water: ' +
                                  str(int(amount)) + '%')
                    set_output()
            except Exception as ex:
                log_event('Unexpected action: ' + action['what'] + ' ex: ' +
                          str(ex))
            del actions[i]
Ejemplo n.º 11
0
def restart(wait=1, block=False):
    """
    Restarts the software from a new thread.
    Set to True at start of thread (recursive).
    """
    if block:
        report_restart()
        from gpio_pins import set_output

        gv.srvals = [0] * (gv.sd[u"nst"])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print(_(u"Restarting..."))
        except Exception:
            pass
        gv.restarted = 0
        if six.PY2:
            subprocess.Popen(u"systemctl restart sip.service".split())
        elif six.PY3:
            subprocess.Popen(u"systemctl restart sip3.service".split())
    else:
        t = Thread(target=restart, args=(wait, True))
        t.start()
Ejemplo n.º 12
0
 def GET(self):
     qdict = web.input()
     print 'qdict: ', qdict
     if 'rsn' in qdict and qdict['rsn'] == '1':
         stop_stations()
         raise web.seeother('/')
     if 'en' in qdict and qdict['en'] == '':
         qdict['en'] = '1'  # default
     elif 'en' in qdict and qdict['en'] == '0':
         gv.srvals = [0] * (gv.sd['nst'])  # turn off all stations
         set_output()
     if 'mm' in qdict and qdict['mm'] == '0':
         clear_mm()
     if 'rd' in qdict and qdict['rd'] != '0' and qdict['rd'] != '':
         gv.sd['rd'] = int(float(qdict['rd']))
         gv.sd['rdst'] = int(
             gv.now + gv.sd['rd'] * 3600
         )  # + 1  # +1 adds a smidge just so after a round trip the display hasn't already counted down by a minute.
         stop_onrain()
     elif 'rd' in qdict and qdict['rd'] == '0':
         gv.sd['rdst'] = 0
     for key in qdict.keys():
         try:
             gv.sd[key] = int(qdict[key])
         except Exception:
             pass
     jsave(gv.sd, 'sd')
     report_value_change()
     raise web.seeother('/')  # Send browser back to home page
Ejemplo n.º 13
0
def set_boiler_mode(md, remove=True):
    global boiler_mode, last_boiler_on, last_boiler_off

    if remove:
        remove_action({'what': 'set_boiler_mode', 'mode': 'any'})
    if md == 'heating':
        gv.srvals[boiler_call] = 1
        set_output()
        last_boiler_on = gv.now
#        gv.logger.info('set_boiler_mode ' + md + ' last_boiler_on: ' + str(last_boiler_on))
    else:
        gv.srvals[boiler_call] = 0
        set_output()
        if gv.sd['mode'] not in [
                'Boiler Only'
        ] and not boiler_through_buffer_tank:  # put valve back to all buffer tank
            remove_action({'what': 'set_valve_change'})
            insert_action(gv.now, {
                'what': 'set_valve_change',
                'valve_change_percent': 100
            })
        last_boiler_off = gv.now


#        gv.logger.info('set_boiler_mode ' + md + ' last_boiler_off: ' + str(last_boiler_off))
    boiler_mode = md
    log_event('set_boiler_mode: ' + md)
Ejemplo n.º 14
0
 def GET(self):
     qdict = web.input()
     print 'qdict: ', qdict
     if 'rsn' in qdict and qdict['rsn'] == '1':
         stop_stations()
         raise web.seeother('/')
     if 'en' in qdict and qdict['en'] == '':
         qdict['en'] = '1'  # default
     elif 'en' in qdict and qdict['en'] == '0':
         gv.srvals = [0] * (gv.sd['nst'])  # turn off all stations
         set_output()
     if 'mm' in qdict and qdict['mm'] == '0':
         clear_mm()
     if 'rd' in qdict and qdict['rd'] != '0' and qdict['rd'] != '':
         gv.sd['rd'] = int(float(qdict['rd']))
         gv.sd['rdst'] = int(gv.now + gv.sd['rd'] * 3600) # + 1  # +1 adds a smidge just so after a round trip the display hasn't already counted down by a minute.
         stop_onrain()
     elif 'rd' in qdict and qdict['rd'] == '0':
         gv.sd['rdst'] = 0
     for key in qdict.keys():
         try:
             gv.sd[key] = int(qdict[key])
         except Exception:
             pass
     jsave(gv.sd, 'sd')
     report_value_change()
     raise web.seeother('/')  # Send browser back to home page
Ejemplo n.º 15
0
def restart(wait=1, block=False):
    """
    Restarts the software from a new thread.
    
    @type wait: int
    @param wait: length of time to wait before rebooting
    @type block: bool
    @param block: If True, clear output and perform reboot after wait.
        Set to True at start of thread (recursive).
    """
    if block:
        report_restart()
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print _('Restarting...')
        except Exception:
            pass
        gv.restarted = 0
        subprocess.Popen('systemctl restart sip.service'.split())
    else:
        t = Thread(target=restart, args=(wait, True))
        t.start()
Ejemplo n.º 16
0
def restart(wait=1, block=False):
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        time.sleep(wait)
        print 'Restarting...'
        subprocess.Popen('service ospi restart'.split())
    else:
        t = Thread(target=restart, args=(wait, True))
        t.start()
Ejemplo n.º 17
0
def poweroff(wait=1, block=False):
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        time.sleep(wait)
        print 'Powering off...'
        subprocess.Popen(['poweroff'])
    else:
        t = Thread(target=poweroff, args=(wait, True))
        t.start()
Ejemplo n.º 18
0
def reboot(wait=1, block=False):
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        time.sleep(wait)
        print 'Rebooting...'
        subprocess.Popen(['reboot'])
    else:
        t = Thread(target=reboot, args=(wait, True))
        t.start()
Ejemplo n.º 19
0
def chatter(cct):
    stop_stations()
    t = 0
    for cnt in range(150):      
        t = 1 - t #  toggle cct
        gv.srvals[cct] = t      
        set_output()
        sleep(0.2)
        if stop:
            break
    #  switch everything off
    stop_stations()
Ejemplo n.º 20
0
    def GET(self):
        qdict = web.input()

        sid = get_input(qdict, u"sid", 0, int) - 1
        set_to = get_input(qdict, u"set_to", None, int)
        set_time = get_input(qdict, u"set_time", 0, int)

        if set_to is None:
            if sid < 0:
                status = u"<!DOCTYPE html>\n"
                status += u"".join(str(x) for x in gv.srvals)
                return status
            elif sid < gv.sd[u"nbrd"] * 8:
                status = u"<!DOCTYPE html>\n"
                status += str(gv.srvals[sid])
                return status
            else:
                return _(u"Station ") + str(sid + 1) + _(u" not found.")
        elif gv.sd[u"mm"]:
            if set_to:  # if status is on
                if gv.sd[u"seq"]:
                    if gv.sd["mas"]: # if a master is set
                        for i in range(gv.sd[u"nst"]):
                            if i != gv.sd["mas"] - 1:
                                gv.srvals[i] = 0
                                gv.rs[i] = [0, 0, 0, 0]
                                gv.ps[i] = [0, 0]
                        set_output()
                        sb_byte = (gv.sd["mas"] - 1) // 8
                        gv.sbits[sb_byte] = 1 << (gv.sd["mas"] - 1) % 8
                        for b in range(len(gv.sbits)):
                            if b != sb_byte:
                                gv.sbits[b] = 0
                    else:
                      stop_stations() 
                gv.rs[sid][0] = gv.now  # set start time to current time
                if set_time > 0:  # if an optional duration time is given
                    gv.rs[sid][2] = set_time
                    gv.rs[sid][1] = (
                        gv.rs[sid][0] + set_time
                    )  # stop time = start time + duration
                else:
                    gv.rs[sid][1] = float(u"inf")  # stop time = infinity
                gv.rs[sid][3] = 99  # set program index
                gv.ps[sid][1] = set_time
                gv.sd[u"bsy"] = 1
                time.sleep(1)
            else:  # If status is off
                gv.rs[sid][1] = gv.now + 2
                time.sleep(2)
            raise web.seeother(u"/")
        else:
            return _(u"Manual mode not active.")
Ejemplo n.º 21
0
def stop_stations():
    """Stop all running stations, clear schedules."""
    gv.srvals = [0] * (gv.sd['nst'])
    set_output()
    gv.ps = []
    for i in range(gv.sd['nst']):
        gv.ps.append([0, 0])
    gv.sbits = [0] * (gv.sd['nbrd'] + 1)
    gv.rs = []
    for i in range(gv.sd['nst']):
        gv.rs.append([0, 0, 0, 0])
    gv.sd['bsy'] = 0
    return
Ejemplo n.º 22
0
def clear_mm():
    """Clear manual mode settings."""
    if gv.sd['mm']:
        gv.sbits = [0] * (gv.sd['nbrd'] + 1)
        gv.ps = []
        for i in range(gv.sd['nst']):
            gv.ps.append([0, 0])
        gv.rs = []
        for i in range(gv.sd['nst']):
            gv.rs.append([0, 0, 0, 0])
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
    return
Ejemplo n.º 23
0
def stop_onrain():
    """Stop stations that do not ignore rain."""
    for b in range(gv.sd['nbrd']):
        for s in range(8):
            sid = b * 8 + s # station index
            if gv.sd['ir'][b] & 1 << s: # if station ignores rain...
                continue
            elif not all(v == 0 for v in gv.rs[sid]):
                gv.srvals[sid] = 0
                set_output()
                gv.sbits[b] &= ~1 << s# Clears stopped stations from display
                gv.ps[sid] = [0, 0]
                gv.rs[sid] = [0, 0, 0, 0]
    return
Ejemplo n.º 24
0
def stop_onrain():
    """Stop stations that do not ignore rain."""
    for b in range(gv.sd['nbrd']):
        for s in range(8):
            sid = b * 8 + s  # station index
            if gv.sd['ir'][b] & 1 << s:  # if station ignores rain...
                continue
            elif not all(v == 0 for v in gv.rs[sid]):
                gv.srvals[sid] = 0
                set_output()
                gv.sbits[b] &= ~1 << s  # Clears stopped stations from display
                gv.ps[sid] = [0, 0]
                gv.rs[sid] = [0, 0, 0, 0]
    return
Ejemplo n.º 25
0
def stop_stations():
    """Stop all running stations, clear schedules."""
    from gpio_pins import set_output
    gv.srvals = [0] * (gv.sd['nst'])
    set_output()
    gv.ps = []
    for i in range(gv.sd['nst']):
        gv.ps.append([0, 0])
    gv.sbits = [0] * (gv.sd['nbrd'] + 1)
    gv.rs = []
    for i in range(gv.sd['nst']):
        gv.rs.append([0, 0, 0, 0])
    gv.sd['bsy'] = 0
    return
Ejemplo n.º 26
0
def clear_mm():
    """Clear manual mode settings."""
    from gpio_pins import set_output
    if gv.sd['mm']:
        gv.sbits = [0] * (gv.sd['nbrd'] + 1)
        gv.ps = []
        for i in range(gv.sd['nst']):
            gv.ps.append([0, 0])
        gv.rs = []
        for i in range(gv.sd['nst']):
            gv.rs.append([0, 0, 0, 0])
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
    return
Ejemplo n.º 27
0
def poweroff(wait=1, block=False):
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        GPIO.cleanup()
        time.sleep(wait)
        try:
            print _('Powering off...')
        except Exception:
            pass
        subprocess.Popen(['poweroff'])
    else:
        t = Thread(target=poweroff, args=(wait, True))
        t.start()
Ejemplo n.º 28
0
def poweroff(wait=1, block=False):
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        GPIO.cleanup()
        time.sleep(wait)
        try:
            print _('Powering off...')
        except Exception:
            pass
        subprocess.Popen(['poweroff'])
    else:
        t = Thread(target=poweroff, args=(wait, True))
        t.start()
Ejemplo n.º 29
0
def clear_mm():
    """
    Clear manual mode settings and stop any running zones.
    """
    from gpio_pins import set_output
    if gv.sd['mm']:
        gv.sbits = [0] * (gv.sd['nbrd'] + 1)
        gv.ps = []
        for i in range(gv.sd['nst']):
            gv.ps.append([0, 0])
        gv.rs = []
        for i in range(gv.sd['nst']):
            gv.rs.append([0, 0, 0, 0])
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
    return
Ejemplo n.º 30
0
def clear_mm():
    """
    Clear manual mode settings and stop any running zones.
    """
    from gpio_pins import set_output

    if gv.sd[u"mm"]:
        gv.sbits = [0] * (gv.sd[u"nbrd"] + 1)
        gv.ps = []
        for i in range(gv.sd[u"nst"]):
            gv.ps.append([0, 0])
        gv.rs = []
        for i in range(gv.sd[u"nst"]):
            gv.rs.append([0, 0, 0, 0])
        gv.srvals = [0] * (gv.sd[u"nst"])
        set_output()
    return
Ejemplo n.º 31
0
Archivo: sip.py Proyecto: bkoblenz/HVAC
def process_actions():
    global logged_internal_error

    if len(actions) > 10 and not logged_internal_error:
        email('Internal error', 'Action list likely too long len: ' + str(len(actions)))
        log_event('Action list likely too long len: ' + str(len(actions)))
        for a in actions:
            log_event('action time: ' + str(a['time']) + ' what: ' + a['action']['what'])
        logged_internal_error = True

    for i, a in enumerate(actions[:]):
        if a['time'] > gv.now: # actions are sorted in time
            break
        else:
            action = a['action']
            try:
                if action['what'] == 'set_heatpump_mode':
                    set_heatpump_mode(action['mode'], False)
                elif action['what'] == 'set_heatpump_pump_mode':
                    set_heatpump_pump_mode(action['mode'], False)
                elif action['what'] == 'set_boiler_mode':
                    set_boiler_mode(action['mode'], False)
                elif action['what'] == 'set_valve_change':
                    amount = action['valve_change_percent']
                    amount = min(amount, 100)
                    amount = max(amount, -100)
                    if amount == 0: # stop valve movement
#                        log_event('stop valve')
                        gv.srvals[close_ret] = 0
                        gv.srvals[open_ret] = 0
                    elif amount < 0: # more return, less buffer tank
                        # assume 100 seconds to fully move valve, so each amount request is actually a second
                        insert_action(gv.now-int(amount), {'what':'set_valve_change', 'valve_change_percent':0})
                        gv.srvals[close_ret] = 0
                        gv.srvals[open_ret] = 1
                        log_event('more return water: ' + str(-int(amount)) + '%')
                    else: # less return, more buffer tank
                        insert_action(gv.now+int(amount), {'what':'set_valve_change', 'valve_change_percent':0})
                        gv.srvals[close_ret] = 1
                        gv.srvals[open_ret] = 0
                        log_event('more buffer tank water: ' + str(int(amount)) + '%')
                    set_output()
            except Exception as ex:
                log_event('Unexpected action: ' + action['what'] + ' ex: ' + str(ex))
            del actions[i]
Ejemplo n.º 32
0
def restart(wait=1, block=False):
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        try:
            GPIO.cleanup()
        except Exception:
            pass
        time.sleep(wait)
        try:
            print _('Restarting...')
        except Exception:
            pass
        subprocess.Popen('service ospi restart'.split())
    else:
        t = Thread(target=restart, args=(wait, True))
        t.start()
Ejemplo n.º 33
0
def restart(wait=1, block=False):
    if block:
        from gpio_pins import set_output
        gv.srvals = [0] * (gv.sd['nst'])
        set_output()
        try:
            GPIO.cleanup()
        except Exception:
            pass
        time.sleep(wait)
        try:
            print _('Restarting...')
        except Exception:
            pass
        subprocess.Popen('service ospi restart'.split())
    else:
        t = Thread(target=restart, args=(wait, True))
        t.start()
Ejemplo n.º 34
0
Archivo: sip.py Proyecto: bkoblenz/HVAC
def set_boiler_mode(md, remove=True):
    global boiler_mode, last_boiler_on, last_boiler_off

    if remove:
        remove_action({'what':'set_boiler_mode', 'mode':'any'})
    if md == 'heating':
        gv.srvals[boiler_call] = 1
        set_output()
        last_boiler_on = gv.now
    else:
        gv.srvals[boiler_call] = 0
        set_output()
        if gv.sd['mode'] not in ['Boiler Only'] and not boiler_through_buffer_tank: # put valve back to all buffer tank
            remove_action({'what':'set_valve_change'})
            insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':100})
        last_boiler_off = gv.now
    boiler_mode = md
    log_event('set_boiler_mode: ' + md)
Ejemplo n.º 35
0
def set_stations(virt):
    """
    Activate stations associated with a virtual station.
    Selected stations wil run concurrently.
    """
    vid = ((gv.sd[u'nbrd'] - 1) *
           8) + virt  # vid = key of station group in com_stations dict.
    stn_list = [int(i) - 1 for i in com_stations[str(vid)].split(",")]
    for sid in stn_list:
        gv.srvals[sid] = 1  #  set gv.srvals on for stations in this group
    for b in range(gv.sd[u"nbrd"] - 1):  #  don't include virtual stations
        for s in range(8):  # for each station per board
            sidx = b * 8 + s
            if gv.srvals[sidx]:  #  If this station should be on
                gv.sbits[
                    b] |= 1 << s  #  station bits, used to display stations that are on in UI (list of bytes, one byte per board)
                gv.ps[sidx][0] = 1
                gv.rs[sidx] = gv.rs[vid]
                if not gv.sd[u'mm']:  #  If under program control
                    gv.ps[sidx][1] = gv.rs[vid][2]
    set_output()
Ejemplo n.º 36
0
def stop_onrain():
    """
    Stop stations that do not ignore rain.
    """

    from gpio_pins import set_output

    do_set_output = False
    for b in range(gv.sd[u"nbrd"]):
        for s in range(8):
            sid = b * 8 + s  # station index
            if gv.sd[u"ir"][b] & 1 << s:  # if station ignores rain...
                continue
            elif not all(v == 0 for v in gv.rs[sid]):
                gv.srvals[sid] = 0
                do_set_output = True
                gv.sbits[b] &= ~1 << s  # Clears stopped stations from display
                gv.ps[sid] = [0, 0]
                gv.rs[sid] = [0, 0, 0, 0]

    if do_set_output:
        set_output()
    return
Ejemplo n.º 37
0
def reboot(wait=1, block=False):
    """
    Reboots the Raspberry Pi from a new thread.
    Set to True at start of thread (recursive).
    """
    if block:
        from gpio_pins import set_output

        gv.srvals = [0] * (gv.sd[u"nst"])
        set_output()
        if gv.use_pigpio:
            pass
        else:
            GPIO.cleanup()
        time.sleep(wait)
        try:
            print(_(u"Rebooting..."))
        except Exception:
            pass
        subprocess.Popen([u"reboot"])
    else:
        t = Thread(target=reboot, args=(wait, True))
        t.start()
Ejemplo n.º 38
0
def chatter(cct):
    gv.srvals = [0]*8 #TODO read how many valves are in service, and which ones
    gpio.set_output() #TODO switch on gpio functions after debugging
    lv = 1
    for cnt in range(150):
        #toggle cct
        gv.srvals[cct] ^= lv
        gpio.set_output()
        sleep(0.2)
    #switch everything off
    gv.srvals = [0]*8
    gpio.set_output()
Ejemplo n.º 39
0
def set_heatpump_mode(md, remove=True):
    """Turn on dry3,4 for cooling; dry 2,4 for heating"""
    global heatpump_mode, last_heatpump_off, last_heatpump_on

    if remove:
        remove_action({'what': 'set_heatpump_mode', 'mode': 'any'})
    if md == 'cooling':
        #        gv.srvals[dry4] = 1
        #        set_output()
        time.sleep(.1)  # make sure 4's state is set first
        gv.srvals[dry1] = 0
        gv.srvals[dry2] = 0
        #        gv.srvals[dry3] = 1
        set_output()
        heatpump_mode = 'cooling'
        set_heatpump_pump_mode('on')
        last_heatpump_on = gv.now
    elif md == 'heating':
        #        gv.srvals[dry4] = 1
        #        set_output()
        time.sleep(.1)  # make sure 4's state is set first
        gv.srvals[dry1] = 0
        #        gv.srvals[dry2] = 1
        gv.srvals[dry3] = 0
        set_output()
        heatpump_mode = 'heating'
        set_heatpump_pump_mode('on')
        last_heatpump_on = gv.now
    else:
        gv.srvals[dry4] = 0
        set_output()
        time.sleep(.1)  # make sure 4's state is set first
        gv.srvals[dry1] = 0
        gv.srvals[dry2] = 0
        gv.srvals[dry3] = 0
        set_output()
        heatpump_mode = 'none'
        insert_action(gv.now + 2 * 60, {
            'what': 'set_heatpump_pump_mode',
            'mode': 'off'
        })
        last_heatpump_off = gv.now
Ejemplo n.º 40
0
Archivo: sip.py Proyecto: bkoblenz/HVAC
def set_heatpump_mode(md, remove=True):
    """Turn on dry3,4 for cooling; dry 2,4 for heating"""
    global heatpump_mode, last_heatpump_off, last_heatpump_on

    if remove:
        remove_action({'what':'set_heatpump_mode', 'mode':'any'})
    if md == 'cooling':
#        gv.srvals[dry4] = 1
#        set_output()
        time.sleep(.1) # make sure 4's state is set first
        gv.srvals[dry1] = 0
        gv.srvals[dry2] = 0
#        gv.srvals[dry3] = 1
        set_output()
        heatpump_mode = 'cooling'
        set_heatpump_pump_mode('on')
        last_heatpump_on = gv.now
    elif md == 'heating':
#        gv.srvals[dry4] = 1
#        set_output()
        time.sleep(.1) # make sure 4's state is set first
        gv.srvals[dry1] = 0
#        gv.srvals[dry2] = 1
        gv.srvals[dry3] = 0
        set_output()
        heatpump_mode = 'heating'
        set_heatpump_pump_mode('on')
        last_heatpump_on = gv.now
    else:
        gv.srvals[dry4] = 0
        set_output()
        time.sleep(.1) # make sure 4's state is set first
        gv.srvals[dry1] = 0
        gv.srvals[dry2] = 0
        gv.srvals[dry3] = 0
        set_output()
        heatpump_mode = 'none'
        insert_action(gv.now+2*60, {'what':'set_heatpump_pump_mode', 'mode':'off'})
        last_heatpump_off = gv.now
Ejemplo n.º 41
0
def timing_loop():
    """ ***** Main timing algorithm. Runs in a separate thread.***** """
    print 'Starting timing loop \n'
    last_min = 0
    while True:  # infinite loop
        gv.now = timegm(time.localtime())   # Current time based on local time from the Pi. updated once per second.
        gv.gmtnow = time.time()             # Current gmt time (needed for client-side JS code).
        if gv.sd['en'] and not gv.sd['mm'] and (not gv.sd['bsy'] or not gv.sd['seq']):
            lt = time.gmtime(gv.now)
            if (lt[3] * 60) + lt[4] != last_min:  # only check programs once a minute
                last_min = (lt[3] * 60) + lt[4]
                extra_adjustment = plugin_adjustment()
                for i, p in enumerate(gv.pd):  # get both index and prog item
                    # check if program time matches current time, is active, and has a duration
                    if prog_match(p) and p[0] and p[6]:
                        duration = p[6] * gv.sd['wl'] / 100 * extra_adjustment  # program duration scaled by "water level"
                        # check each station for boards listed in program up to number of boards in Options
                        for b in range(len(p[7:7 + gv.sd['nbrd']])):
                            for s in range(8):
                                sid = b * 8 + s  # station index
                                if sid + 1 == gv.sd['mas']:
                                    continue  # skip if this is master station
                                if gv.srvals[sid]:  # skip if currently on
                                    continue

                                if p[7 + b] & 1 << s:  # if this station is scheduled in this program
                                    if gv.sd['seq']:  # sequential mode
                                        gv.rs[sid][2] = duration
                                        gv.rs[sid][3] = i + 1  # store program number for scheduling
                                        gv.ps[sid][0] = i + 1  # store program number for display
                                        gv.ps[sid][1] = duration
                                    else:  # concurrent mode
                                        # If duration is shortter than any already set for this station
                                        if duration < gv.rs[sid][2]:
                                            continue
                                        else:
                                            gv.rs[sid][2] = duration
                                            gv.rs[sid][3] = i + 1  # store program number
                                            gv.ps[sid][0] = i + 1  # store program number for display
                                            gv.ps[sid][1] = duration
                        schedule_stations(p[7:7 + gv.sd['nbrd']])  # turns on gv.sd['bsy']

        if gv.sd['bsy']:
            for b in range(gv.sd['nbrd']):  # Check each station once a second
                for s in range(8):
                    sid = b * 8 + s  # station index
                    if gv.srvals[sid]:  # if this station is on
                        if gv.now >= gv.rs[sid][1]:  # check if time is up
                            gv.srvals[sid] = 0
                            set_output()
                            gv.sbits[b] &= ~1 << s
                            if gv.sd['mas'] - 1 != sid:  # if not master, fill out log
                                gv.ps[sid] = [0, 0]
                                gv.lrun[0] = sid
                                gv.lrun[1] = gv.rs[sid][3]
                                gv.lrun[2] = int(gv.now - gv.rs[sid][0])
                                gv.lrun[3] = gv.now
                                log_run()
                                gv.pon = None  # Program has ended
                            gv.rs[sid] = [0, 0, 0, 0]
                    else:  # if this station is not yet on
                        if gv.rs[sid][0] <= gv.now < gv.rs[sid][1]:
                            if gv.sd['mas'] - 1 != sid:  # if not master
                                gv.srvals[sid] = 1  # station is turned on
                                set_output()
                                gv.sbits[b] |= 1 << s  # Set display to on
                                gv.ps[sid][0] = gv.rs[sid][3]
                                gv.ps[sid][1] = gv.rs[sid][2] + 1  # testing display
                                if gv.sd['mas'] and gv.sd['mo'][b] & 1 << (s - (s / 8) * 80):  # Master settings
                                    masid = gv.sd['mas'] - 1  # master index
                                    gv.rs[masid][0] = gv.rs[sid][0] + gv.sd['mton']
                                    gv.rs[masid][1] = gv.rs[sid][1] + gv.sd['mtoff']
                                    gv.rs[masid][3] = gv.rs[sid][3]
                            elif gv.sd['mas'] == sid + 1:
                                gv.sbits[b] |= 1 << sid  # (gv.sd['mas'] - 1)
                                gv.srvals[masid] = 1
                                set_output()

            for s in range(gv.sd['nst']):
                if gv.rs[s][1]:  # if any station is scheduled
                    program_running = True
                    gv.pon = gv.rs[s][3]  # Store number of running program
                    break
                program_running = False
                gv.pon = None

            if program_running:
                if gv.sd['urs'] and gv.sd['rs']:  # Stop stations if use rain sensor and rain detected.
                    stop_onrain()  # Clear schedule for stations that do not ignore rain.
                for idx in range(len(gv.rs)):  # loop through program schedule (gv.ps)
                    if gv.rs[idx][2] == 0:  # skip stations with no duration
                        continue
                    if gv.srvals[idx]:  # If station is on, decrement time remaining display
                        gv.ps[idx][1] -= 1

            if not program_running:
                gv.srvals = [0] * (gv.sd['nst'])
                set_output()
                gv.sbits = [0] * (gv.sd['nbrd'] + 1)
                gv.ps = []
                for i in range(gv.sd['nst']):
                    gv.ps.append([0, 0])
                gv.rs = []
                for i in range(gv.sd['nst']):
                    gv.rs.append([0, 0, 0, 0])
                gv.sd['bsy'] = 0

            if gv.sd['mas'] and (gv.sd['mm'] or not gv.sd['seq']):  # handle master for maual or concurrent mode.
                mval = 0
                for sid in range(gv.sd['nst']):
                    bid = sid / 8
                    s = sid - bid * 8
                    if gv.sd['mas'] != sid + 1 and (gv.srvals[sid] and gv.sd['mo'][bid] & 1 << s):
                        mval = 1
                        break
                if not mval:
                    gv.rs[gv.sd['mas'] - 1][1] = gv.now  # turn off master

        if gv.sd['urs']:
            check_rain()

        if gv.sd['rd'] and gv.now >= gv.sd['rdst']:  # Check of rain delay time is up
            gv.sd['rd'] = 0
            gv.sd['rdst'] = 0  # Rain delay stop time
            jsave(gv.sd, 'sd')
        time.sleep(1)
Ejemplo n.º 42
0
if web.config.get('_session') is None:
    web.config._session = web.session.Session(app, web.session.DiskStore('sessions'),
                                              initializer={'user': '******'})
template_globals = {
    'gv': gv,
    'str': str,
    'eval': eval,
    'session': web.config._session,
    'json': json
}

template_render = web.template.render('templates', globals=template_globals, base='base')

if __name__ == '__main__':

    #########################################################
    #### Code to import all webpages and plugin webpages ####
    import plugins

    print 'plugins loaded:'
    for name in plugins.__all__:
        print ' ', name

    gv.plugin_menu.sort(key=lambda entry: entry[0])

    set_output()
    thread.start_new_thread(timing_loop, ())

    app.notfound = lambda: web.seeother('/')

    app.run()
Ejemplo n.º 43
0
def timing_loop():
    """ ***** Main timing algorithm. Runs in a separate thread.***** """
    try:
        print _('Starting timing loop') + '\n'
    except Exception:
        pass
    last_min = 0
    while True:  # infinite loop
        gv.nowt = time.localtime()   # Current time as time struct.  Updated once per second.
        gv.now = timegm(gv.nowt)   # Current time as timestamp based on local time from the Pi. Updated once per second.
        if gv.sd['en'] and not gv.sd['mm'] and (not gv.sd['bsy'] or not gv.sd['seq']):
            if gv.now / 60 != last_min:  # only check programs once a minute
                last_min = gv.now / 60
                extra_adjustment = plugin_adjustment()
                for i, p in enumerate(gv.pd):  # get both index and prog item
                    # check if program time matches current time, is active, and has a duration
                    if prog_match(p) and p[0] and p[6]:
                        # check each station for boards listed in program up to number of boards in Options
                        for b in range(len(p[7:7 + gv.sd['nbrd']])):
                            for s in range(8):
                                sid = b * 8 + s  # station index
                                if sid + 1 == gv.sd['mas']:
                                    continue  # skip if this is master station
                                if gv.srvals[sid]:  # skip if currently on
                                    continue

            				# station duration condionally scaled by "water level"
                                if gv.sd['iw'][b] & 1 << s:
                                    duration_adj = 1.0
                                    if gv.sd['idd'] == 1:
                                        duration = p[-1][sid]
                                    else:
                                        duration = p[6]
                                else:
                                    duration_adj = gv.sd['wl'] / 100 * extra_adjustment
                                    if gv.sd['idd'] == 1:
                                        duration = p[-1][sid] * duration_adj
                                    else:
                                        duration = p[6] * duration_adj
                                    duration = int(round(duration)) # convert to int
                                if p[7 + b] & 1 << s:  # if this station is scheduled in this program
                                    if gv.sd['seq']:  # sequential mode
                                        gv.rs[sid][2] = duration
                                        gv.rs[sid][3] = i + 1  # store program number for scheduling
                                        gv.ps[sid][0] = i + 1  # store program number for display
                                        gv.ps[sid][1] = duration
                                    else:  # concurrent mode
                                        # If duration is shortter than any already set for this station
                                        if duration < gv.rs[sid][2]:
                                            continue
                                        else:
                                            gv.rs[sid][2] = duration
                                            gv.rs[sid][3] = i + 1  # store program number
                                            gv.ps[sid][0] = i + 1  # store program number for display
                                            gv.ps[sid][1] = duration
                        schedule_stations(p[7:7 + gv.sd['nbrd']])  # turns on gv.sd['bsy']

        if gv.sd['bsy']:
            for b in range(gv.sd['nbrd']):  # Check each station once a second
                for s in range(8):
                    sid = b * 8 + s  # station index
                    if gv.srvals[sid]:  # if this station is on
                        if gv.now >= gv.rs[sid][1]:  # check if time is up
                            gv.srvals[sid] = 0
                            set_output()
                            gv.sbits[b] &= ~(1 << s)
                            if gv.sd['mas'] - 1 != sid:  # if not master, fill out log
                                gv.ps[sid] = [0, 0]
                                gv.lrun[0] = sid
                                gv.lrun[1] = gv.rs[sid][3]
                                gv.lrun[2] = int(gv.now - gv.rs[sid][0])
                                gv.lrun[3] = gv.now
                                log_run()
                                gv.pon = None  # Program has ended
                            gv.rs[sid] = [0, 0, 0, 0]
                    else:  # if this station is not yet on
                        if gv.rs[sid][0] <= gv.now < gv.rs[sid][1]:
                            if gv.sd['mas'] - 1 != sid:  # if not master
                                gv.srvals[sid] = 1  # station is turned on
                                set_output()
                                gv.sbits[b] |= 1 << s  # Set display to on
                                gv.ps[sid][0] = gv.rs[sid][3]
                                gv.ps[sid][1] = gv.rs[sid][2]
                                if gv.sd['mas'] and gv.sd['mo'][b] & 1 << (s - (s / 8) * 80):  # Master settings
                                    masid = gv.sd['mas'] - 1  # master index
                                    gv.rs[masid][0] = gv.rs[sid][0] + gv.sd['mton']
                                    gv.rs[masid][1] = gv.rs[sid][1] + gv.sd['mtoff']
                                    gv.rs[masid][3] = gv.rs[sid][3]
                            elif gv.sd['mas'] == sid + 1:
                                gv.sbits[b] |= 1 << sid
                                gv.srvals[masid] = 1
                                set_output()

            for s in range(gv.sd['nst']):
                if gv.rs[s][1]:  # if any station is scheduled
                    program_running = True
                    gv.pon = gv.rs[s][3]  # Store number of running program
                    break
                program_running = False
                gv.pon = None

            if program_running:
                if gv.sd['urs'] and gv.sd['rs']:  #  Stop stations if use rain sensor and rain detected.
                    stop_onrain()  # Clear schedule for stations that do not ignore rain.
                for idx in range(len(gv.rs)):  # loop through program schedule (gv.ps)
                    if gv.rs[idx][2] == 0:  # skip stations with no duration
                        continue
                    if gv.srvals[idx]:  # If station is on, decrement time remaining display
                        gv.ps[idx][1] -= 1

            if not program_running:
                gv.srvals = [0] * (gv.sd['nst'])
                set_output()
                gv.sbits = [0] * (gv.sd['nbrd'] + 1)
                gv.ps = []
                for i in range(gv.sd['nst']):
                    gv.ps.append([0, 0])
                gv.rs = []
                for i in range(gv.sd['nst']):
                    gv.rs.append([0, 0, 0, 0])
                gv.sd['bsy'] = 0

            if (gv.sd['mas'] #  master is defined
                and (gv.sd['mm'] or not gv.sd['seq']) #  manual or concurrent mode.
                ):
                stayon = 0
                for octet in xrange(gv.sd['nbrd']):
                    base = octet * 8
                    for s in xrange(8):
                        stn = base + s
                        if (gv.srvals[stn] #  station is on
                            and gv.rs[stn][1] >= gv.now #  station has a stop time >= now
                            and gv.sd['mo'][octet] & 1 << s #  station activates master   
                            ):                  
                            stayon = 1
                            break
                if not stayon:
                    gv.rs[gv.sd['mas'] - 1][1] = gv.now  # set master to turn off next cycle 

        if gv.sd['urs']:
            check_rain()  # in helpers.py

        if gv.sd['rd'] and gv.now >= gv.sd['rdst']:  # Check if rain delay time is up
            gv.sd['rd'] = 0
            gv.sd['rdst'] = 0  # Rain delay stop time
            jsave(gv.sd, 'sd')        

        time.sleep(1)
Ejemplo n.º 44
0
    def GET(self):
        qdict = web.input()
        if u"opw" in qdict and qdict[u"opw"] != u"":
            try:
                if password_hash(qdict[u"opw"]) == gv.sd[u"passphrase"]:
                    if qdict[u"npw"] == u"":
                        raise web.seeother(u"/vo?errorCode=pw_blank")
                    elif qdict[u"cpw"] != u"" and qdict[u"cpw"] == qdict[
                            u"npw"]:
                        gv.sd[
                            u"passphrase"] = password_hash(  #  Set new passphrase.
                                qdict[u"npw"])
                    else:
                        raise web.seeother(u"/vo?errorCode=pw_mismatch")
                else:
                    raise web.seeother(u"/vo?errorCode=pw_wrong")
            except KeyError:
                pass

        for f in [u"name"]:
            if u"o" + f in qdict:
                gv.sd[f] = qdict[u"o" + f]

        for f in [u"loc", u"lang"]:
            if u"o" + f in qdict:
                if f not in gv.sd or gv.sd[f] != qdict[u"o" + f]:
                    qdict[u"rstrt"] = u"1"  # force restart with change
                gv.sd[f] = qdict[u"o" + f]

        if u"onbrd" in qdict:
            if int(qdict[u"onbrd"]) + 1 != gv.sd[u"nbrd"]:
                self.update_scount(qdict)
            gv.sd[u"nbrd"] = int(qdict[u"onbrd"]) + 1
            gv.sd[u"nst"] = gv.sd[u"nbrd"] * 8
            self.update_prog_lists(u"nbrd")

        if u"ohtp" in qdict:
            if u"htp" not in gv.sd or gv.sd[u"htp"] != int(qdict[u"ohtp"]):
                qdict[u"rstrt"] = u"1"  # force restart with change in htp
            gv.sd[u"htp"] = int(qdict[u"ohtp"])

        if u"oidd" in qdict:
            idd_int = 1
        else:
            idd_int = 0
        if idd_int != gv.sd[u"idd"]:
            gv.sd[u"idd"] = idd_int
            self.update_prog_lists(u"idd")

        if u"ohtip" in qdict:
            if u"htip" not in gv.sd or gv.sd[u"htip"] != qdict[u"ohtip"]:
                qdict[u"rstrt"] = u"1"  # force restart with change in htip
            gv.sd[u"htip"] = qdict[u"ohtip"]

        for f in [u"sdt", u"mas", u"mton", u"mtoff", u"wl", u"lr", u"tz"]:
            if u"o" + f in qdict:
                if (f == u"mton" and int(qdict[u"o" + f]) <
                        0):  # handle values less than zero (temp fix)
                    raise web.seeother(u"/vo?errorCode=mton_minus")
                gv.sd[f] = int(qdict[u"o" + f])

        for f in [
                u"upas",
                u"tf",
                u"urs",
                u"seq",
                u"rst",
                u"lg",
                u"pigpio",
                u"alr",
        ]:
            if u"o" + f in qdict and (qdict[u"o" + f] == u"on"
                                      or qdict[u"o" + f] == u"1"):
                gv.sd[f] = 1
            else:
                gv.sd[f] = 0

        jsave(gv.sd, u"sd")
        report_option_change()
        if u"rbt" in qdict and qdict[u"rbt"] == u"1":
            gv.srvals = [0] * (gv.sd[u"nst"])
            set_output()
            report_rebooted()
            reboot()
        if u"shutdown" in qdict and qdict[u"shutdown"] == u"1":
            gv.srvals = [0] * (gv.sd[u"nst"])
            set_output()
            poweroff()

        if u"rstrt" in qdict and qdict[u"rstrt"] == u"1":
            restart(2)
            raise web.seeother(u"/restart")
        raise redirect_back()
Ejemplo n.º 45
0
def timing_loop():
    """ ***** Main timing algorithm. Runs in a separate thread.***** """
    last_min = 0
    last_day = 0
    last_master_station_running = 0
    master_turn_on = 0
    mton_delay = 0
    gv.sd['bsy'] = 0

    check_and_update_upnp()
    last_upnp_refresh = gv.now

    # Log the image and all the vsb board fw
    try:
        with open('data/version', 'r') as f:
            image_version = f.read()
        gv.logger.info('Image version: ' + image_version)
    except:
        pass
    boards = i2c.get_vsb_boards()
    for board, version in boards.items():
        gv.logger.info('VSB Firmware for board: ' + str(board) + ' value: ' + hex(version))

    for delay in range(15):
        time.sleep(1) # wait for ip addressing to settle but keep updating time
        gv.nowt = time.localtime()   # Current time as time struct.  Updated once per second.
        gv.now = timegm(gv.nowt)   # Current time as timestamp based on local time from the Pi. Updated once per second.

    for i, p in enumerate(gv.pd):  # get future instances of programs that recur but started earlier in the day
        if prog_match(p, True):
            schedule_recurring_instances(i)

    ip_countdown = 2
    while True:  # infinite loop
        gv.nowt = time.localtime()   # Current time as time struct.  Updated once per second.
        gv.now = timegm(gv.nowt)   # Current time as timestamp based on local time from the Pi. Updated once per second.
        if gv.sd['en'] and not gv.sd['mm']:
            if gv.now // 60 != last_min:  # only check programs once a minute
                last_min = gv.now // 60
                update_radio_present()
                max_bd = -1
                boards = i2c.get_vsb_boards()
                for bd, version in boards.items():
                    if bd not in gv.in_bootloader:
                        try:
                            max_bd = max(max_bd, bd)
                            v = i2c_read(i2c.ADDRESS+bd, 0xc) # verify scratch value is as expected.  Acts as a touch of the vsb too!
                            if v != bd+16:
                                gv.logger.critical('Main bad scratch value on board: ' + str(bd) + ' value: ' + str(v))
                                i2c_write(i2c.ADDRESS+bd, 0xc, bd+16) # write scratch register as keepalive
                        except:
                            gv.logger.critical('Cant access scratch register on board: ' + str(bd))
                            pass

                        # read deadman debug register ignoring all errors.
                        try:
                            v = i2c_read(i2c.ADDRESS+bd, 0xd)
                            if v != 0:
                                 gv.logger.critical('Deadman register triggered on board: ' + str(bd) + ' value: ' + str(v))
                        except:
                            pass

                cur_bd = (gv.sd['nst']-gv.sd['radiost'])//8
                if max_bd+1 > cur_bd: # ensure at nbrd captures all attached VSMs
                    gv.logger.info('Changing nbrd based on attached boards: ' + str(max_bd+1))
                    adjust_gv_nbrd(max_bd+1)
                    gv.sd['nst'] += 8*(max_bd+1-cur_bd)
                    jsave(gv.sd, 'sd')

                cur_ip = get_ip()
                ext_ip_addr = get_external_ip()
                ip_countdown = 2 if cur_ip == gv.last_ip else ip_countdown-1
                # when establishing bridge, wlan0 appears to drop then come back....just take a couple of iterations to
                # be sure we have an ip change.
                if ip_countdown == 0:
                    ip_countdown = 2 # reset
                    if gv.sd['master'] and (ext_ip_addr != gv.external_ip or cur_ip != gv.last_ip):
                        gv.external_ip = ext_ip_addr
                        try:
                            # send email if ip addressing changed
                            if gv.sd['teipchange'] and gv.plugin_data['te']['tesender']:
                                subject = "Report from Irricloud"
                                body = 'IP change.  Local IP: ' + cur_ip
                                if gv.sd['htp'] != 0 and gv.sd['htp'] != 80:
                                    body += ':' + str(gv.sd['htp'])
                                body += ' External IP: ' + ext_ip_addr
                                if gv.sd['external_htp'] != 0:
                                    body += ':' + str(gv.sd['external_htp'])
                                gv.plugin_data['te']['tesender'].try_mail(subject, body)
                        except:
                            pass

                    if cur_ip != gv.last_ip:
                        gv.logger.info('IP changed from: ' + gv.last_ip + ' to: ' + cur_ip)
                        gv.last_ip = cur_ip
                        if cur_ip != "No IP Settings":
                            # find router, set up upnp port mapping
                            check_and_update_upnp(cur_ip)
                            last_upnp_refresh = gv.now

                    if gv.sd['upnp_refresh_rate'] > 0 and \
                           (gv.now-last_upnp_refresh)//60 >= gv.sd['upnp_refresh_rate']:
                        check_and_update_upnp(cur_ip)
                        last_upnp_refresh = gv.now

                cur_day = gv.now//86400
                if cur_day != last_day:
                    for i in range(gv.sd['nst']):
                        for j in range(len(gv.rs[i])-1,0,-1):
                            if gv.rs[i][j]['rs_stop_sec'] < gv.now:
                                gv.logger.critical('Left over data on gv.rs['+str(i)+']')
                                del gv.rs[i][j]
                            elif gv.rs[i][j]['rs_stop_sec'] > gv.now + 86400: # indefinite program?
                                gv.rs[i][j]['rs_stop_sec'] += 86400 # keep extending
                        update_rs_order(i)
                    last_day = cur_day

                for i, p in enumerate(gv.pd):  # get both index and prog item
                    if prog_match(p):
                        gv.logger.debug('prog_match for program: ' + p[-1])
                        run_program(i)
                        schedule_recurring_instances(i)

                for e in gv.recur[:]: # sorted by start times of recurring programs to run
                    now_min = (gv.now%86400)//60
                    if e[0] <= now_min:
                        try:
                            gv.logger.debug('recur match for program: ' + gv.pd[e[1]][-1])
                        except:
                            pass
                        run_program(e[1]) # pid
                        del gv.recur[0] # always deleting what is (now) first in list
                    else:
                        break

        if gv.sd['bsy']:
            with gv.rs_lock:
                program_running = False
                masid = gv.sd['mas']-1
                for sid in range(gv.sd['nst']):  # Check each station once a second
                    b = sid >> 3
                    s = sid % 8
                    prog_id = gv.rs[sid][len(gv.rs[sid])-1]['rs_program_id']
                    p = None if prog_id >= len(gv.pd) else gv.pd[prog_id-1]
                        
                    if gv.now >= gv.rs[sid][len(gv.rs[sid])-1]['rs_stop_sec'] and len(gv.rs[sid]) > 1:  # check if time is up
                        stop_station(sid, **{'stop_only_current':1})
                    elif gv.rs[sid][len(gv.rs[sid])-1]['rs_start_sec'] <= gv.now < gv.rs[sid][len(gv.rs[sid])-1]['rs_stop_sec']:
                        if (gv.sbits[b] & (1<<s)) == 0: # not yet displayed?
                            duration = gv.rs[sid][len(gv.rs[sid])-1]['rs_stop_sec'] - gv.now
                            gv.logger.info('start station display sid: ' + str(sid+1) + ' for: ' + to_relative_time(duration))
                            gv.sbits[b] |= 1 << s  # Set display to on
                            gv.ps[sid][0] = prog_id
                            if gv.ps[sid][1] != duration:
                                gv.logger.info('sip_loop ps_set: change ps sid: ' + str(sid+1) + ' from: ' + to_relative_time(gv.ps[sid][1])+ ' to: ' + to_relative_time(duration))
                                gv.ps[sid][1] = duration
                            if p is None or (p[gv.p_flags]&2) == 0:  # if not ban program
                                gv.logger.info('turn on sid: ' + str(sid+1) + ' prog: ' + str(prog_id) + ' (ps set) dur: ' + to_relative_time(duration))
                                gv.srvals[sid] = 1
                                set_output()
                            else: # already stopped what was running in schedule_stations
                                gv.logger.info('turn on ban sid: ' + str(sid+1) + ' prog: ' + str(prog_id) + ' (ps set) dur: ' + to_relative_time(duration))
                            if sid == gv.sd['mas']-1: # when we turn on master, start mton countdown
                                mton_delay = -gv.sd['mton']
                    elif gv.rs[sid][len(gv.rs[sid])-1]['rs_start_sec'] > gv.now and gv.ps[sid][0] == 0:
                        duration = gv.rs[sid][len(gv.rs[sid])-1]['rs_stop_sec'] - gv.rs[sid][len(gv.rs[sid])-1]['rs_start_sec']
                        gv.ps[sid][0] = prog_id
                        if gv.ps[sid][1] != duration:
                            gv.logger.info('sip_loop ps_change: change ps sid: ' + str(sid+1) + ' from: ' + to_relative_time(gv.ps[sid][1]) + ' to: ' + to_relative_time(duration))
                        gv.ps[sid][1] = duration 
                        gv.logger.info('future: ' + to_relative_time(gv.rs[sid][len(gv.rs[sid])-1]['rs_start_sec']) +
                                        ' turn on sid: ' + str(sid+1) + ' prog: ' + str(prog_id) + ' (ps set) dur: ' + to_relative_time(duration))

                    if masid >= 0 and sid != masid and gv.srvals[sid] and gv.sd['mo'][b]&(1<<s):  # Master settings
                        last_master_station_running = gv.now
                    if len(gv.rs[sid]) > 1:  # if any station is scheduled or on
                        program_running = True

                # delays may have screwed up master scheduling.
                # If a station requiring master is running and master is not started, start it.
                if masid >= 0 and gv.srvals[masid] == 0:
                    if master_turn_on == 0 and last_master_station_running == gv.now:
                        master_turn_on = last_master_station_running + gv.sd['mton']
                    if master_turn_on != 0 and master_turn_on <= gv.now:
                        gv.logger.info('turn on master without prescheduling mton: ' + str(master_turn_on))
                        gv.sbits[masid>>3] |= 1 << (masid%8)  # Set display to on
                        gv.ps[masid][0] = 98
                        gv.ps[masid][1] = 0
                        gv.srvals[masid] = 1
                        set_output()
                        master_turn_on = 0

                # If no station requiring master is running and master is not stopped, stop it.
                if masid >= 0 and gv.srvals[masid] == 1:
                    if mton_delay >= 0:
                        mton_delay -= 1
                    if (mton_delay < 0 and # allow for windown where master starts early
                        last_master_station_running < gv.now and
                        ((gv.sd['mtoff'] <= 0 and last_master_station_running >= gv.now + gv.sd['mtoff']) or \
                         (gv.sd['mtoff'] > 0 and last_master_station_running + gv.sd['mtoff'] <= gv.now))):
                        gv.logger.info('turn off master without prescheduling')
                        stop_station(masid, **{'stop_active':1})
                        mton_delay = 0
                    else:
                        program_running = True # give time for master to shut down

                if program_running:
                    # todo check stop_onrain for ban programs
                    if gv.sd['urs'] and gv.sd['rs']:  # Stop stations if use rain sensor and rain detected.
                        stop_onrain()  # Clear schedule for stations that do not ignore rain.
                    for sid in range(len(gv.rs)):  # loop through program schedule (gv.ps)
                        if (gv.sbits[sid>>3] & (1<<(sid%8))) != 0:  # If station is on, decrement time remaining display
                            if gv.ps[sid][1] < 86400: # dont reduce indefinite program
                                if gv.ps[sid][1] == -1:
                                    gv.logger.critical('sip negative ps decrement sid: ' + str(sid+1) + ' to: ' + to_relative_time(gv.ps[sid][1]) + \
                                                    ' start: ' + to_relative_time(gv.rs[sid][len(gv.rs[sid])-1]['rs_start_sec']) + \
                                                    ' stop: '  + to_relative_time(gv.rs[sid][len(gv.rs[sid])-1]['rs_stop_sec']))
                                gv.ps[sid][1] -= 1
                            else:
                                gv.logger.debug('sip_ indefinite program sid: ' + str(sid+1) + ' to: ' + to_relative_time(gv.ps[sid][1]) + \
                                                   ' start: ' + to_relative_time(gv.rs[sid][len(gv.rs[sid])-1]['rs_start_sec']) + \
                                                   ' stop: '  + to_relative_time(gv.rs[sid][len(gv.rs[sid])-1]['rs_stop_sec']))
                                pass

                if not program_running:
                    gv.sd['bsy'] = 0
                    for sid in range(gv.sd['nst']):
                        b = sid >> 3
                        s = sid % 8
                        if gv.srvals[sid]:
                            gv.logger.critical('srval set with no program running sid: ' + str(sid+1))
                        if gv.sbits[b]&(1<<s):
                            gv.logger.critical('sbits set with no program running sid: ' + str(sid+1))
                        if gv.ps[sid][0]:
                            gv.logger.critical('ps[0] set with no program running sid: ' + str(sid+1))
                        if gv.ps[sid][1]:
                            gv.logger.critical('ps[1] set with no program running sid: ' + str(sid+1))

        if gv.sd['urs']:
            check_rain()  # in helpers.py

        if gv.sd['rd'] and gv.now >= gv.sd['rdst']:  # Check of rain delay time is up
            gv.sd['rd'] = 0
            gv.sd['rdst'] = 0  # Rain delay stop time
            jsave(gv.sd, 'sd')

        new_now = timegm(time.localtime())
        if new_now - gv.now == 0: # try to avoid drift
            time.sleep(1)
Ejemplo n.º 46
0
    def GET(self):
        qdict = web.input()
        if 'opw' in qdict and qdict['opw'] != "":
            try:
                if password_hash(qdict['opw'],
                                 gv.sd['salt']) == gv.sd['password']:
                    if qdict['npw'] == "":
                        raise web.seeother('/vo?errorCode=pw_blank')
                    elif qdict['cpw'] != '' and qdict['cpw'] == qdict['npw']:
                        gv.sd['salt'] = password_salt()  # Make a new salt
                        gv.sd['password'] = password_hash(
                            qdict['npw'], gv.sd['salt'])
                    else:
                        raise web.seeother('/vo?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/vo?errorCode=pw_wrong')
            except KeyError:
                pass

        for f in ['name']:
            if 'o' + f in qdict:
                gv.sd[f] = qdict['o' + f]

        for f in ['loc', 'lang']:
            if 'o' + f in qdict:
                if f not in gv.sd or gv.sd[f] != qdict['o' + f]:
                    qdict['rstrt'] = '1'  # force restart with change
                gv.sd[f] = qdict['o' + f]

        if 'onbrd' in qdict:
            if int(qdict['onbrd']) + 1 != gv.sd['nbrd']:
                self.update_scount(qdict)
            gv.sd['nbrd'] = int(qdict['onbrd']) + 1
            gv.sd['nst'] = gv.sd['nbrd'] * 8

        if 'ohtp' in qdict:
            if 'htp' not in gv.sd or gv.sd['htp'] != int(qdict['ohtp']):
                qdict['rbt'] = '1'  # force reboot with change in htp
            gv.sd['htp'] = int(qdict['ohtp'])

        for f in ['sdt', 'mas', 'mton', 'mtoff', 'wl', 'lr', 'tz']:
            if 'o' + f in qdict:
                gv.sd[f] = int(qdict['o' + f])

        for f in ['ipas', 'tf', 'urs', 'seq', 'rst', 'lg']:
            if 'o' + f in qdict and (qdict['o' + f] == 'on'
                                     or qdict['o' + f] == '1'):
                gv.sd[f] = 1
            else:
                gv.sd[f] = 0

        jsave(gv.sd, 'sd')
        report_option_change()
        if 'rbt' in qdict and qdict['rbt'] == '1':
            gv.srvals = [0] * (gv.sd['nst'])
            set_output()
            report_rebooted()
            #            os.system('reboot')
            reboot()

        if 'rstrt' in qdict and qdict['rstrt'] == '1':
            #            restart(2)
            raise web.seeother('/restart')
        raise web.seeother('/')
Ejemplo n.º 47
0
    def GET(self):
        qdict = web.input()
        if 'opw' in qdict and qdict['opw'] != "":
            try:
                if password_hash(qdict['opw'],
                                 gv.sd['salt']) == gv.sd['password']:
                    if qdict['npw'] == "":
                        raise web.seeother('/vo?errorCode=pw_blank')
                    elif qdict['cpw'] != '' and qdict['cpw'] == qdict['npw']:
                        gv.sd['salt'] = password_salt()  # Make a new salt
                        gv.sd['password'] = password_hash(
                            qdict['npw'], gv.sd['salt'])
                    else:
                        raise web.seeother('/vo?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/vo?errorCode=pw_wrong')
            except KeyError:
                pass

        try:
            if 'oipas' in qdict and (qdict['oipas'] == 'on'
                                     or qdict['oipas'] == '1'):
                gv.sd['ipas'] = 1
            else:
                gv.sd['ipas'] = 0
        except KeyError:
            pass

        if 'oname' in qdict:
            gv.sd['name'] = qdict['oname']
        if 'oloc' in qdict:
            gv.sd['loc'] = qdict['oloc']
        if 'otz' in qdict:
            gv.sd['tz'] = int(qdict['otz'])
        try:
            if 'otf' in qdict and (qdict['otf'] == 'on'
                                   or qdict['otf'] == '1'):
                gv.sd['tf'] = 1
            else:
                gv.sd['tf'] = 0
        except KeyError:
            pass

        if int(qdict['onbrd']) + 1 != gv.sd['nbrd']:
            self.update_scount(qdict)
        gv.sd['nbrd'] = int(qdict['onbrd']) + 1

        gv.sd['nst'] = gv.sd['nbrd'] * 8
        if 'ohtp' in qdict:
            gv.sd['htp'] = int(qdict['ohtp'])
        if 'osdt' in qdict:
            gv.sd['sdt'] = int(qdict['osdt'])
        if 'olang' in qdict:
            gv.sd['lang'] = qdict['olang']
        if 'omas' in qdict:
            gv.sd['mas'] = int(qdict['omas'])
        if 'omton' in qdict:
            gv.sd['mton'] = int(qdict['omton'])
        if 'omtoff' in qdict:
            gv.sd['mtoff'] = int(qdict['omtoff'])
        if 'owl' in qdict:
            gv.sd['wl'] = int(qdict['owl'])

        if 'ours' in qdict and (qdict['ours'] == 'on' or qdict['ours'] == '1'):
            gv.sd['urs'] = 1
        else:
            gv.sd['urs'] = 0

        if 'oseq' in qdict and (qdict['oseq'] == 'on' or qdict['oseq'] == '1'):
            gv.sd['seq'] = 1
        else:
            gv.sd['seq'] = 0

        if 'orst' in qdict and (qdict['orst'] == 'on' or qdict['orst'] == '1'):
            gv.sd['rst'] = 1
        else:
            gv.sd['rst'] = 0

        if 'olg' in qdict and (qdict['olg'] == 'on' or qdict['olg'] == '1'):
            gv.sd['lg'] = 1
        else:
            gv.sd['lg'] = 0

        if 'olr' in qdict:
            gv.sd['lr'] = int(qdict['olr'])

        jsave(gv.sd, 'sd')
        report_option_change()
        if 'rbt' in qdict and qdict['rbt'] == '1':
            gv.srvals = [0] * (gv.sd['nst'])
            set_output()
            report_rebooted()
            #            os.system('reboot')
            reboot()

        if 'rstrt' in qdict and qdict['rstrt'] == '1':
            #            restart(2)
            raise web.seeother('/restart')
        raise web.seeother('/')
Ejemplo n.º 48
0
def timing_loop():
    """ ***** Main timing algorithm. Runs in a separate thread.***** """
    try:
        print _('Starting timing loop') + '\n'
    except Exception:
        pass
    last_min = 0
    while True:  # infinite loop
        gv.nowt = time.localtime(
        )  # Current time as time struct.  Updated once per second.
        gv.now = timegm(
            gv.nowt
        )  # Current time as timestamp based on local time from the Pi. Updated once per second.
        if (gv.sd['en'] and not gv.sd['mm']
                and (not gv.sd['bsy'] or not gv.sd['seq'])):
            if gv.now / 60 != last_min:  # only check programs once a minute
                last_min = gv.now / 60
                extra_adjustment = plugin_adjustment()
                for i, p in enumerate(gv.pd):  # get both index and prog item
                    # check if program time matches current time, is active, and has a duration
                    if prog_match(p) and p[0] and p[6]:
                        # check each station for boards listed in program up to number of boards in Options
                        for b in range(len(p[7:7 + gv.sd['nbrd']])):
                            for s in range(8):
                                sid = b * 8 + s  # station index
                                if gv.sd['mas'] == sid + 1:
                                    continue  # skip if this is master station
                                if gv.srvals[sid] and gv.sd[
                                        'seq']:  # skip if currently on and sequential mode
                                    continue

                                # station duration conditionally scaled by "water level"
                                if gv.sd['iw'][b] & 1 << s:
                                    duration_adj = 1.0
                                    if gv.sd['idd'] == 1:
                                        duration = p[-1][sid]
                                    else:
                                        duration = p[6]
                                else:
                                    duration_adj = (float(gv.sd['wl']) /
                                                    100) * extra_adjustment
                                    if gv.sd['idd'] == 1:
                                        duration = p[-1][sid] * duration_adj
                                    else:
                                        duration = p[6] * duration_adj
                                    duration = int(
                                        round(duration))  # convert to int
                                if p[7 +
                                     b] & 1 << s:  # if this station is scheduled in this program
                                    if gv.sd['seq']:  # sequential mode
                                        gv.rs[sid][2] = duration
                                        gv.rs[sid][
                                            3] = i + 1  # store program number for scheduling
                                        gv.ps[sid][
                                            0] = i + 1  # store program number for display
                                        gv.ps[sid][1] = duration
                                    else:  # concurrent mode
                                        if gv.srvals[
                                                sid]:  # if currently on, log result
                                            gv.lrun[0] = sid
                                            gv.lrun[1] = gv.rs[sid][3]
                                            gv.lrun[2] = int(gv.now -
                                                             gv.rs[sid][0])
                                            gv.lrun[
                                                3] = gv.now  # think this is unused
                                            log_run()
                                            report_station_completed(sid + 1)
                                        gv.rs[sid][2] = duration
                                        gv.rs[sid][
                                            3] = i + 1  # store program number
                                        gv.ps[sid][
                                            0] = i + 1  # store program number for display
                                        gv.ps[sid][1] = duration
                        schedule_stations(
                            p[7:7 + gv.sd['nbrd']])  # turns on gv.sd['bsy']

        if gv.sd['bsy']:
            for b in range(gv.sd['nbrd']):  # Check each station once a second
                for s in range(8):
                    sid = b * 8 + s  # station index
                    if gv.srvals[sid]:  # if this station is on
                        if gv.now >= gv.rs[sid][1]:  # check if time is up
                            gv.srvals[sid] = 0
                            set_output()
                            gv.sbits[b] &= ~(1 << s)
                            if gv.sd['mas'] != sid + 1:  # if not master, fill out log
                                gv.ps[sid] = [0, 0]
                                gv.lrun[0] = sid
                                gv.lrun[1] = gv.rs[sid][3]
                                gv.lrun[2] = int(gv.now - gv.rs[sid][0])
                                gv.lrun[3] = gv.now
                                log_run()
                                report_station_completed(sid + 1)
                                gv.pon = None  # Program has ended
                            gv.rs[sid] = [0, 0, 0, 0]
                    else:  # if this station is not yet on
                        if gv.rs[sid][0] <= gv.now < gv.rs[sid][1]:
                            if gv.sd['mas'] != sid + 1:  # if not master
                                gv.srvals[sid] = 1  # station is turned on
                                set_output()
                                gv.sbits[b] |= 1 << s  # Set display to on
                                gv.ps[sid][0] = gv.rs[sid][3]
                                gv.ps[sid][1] = gv.rs[sid][2]
                                if gv.sd['mas'] and gv.sd['mo'][b] & (
                                        1 << s):  # Master settings
                                    masid = gv.sd['mas'] - 1  # master index
                                    gv.rs[masid][
                                        0] = gv.rs[sid][0] + gv.sd['mton']
                                    gv.rs[masid][
                                        1] = gv.rs[sid][1] + gv.sd['mtoff']
                                    gv.rs[masid][3] = gv.rs[sid][3]
                            elif gv.sd['mas'] == sid + 1:
                                gv.sbits[b] |= 1 << sid
                                gv.srvals[masid] = 1
                                set_output()

            for s in range(gv.sd['nst']):
                if gv.rs[s][1]:  # if any station is scheduled
                    program_running = True
                    gv.pon = gv.rs[s][3]  # Store number of running program
                    break
                program_running = False
                gv.pon = None

            if program_running:
                if gv.sd['urs'] and gv.sd[
                        'rs']:  #  Stop stations if use rain sensor and rain detected.
                    stop_onrain(
                    )  # Clear schedule for stations that do not ignore rain.
                for sid in range(len(
                        gv.rs)):  # loop through program schedule (gv.ps)
                    if gv.rs[sid][2] == 0:  # skip stations with no duration
                        continue
                    if gv.srvals[
                            sid]:  # If station is on, decrement time remaining display
                        if gv.ps[sid][1] > 0:  # if time is left
                            gv.ps[sid][1] -= 1

            if not program_running:
                gv.srvals = [0] * (gv.sd['nst'])
                set_output()
                gv.sbits = [0] * (gv.sd['nbrd'] + 1)
                gv.ps = []
                for i in range(gv.sd['nst']):
                    gv.ps.append([0, 0])
                gv.rs = []
                for i in range(gv.sd['nst']):
                    gv.rs.append([0, 0, 0, 0])
                gv.sd['bsy'] = 0

            if (gv.sd['mas']  #  master is defined
                    and (gv.sd['mm'] or not gv.sd['seq']
                         )  #  manual or concurrent mode.
                ):
                for b in range(gv.sd['nbrd']):  # set stop time for master
                    for s in range(8):
                        sid = b * 8 + s
                        if (gv.sd['mas'] != sid + 1  # if not master
                                and gv.srvals[sid]  #  station is on
                                and gv.rs[sid][1] >=
                                gv.now  #  station has a stop time >= now
                                and gv.sd['mo'][b] &
                            (1 << s)  #  station activates master   
                            ):
                            gv.rs[gv.sd['mas'] - 1][1] = gv.rs[sid][1] + gv.sd[
                                'mtoff']  # set to future...
                            break  # first found will do

        if gv.sd['urs']:
            check_rain()  # in helpers.py

        if gv.sd['rd'] and gv.now >= gv.sd[
                'rdst']:  # Check if rain delay time is up
            gv.sd['rd'] = 0
            gv.sd['rdst'] = 0  # Rain delay stop time
            jsave(gv.sd, 'sd')

        time.sleep(1)
Ejemplo n.º 49
0
    def GET(self):
        qdict = web.input()
        if 'opw' in qdict and qdict['opw'] != "":
            try:
                if password_hash(qdict['opw'], gv.sd['salt']) == gv.sd['password']:
                    if qdict['npw'] == "":
                        raise web.seeother('/vo?errorCode=pw_blank')
                    elif qdict['cpw'] != '' and qdict['cpw'] == qdict['npw']:
                        gv.sd['salt'] = password_salt()  # Make a new salt
                        gv.sd['password'] = password_hash(qdict['npw'], gv.sd['salt'])
                    else:
                        raise web.seeother('/vo?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/vo?errorCode=pw_wrong')
            except KeyError:
                pass

        for f in ['name']:
            if 'o'+f in qdict:
                gv.sd[f] = qdict['o'+f]

        for f in ['loc', 'lang']:
            if 'o'+f in qdict:
                if f not in gv.sd or gv.sd[f] != qdict['o'+f]:
                    qdict['rstrt'] = '1'  # force restart with change
                gv.sd[f] = qdict['o'+f]

        if 'onbrd' in qdict:
            if int(qdict['onbrd']) + 1 != gv.sd['nbrd']:
                self.update_scount(qdict)
            gv.sd['nbrd'] = int(qdict['onbrd']) + 1
            gv.sd['nst'] = gv.sd['nbrd'] * 8

        if 'ohtp' in qdict:
            if 'htp' not in gv.sd or gv.sd['htp'] != int(qdict['ohtp']):
                qdict['rbt'] = '1'  # force reboot with change in htp
            gv.sd['htp'] = int(qdict['ohtp'])

        for f in ['sdt', 'mas', 'mton', 'mtoff', 'wl', 'lr', 'tz']:
            if 'o'+f in qdict:
                if f == 'mton'  and int(qdict['o'+f])<0: #handle values less than zero (temp fix)
                    raise web.seeother('/vo?errorCode=mton_minus')                 
                gv.sd[f] = int(qdict['o'+f])

        for f in ['ipas', 'tf', 'urs', 'seq', 'rst', 'lg', 'idd', 'pigpio']:
            if 'o'+f in qdict and (qdict['o'+f] == 'on' or qdict['o'+f] == '1'):
                gv.sd[f] = 1
            else:
                gv.sd[f] = 0

        jsave(gv.sd, 'sd')
        report_option_change()
        if 'rbt' in qdict and qdict['rbt'] == '1':
            gv.srvals = [0] * (gv.sd['nst'])
            set_output()
            report_rebooted()
#            os.system('reboot')
            reboot()

        if 'rstrt' in qdict and qdict['rstrt'] == '1':
#            restart(2)
            raise web.seeother('/restart')
        raise web.seeother('/')
Ejemplo n.º 50
0
Archivo: sip.py Proyecto: bkoblenz/HVAC
def timing_loop():
    """ ***** Main timing algorithm. Runs in a separate thread.***** """
    last_min = 0
    zc = 0
    supply_temp_readings = []
    return_temp_readings = []
#    last_mode = gv.sd['mode']
    last_mode = 'Invalid Mode' # force intialization
    last_temp_log = 0
    failed_temp_read = 0
    last_dewpoint_adjust = 0

    # Log the image and all the vsb board fw
    try:
        with open('data/version', 'r') as f:
            image_version = f.read()
        gv.logger.info('Image version: ' + image_version)
    except:
        pass
    boards = i2c.get_vsb_boards()
    for board, version in boards.items():
        gv.logger.info('VSB Firmware for board: ' + str(board) + ' value: ' + hex(version))

    for delay in range(15):
        time.sleep(1) # wait for ip addressing to settle but keep updating time
        gv.nowt = time.localtime()   # Current time as time struct.  Updated once per second.
        gv.now = timegm(gv.nowt)   # Current time as timestamp based on local time from the Pi. Updated once per second.

    start_time = gv.now
    check_and_update_upnp()
    last_upnp_refresh = gv.now

    # one_way_cooling_adjustments tracks the direction of the last valve change and how many changes we have made
    # in that direction without going the other direction.  This stops us from constantly moving the valve when the
    # heatpump is off or we cannot achieve our target.
    one_way_cooling_adjustments = 0
    last_ave_supply_temp = None

    # force everything off

    set_output()
    while True:  # infinite loop
        time.sleep(1)
        gv.nowt = time.localtime()   # Current time as time struct.  Updated once per second.
        gv.now = timegm(gv.nowt)   # Current time as timestamp based on local time from the Pi. Updated once per second.
        # perform once per minute processing
        if gv.now // 60 != last_min:  # only check programs once a minute
            last_min = gv.now // 60
            update_radio_present()
            max_bd = -1
            boards = i2c.get_vsb_boards()
            for bd, version in boards.items():
                if bd not in gv.in_bootloader:
                    try:
                        max_bd = max(max_bd, bd)
                        v = i2c_read(i2c.ADDRESS+bd, 0xc) # verify scratch value is as expected.  Acts as a touch of the vsb too!
                        if v != bd+16:
                            gv.logger.critical('Main bad scratch value on board: ' + str(bd) + ' value: ' + str(v))
                            i2c_write(i2c.ADDRESS+bd, 0xc, bd+16) # write scratch register as keepalive
                    except:
                        gv.logger.critical('Cant access scratch register on board: ' + str(bd))
                        pass

                    # read deadman debug register ignoring all errors.
                    try:
                        v = i2c_read(i2c.ADDRESS+bd, 0xd)
                        if v != 0:
                             gv.logger.critical('Deadman register triggered on board: ' + str(bd) + ' value: ' + str(v))
                    except:
                        pass

            cur_bd = (gv.sd['nst']-gv.sd['radiost'])//8
            if max_bd+1 > cur_bd: # ensure at nbrd captures all attached VSMs
                gv.logger.info('Changing nbrd based on attached boards: ' + str(max_bd+1))
                adjust_gv_nbrd(max_bd+1)
                gv.sd['nst'] += 8*(max_bd+1-cur_bd)
                jsave(gv.sd, 'sd')

            cur_ip = get_ip()
            ext_ip_addr = get_external_ip()
            if gv.sd['master'] and (ext_ip_addr != gv.external_ip or cur_ip != gv.last_ip):
                gv.external_ip = ext_ip_addr
                try:
                    # send email if ip addressing changed
                    if gv.sd['teipchange'] and gv.plugin_data['te']['tesender']:
                        subject = "Report from Irricloud"
                        body = 'IP change.  Local IP: ' + cur_ip
                        if gv.sd['htp'] != 0 and gv.sd['htp'] != 80:
                            body += ':' + str(gv.sd['htp'])
                        body += ' External IP: ' + ext_ip_addr
                        if gv.sd['external_htp'] != 0:
                            body += ':' + str(gv.sd['external_htp'])
                        gv.plugin_data['te']['tesender'].try_mail(subject, body)
                except:
                    pass

            if cur_ip != gv.last_ip:
                gv.logger.info('IP changed from: ' + gv.last_ip + ' to: ' + cur_ip)
                gv.last_ip = cur_ip
                if cur_ip != "No IP Settings":
                    # find router, set up upnp port mapping
                    check_and_update_upnp(cur_ip)
                    last_upnp_refresh = gv.now

            if gv.sd['upnp_refresh_rate'] > 0 and \
                   (gv.now-last_upnp_refresh)//60 >= gv.sd['upnp_refresh_rate']:
                check_and_update_upnp(cur_ip)
                last_upnp_refresh = gv.now

        process_actions()
        last_zc = zc
        zc = read_sensor_value('zone_call')
        if zc == None:
            zc = last_zc
            log_event('Failed to read zone_call')
        boiler_md = get_boiler_mode()
        heatpump_md = get_heatpump_mode()
        if gv.sd['mode'] != last_mode: # turn everything off
            log_event('change mode.  Turn off boiler, heatpump, circ_pump')
            if boiler_md != 'none':
                set_boiler_mode('none')
            if heatpump_md != 'none':
                set_heatpump_mode('none')
            gv.srvals[circ_pump] = 0
            set_output()
            last_zc = 0 # mark as was off
            last_mode = gv.sd['mode']
            remove_action({'what':'set_valve_change'})
            if gv.sd['mode'] in ['Heatpump Cooling'] or \
                   (gv.sd['mode'] in ['Boiler Only'] and not boiler_through_buffer_tank): # use only return water
                insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':-100})
            else:
                insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':100})

        try:
            temps = read_temps()
            failed_temp_read = 0
            # rather than tracking serial # of thermistors, just assume higher readings are supply
            # and cooler readings are return (if heating) and vice versa if cooling
            min_temp = min(temps)
            max_temp = max(temps)
            if min_temp < 0 or max_temp < 0:
                log_event('Bad min/max temps.  min: ' + str(min_temp) + ' max: ' + str(max_temp))
            if gv.sd['mode'] == 'Heatpump Cooling':
                supply_temp_readings.append(min_temp)
                return_temp_readings.append(max_temp)
            else:
                supply_temp_readings.append(max_temp)
                return_temp_readings.append(min_temp)
        except:
            if gv.now - start_time > 120: # let things start up before capturing errors
                failed_temp_read += 1
                if failed_temp_read < 300:
                    if failed_temp_read % 10 == 1: # first exception should get cleared by reconnect and is normal
                        log_event('cant read temperatures.  Failcount: ' + str(failed_temp_read))
                elif failed_temp_read == 300:
                    log_event('TEMPERATURE SENSOR FAILURE')
                    email('Heating', 'TEMPERATURE SENSOR FAILURE')
                elif failed_temp_read % 300 == 0:
                    log_event('Ongoing temp failure.  Failcount: ' + str(failed_temp_read))

        if len(supply_temp_readings) > 5:
            supply_temp_readings.pop(0)
        if len(return_temp_readings) > 5:
            return_temp_readings.pop(0)
        try:
            ave_supply_temp = sum(supply_temp_readings)/float(len(supply_temp_readings))
            if ave_supply_temp < 0:
                log_event('Bad ave_supply_temp: ' + str(ave_supply_temp))
        except ZeroDivisionError:
            ave_supply_temp = -1
        try:
            ave_return_temp = sum(return_temp_readings)/float(len(return_temp_readings))
            if ave_return_temp < 0:
                log_event('Bad ave_return_temp: ' + str(ave_return_temp))
        except ZeroDivisionError:
            ave_return_temp = -1

        if gv.now - last_temp_log >= 600:
            last_temp_log = gv.now
            ast_c = ave_supply_temp
            ast_f = ast_c*1.8 + 32
            art_c = ave_return_temp
            art_f = art_c*1.8 + 32
            dew_f = dew*1.8 + 32
            log_event('supply temp: ' + "{0:.2f}".format(ast_c) + 'C ' + "{0:.2f}".format(ast_f) + 'F' + '; ' + \
                      'return temp: ' + "{0:.2f}".format(art_c) + 'C ' + "{0:.2f}".format(art_f) + 'F' + '; ' + \
                      'dewpoint: ' + "{0:.2f}".format(dew) + 'C ' + "{0:.2f}".format(dew_f) + 'F')

        if zc != last_zc: # change in zone call
            if gv.sd['mode'] == 'None':
                zc = last_zc # dont do anything in terms of moving water
            elif last_zc == 0: # was off, now on?
                supply_temp_readings = []
                return_temp_readings = []
                last_ave_supply_temp = None
                log_event('zone call on; enable circ pump')
                gv.srvals[circ_pump] = 1
                set_output()
                # for cooling or boiler operation start with only return water.  For heating, only buffer tank water
                if gv.sd['mode'] in ['Heatpump Cooling']:
                    remove_action({'what':'set_valve_change'})
                    insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':-100})
                    one_way_cooling_adjustments = 0
                elif not boiler_through_buffer_tank:
                    remove_action({'what':'set_valve_change'})
                    if gv.sd['mode'] in ['Boiler Only']:
                        insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':-100})
                    else:
                        insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':100})
 
                if gv.sd['mode'] in ['Boiler Only', 'Boiler and Heatpump']:
                    log_event('zone call on; enable boiler')
                    set_boiler_mode('heating')
            else: # was on, now off
                msg_start = 'zone call off; '
                gv.srvals[circ_pump] = 0
                set_output()
                if boiler_md == 'heating' and \
                        gv.sd['mode'] in ['Boiler Only', 'Boiler and Heatpump', 'Heatpump then Boiler']:
                    msg_start += 'disable boiler; '
                    set_boiler_mode('none')
                if heatpump_md == 'heating' and \
                        gv.sd['mode'] in ['Boiler and Heatpump', 'Heatpump then Boiler', 'Heatpump Only']:
                    msg_start += 'disable heatpump; '
                    set_heatpump_mode('none')
                if heatpump_md == 'cooling' and gv.sd['mode'] == 'Heatpump Cooling':
                    msg_start += 'disable heatpump; '
                    set_heatpump_mode('none')
                log_event(msg_start + 'supply: ' + "{0:.2f}".format(ave_supply_temp) + ' return: ' + "{0:.2f}".format(ave_return_temp))
        elif zc == 1: # still on?
            if len(supply_temp_readings) < 5 or len(return_temp_readings) < 5:
                continue
            if gv.sd['mode'] in ['Heatpump Only', 'Boiler and Heatpump', 'Heatpump then Boiler']:
                if ave_supply_temp < heatpump_setpoint_h-5:
                    if heatpump_md == 'none' and gv.now-last_heatpump_off > 3*60:
#                        log_event('reenable heatpump; supply: ' + str(ave_supply_temp))
                        set_heatpump_mode('heating')
                if ave_supply_temp > heatpump_setpoint_h-2:
                    if heatpump_md == 'heating' and gv.now-last_heatpump_on > 3*60:
#                        log_event('disable heatpump; supply: ' + str(ave_supply_temp))
                        set_heatpump_mode('none')
            if gv.sd['mode'] == 'Heatpump then Boiler':
                if ave_supply_temp < heatpump_setpoint_h-13 or ave_return_temp < 33:
                    if boiler_md == 'none' and gv.now-last_boiler_off > 2*60 and \
                             gv.now-last_heatpump_on > 3*60:
                        log_event('reenable boiler; supply: ' + "{0:.2f}".format(ave_supply_temp) + ' return: ' + "{0:.2f}".format(ave_return_temp))
                        # Use only boiler for a while
                        if not boiler_through_buffer_tank:
                            remove_action({'what':'set_valve_change'})
                            insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':-100})
                        set_heatpump_mode('none')
                        set_boiler_mode('heating')
                        insert_action(gv.now+45*60, {'what':'set_boiler_mode', 'mode':'none'})
            if gv.sd['mode'] == 'Heatpump Cooling' and gv.now-last_dewpoint_adjust >= 60:
                 dewpoint_margin = 1.5
                 target = max(dew+dewpoint_margin+1, 10.)
                 adjust = 0
                 if ave_supply_temp <= dew+dewpoint_margin and one_way_cooling_adjustments > min_cooling_adjustments:
                     remove_action({'what':'set_valve_change'})
                     insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':-100})
                     msg = 'Close valve; avoid condensation'
                     log_event(msg + ': ' + "{0:.2f}".format(dew) + 'C target: ' + "{0:.2f}".format(target) + 'C supply: ' + "{0:.2f}".format(ave_supply_temp) + 'C')
                     last_dewpoint_adjust = gv.now
                     last_ave_supply_temp = None
                     one_way_cooling_adjustments = min_cooling_adjustments
                 elif target < ave_supply_temp - .1:
                     remove_action({'what':'set_valve_change'})
                     adjust = 0
                     if one_way_cooling_adjustments < 0:
                         one_way_cooling_adjustments = 0
                         adjust += 2
                     adjust += cooling_adjust_per_degree * (ave_supply_temp - target)
                     if last_ave_supply_temp != None and last_ave_supply_temp - ave_supply_temp > 0 and \
                            gv.now-last_dewpoint_adjust <= 180: # already going down?  Be patient
                         new_adjust = adjust - 2*cooling_adjust_per_degree * (last_ave_supply_temp - ave_supply_temp)
                         msg = 'already going down'
                         gv.logger.debug(msg + ': ' + \
                                         ' adjust: ' + "{0:.2f}".format(adjust) + \
                                         ' new_adjust: ' + "{0:.2f}".format(new_adjust))
                         adjust = max(0, new_adjust)
                     adjust = int(round(adjust))
                     msg = 'Ignoring request for more buffer tank water'
                     if adjust > 0 and one_way_cooling_adjustments < max_cooling_adjustments:
                         insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':adjust})
                         last_dewpoint_adjust = gv.now
                         last_ave_supply_temp = ave_supply_temp
                         msg = 'More buffer tank water'
                 elif target > ave_supply_temp + .1:
                     remove_action({'what':'set_valve_change'})
                     adjust = 0
                     if one_way_cooling_adjustments > 0:
                         one_way_cooling_adjustments = 0
                         adjust -= 2
                     adjust += cooling_adjust_per_degree * (ave_supply_temp - target)
                     if last_ave_supply_temp != None and last_ave_supply_temp - ave_supply_temp < 0 and \
                            gv.now-last_dewpoint_adjust <= 180: # already going up?  Be patient
                         new_adjust = adjust - 2*cooling_adjust_per_degree * (last_ave_supply_temp - ave_supply_temp)
                         msg = 'already going up'
                         gv.logger.debug(msg + ': ' + \
                                         ' adjust: ' + "{0:.2f}".format(adjust) + \
                                         ' new_adjust: ' + "{0:.2f}".format(new_adjust))
                         adjust = min(0, new_adjust)
                     adjust = int(round(adjust))
                     msg = 'Ignoring request for more return water'
                     if adjust < 0 and one_way_cooling_adjustments > min_cooling_adjustments:
                         insert_action(gv.now, {'what':'set_valve_change', 'valve_change_percent':adjust})
                         last_dewpoint_adjust = gv.now
                         last_ave_supply_temp = ave_supply_temp
                         msg = 'More return water'
                 else:
                     msg = 'Not changing valve'
                 gv.logger.debug(msg + ': ' + str(one_way_cooling_adjustments) + \
                                 ' dew: ' + "{0:.2f}".format(dew) + 'C' + \
                                 ' target: ' + "{0:.2f}".format(target) + 'C' + \
                                 ' supply: ' + "{0:.2f}".format(ave_supply_temp) + 'C')
                 if (adjust > 0 and one_way_cooling_adjustments < max_cooling_adjustments) or \
                        (adjust < 0 and one_way_cooling_adjustments > min_cooling_adjustments):
                     one_way_cooling_adjustments += adjust
Ejemplo n.º 51
0
def timing_loop():
    """ ***** Main timing algorithm. Runs in a separate thread.***** """
    try:
        print(_(u"Starting timing loop") + u"\n")
    except Exception:
        pass
    last_min = 0
    while True:  # infinite loop
        cur_ord = (
            date.today().toordinal() 
        )  # day of year
        if cur_ord > gv.day_ord:
            gv.day_ord = cur_ord
            report_new_day()
        gv.nowt = (
            time.localtime()
        )  # Current time as time struct.  Updated once per second.
        gv.now = timegm(
            gv.nowt
        )  # Current time as timestamp based on local time from the Pi. Updated once per second.
        
        if (
            gv.sd[u"en"]
            and not gv.sd[u"mm"]
            and (not gv.sd[u"bsy"] or not gv.sd[u"seq"])
        ):
            if int(gv.now // 60) != last_min:  # only check programs once a minute
                last_min = int(gv.now // 60)
                extra_adjustment = plugin_adjustment()
                for i, p in enumerate(gv.pd):  # get both index and prog item
                    if prog_match(p) and any(p[u"duration_sec"]):
                        # check each station per boards listed in program up to number of boards in Options
                        for b in range(len(p[u"station_mask"])):
                            for s in range(8):
                                sid = b * 8 + s  # station index
                                if gv.sd[u"mas"] == sid + 1:
                                    continue  # skip, this is master station
                                if (
                                    gv.srvals[sid]
                                    and gv.sd[u"seq"]
                                ):  # skip if currently on and sequential mode
                                    continue

                                # station duration conditionally scaled by "water level"
                                if gv.sd[u"iw"][b] & 1 << s:
                                    duration_adj = 1.0
                                    if gv.sd[u"idd"]:
                                        duration = p[u"duration_sec"][sid]
                                    else:
                                        duration = p[u"duration_sec"][0]
                                else:
                                    duration_adj = (
                                        gv.sd[u"wl"] / 100.0
                                    ) * extra_adjustment
                                    if gv.sd[u"idd"]:
                                        duration = (
                                            p[u"duration_sec"][sid] * duration_adj
                                        )
                                    else:
                                        duration = p[u"duration_sec"][0] * duration_adj
                                    duration = int(round(duration))  # convert to int
                                if (
                                    p[u"station_mask"][b] & 1 << s
                                ):  # if this station is scheduled in this program
                                    gv.rs[sid][2] = duration
                                    gv.rs[sid][3] = i + 1  # program number for scheduling
                                    gv.ps[sid][0] = i + 1  # program number for display
                                    gv.ps[sid][1] = duration
                        schedule_stations(p[u"station_mask"])  # turns on gv.sd["bsy"]

        if gv.sd[u"bsy"]:
            for b in range(gv.sd[u"nbrd"]):  # Check each station once a second
                for s in range(8):
                    sid = b * 8 + s  # station index
                    if gv.srvals[sid]:  # if this station is on
                        if gv.now >= gv.rs[sid][1]:  # check if time is up
                            gv.srvals[sid] = 0
                            set_output()
                            gv.sbits[b] &= ~(1 << s)
                            if gv.sd[u"mas"] != sid + 1:  # if not master, fill out log
                                gv.ps[sid] = [0, 0]
                                gv.lrun[0] = sid
                                gv.lrun[1] = gv.rs[sid][3]
                                gv.lrun[2] = int(gv.now - gv.rs[sid][0])
                                print(u"logging @ time check")
                                log_run()
                                report_station_completed(sid + 1)
                                gv.pon = None  # Program has ended
                            gv.rs[sid] = [0, 0, 0, 0]
                    else:  # if this station is not yet on
                        if gv.rs[sid][0] <= gv.now < gv.rs[sid][1]:
                            if gv.sd[u"mas"] != sid + 1:  # if not master
                                gv.srvals[sid] = 1  # station is turned on
                                set_output()
                                gv.sbits[b] |= 1 << s  # Set display to on
                                gv.ps[sid][0] = gv.rs[sid][3]
                                gv.ps[sid][1] = gv.rs[sid][2]
                                if gv.sd[u"mas"] and gv.sd[u"mo"][b] & (
                                    1 << s
                                ):  # Master settings
                                    masid = gv.sd[u"mas"] - 1  # master index
                                    gv.rs[masid][0] = gv.rs[sid][0] + gv.sd[u"mton"]
                                    gv.rs[masid][1] = gv.rs[sid][1] + gv.sd[u"mtoff"]
                                    gv.rs[masid][3] = gv.rs[sid][3]
                            elif gv.sd[u"mas"] == sid + 1: # if this is master
                                masid = gv.sd[u"mas"] - 1  # master index
                                gv.sbits[b] |= 1 << sid
                                gv.srvals[masid] = 1
                                set_output()

            for s in range(gv.sd[u"nst"]):
                if gv.rs[s][1]:  # if any station is scheduled
                    program_running = True
                    gv.pon = gv.rs[s][3]  # Store number of running program
                    break
                program_running = False
                gv.pon = None

            if program_running:
                if (
                    gv.sd[u"urs"] and gv.sd[u"rs"]
                ):  #  Stop stations if use rain sensor and rain detected.
                    stop_onrain()  # Clear schedule for stations that do not ignore rain.
                for sid in range(len(gv.rs)):  # loop through program schedule (gv.ps)
                    if gv.rs[sid][2] == 0:  # skip stations with no duration
                        continue
                    if gv.srvals[
                        sid
                    ]:  # If station is on, decrement time remaining display
                        if gv.ps[sid][1] > 0:  # if time is left
                            gv.ps[sid][1] -= 1

            if not program_running:
                gv.srvals = [0] * (gv.sd[u"nst"])
                set_output()
                gv.sbits = [0] * (gv.sd[u"nbrd"] + 1)
                gv.ps = []
                for i in range(gv.sd[u"nst"]):
                    gv.ps.append([0, 0])
                gv.rs = []
                for i in range(gv.sd[u"nst"]):
                    gv.rs.append([0, 0, 0, 0])
                gv.sd[u"bsy"] = 0

            if gv.sd[u"mas"] and (  #  master is defined
                gv.sd[u"mm"] or not gv.sd[u"seq"]
            ):  #  manual or concurrent mode.
                for b in range(gv.sd[u"nbrd"]):  # set stop time for master
                    for s in range(8):
                        sid = b * 8 + s
                        if (
                            gv.sd[u"mas"] != sid + 1  # if not master
                            and gv.srvals[sid]  #  station is on
                            and gv.rs[sid][1]
                            >= gv.now  #  station has a stop time >= now
                            and gv.sd[u"mo"][b] & (1 << s)  #  station activates master
                        ):
                            gv.rs[gv.sd[u"mas"] - 1][1] = (
                                gv.rs[sid][1] + gv.sd[u"mtoff"]
                            )  # set to future...
                            break  # first found will do

        if gv.sd[u"urs"]:
            check_rain()  # in helpers.py

        if gv.sd[u"rd"] and gv.now >= gv.sd[u"rdst"]:  # Check if rain delay time is up
            gv.sd[u"rd"] = 0
            gv.sd[u"rdst"] = 0  # Rain delay stop time
            jsave(gv.sd, u"sd")

        time.sleep(1)
Ejemplo n.º 52
0
    gv.plugin_menu.sort(key=lambda entry: entry[0])

    #  Keep plugin manager at top of menu
    try:
        for i, item in enumerate(gv.plugin_menu):
            if u"/plugins" in item:
                gv.plugin_menu.pop(i)
    except Exception as e:
        print(u"Creating plugins menu", e)
        pass
    tl = Thread(target=timing_loop)
    tl.daemon = True
    tl.start()

    if gv.use_gpio_pins:
        set_output()

    app.notfound = lambda: web.seeother(u"/")

    ###########################
    #### For HTTPS (SSL):  ####

    if gv.sd["htp"] == 443:
        try:
            from cheroot.server import HTTPServer
            from cheroot.ssl.builtin import BuiltinSSLAdapter
            HTTPServer.ssl_adapter = BuiltinSSLAdapter(
                certificate='/usr/lib/ssl/certs/SIP.crt',
                private_key='/usr/lib/ssl/private/SIP.key'
            )
        except IOError as e:
Ejemplo n.º 53
0
    def GET(self):
        qdict = web.input()
        if 'opw' in qdict and qdict['opw'] != "":
            try:
                if password_hash(qdict['opw'], gv.sd['salt']) == gv.sd['password']:
                    if qdict['npw'] == "":
                        raise web.seeother('/vo?errorCode=pw_blank')
                    elif qdict['cpw'] != '' and qdict['cpw'] == qdict['npw']:
                        gv.sd['salt'] = password_salt()  # Make a new salt
                        gv.sd['password'] = password_hash(qdict['npw'], gv.sd['salt'])
                    else:
                        raise web.seeother('/vo?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/vo?errorCode=pw_wrong')
            except KeyError:
                pass

        try:
            if 'oipas' in qdict and (qdict['oipas'] == 'on' or qdict['oipas'] == '1'):
                gv.sd['ipas'] = 1
            else:
                gv.sd['ipas'] = 0
        except KeyError:
            pass

        if 'oname' in qdict:
            gv.sd['name'] = qdict['oname']
        if 'oloc' in qdict:
            gv.sd['loc'] = qdict['oloc']
        if 'otz' in qdict:
            gv.sd['tz'] = int(qdict['otz'])
        try:
            if 'otf' in qdict and (qdict['otf'] == 'on' or qdict['otf'] == '1'):
                gv.sd['tf'] = 1
            else:
                gv.sd['tf'] = 0
        except KeyError:
            pass

        if int(qdict['onbrd']) + 1 != gv.sd['nbrd']:
            self.update_scount(qdict)
        gv.sd['nbrd'] = int(qdict['onbrd']) + 1

        gv.sd['nst'] = gv.sd['nbrd'] * 8
        if 'ohtp' in qdict:
            gv.sd['htp'] = int(qdict['ohtp'])
        if 'osdt' in qdict:
            gv.sd['sdt'] = int(qdict['osdt'])
        if 'olang' in qdict:
           gv.sd['lang'] = qdict['olang']
        if 'omas' in qdict:
            gv.sd['mas'] = int(qdict['omas'])
        if 'omton' in qdict:
            gv.sd['mton'] = int(qdict['omton'])
        if 'omtoff' in qdict:
            gv.sd['mtoff'] = int(qdict['omtoff'])
        if 'owl' in qdict:
            gv.sd['wl'] = int(qdict['owl'])

        if 'ours' in qdict and (qdict['ours'] == 'on' or qdict['ours'] == '1'):
            gv.sd['urs'] = 1
        else:
            gv.sd['urs'] = 0

        if 'oseq' in qdict and (qdict['oseq'] == 'on' or qdict['oseq'] == '1'):
            gv.sd['seq'] = 1
        else:
            gv.sd['seq'] = 0

        if 'orst' in qdict and (qdict['orst'] == 'on' or qdict['orst'] == '1'):
            gv.sd['rst'] = 1
        else:
            gv.sd['rst'] = 0

        if 'olg' in qdict and (qdict['olg'] == 'on' or qdict['olg'] == '1'):
            gv.sd['lg'] = 1
        else:
            gv.sd['lg'] = 0

        if 'olr' in qdict:
            gv.sd['lr'] = int(qdict['olr'])

        jsave(gv.sd, 'sd')
        report_option_change()
        if 'rbt' in qdict and qdict['rbt'] == '1':
            gv.srvals = [0] * (gv.sd['nst'])
            set_output()
            report_rebooted()
#            os.system('reboot')
            reboot()

        if 'rstrt' in qdict and qdict['rstrt'] == '1':
#            restart(2)
            raise web.seeother('/restart')
        raise web.seeother('/')
Ejemplo n.º 54
0
def timing_loop():
    """ ***** Main timing algorithm. Runs in a separate thread.***** """
    try:
        print _('Starting timing loop') + '\n'
    except Exception:
        pass
    last_min = 0
    while True:  # infinite loop
        gv.now = timegm(
            time.localtime()
        )  # Current time as timestamp based on local time from the Pi. updated once per second.
        if gv.sd['en'] and not gv.sd['mm'] and (not gv.sd['bsy']
                                                or not gv.sd['seq']):
            if gv.now / 60 != last_min:  # only check programs once a minute
                last_min = gv.now / 60
                extra_adjustment = plugin_adjustment()
                for i, p in enumerate(gv.pd):  # get both index and prog item
                    # check if program time matches current time, is active, and has a duration
                    if prog_match(p) and p[0] and p[6]:
                        duration = p[6] * gv.sd[
                            'wl'] / 100 * extra_adjustment  # program duration scaled by "water level"
                        # check each station for boards listed in program up to number of boards in Options
                        for b in range(len(p[7:7 + gv.sd['nbrd']])):
                            for s in range(8):
                                sid = b * 8 + s  # station index
                                if sid + 1 == gv.sd['mas']:
                                    continue  # skip if this is master station
                                if gv.srvals[sid]:  # skip if currently on
                                    continue

                                if p[7 +
                                     b] & 1 << s:  # if this station is scheduled in this program
                                    if gv.sd['seq']:  # sequential mode
                                        gv.rs[sid][2] = duration
                                        gv.rs[sid][
                                            3] = i + 1  # store program number for scheduling
                                        gv.ps[sid][
                                            0] = i + 1  # store program number for display
                                        gv.ps[sid][1] = duration
                                    else:  # concurrent mode
                                        # If duration is shortter than any already set for this station
                                        if duration < gv.rs[sid][2]:
                                            continue
                                        else:
                                            gv.rs[sid][2] = duration
                                            gv.rs[sid][
                                                3] = i + 1  # store program number
                                            gv.ps[sid][
                                                0] = i + 1  # store program number for display
                                            gv.ps[sid][1] = duration
                        schedule_stations(
                            p[7:7 + gv.sd['nbrd']])  # turns on gv.sd['bsy']

        if gv.sd['bsy']:
            for b in range(gv.sd['nbrd']):  # Check each station once a second
                for s in range(8):
                    sid = b * 8 + s  # station index
                    if gv.srvals[sid]:  # if this station is on
                        if gv.now >= gv.rs[sid][1]:  # check if time is up
                            gv.srvals[sid] = 0
                            set_output()
                            gv.sbits[b] &= ~(1 << s)
                            if gv.sd['mas'] - 1 != sid:  # if not master, fill out log
                                gv.ps[sid] = [0, 0]
                                gv.lrun[0] = sid
                                gv.lrun[1] = gv.rs[sid][3]
                                gv.lrun[2] = int(gv.now - gv.rs[sid][0])
                                gv.lrun[3] = gv.now
                                log_run()
                                gv.pon = None  # Program has ended
                            gv.rs[sid] = [0, 0, 0, 0]
                    else:  # if this station is not yet on
                        if gv.rs[sid][0] <= gv.now < gv.rs[sid][1]:
                            if gv.sd['mas'] - 1 != sid:  # if not master
                                gv.srvals[sid] = 1  # station is turned on
                                set_output()
                                gv.sbits[b] |= 1 << s  # Set display to on
                                gv.ps[sid][0] = gv.rs[sid][3]
                                gv.ps[sid][1] = gv.rs[sid][2]
                                if gv.sd['mas'] and gv.sd['mo'][b] & 1 << (
                                        s - (s / 8) * 80):  # Master settings
                                    masid = gv.sd['mas'] - 1  # master index
                                    gv.rs[masid][
                                        0] = gv.rs[sid][0] + gv.sd['mton']
                                    gv.rs[masid][
                                        1] = gv.rs[sid][1] + gv.sd['mtoff']
                                    gv.rs[masid][3] = gv.rs[sid][3]
                            elif gv.sd['mas'] == sid + 1:
                                gv.sbits[b] |= 1 << sid  # (gv.sd['mas'] - 1)
                                gv.srvals[masid] = 1
                                set_output()

            for s in range(gv.sd['nst']):
                if gv.rs[s][1]:  # if any station is scheduled
                    program_running = True
                    gv.pon = gv.rs[s][3]  # Store number of running program
                    break
                program_running = False
                gv.pon = None

            if program_running:
                if gv.sd['urs'] and gv.sd[
                        'rs']:  # Stop stations if use rain sensor and rain detected.
                    stop_onrain(
                    )  # Clear schedule for stations that do not ignore rain.
                for idx in range(len(
                        gv.rs)):  # loop through program schedule (gv.ps)
                    if gv.rs[idx][2] == 0:  # skip stations with no duration
                        continue
                    if gv.srvals[
                            idx]:  # If station is on, decrement time remaining display
                        gv.ps[idx][1] -= 1

            if not program_running:
                gv.srvals = [0] * (gv.sd['nst'])
                set_output()
                gv.sbits = [0] * (gv.sd['nbrd'] + 1)
                gv.ps = []
                for i in range(gv.sd['nst']):
                    gv.ps.append([0, 0])
                gv.rs = []
                for i in range(gv.sd['nst']):
                    gv.rs.append([0, 0, 0, 0])
                gv.sd['bsy'] = 0

            if gv.sd['mas'] and (
                    gv.sd['mm'] or not gv.sd['seq']
            ):  # handle master for maual or concurrent mode.
                mval = 0
                for sid in range(gv.sd['nst']):
                    bid = sid / 8
                    s = sid - bid * 8
                    if gv.sd['mas'] != sid + 1 and (gv.srvals[sid] and
                                                    gv.sd['mo'][bid] & 1 << s):
                        mval = 1
                        break
                if not mval:
                    gv.rs[gv.sd['mas'] - 1][1] = gv.now  # turn off master

        if gv.sd['urs']:
            check_rain()  # in helpers.py

        if gv.sd['rd'] and gv.now >= gv.sd[
                'rdst']:  # Check of rain delay time is up
            gv.sd['rd'] = 0
            gv.sd['rdst'] = 0  # Rain delay stop time
            jsave(gv.sd, 'sd')
        time.sleep(1)