def on_message(client, msg): "Callback when MQTT message is received." if not gv.sd['en']: # check operation status return num_brds = gv.sd['nbrd'] num_sta = num_brds * 8 try: cmd = json.loads(msg.payload) except ValueError as e: print("MQTT Schedule could not decode command: ", msg.payload, e) return if type(cmd) is list: if len(cmd) < num_sta: print( "MQTT schedule, not enough stations specified, assuming first {} of {}" .format(len(cmd), num_sta)) rovals = cmd + ([0] * (num_sta - len(cmd))) elif len(cmd) > num_sta: print( "MQTT schedule, too many stations specified, truncating to {}". format(num_sta)) rovals = cmd[0:num_sta] else: rovals = cmd elif type(cmd) is dict: rovals = [0] * num_sta for k, v in cmd.items(): if k not in gv.snames: print("MQTT schedule, no station named:", k) else: rovals[gv.snames.index(k)] = v else: print("MQTT schedule unexpected command: ", msg.payload) return if any(rovals): print("MQTT schedule:", rovals) gv.rovals = rovals stations = [0] * num_brds gv.ps = [] # program schedule (for display) gv.rs = [] # run schedule for i in range(gv.sd['nst']): gv.ps.append([0, 0]) gv.rs.append([0, 0, 0, 0]) for i, v in enumerate(gv.rovals): if v: # if this element has a value gv.rs[i][0] = gv.now gv.rs[i][2] = v gv.rs[i][3] = 98 gv.ps[i][0] = 98 gv.ps[i][1] = v stations[i / 8] += 2**(i % 8) schedule_stations(stations)
def on_message(client, msg): "Callback when MQTT message is received." if not gv.sd['en']: # check operation status return num_brds = gv.sd['nbrd'] num_sta = num_brds * 8 try: cmd = json.loads(msg.payload) except ValueError as e: print("MQTT Schedule could not decode command: ", msg.payload, e) return if type(cmd) is list: if len(cmd) < num_sta: print("MQTT schedule, not enough stations specified, assuming first {} of {}".format(len(cmd), num_sta)) rovals = cmd + ([0] * (num_sta - len(cmd))) elif len(cmd) > num_sta: print("MQTT schedule, too many stations specified, truncating to {}".format(num_sta)) rovals = cmd[0:num_sta] else: rovals = cmd elif type(cmd) is dict: rovals = [0] * num_sta for k, v in cmd.items(): if k not in gv.snames: print("MQTT schedule, no station named:", k) else: rovals[gv.snames.index(k)] = v else: print("MQTT schedule unexpected command: ", msg.payload) return if any(rovals): print("MQTT schedule:", rovals) gv.rovals = rovals stations = [0] * num_brds gv.ps = [] # program schedule (for display) gv.rs = [] # run schedule for i in range(gv.sd['nst']): gv.ps.append([0, 0]) gv.rs.append([0, 0, 0, 0]) for i, v in enumerate(gv.rovals): if v: # if this element has a value gv.rs[i][0] = gv.now gv.rs[i][2] = v gv.rs[i][3] = 98 gv.ps[i][0] = 98 gv.ps[i][1] = v stations[i / 8] += 2 ** (i % 8) schedule_stations(stations)
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)
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)
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)
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)
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)