def _botCmd_enable(self, bot, update): chat_id = update.message.chat_id if chat_id in self.currentChats: txt = "{} System <b>ON</b>".format(gv.sd[u'name']) gv.sd['en'] = 1 # enable system SIP gv.sd['mm'] = 0 # Disable Manual Mode jsave(gv.sd, 'sd') # save en = 1 else: txt = "I'm sorry Dave I'm afraid I can't do that." bot.sendMessage(chat_id, text=txt, parse_mode='HTML')
def _botCmd_enable(self, bot, update): chat_id = update.message.chat_id if chat_id in self.currentChats: txt = u"{} System <b>ON</b>".format(gv.sd[u"name"]) gv.sd[u"en"] = 1 # enable system SIP gv.sd[u"mm"] = 0 # Disable Manual Mode jsave(gv.sd, u"sd") # save en = 1 else: txt = u"I'm sorry Dave I'm afraid I can't do that." bot.sendMessage(chat_id, text=txt, parse_mode=u"HTML")
def _botCmd_disable(self, bot, update): chat_id = update.message.chat_id if chat_id in self.currentChats: txt = "{} System <b>OFF</b>".format(gv.sd[u'name']) gv.sd['en'] = 0 # disable system SIP jsave(gv.sd, 'sd') # save en = 0 stop_stations() else: txt = "I'm sorry Dave I'm afraid I can't do that." bot.sendMessage(chat_id, text=txt, parse_mode='HTML')
def GET(self): qdict = web.input() print(u"qdict: ", qdict) for i in range(gv.sd[u"nbrd"]): if u"sh" + str(i) in qdict: try: gv.sd[u"show"][i] = int(qdict[u"sh" + str(i)]) except ValueError: gv.sd[u"show"][i] = 255 if "d" + str(i) in qdict: try: gv.sd[u"show"][i] = ~int(qdict[u"d" + str(i)]) & 255 except ValueError: gv.sd[u"show"][i] = 255 jsave(gv.sd, u"sd") raise web.seeother(u"/")
def GET(self): qdict = web.input() print 'qdict: ', qdict for i in range(gv.sd['nbrd']): if 'sh' + str(i) in qdict: try: gv.sd['show'][i] = int(qdict['sh' + str(i)]) except ValueError: gv.sd['show'][i] = 255 if 'd' + str(i) in qdict: try: gv.sd['show'][i] = ~int(qdict['d' + str(i)])&255 except ValueError: gv.sd['show'][i] = 255 jsave(gv.sd, 'sd') raise web.seeother('/')
def load_substations(): """Load the substation data from file.""" subdesco = {'programs':[],'sd':{},'wlog':[], 'elog':[], 'slog':[], 'evlog':[], 'snames':[], 'snotes':[]} subinfoo = {'subinfo':[{'name':'','ip':'localhost','port':gv.sd['htp'],'proxy':'','status':'unknown','last_join':0}]} # hold position 0 vacant try: with open('./data/substations.json', 'r') as f: gv.plugin_data['su'] = subinfoo.copy() # gv.plugin_data['su'] = json.load(f) gv.plugin_data['su']['subdesc'] = [subdesco.copy()] # hold position 0 vacant for i in range(1,len(gv.plugin_data['su']['subinfo'])): gv.plugin_data['su']['subdesc'].append(subdesco.copy()) except IOError: gv.plugin_data['su'] = subinfoo.copy() gv.plugin_data['su']['subdesc'] = [subdesco.copy()] # hold position 0 vacant jsave(subinfoo, 'substations')
def GET(self): qdict = web.input() head = '' if 'head' not in qdict else qdict['head'] cont = '' if 'continuation' not in qdict else qdict['continuation'] subid = 0 if 'substation' not in qdict else int(qdict['substation']) if 0 < subid < len(gv.plugin_data['su']['subinfo']): gv.logger.info('delete_substation: Deleting substation: ' + gv.plugin_data['su']['subinfo'][subid]['name']) del gv.plugin_data['su']['subinfo'][subid] del gv.plugin_data['su']['subdesc'][subid] if subid == gv.substation_index: if len(gv.plugin_data['su']['subinfo']) > 1: gv.substation = gv.plugin_data['su']['subinfo'][1]['name'] gv.substation_index = 1 else: gv.substation = '' gv.substation_index = 0 if 'te' in gv.plugin_data and 'tesubstatus' in gv.plugin_data['te']: del gv.plugin_data['te']['tesubstatus'][subid] jsave(gv.plugin_data['te'], 'text_email') su_strip = gv.plugin_data['su'].copy() del su_strip['subdesc'] # dont save active data jsave(su_strip, 'substations') raise web.seeother('/suslv?head='+head+'&continuation='+cont)
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 sms_check(self): """Control and processing SMS""" data = get_sms_options() # Load data from json file tels = data['tels'] comm1 = data['txt1'] comm2 = data['txt2'] comm3 = data['txt3'] comm4 = data['txt4'] comm5 = data['txt5'] comm6 = data['txt6'] comm7 = data['txt7'] sm = gammu.StateMachine() sm.ReadConfig() try: sm.Init() print "Checking SMS..." except: print "Error: SMS modem fault" status = sm.GetSMSStatus() remain = status['SIMUsed'] + status['PhoneUsed'] + status['TemplatesUsed'] sms = [] start = True while remain > 0: if start: cursms = sm.GetNextSMS(Start=True, Folder=0) start = False else: cursms = sm.GetNextSMS(Location=cursms[0]['Location'], Folder=0) remain = remain - len(cursms) sms.append(cursms) data = gammu.LinkSMS(sms) for x in data: v = gammu.DecodeSMS(x) m = x[0] print '%-15s: %s' % ('Sender', m['Number']) print '%-15s: %s' % ('Date', str(m['DateTime'])) print '%-15s: %s' % ('State', m['State']) print '%-15s: %s' % ('SMS command', m['Text']) if m['Number'] in tels: # If telephone in admin lists self.add_status(time.strftime("%d.%m.%Y at %H:%M:%S", time.localtime(time.time())) + ' SMS from admin') if m['State'] == "UnRead": # If SMS is unread if m['Text'].upper().strip() == comm1.upper(): # If command = comm1 (info - send SMS to admin phone1 and phone2) self.add_status('Command ' + comm1 + ' is processed') # Current Status logline = "Status: " if gv.srvals == [0] * len(gv.srvals): logline += "Idle. " elif gv.sd['mm'] == 1: # manual mode logline += "Manual Mode." for sid in range(len(gv.srvals)): if gv.srvals[sid]: if gv.rs[sid][1] == float('inf'): end_time = 'inf' else: end_time = time.strftime('%m-%d %H:%M', time.gmtime(gv.rs[sid][1])) logline += '\n st: ' + str(sid + 1) + ' dur: ' + end_time logline += "\n" else: logline += "Auto Mode." for sid in range(len(gv.srvals)): if gv.srvals[sid]: if gv.rs[sid][1] == float('inf'): end_time = 'inf' else: end_time = time.strftime('%m-%d %H:%M', time.gmtime(gv.rs[sid][1])) logline += '\n st: ' + str(sid + 1 ) + ' dur: ' + end_time logline += "\n" # Last RUN if gv.lrun[1] == 98: pgr = 'Run-once' elif gv.lrun[1] == 99: pgr = 'Manual' else: pgr = str(gv.lrun[1]) start = time.gmtime(gv.now - gv.lrun[2]) if pgr != '0': logline += 'Last RUN: { prg: ' + pgr + ',st: ' + str(gv.lrun[0]) + ',dur: ' + timestr( gv.lrun[2]) + ',start: ' + time.strftime("%H:%M - %m-%d", start) + '}' else: logline += ' Last program none' # revision = ' Rev: ' + gv.ver_date datastr = ('On ' + time.strftime("%d.%m.%Y at %H:%M", time.localtime( time.time())) + '. ' + logline) msgs=[""] idx = 0 for line in datastr.splitlines(): if (len(msgs[idx]) + len(line)) < 140: msgs[idx] += line + "\n" else: msgs[idx] += "{continues....}" idx += 1 msgs.append(line) for txt in msgs: message = { 'Text': txt, 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm1 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) self.add_status('SMS text: ' + datastr) sm.DeleteSMS(m['Folder'], m['Location']) # SMS deleted self.add_status('Received SMS was deleted') self.add_status('Command ' + comm2 + ' is processed') stop_stations() time.sleep(3) gv.sd['en'] = 0 # disable system SIP jsave(gv.sd, 'sd') # save en = 0 message = { 'Text': 'Command: ' + comm2 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm2 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted') elif m['Text'].upper().strip() == comm3.upper(): # If command = comm3 (start - system sip on) self.add_status('Command ' + comm3 + ' is processed') gv.sd['en'] = 1 # enable system SIP stop_stations() gv.sd['mm'] = 0 # Put in auto mode jsave(gv.sd, 'sd') # save en = 1 message = { 'Text': 'Command: ' + comm3 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm3 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted') elif m['Text'].upper().strip() == comm4.upper(): # If command = comm4 (reboot system) self.add_status('Command ' + comm4 + ' is processed') message = { 'Text': 'Command: ' + comm4 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm4 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted and system is now reboot') self._sleep(10) reboot() # restart linux system elif m['Text'].upper().strip() == comm5.upper(): # If command = comm5 (poweroff system) self.add_status('Command ' + comm5 + ' is processed') message = { 'Text': 'Command: ' + comm5 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm5 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted and system is now poweroff') self._sleep(10) poweroff() # poweroff linux system elif m['Text'].upper().strip() == comm6.upper(): # If command = comm6 (update sip system) self.add_status('Command ' + comm6 + ' is processed') message = { 'Text': 'Command: ' + comm6 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm6 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) try: from plugins.system_update import perform_update perform_update() self.add_status('Received SMS was deleted, update was performed and program will restart') except ImportError: self.add_status('Received SMS was deleted, but could not perform update') sm.DeleteSMS(m['Folder'], m['Location']) elif m['Text'].strip().split()[0].upper() == comm7.upper(): # If command = comm7 (manual mode) self.add_status('Command ' + comm7 + ' is processed') message = "" command = m['Text'].strip().split()[1].upper() if (gv.sd['en'] == 0 or gv.sd['mm'] == 0 ) and command != "ON": message = { 'Text': 'Command: ' + comm7 + ' cannot continue, enable manual mode first with: ' +comm7+ ' on', 'SMSC': {'Location': 1}, 'Number': m['Number'], } elif command == "ON": # enable manual mode stop_stations() gv.sd['en'] = 1 gv.sd['mm'] = 1 jsave(gv.sd, 'sd') message = { 'Text': 'Command: ' + comm7 + ' manual mode enabled', 'SMSC': {'Location': 1}, 'Number': m['Number'], } else : # check the correct formatting # should be a pair of int separated by comma stations_duration = [0] * len(gv.srvals) try: for c in m['Text'].split()[1:]: station,duration = c.split(',') if not (0 < (int(station) -1) < len(stations_duration)): # out of range raise ValueError("Out of Range station ID") stations_duration[int(station) - 1 ] = int(duration)*60 except ValueError: message = { 'Text': 'Command: ' + comm7 + ' cannot continue, wrong command formatting, should be ' 'station,duration (in minutes)\n Example: ' + comm7 + ' 2,10 3,10', 'SMSC': {'Location': 1}, 'Number': m['Number'], } self.add_status('Command ' + comm7 + ' has formatting errors') if message == "": # logic copied from webpages.get_set_station for sid in range(len(stations_duration)): print "sid: " + str(sid) if sid == gv.sd['mas'] - 1: continue duration = stations_duration[sid] print "duration: " + str(duration) if duration > 0: gv.rs[sid][0] = gv.now # set start time to current time gv.rs[sid][2] = duration gv.rs[sid][1] = gv.rs[sid][0] + duration # stop time = start time + duration gv.rs[sid][3] = 99 # set program index gv.ps[sid][1] = duration gv.sd['bsy'] = 1 elif duration <= 0 and gv.srvals[sid]: # we should stop the running station gv.rs[sid][1] = gv.now time.sleep(1) message = { 'Text': 'Command: ' + comm7 + ' Processed OK ', 'SMSC': {'Location': 1}, 'Number': m['Number'], } self.add_status('Command ' + comm7 + ' Command OK') sm.SendSMS(message) self.add_status( 'Command: ' + comm7 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted') self._sleep(10) else: # If SMS command is not defined sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received command ' + m['Text'] + ' is not defined!') else: # If SMS was read sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted - SMS was read') else: # If telephone number is not admin 1 or admin 2 phone number sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted - SMS was not from admin')
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)
def GET(self): qdict = web.input() try: ddict = json.loads(qdict['data']) except: raise web.unauthorized() validate_remote(ddict) # may raise unauthorized ddict['last_join'] = gv.now ddict['status'] = 'ok' # gv.logger.debug('joining ip: ' + ddict['ip'] + ' name: ' + ddict['name'] + ' proxy: ' + ddict['proxy']) found_slave = 0 for i,d in enumerate(gv.plugin_data['su']['subinfo']): if i == 0: continue if d['name'] == ddict['name']: if d['ip'] != ddict['ip'] or d['port'] != ddict['port'] or d['proxy'] != ddict['proxy']: gv.logger.info('Substation changed address from: ' + \ d['ip'] + ':' + str(d['port']) + ' to: ' + \ ddict['ip'] + ':' + str(ddict['port']) + \ '; proxy from: ' + d['proxy'] + ' to: ' + ddict['proxy']) su_strip = gv.plugin_data['su'].copy() for p in ['ip', 'port', 'proxy']: su_strip['subinfo'][i][p] = ddict[p] del su_strip['subdesc'] # dont save active data jsave(su_strip, 'substations') for p in ['ip', 'port', 'proxy', 'status', 'last_join']: gv.plugin_data['su']['subinfo'][i][p] = ddict[p] found_slave = i break if found_slave == 0: gv.logger.info('join_master adding substation: ' + ddict['name'] + ' at ip: ' + ddict['ip'] + ' proxy: ' + ddict['proxy']) gv.plugin_data['su']['subinfo'].append(ddict) found_slave = len(gv.plugin_data['su']['subinfo']) - 1 if gv.substation == '': gv.substation = ddict['name'] gv.substation_index = found_slave gv.plugin_data['su']['subdesc'].append(gv.plugin_data['su']['subdesc'][0].copy()) su_strip = gv.plugin_data['su'].copy() del su_strip['subdesc'] # dont save active data jsave(su_strip, 'substations') result = {'sd':{}, 'other':{}} web.header('Content-Type', 'application/json') for entry in gv.options: f = entry[2] if f in ['name', 'htp', 'nbrd', 'opw', 'npw', 'cpw', 'external_htp', 'enable_upnp', 'remote_support_port']: continue if len(f) > 2 and (f[0:2] == 'te' or f[0:2] == 'et'): # filter out email and et stuff unless explicitly added below continue result['sd'][f] = gv.sd[f] for f in ['tu', 'password', 'salt', 'wl_et_weather', 'teprogramrun', 'teipchange', 'tepoweron']: result['sd'][f] = gv.sd[f] result['other']['websession'] = web.config._session.user # capture login and logout result['other']['datetime'] = time.strftime("%a %d %b %Y %H:%M:%S", time.localtime()) return json.dumps(result)
def sms_check(self): """Control and processing SMS""" data = get_sms_options() # Load data from json file tel1 = data['tel1'] tel2 = data['tel2'] comm1 = data['txt1'] comm2 = data['txt2'] comm3 = data['txt3'] comm4 = data['txt4'] comm5 = data['txt5'] comm6 = data['txt6'] sm = gammu.StateMachine() sm.ReadConfig() try: sm.Init() print "Checking SMS..." except: print "Error: SMS modem fault" status = sm.GetSMSStatus() remain = status['SIMUsed'] + status['PhoneUsed'] + status['TemplatesUsed'] sms = [] start = True while remain > 0: if start: cursms = sm.GetNextSMS(Start=True, Folder=0) start = False else: cursms = sm.GetNextSMS(Location=cursms[0]['Location'], Folder=0) remain = remain - len(cursms) sms.append(cursms) data = gammu.LinkSMS(sms) for x in data: v = gammu.DecodeSMS(x) m = x[0] print '%-15s: %s' % ('Sender', m['Number']) print '%-15s: %s' % ('Date', str(m['DateTime'])) print '%-15s: %s' % ('State', m['State']) print '%-15s: %s' % ('SMS command', m['Text']) if (m['Number'] == tel1) or (m['Number'] == tel2): # If telephone is admin 1 or admin 2 self.add_status(time.strftime("%d.%m.%Y at %H:%M:%S", time.localtime(time.time())) + ' SMS from admin') if m['State'] == "UnRead": # If SMS is unread if m['Text'] == comm1: # If command = comm1 (info - send SMS to admin phone1 and phone2) self.add_status('Command ' + comm1 + ' is processed') if gv.lrun[1] == 98: pgr = 'Run-once' elif gv.lrun[1] == 99: pgr = 'Manual' else: pgr = str(gv.lrun[1]) start = time.gmtime(gv.now - gv.lrun[2]) if pgr != '0': logline = ' {program: ' + pgr + ',station: ' + str(gv.lrun[0]) + ',duration: ' + timestr( gv.lrun[2]) + ',start: ' + time.strftime("%H:%M:%S - %Y-%m-%d", start) + '}' else: logline = ' Last program none' revision = ' Rev: ' + gv.ver_date datastr = ('On ' + time.strftime("%d.%m.%Y at %H:%M:%S", time.localtime( time.time())) + '. Run time: ' + uptime() + ' IP: ' + get_ip() + logline + revision) message = { 'Text': datastr, 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm1 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) self.add_status('SMS text: ' + datastr) sm.DeleteSMS(m['Folder'], m['Location']) # SMS deleted self.add_status('Received SMS was deleted') elif m['Text'] == comm2: # If command = comm2 (stop - system SIP off) self.add_status('Command ' + comm2 + ' is processed') gv.sd['en'] = 0 # disable system SIP jsave(gv.sd, 'sd') # save en = 0 message = { 'Text': 'Command: ' + comm2 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm2 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted') elif m['Text'] == comm3: # If command = comm3 (start - system SIP on) self.add_status('Command ' + comm3 + ' is processed') gv.sd['en'] = 1 # enable system SIP jsave(gv.sd, 'sd') # save en = 1 message = { 'Text': 'Command: ' + comm3 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm3 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted') elif m['Text'] == comm4: # If command = comm4 (reboot system) self.add_status('Command ' + comm4 + ' is processed') message = { 'Text': 'Command: ' + comm4 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm4 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted and system is now reboot') self._sleep(10) reboot() # restart linux system elif m['Text'] == comm5: # If command = comm5 (poweroff system) self.add_status('Command ' + comm5 + ' is processed') message = { 'Text': 'Command: ' + comm5 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm5 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted and system is now poweroff') self._sleep(10) poweroff() # poweroff linux system elif m['Text'] == comm6: # If command = comm6 (update SIP system) self.add_status('Command ' + comm6 + ' is processed') message = { 'Text': 'Command: ' + comm6 + ' was processed', 'SMSC': {'Location': 1}, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm6 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) try: from plugins.system_update import perform_update perform_update() self.add_status('Received SMS was deleted, update was performed and program will restart') except ImportError: self.add_status('Received SMS was deleted, but could not perform update') sm.DeleteSMS(m['Folder'], m['Location']) else: # If SMS command is not defined sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received command ' + m['Text'] + ' is not defined!') else: # If SMS was read sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted - SMS was read') else: # If telephone number is not admin 1 or admin 2 phone number sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted - SMS was not from admin')
def GET(self): qdict = web.input( ) # Dictionary of values returned as query string from settings page. # print "save_settings: qdict:" # print qdict # for testing # print if 'relay1_ena' not in qdict: controller.settings['relay']['1']['ena'] = 0 else: controller.settings['relay']['1']['ena'] = 1 if 'relay1_pin' in qdict and qdict['relay1_pin'] != '': controller.settings['relay']['1']['pin'] = int(qdict['relay1_pin']) if 'relay1_pol' not in qdict: controller.settings['relay']['1']['pol'] = 0 else: controller.settings['relay']['1']['pol'] = 1 if 'relay1_opa' not in qdict: controller.settings['relay']['1']['prm'] = 0 else: controller.settings['relay']['1']['prm'] = 1 if 'relay1_iad' not in qdict: controller.settings['relay']['1']['typ'] = 0 else: controller.settings['relay']['1']['typ'] = 1 if 'relay2_ena' not in qdict: controller.settings['relay']['2']['ena'] = 0 else: controller.settings['relay']['2']['ena'] = 1 if 'relay2_pin' in qdict and qdict['relay2_pin'] != '': controller.settings['relay']['2']['pin'] = int(qdict['relay2_pin']) if 'relay2_pol' not in qdict: controller.settings['relay']['2']['pol'] = 0 else: controller.settings['relay']['2']['pol'] = 1 if 'relay2_opa' not in qdict: controller.settings['relay']['2']['prm'] = 0 else: controller.settings['relay']['2']['prm'] = 1 if 'relay2_iad' not in qdict: controller.settings['relay']['2']['typ'] = 0 else: controller.settings['relay']['2']['typ'] = 1 if 'sensor1_ena' not in qdict: controller.settings['sensor']['1']['ena'] = 0 else: controller.settings['sensor']['1']['ena'] = 1 if 'sensor1_pin' in qdict and qdict['sensor1_pin'] != '': controller.settings['sensor']['1']['pin'] = int( qdict['sensor1_pin']) if 'sensor1_pud' not in qdict: controller.settings['sensor']['1']['pud'] = 0 else: controller.settings['sensor']['1']['pud'] = 1 if 'sensor2_ena' not in qdict: controller.settings['sensor']['2']['ena'] = 0 else: controller.settings['sensor']['2']['ena'] = 1 if 'sensor2_pin' in qdict and qdict['sensor2_pin'] != '': controller.settings['sensor']['2']['pin'] = int( qdict['sensor2_pin']) if 'sensor2_pud' not in qdict: controller.settings['sensor']['2']['pud'] = 0 else: controller.settings['sensor']['2']['pud'] = 1 if 'mail_en' not in qdict: controller.settings['mail_en'] = 'off' else: controller.settings['mail_en'] = qdict['mail_en'] if 'mail_usr' in qdict and qdict['mail_usr'] != '': controller.settings['mail_usr'] = qdict['mail_usr'] # # note: I recommend you use a burner gmail account, that can # forward notifications on to other emails, or send to # a mobile provider's SMS gateway address, i.e., # [email protected], etc. See this page for a good list: # https://en.wikipedia.org/wiki/SMS_gateway # if 'mail_pwd' in qdict and qdict['mail_pwd'] != '': controller.settings['mail_pwd'] = qdict['mail_pwd'] if 'mail_adr' in qdict and qdict['mail_adr'] != '': controller.settings['mail_adr'] = qdict['mail_adr'] if 'ntfy_log' not in qdict: controller.settings['ntfy_log'] = 'off' else: controller.settings['ntfy_log'] = qdict['ntfy_log'] if 'ntfy_rain' not in qdict: controller.settings['ntfy_rain'] = 'off' else: controller.settings['ntfy_rain'] = qdict['ntfy_rain'] if 'ntfy_run' not in qdict: controller.settings['ntfy_run'] = 'off' else: controller.settings['ntfy_run'] = qdict['ntfy_run'] if 'ntfy_gev' not in qdict: controller.settings['ntfy_gev'] = 'off' else: controller.settings['ntfy_gev'] = qdict['ntfy_gev'] if 'ntfy_gdo[0]' not in qdict: controller.settings['ntfy_gdo'][0] = 'off' else: controller.settings['ntfy_gdo'][0] = qdict['ntfy_gdo[0]'] controller.settings['ntfy_gdo'][1] = int(qdict['ntfy_gdo[1]']) controller.settings['ntfy_gdo'][2] = int(qdict['ntfy_gdo[2]']) if 'ntfy_gdq[0]' not in qdict: controller.settings['ntfy_gdq'][0] = 'off' else: controller.settings['ntfy_gdq'][0] = qdict['ntfy_gdq[0]'] if 'ntfy_gdq[1]' not in qdict: controller.settings['ntfy_gdq'][1] = 'off' else: controller.settings['ntfy_gdq'][1] = qdict['ntfy_gdq[1]'] if 'ntfy_gdq[2]' not in qdict: controller.settings['ntfy_gdq'][2] = 'off' else: controller.settings['ntfy_gdq'][2] = qdict['ntfy_gdq[2]'] if 'ntfy_gdq[3]' not in qdict: controller.settings['ntfy_gdq'][3] = 'off' else: controller.settings['ntfy_gdq'][3] = qdict['ntfy_gdq[3]'] if 'ntfy_gdc[0]' not in qdict: controller.settings['ntfy_gdc'][0] = 'off' else: controller.settings['ntfy_gdc'][0] = qdict['ntfy_gdc[0]'] controller.settings['ntfy_gdc'][1] = int(qdict['ntfy_gdc[1]']) controller.settings['ntfy_gdc'][2] = int(qdict['ntfy_gdc[2]']) if 'twil_en' not in qdict: controller.settings['twil_en'] = 'off' else: controller.settings['twil_en'] = qdict['twil_en'] if 'twil_sid' in qdict and qdict['twil_sid'] != '': controller.settings['twil_sid'] = qdict['twil_sid'] if 'twil_atok' in qdict and qdict['twil_atok'] != '': controller.settings['twil_atok'] = qdict['twil_atok'] if 'twil_to' in qdict and qdict['twil_to'] != '': controller.settings['twil_to'] = qdict['twil_to'] if 'twil_from' in qdict and qdict['twil_from'] != '': controller.settings['twil_from'] = qdict['twil_from'] # don't save status in the data file controller.settings['status'] = "" jsave(controller.settings, 'garage') controller.settings['status'] = controller.status raise web.seeother( '/restart') # restart after settings change required
def GET(self): qdict = web.input() try: ddict = json.loads(qdict['data']) except: raise web.unauthorized() force_reboot = False info = {} for l in ['wlog', 'elog', 'slog', 'evlog']: if l in ddict and ddict[l]: end = ddict['end_date'] days = ddict['days_before'] prefix = '' try: if l in ['slog', 'evlog']: prefix = 'sensors/' + gv.plugin_data['ld'][int(ddict['ldi'])]['name'] + '/logs/' except: pass records = read_log(prefix+l, end, days) info[l] = records for dlog in ['dlogirricloud', 'dlogirricloud_monitor', 'dlogirricloud_net_config']: if dlog in ddict and ddict[dlog]: records = [] try: with open('./logs/' + dlog[4:] + '.out', 'r') as file: records = file.readlines() except: pass info[dlog] = [] for r in records: info[dlog].append(r) if 'lrun' in ddict and ddict['lrun']: info['lrun'] = gv.lrun if 'programs' in ddict: if ddict['programs'] == 1: info['programs'] = gv.pd else: gv.pd = ddict['programs'] jsave(gv.pd, 'programs') info['programs'] = 1 if 'ps' in ddict and ddict['ps']: info['ps'] = gv.ps if 'sbits' in ddict and ddict['sbits']: info['sbits'] = gv.sbits if 'srvals' in ddict and ddict['srvals']: info['srvals'] = gv.srvals if 'sensors' in ddict and 'ld' in gv.plugin_data: if ddict['sensors'] == 1: info['sensors'] = [] try: if 'ldi' not in ddict or int(ddict['ldi']) == -1: info['sensors'] = gv.plugin_data['ld'] else: info['sensors'] = gv.plugin_data['ld'][int(ddict['ldi'])] except: pass info['sensboards'] = i2c.get_vsb_boards().keys() info['remotesensboards'] = get_remote_sensor_boards() else: try: if 'ldi' not in ddict or int(ddict['ldi']) == -1: gv.plugin_data['ld'] = ddict['sensors'] else: gv.plugin_data['ld'][int(ddict['ldi'])] = ddict['sensors'] except: gv.plugin_data['ld'] = ddict['sensors'] jsave(gv.plugin_data['ld'], 'sensors') info['sensors'] = 1 if 'camera' in ddict and 'ca' in gv.plugin_data: if ddict['camera'] == 1: info['camera'] = gv.plugin_data['ca'] if 'cai' in ddict and ddict['cai']: info['cai'] = '' if gv.plugin_data['ca']['enable_camera'] == 'on': try: with open('./static/images/camera.jpg', mode='rb') as file: # b is important -> binary info['cai'] = base64.b64encode(file.read()) except: pass else: gv.plugin_data['ca'] = ddict['camera'] jsave(gv.plugin_data['ca'], 'camera') info['camera'] = 1 if 'sd' in ddict: if ddict['sd'] == 1: sd = gv.sd.copy() del sd['substation_network'] del sd['salt'] del sd['password'] del sd['pwd'] del sd['enable_upnp'] # stuff from base configuration stays as was del sd['subnet_only_substations'] del sd['external_proxy_port'] kill_keys = [] for k,v in sd.iteritems(): if len(k) > 2 and (k[0:2] == 'te' or k[0:2] == 'et'): kill_keys.append(k) for k in kill_keys: del sd[k] # dont send textemail or et_weather stuff info['sd'] = sd else: for field in ddict['sd']: gv.sd[field] = ddict['sd'][field] update_hostname(gv.sd['name']) update_tza(gv.sd['tza']) jsave(gv.sd, 'sd') info['sd'] = 1 force_reboot = True if 'snames' in ddict: if ddict['snames'] == 1: info['snames'] = gv.snames else: gv.snames = ddict['snames'] jsave(gv.snames, 'snames') info['snames'] = 1 if 'snotes' in ddict: if ddict['snotes'] == 1: info['snotes'] = gv.snotes else: gv.snotes = ddict['snotes'] jsave(gv.snotes, 'snotes') info['snotes'] = 1 if 'update_status' in ddict and ddict['update_status']: updatechecker.update_rev_data() info['update_status'] = updatechecker.status web.header('Content-Type', 'application/json') ret_str = json.dumps(info) if force_reboot: reboot(5) # give a few seconds to reply return ret_str
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.***** """ 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 POST(self): self.logger.debug('in Net POST') save_last_get('Net POST') form = web.input() outdata = [] net = 'eth0' if 'Use Hardwired eth0' in form else 'wlan0' # use hidden SSID if provided using_hidden_ssid = False if 'Hidden SSID' in form and form['Hidden SSID'].strip() != '': using_hidden_ssid = True form['SSID'] = form['Hidden SSID'] self.logger.info('using Hidden SSID') use_eth0 = 'SSID' not in form if not use_eth0: form['SSID'] = form['SSID'].strip() form['Password'] = form['Password'].strip() else: form['SSID'] = 'using eth0' self.logger.debug('in Net POST: ' + form['SSID']) try: drop = 0 with open('/etc/network/interfaces', 'r') as infile: iface = infile.readlines() for line in iface: did_iface_wlan0 = False if drop > 0: drop -= 1 continue if 'iface ' + net + ' inet' in line: if net == 'wlan0': did_iface_wlan0 = True if 'Use DHCP' in form: self.logger.debug('Using dhcp: ' + form['SSID']) if 'static' in line: drop = 3 line = 'iface ' + net + ' inet manual\n' else: self.logger.debug('Using static ip: ' + form['Static IP'] + ' ' + form['Netmask'] + ' ' + form['Gateway']) if 'static' in line: drop = 3 outdata.append('iface ' + net + ' inet static\n') outdata.append(' address ' + form['Static IP'] + '\n') outdata.append(' netmask ' + form['Netmask'] + '\n') line = ' gateway ' + form['Gateway'] + '\n' outdata.append(line) if did_iface_wlan0: outdata.append( ' wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf\n' ) except Exception as ex: self.logger.exception( 'Unexpected exception trying to configure network: ' + str(ex)) raise web.seeother('/cn') if len(outdata) == 0: self.logger.error('Expected data in /etc/network/interfaces') raise web.seeother('/cn') self.logger.debug( 'stopping daemons before updating network interfaces') # if not use_eth0: # stop_daemons() try: with open('/etc/network/interfaces', 'w') as outfile: outfile.writelines(outdata) if not use_eth0: wpa_supp_lines = [ 'ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n' ] wpa_supp_lines.append('update_config=1\n\n') if form['SSID'] != '' and form['Password'] != '': # wpa_passphrase cannot handle blanks cmd = 'wpa_passphrase ' + form['SSID'] + ' ' + form[ 'Password'] + ' > passphrase' subprocess.call(cmd, shell=True) with open('passphrase', 'r') as f: pl = f.readlines() for line in pl: wpa_supp_lines.append(line) if using_hidden_ssid and 'ssid' in line: wpa_supp_lines.append('\tscan_ssid=1\n') subprocess.call(['rm', 'passphrase']) else: self.logger.warning('missing ssid or password') with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') as outfile: outfile.writelines(wpa_supp_lines) # check if network connection was made self.logger.debug('wpa_action stopping wlan0') rc = subprocess.call(['wpa_action', 'wlan0', 'stop']) self.logger.debug('wpa_action return: ' + str(rc)) time.sleep(1) self.logger.debug('ifup wlan0') rc = subprocess.call(['ifup', net]) self.logger.debug('ifup return: ' + str(rc)) time.sleep(2) if network_up(net): #successful network connection. Finalize # copy the current versions to the save version if gv.sd['enable_upnp']: # was enabled? Then cleanup cur_ip = get_ip(net) deletes = [] if gv.sd['external_htp'] != 0: deletes.append(gv.sd['external_htp']) if gv.sd['remote_support_port'] != 0: deletes.append(gv.sd['remote_support_port']) update_upnp(cur_ip, deletes) gv.sd['enable_upnp'] = 1 if 'Enable UPnP' in form else 0 if gv.sd['enable_upnp']: if 'UPnP Refresh Rate' in form: gv.sd['upnp_refresh_rate'] = int( form['UPnP Refresh Rate']) if 'System Name' in form: gv.sd['name'] = form['System Name'] jsave(gv.sd, 'sd') if 'System Port' in form: gv.sd['htp'] = int(form['System Port']) jsave(gv.sd, 'sd') if 'External System Port' in form: gv.sd['external_htp'] = int(form['External System Port']) self.logger.info('success....copying back interfaces and wpa') shutil.copy('/etc/network/interfaces', '/etc/network/interfaces.save') shutil.copy('/etc/wpa_supplicant/wpa_supplicant.conf', '/etc/wpa_supplicant/wpa_supplicant.conf.save') # self.logger.info('success....enabling boiler') # subprocess.call(['update-rc.d', 'boiler', 'defaults']) # self.logger.info('disabling boiler_net_finish') # subprocess.call(['update-rc.d', 'boiler_net_finish', 'remove']) self.logger.info('rebooting') subprocess.call(['reboot', '-h']) exit(0) else: raise Exception('Network Inaccessible') except Exception as ex: self.logger.exception('failed: ' + str(ex)) # restore saved /etc/network/interfaces and wpa_suplicant.conf self.logger.info('restore network files and exit. Exception: ' + str(ex)) shutil.move('/etc/network/interfaces.save', '/etc/network/interfaces') shutil.move('/etc/wpa_supplicant/wpa_supplicant.conf.save', '/etc/wpa_supplicant/wpa_supplicant.conf') exit(1) self.logger.error( 'boiler_net_config: should have exited above. boiler_monitor will restart' ) raise web.seeother('/')
def POST(self): global error_msg if not been_through_subconfig: self.logger.info('tried Net POST....back to /su') raise web.seeother('/su') self.logger.debug('in Net POST') save_last_get('Net POST') form = web.input() error_msg = '' outdata = [] for f in ['Static IP', 'Netmask', 'Gateway', 'DNS Nameservers', 'SSID', 'Password', 'Hidden SSID', 'UPnP Refresh Rate', 'Station Name', 'Station Port', 'External Station Port', 'Remote Substation Access Port', 'Extender SSID', 'Extender Password']: if f in form: form[f] = form[f].strip() # use hidden SSID if provided using_hidden_ssid = False if 'Hidden SSID' in form and form['Hidden SSID'] != '': using_hidden_ssid = True form['SSID'] = form['Hidden SSID'] self.logger.info('using Hidden SSID') use_eth0 = 'SSID' not in form or form['SSID'] == 'ethernet' if gv.sd['remote_radio_substation']: form['SSID'] = 'using radio' net = 'radio' elif not use_eth0: net = 'wlan0' else: form['SSID'] = 'using eth0' net = 'eth0' self.logger.debug('in Net POST: ' + form['SSID']) gv.sd['light_ip'] = 1 try: if form['DNS Nameservers'][0:1] == 'X' and \ (len(form['DNS Nameservers']) == 1 or form['DNS Nameservers'][1:2] == ' '): gv.sd['light_ip'] = 0 # hack to disable blinking led on startup with leading X in nameservers form['DNS Nameservers'] = form['DNS Nameservers'][1:].strip() except: pass if not gv.sd['remote_radio_substation'] and 'Use DHCP' in form: for d in ['DNS Search', 'DNS Nameservers']: if d in form and form[d] != '': error_msg = 'Error: "' + d + '" must be blank with "Use DHCP".' raise web.seeother('/cn') # back to form pass_len = 0 if 'Extender Password' not in form else len(form['Extender Password']) if 'Extender SSID' in form and form['Extender SSID'] != '': if pass_len < 8 or pass_len > 63: error_msg = 'Error: "Extender Password" must be between 8 and 63 characters.' raise web.seeother('/cn') # back to form else: # force data to be present and safe form['Extender SSID'] = '' form['Extender Password'] = '' pass_len = 0 if 'Password' not in form else len(form['Password']) if not gv.sd['remote_radio_substation'] and not using_eth0 and (pass_len < 8 or pass_len > 63): error_msg = 'Error: "Password" must be between 8 and 63 characters.' raise web.seeother('/cn') # back to form if 'Station Name' in form: sn = validate_fqdn(form['Station Name']) if sn == 'Irricloud': # error condition error_msg = 'Error: "Station Name" must have only letter and numbers.' raise web.seeother('/cn') # back to form elif len(sn) > 50 or len(sn) < 1: error_msg = 'Error: "Station Name" must be at most 50 characters.' raise web.seeother('/cn') # back to form form['Station Name'] = sn for portn in ['Station Port', 'External Station Port', 'Remote Substation Access Port', 'UPnP Refresh Rate']: if portn in form: try: port = int(form[portn]) except: error_msg = 'Error: "' + portn + '" must be integer.' raise web.seeother('/cn') # back to form if port < 0 or port > 65535: error_msg = 'Error: "' + portn + '" must be between 0 and 65535.' raise web.seeother('/cn') # back to form if portn == 'Station Port' and port == 9080: # specially reserved for proxy error_msg = 'Error: "' + portn + '" cannot be 9080.' raise web.seeother('/cn') # back to form try: drop = 0 with open('/etc/network/interfaces','r') as infile: iface = infile.readlines() for line in iface: if 'dns-nameservers' in line: continue # delete any old dns stuff did_iface_wlan0 = False if drop > 0: drop -= 1 continue if 'iface ' + net + ' inet' in line: if net == 'wlan0': did_iface_wlan0 = True if 'Use DHCP' in form: self.logger.info('Using dhcp: ' + form['SSID']) if 'static' in line: drop = 3 line = 'iface ' + net + ' inet manual\n' else: self.logger.info('Using static ip: ' + form['Static IP'] + ' ' + form['Netmask'] + ' ' + form['Gateway']) if 'static' in line: drop = 3 outdata.append('iface ' + net + ' inet static\n') outdata.append(' address ' + form['Static IP'] + '\n') outdata.append(' netmask ' + form['Netmask'] + '\n') line = ' gateway ' + form['Gateway'] +'\n' outdata.append(line) if 'DNS Nameservers' in form and form['DNS Nameservers'] != '': line = ' dns-nameservers ' + form['DNS Nameservers'] +'\n' else: # use gateway line = ' dns-nameservers ' + form['Gateway'] +'\n' elif 'iface ' + 'wlan0' + ' inet' in line: # using eth0 or radio only, but need to clean up 10.0.0.1 entry if 'static' in line: drop = 3 line = 'iface ' + 'wlan0' + ' inet manual\n' did_iface_wlan0 = True outdata.append(line) if did_iface_wlan0: outdata.append(' wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf\n') except Exception as ex: self.logger.exception('Unexpected exception trying to configure network: ' + str(ex)) raise web.seeother('/cn') if len(outdata) == 0: self.logger.error('Expected data in /etc/network/interfaces') raise web.seeother('/cn') self.logger.info('stopping daemons before updating network interfaces') stop_daemons() try: with open('/etc/network/interfaces','w') as outfile: outfile.writelines(outdata) # Do not let dhcpcd get a dhcp address (and dns info?) if we are using a static config if 'Use DHCP' in form: shutil.copy2('/etc/dhcpcd.conf.yeswlan0', '/etc/dhcpcd.conf') else: shutil.copy2('/etc/dhcpcd.conf.nowlan0', '/etc/dhcpcd.conf') # if we are going to broadcast our own ssid to extend reach, save ssid and password broad_wpa_info = wpa_passphrase(form['Extender SSID'], form['Extender Password']) if len(broad_wpa_info['ssid']) > 2 and broad_wpa_info['ssid'][0] == '"': # strip off quotes for hostapd.conf broad_wpa_info['ssid'] = broad_wpa_info['ssid'][1:len(broad_wpa_info['ssid'])-1] gv.sd['extender_ssid'] = broad_wpa_info['ssid'] gv.sd['extender_psk'] = broad_wpa_info['psk'] if not gv.sd['remote_radio_substation'] and not use_eth0: wpa_supp_lines = ['ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n'] wpa_supp_lines.append('update_config=1\n\n') if form['SSID'] != '' and form['Password'] != '': wpa_info = wpa_passphrase(form['SSID'], form['Password']) wpa_supp_lines.append('network={\n') wpa_supp_lines.append('\tssid=' + wpa_info['ssid'] + '\n') if using_hidden_ssid: wpa_supp_lines.append('\tscan_ssid=1\n') wpa_supp_lines.append('\tpsk=' + wpa_info['psk'] + '\n') wpa_supp_lines.append('}\n') else: self.logger.warning('missing ssid or password') with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') as outfile: outfile.writelines(wpa_supp_lines) # check if network connection was made # self.logger.debug('wpa_action stopping wlan0') # rc = subprocess.call(['wpa_action', 'wlan0', 'stop']) # self.logger.debug( 'wpa_action wlan0 stop return: ' + str(rc)) # time.sleep(1) # self.logger.debug('ifup wlan0') # rc = subprocess.call(['ifup', 'wlan0']) # self.logger.debug( 'ifup return: ' + str(rc)) # time.sleep(1) # rc = subprocess.call(['wpa_action', 'wlan0', 'reload']) # self.logger.debug( 'wpa_action wlan0 reload return: ' + str(rc)) # time.sleep(1) # reset_networking() if True or 'Do not validate network connection' in form or network_up(net, self.logger): #successful network connection. Finalize # copy the current versions to the save version cur_ip = get_ip(net) self.logger.info('success...cur_ip: ' + cur_ip) if gv.sd['enable_upnp']: # was enabled? Then cleanup. If network still points to 10.0.0.1 network cant cleanup! deletes = [] if gv.sd['external_htp'] != 0: deletes.append(gv.sd['external_htp']) if gv.sd['remote_support_port'] != 0: deletes.append(gv.sd['remote_support_port']) if gv.sd['external_proxy_port'] != 0: deletes.append(gv.sd['external_proxy_port']) update_upnp(cur_ip, self.logger, deletes) gv.sd['enable_upnp'] = 1 if 'Enable UPnP' in form else 0 if gv.sd['enable_upnp']: if 'UPnP Refresh Rate' in form: gv.sd['upnp_refresh_rate'] = int(form['UPnP Refresh Rate']) if 'Station Name' in form: gv.sd['name'] = form['Station Name'] update_hostname(gv.sd['name']) if 'Station Port' in form: gv.sd['htp'] = int(form['Station Port']) if gv.sd['master']: gv.sd['master_ip'] = 'localhost' # update local master_port gv.sd['master_port'] == gv.sd['htp'] else: gv.sd['master_port'] = 0 gv.sd['external_htp'] = int(form['External Station Port']) if 'External Station Port' in form else 0 gv.sd['external_proxy_port'] = int(form['Remote Substation Access Port']) if 'Remote Substation Access Port' in form else 0 jsave(gv.sd, 'sd') self.logger.info('success....copying back interfaces and wpa') try: os.remove('/etc/resolv.conf') except: pass shutil.copy('/etc/network/interfaces', '/etc/network/interfaces.save') shutil.copy('/etc/wpa_supplicant/wpa_supplicant.conf', '/etc/wpa_supplicant/wpa_supplicant.conf.save') # self.logger.info('success....enabling sip') # subprocess.call(['systemctl', 'enable', 'sip.service']) ## subprocess.call(['update-rc.d', 'sip', 'enable']) ## subprocess.call(['update-rc.d', 'sip', 'defaults']) ## self.logger.info('disabling sip_net_finish') # subprocess.call(['systemctl', 'disable', 'sip_net_finish.service']) ## subprocess.call(['update-rc.d', '-f', 'sip_net_finish', 'remove']) # light_ip(cur_ip) self.logger.info('rebooting') subprocess.call(['reboot', '-h']) exit(0) else: raise Exception('Network Inaccessible') except Exception as ex: self.logger.exception('failed: ' + str(ex)) # restore saved /etc/network/interfaces and wpa_suplicant.conf self.logger.info('restore network files and exit. Exception: ' + str(ex)) shutil.move('/etc/network/interfaces.save', '/etc/network/interfaces') shutil.move('/etc/wpa_supplicant/wpa_supplicant.conf.save', '/etc/wpa_supplicant/wpa_supplicant.conf') exit(1) self.logger.error('sip_net_config: should have exited above. sip_monitor will restart') raise web.seeother('/cn')
def run(self): if disable_substations: return gv.logger.info('Substation plugin started') time.sleep(7) # let things wake up, but keep less than delay for sending email last_message_base = gv.now - 60 last_day = gv.now//86400 # wait at least a day before removing stale log files so startup does not delete them while True: try: cur_day = gv.now//86400 if gv.sd['slave'] and gv.now - last_message_base >= 60: try: last_message_base = gv.now data = message_base('suslj') if 'unreachable' in data: raise IOError, 'UnreachableMaster' force_reboot = False # update common data that has changed on the master for grouping in data: if gv.sd['master']: continue for key in data[grouping]: if grouping == 'sd': if key in gv.sd: if gv.sd[key] != data['sd'][key]: gv.logger.info('Changing gv.sd[' + key + '] from ' + str(gv.sd[key]) + ' to ' + str(data['sd'][key])) if key == 'remote_support_port' and gv.sd['enable_upnp']: gv.logger.critical('substation_run: Unexpected key of remote_support_port') if gv.sd[key] != 0: # delete old update_upnp(get_ip(), [gv.sd[key]]) if data['sd'][key] != 0: update_upnp(get_ip(), [], [[22, data['sd'][key]]]) gv.sd[key] = data['sd'][key] if key == 'tza': with open('/etc/timezone','w') as file: file.write(qdict['o'+f]+'\n') subprocess.call(['dpkg-reconfigure', '-f', 'non-interactive', 'tzdata']) force_reboot = True elif key == 'loc' or key == 'lang': force_reboot = True else: gv.logger.info('Setting gv.sd[' + key + '] to ' + str(data['sd'][key])) gv.sd[key] = data['sd'][key] elif grouping in gv.plugin_data: if key in gv.plugin_data[grouping]: if gv.plugin_data[grouping][key] != data[grouping][key]: gv.logger.info('Changing gv.plugin_data[' + grouping +'][' + key + '] from ' + str(gv.plugin_data[grouping][key]) + ' to ' + str(data[grouping][key])) gv.plugin_data[grouping][key] = data[grouping][key] else: gv.logger.info('Setting gv.plugin_data[' + grouping +'][' + key + '] to ' + str(data[grouping][key])) gv.plugin_data[grouping][key] = data[grouping][key] elif grouping == 'other': if key == 'websession': web.config._session.user = data[grouping][key] elif key == 'datetime': try: pass # subprocess.call(['date', '--set='+data[grouping][key]]) except: gv.logger.exception('Could not set datetime to ' + data[grouping][key]) if grouping == 'sd': jsave(gv.sd, 'sd') elif grouping != 'other': pass if force_reboot: reboot(5) # give a few seconds before reboot except Exception as ex: gv.logger.info('No master response. ip: ' + get_ip_to_base() + \ ' port: ' + str(gv.sd['master_port']) + \ ' Exception: ' + str(ex)) try: iwout = subprocess.check_output(['iwconfig', 'wlan0']) lines = iwout.split('\n') for l in lines: if 'ESSID:' in l: gv.logger.info('slave iwconfig wlan0 ' + l[l.find('ESSID:'):]) except Exception as ex: gv.logger.info('slave could not check iwconfig: ' + str(ex)) if gv.sd['master']: for subid in range(1,len(gv.plugin_data['su']['subinfo'])): sub = gv.plugin_data['su']['subinfo'][subid] try: if sub['status'] != 'unreachable' and gv.now - sub['last_join'] >= 90: # if havent received join in a while reach out qd = {'substation':subid} load_and_save_remote(qd, [], 'susldr', 'data', {}) # touch a slave to ensure still alive except Exception as ex: gv.logger.info('substations reach out to slave: No response from slave: ' + sub['name'] + ' Exception: ' + str(ex)) sub['status'] = 'unreachable' try: iwout = subprocess.check_output(['iwconfig', 'wlan0']) lines = iwout.split('\n') for l in lines: if 'ESSID:' in l: gv.logger.info('master iwconfig wlan0 ' + l[l.find('ESSID:'):]) except Exception as ex: gv.logger.info('master could not check iwconfig: ' + str(ex)) if cur_day != last_day: last_day = cur_day # delete any imported log files from substations that are no longer active files = glob.glob('./data/imported_logs/*') for full_name in files: sub_name = full_name[full_name.rfind('/')+1:] found_slave = 0 for subid in range(1,len(gv.plugin_data['su']['subinfo'])): if sub_name == gv.plugin_data['su']['subinfo'][subid]['name']: found_slave = subid break if found_slave == 0: try: shutil.rmtree(full_name) gv.logger.info('removed substree: ' + full_name) except Exception as ex: gv.logger.warning('failed to remove substree: ' + full_name + ' ex: ' + str(ex)) except Exception as ex: self.start_status('', 'Substation encountered error: ' + str(ex)) self._sleep(30)
def POST(self): self.logger.debug('in Net POST') save_last_get('Net POST') form = web.input() outdata = [] net = 'eth0' if 'Use Hardwired eth0' in form else 'wlan0' # use hidden SSID if provided using_hidden_ssid = False if 'Hidden SSID' in form and form['Hidden SSID'].strip() != '': using_hidden_ssid = True form['SSID'] = form['Hidden SSID'] self.logger.info('using Hidden SSID') use_eth0 = 'SSID' not in form if not use_eth0: form['SSID'] = form['SSID'].strip() form['Password'] = form['Password'].strip() else: form['SSID'] = 'using eth0' self.logger.debug('in Net POST: ' + form['SSID']) try: drop = 0 with open('/etc/network/interfaces','r') as infile: iface = infile.readlines() for line in iface: did_iface_wlan0 = False if drop > 0: drop -= 1 continue if 'iface ' + net + ' inet' in line: if net == 'wlan0': did_iface_wlan0 = True if 'Use DHCP' in form: self.logger.debug('Using dhcp: ' + form['SSID']) if 'static' in line: drop = 3 line = 'iface ' + net + ' inet manual\n' else: self.logger.debug('Using static ip: ' + form['Static IP'] + ' ' + form['Netmask'] + ' ' + form['Gateway']) if 'static' in line: drop = 3 outdata.append('iface ' + net + ' inet static\n') outdata.append(' address ' + form['Static IP'] + '\n') outdata.append(' netmask ' + form['Netmask'] + '\n') line = ' gateway ' + form['Gateway'] +'\n' outdata.append(line) if did_iface_wlan0: outdata.append(' wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf\n') except Exception as ex: self.logger.exception('Unexpected exception trying to configure network: ' + str(ex)) raise web.seeother('/cn') if len(outdata) == 0: self.logger.error('Expected data in /etc/network/interfaces') raise web.seeother('/cn') self.logger.debug('stopping daemons before updating network interfaces') # if not use_eth0: # stop_daemons() try: with open('/etc/network/interfaces','w') as outfile: outfile.writelines(outdata) if not use_eth0: wpa_supp_lines = ['ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n'] wpa_supp_lines.append('update_config=1\n\n') if form['SSID'] != '' and form['Password'] != '': # wpa_passphrase cannot handle blanks cmd = 'wpa_passphrase ' + form['SSID'] + ' ' + form['Password'] + ' > passphrase' subprocess.call(cmd, shell=True) with open('passphrase', 'r') as f: pl = f.readlines() for line in pl: wpa_supp_lines.append(line) if using_hidden_ssid and 'ssid' in line: wpa_supp_lines.append('\tscan_ssid=1\n') subprocess.call(['rm', 'passphrase']) else: self.logger.warning('missing ssid or password') with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') as outfile: outfile.writelines(wpa_supp_lines) # check if network connection was made self.logger.debug('wpa_action stopping wlan0') rc = subprocess.call(['wpa_action', 'wlan0', 'stop']) self.logger.debug( 'wpa_action return: ' + str(rc)) time.sleep(1) self.logger.debug('ifup wlan0') rc = subprocess.call(['ifup', net]) self.logger.debug( 'ifup return: ' + str(rc)) time.sleep(2) if network_up(net): #successful network connection. Finalize # copy the current versions to the save version if gv.sd['enable_upnp']: # was enabled? Then cleanup cur_ip = get_ip(net) deletes = [] if gv.sd['external_htp'] != 0: deletes.append(gv.sd['external_htp']) if gv.sd['remote_support_port'] != 0: deletes.append(gv.sd['remote_support_port']) update_upnp(cur_ip, deletes) gv.sd['enable_upnp'] = 1 if 'Enable UPnP' in form else 0 if gv.sd['enable_upnp']: if 'UPnP Refresh Rate' in form: gv.sd['upnp_refresh_rate'] = int(form['UPnP Refresh Rate']) if 'System Name' in form: gv.sd['name'] = form['System Name'] jsave(gv.sd, 'sd') if 'System Port' in form: gv.sd['htp'] = int(form['System Port']) jsave(gv.sd, 'sd') if 'External System Port' in form: gv.sd['external_htp'] = int(form['External System Port']) self.logger.info('success....copying back interfaces and wpa') shutil.copy('/etc/network/interfaces', '/etc/network/interfaces.save') shutil.copy('/etc/wpa_supplicant/wpa_supplicant.conf', '/etc/wpa_supplicant/wpa_supplicant.conf.save') # self.logger.info('success....enabling boiler') # subprocess.call(['update-rc.d', 'boiler', 'defaults']) # self.logger.info('disabling boiler_net_finish') # subprocess.call(['update-rc.d', 'boiler_net_finish', 'remove']) self.logger.info('rebooting') subprocess.call(['reboot', '-h']) exit(0) else: raise Exception('Network Inaccessible') except Exception as ex: self.logger.exception('failed: ' + str(ex)) # restore saved /etc/network/interfaces and wpa_suplicant.conf self.logger.info('restore network files and exit. Exception: ' + str(ex)) shutil.move('/etc/network/interfaces.save', '/etc/network/interfaces') shutil.move('/etc/wpa_supplicant/wpa_supplicant.conf.save', '/etc/wpa_supplicant/wpa_supplicant.conf') exit(1) self.logger.error('boiler_net_config: should have exited above. boiler_monitor will restart') raise web.seeother('/')
def run(self): if disable_substations: return gv.logger.info('Substation plugin started') time.sleep(7) # let things wake up, but keep less than delay for sending email last_message_base = gv.now - 60 while True: try: if gv.sd['slave'] and gv.now - last_message_base >= 60: try: last_message_base = gv.now data = message_base('suslj') if 'unreachable' in data: raise IOError, 'UnreachableMaster' force_reboot = False # update common data that has changed on the master for grouping in data: if gv.sd['master']: continue for key in data[grouping]: if grouping == 'sd': if key in gv.sd: if gv.sd[key] != data['sd'][key]: gv.logger.info('Changing gv.sd[' + key + '] from ' + str(gv.sd[key]) + ' to ' + str(data['sd'][key])) if key == 'remote_support_port' and gv.sd['enable_upnp']: gv.logger.critical('substation_run: Unexpected key of remote_support_port') if gv.sd[key] != 0: # delete old update_upnp(get_ip(), [gv.sd[key]]) if data['sd'][key] != 0: update_upnp(get_ip(), [], [[22, data['sd'][key]]]) gv.sd[key] = data['sd'][key] if key == 'tza': with open('/etc/timezone','w') as file: file.write(qdict['o'+f]+'\n') subprocess.call(['dpkg-reconfigure', '-f', 'non-interactive', 'tzdata']) force_reboot = True elif key == 'loc' or key == 'lang': force_reboot = True else: gv.logger.info('Setting gv.sd[' + key + '] to ' + str(data['sd'][key])) gv.sd[key] = data['sd'][key] elif grouping in gv.plugin_data: if key in gv.plugin_data[grouping]: if gv.plugin_data[grouping][key] != data[grouping][key]: gv.logger.info('Changing gv.plugin_data[' + grouping +'][' + key + '] from ' + str(gv.plugin_data[grouping][key]) + ' to ' + str(data[grouping][key])) gv.plugin_data[grouping][key] = data[grouping][key] else: gv.logger.info('Setting gv.plugin_data[' + grouping +'][' + key + '] to ' + str(data[grouping][key])) gv.plugin_data[grouping][key] = data[grouping][key] elif grouping == 'other': if key == 'websession': web.config._session.user = data[grouping][key] elif key == 'datetime': try: pass # subprocess.call(['date', '--set='+data[grouping][key]]) except: gv.logger.exception('Could not set datetime to ' + data[grouping][key]) if grouping == 'sd': jsave(gv.sd, 'sd') elif grouping != 'other': pass if force_reboot: reboot(5) # give a few seconds before reboot except Exception as ex: gv.logger.info('No master response. ip: ' + get_ip_to_base() + \ ' port: ' + str(gv.sd['master_port']) + \ ' Exception: ' + str(ex)) try: iwout = subprocess.check_output(['iwconfig', 'wlan0']) lines = iwout.split('\n') for l in lines: if 'ESSID:' in l: gv.logger.info('slave iwconfig wlan0 ' + l[l.find('ESSID:'):]) except Exception as ex: gv.logger.info('slave could not check iwconfig: ' + str(ex)) if gv.sd['master']: for subid in range(1,len(gv.plugin_data['su']['subinfo'])): sub = gv.plugin_data['su']['subinfo'][subid] try: if sub['status'] != 'unreachable' and gv.now - sub['last_join'] >= 90: # if havent received join in a while reach out qd = {'substation':subid} load_and_save_remote(qd, [], 'susldr', 'data', {}) # touch a slave to ensure still alive except Exception as ex: gv.logger.info('substations reach out to slave: No response from slave: ' + sub['name'] + ' Exception: ' + str(ex)) sub['status'] = 'unreachable' try: iwout = subprocess.check_output(['iwconfig', 'wlan0']) lines = iwout.split('\n') for l in lines: if 'ESSID:' in l: gv.logger.info('master iwconfig wlan0 ' + l[l.find('ESSID:'):]) except Exception as ex: gv.logger.info('master could not check iwconfig: ' + str(ex)) except Exception as ex: self.start_status('', 'Substation encountered error: ' + str(ex)) self._sleep(30)
def POST(self): global error_msg, been_through_subconfig been_through_subconfig = False self.logger.debug('in Sub POST') save_last_get('Sub POST') error_msg = '' form = web.input() continuation = '/cn' try: gv.sd['master'] = 1 if 'Master Station' in form else 0 gv.sd['slave'] = 1 if 'Substation' in form else 0 gv.sd[ 'subnet_only_substations'] = 0 if 'Enable Remote Substations' in form else 1 if not gv.sd['master'] and not gv.sd[ 'slave'] and 'Radio Only Substation' not in form: error_msg = 'At least one of "Master Substation" or "Substation" must be checked.' raise web.seeother('/su') # back to form for f in [ 'Master IP', 'Master Port', 'System Network Name', 'Radio Power', 'Radio Network Name', 'Radio Router Number', 'Radio Only Substation Name' ]: if f in form: form[f] = form[f].strip() gv.sd['master_ip'] = form['Master IP'] gv.sd['substation_network'] = form['System Network Name'] if 'Radio Power' in form: try: power = int(form['Radio Power']) except: power = -1 jsave(gv.sd, 'sd') actual_power = power & ~0x10 # disable the "hard power" bit if actual_power < 0 or actual_power > 5: error_msg = 'Error: "Radio Power" must be integer between 0 and 4 inclusive.' raise web.seeother('/su') # back to form # if len(form['Radio Network Name']) < 1: # error_msg = 'Error: "Radio Network Name" must be non-empty.' # raise web.seeother('/su') # back to form if len(form['Radio Network Name']) > 0: radio_network_hash = password_hash( form['Radio Network Name'], 'notarandomstring')[:16] cmd = [ 'python', 'substation_proxy.py', '--onetime', '--power=' + str(power), '--key=' + radio_network_hash ] else: cmd = [ 'python', 'substation_proxy.py', '--onetime', '--power=' + str(power) ] router_id = 255 type = 'base' if gv.sd['master_ip'] else 'remote' self.logger.info('initial radio type: ' + type) if len(form['Radio Router Number'] ) > 0 and form['Radio Router Number'] != '0': try: router_id = int(form['Radio Router Number']) except: router_id = 254 if router_id < 1 or router_id > 63: error_msg = 'Error: "Radio Router Number" must be between 1 and 63 inclusive.' raise web.seeother('/su') # back to form cmd.append('--radio_routing=' + str(router_id)) type = 'router' if 'Radio Only Substation' in form: if len(form['Radio Only Substation Name']) > 12 or len( form['Radio Only Substation Name']) < 1: error_msg = 'Error: "Radio Only Substation Name" must be unique and between 1 and 12 characters.' raise web.seeother('/su') # back to form elif form['Radio Only Substation Name'] == 'localhost': error_msg = 'Error: "Radio Only Substation Name" must not be "localhost".' raise web.seeother('/su') # back to form cmd.append('--radio_name=' + form['Radio Only Substation Name']) type = 'remote' # radio only substations are never base radios cmd.append('--type=' + type) # get pid of substation_proxy. # Tell sip_monitor to not restart it. # Kill it, then setparameters, then allow sip_monitor to restart it proxy_info = subprocess.check_output( "/bin/ps auwx | /bin/grep -e substation_proxy", shell=True) l = proxy_info.split('\n') kill_list = ['kill', '-9'] for e in l: if 'grep -e' not in e and e != '': word_list = re.sub('[^\w]', ' ', e).split() kill_list.append(word_list[1]) subprocess.call(['touch', 'data/substation_proxy_pause']) try: if len(kill_list) > 2: subprocess.call(kill_list) self.logger.info('Executing cmd: ' + " ".join(cmd)) subprocess.call(cmd) self.logger.info('removing substation_proxy_pause') subprocess.call(['rm', 'data/substation_proxy_pause']) except Exception as ex: self.logger.info('removing substation_proxy_pause ex: ' + str(ex)) subprocess.call(['rm', 'data/substation_proxy_pause']) raise if 'Radio Only Substation' in form: continuation = '/cc' else: jsave(gv.sd, 'sd') except Exception as ex: self.logger.info('finish ex: ' + str(ex)) raise web.seeother('/su') # back to form if continuation != '/cc': regenerate_ssh_keys() self.logger.debug('Sub POST been_through True. continuation: ' + continuation) been_through_subconfig = True raise web.seeother(continuation) # configure network parameters
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: gv.sd[u"htp"] = int(80) jsave(gv.sd, u"sd") print(u"SSL error", e) restart(2) app.run()
def POST(self): global error_msg if not been_through_subconfig: self.logger.info('tried Net POST....back to /su') raise web.seeother('/su') self.logger.debug('in Net POST') save_last_get('Net POST') form = web.input() error_msg = '' outdata = [] for f in [ 'Static IP', 'Netmask', 'Gateway', 'DNS Nameservers', 'SSID', 'Password', 'Hidden SSID', 'UPnP Refresh Rate', 'Station Name', 'Station Port', 'External Station Port', 'Remote Substation Access Port' ]: if f in form: form[f] = form[f].strip() # use hidden SSID if provided using_hidden_ssid = False if 'Hidden SSID' in form and form['Hidden SSID'] != '': using_hidden_ssid = True form['SSID'] = form['Hidden SSID'] self.logger.info('using Hidden SSID') use_eth0 = 'SSID' not in form or form['SSID'] == 'ethernet' if not use_eth0: net = 'wlan0' else: form['SSID'] = 'using eth0' net = 'eth0' self.logger.debug('in Net POST: ' + form['SSID']) gv.sd['light_ip'] = 1 try: if form['DNS Nameservers'][0:1] == 'X' and \ (len(form['DNS Nameservers']) == 1 or form['DNS Nameservers'][1:2] == ' '): gv.sd[ 'light_ip'] = 0 # hack to disable blinking led on startup with leading X in nameservers form['DNS Nameservers'] = form['DNS Nameservers'][1:].strip() except: pass if 'Use DHCP' in form: for d in ['DNS Search', 'DNS Nameservers']: if d in form and form[d] != '': error_msg = 'Error: "' + d + '" must be blank with "Use DHCP".' raise web.seeother('/cn') # back to form if 'Station Name' in form: sn = validate_fqdn(form['Station Name']) if sn == 'Irricloud': # error condition error_msg = 'Error: "Station Name" must have only letter and numbers.' raise web.seeother('/cn') # back to form elif len(sn) > 50 or len(sn) < 1: error_msg = 'Error: "Station Name" must be at most 50 characters.' raise web.seeother('/cn') # back to form form['Station Name'] = sn try: drop = 0 with open('/etc/network/interfaces', 'r') as infile: iface = infile.readlines() for line in iface: if 'dns-nameservers' in line: continue # delete any old dns stuff did_iface_wlan0 = False if drop > 0: drop -= 1 continue if 'iface ' + net + ' inet' in line: if net == 'wlan0': did_iface_wlan0 = True if 'Use DHCP' in form: self.logger.info('Using dhcp: ' + form['SSID']) if 'static' in line: drop = 3 line = 'iface ' + net + ' inet manual\n' else: self.logger.info('Using static ip: ' + form['Static IP'] + ' ' + form['Netmask'] + ' ' + form['Gateway']) if 'static' in line: drop = 3 outdata.append('iface ' + net + ' inet static\n') outdata.append(' address ' + form['Static IP'] + '\n') outdata.append(' netmask ' + form['Netmask'] + '\n') line = ' gateway ' + form['Gateway'] + '\n' outdata.append(line) if 'DNS Nameservers' in form and form[ 'DNS Nameservers'] != '': line = ' dns-nameservers ' + form[ 'DNS Nameservers'] + '\n' else: # use gateway line = ' dns-nameservers ' + form[ 'Gateway'] + '\n' elif 'iface ' + 'wlan0' + ' inet' in line: # using eth0 but need to clean up 10.0.0.1 entry if 'static' in line: drop = 3 line = 'iface ' + 'wlan0' + ' inet manual\n' did_iface_wlan0 = True outdata.append(line) if did_iface_wlan0: outdata.append( ' wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf\n' ) except Exception as ex: self.logger.exception( 'Unexpected exception trying to configure network: ' + str(ex)) raise web.seeother('/cn') if len(outdata) == 0: self.logger.error('Expected data in /etc/network/interfaces') raise web.seeother('/cn') for portn in [ 'Station Port', 'External Station Port', 'Remote Substation Access Port', 'UPnP Refresh Rate' ]: if portn in form: try: port = int(form[portn]) except: error_msg = 'Error: "' + portn + '" must be integer.' raise web.seeother('/cn') # back to form if port < 0 or port > 65535: error_msg = 'Error: "' + portn + '" must be between 0 and 65535.' raise web.seeother('/cn') # back to form if portn == 'Station Port' and port == 9080: # specially reserved for proxy error_msg = 'Error: "' + portn + '" cannot be 9080.' raise web.seeother('/cn') # back to form self.logger.info('stopping daemons before updating network interfaces') if not use_eth0: stop_daemons() else: stop_daemons() try: with open('/etc/network/interfaces', 'w') as outfile: outfile.writelines(outdata) # Do not let dhcpcd get a dhcp address (and dns info?) if we are using a static config if 'Use DHCP' in form: shutil.copy2('/etc/dhcpcd.conf.yeswlan0', '/etc/dhcpcd.conf') else: shutil.copy2('/etc/dhcpcd.conf.nowlan0', '/etc/dhcpcd.conf') if not use_eth0: wpa_supp_lines = [ 'ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n' ] wpa_supp_lines.append('update_config=1\n\n') if form['SSID'] != '' and form['Password'] != '': # wpa_passphrase cannot handle blanks so quote strings ssid = form['SSID'].replace('"', '\"') passw = form['Password'].replace('"', '\"') cmd = '/usr/bin/wpa_passphrase "' + ssid + '" "' + passw + '" > passphrase' subprocess.call(cmd, shell=True) with open('passphrase', 'r') as f: pl = f.readlines() for line in pl: if '#psk=' in line: # drop cleartext password continue wpa_supp_lines.append(line) if using_hidden_ssid and 'ssid' in line: wpa_supp_lines.append('\tscan_ssid=1\n') subprocess.call(['rm', 'passphrase']) else: self.logger.warning('missing ssid or password') with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'w') as outfile: outfile.writelines(wpa_supp_lines) # check if network connection was made # self.logger.debug('wpa_action stopping wlan0') # rc = subprocess.call(['wpa_action', 'wlan0', 'stop']) # self.logger.debug( 'wpa_action wlan0 stop return: ' + str(rc)) # time.sleep(1) # self.logger.debug('ifup wlan0') # rc = subprocess.call(['ifup', 'wlan0']) # self.logger.debug( 'ifup return: ' + str(rc)) # time.sleep(1) # rc = subprocess.call(['wpa_action', 'wlan0', 'reload']) # self.logger.debug( 'wpa_action wlan0 reload return: ' + str(rc)) # time.sleep(1) # reset_networking() if True or 'Do not validate network connection' in form or network_up( net, self.logger): #successful network connection. Finalize # copy the current versions to the save version cur_ip = get_ip(net) self.logger.info('success...cur_ip: ' + cur_ip) if gv.sd[ 'enable_upnp']: # was enabled? Then cleanup. If network still points to 10.0.0.1 network cant cleanup! deletes = [] if gv.sd['external_htp'] != 0: deletes.append(gv.sd['external_htp']) if gv.sd['remote_support_port'] != 0: deletes.append(gv.sd['remote_support_port']) if gv.sd['external_proxy_port'] != 0: deletes.append(gv.sd['external_proxy_port']) update_upnp(cur_ip, self.logger, deletes) gv.sd['enable_upnp'] = 1 if 'Enable UPnP' in form else 0 if gv.sd['enable_upnp']: if 'UPnP Refresh Rate' in form: gv.sd['upnp_refresh_rate'] = int( form['UPnP Refresh Rate']) if 'Station Name' in form: gv.sd['name'] = form['Station Name'] update_hostname(gv.sd['name']) if 'Station Port' in form: gv.sd['htp'] = int(form['Station Port']) if gv.sd['master']: gv.sd[ 'master_ip'] = 'localhost' # update local master_port gv.sd['master_port'] == gv.sd['htp'] else: gv.sd['master_port'] = 0 gv.sd['external_htp'] = int( form['External Station Port'] ) if 'External Station Port' in form else 0 gv.sd['external_proxy_port'] = int( form['Remote Substation Access Port'] ) if 'Remote Substation Access Port' in form else 0 jsave(gv.sd, 'sd') self.logger.info('success....copying back interfaces and wpa') try: os.remove('/etc/resolv.conf') except: pass shutil.copy('/etc/network/interfaces', '/etc/network/interfaces.save') shutil.copy('/etc/wpa_supplicant/wpa_supplicant.conf', '/etc/wpa_supplicant/wpa_supplicant.conf.save') # self.logger.info('success....enabling sip') # subprocess.call(['systemctl', 'enable', 'sip.service']) ## subprocess.call(['update-rc.d', 'sip', 'enable']) ## subprocess.call(['update-rc.d', 'sip', 'defaults']) ## self.logger.info('disabling sip_net_finish') # subprocess.call(['systemctl', 'disable', 'sip_net_finish.service']) ## subprocess.call(['update-rc.d', '-f', 'sip_net_finish', 'remove']) # light_ip(cur_ip) self.logger.info('rebooting') subprocess.call(['reboot', '-h']) exit(0) else: raise Exception('Network Inaccessible') except Exception as ex: self.logger.exception('failed: ' + str(ex)) # restore saved /etc/network/interfaces and wpa_suplicant.conf self.logger.info('restore network files and exit. Exception: ' + str(ex)) shutil.move('/etc/network/interfaces.save', '/etc/network/interfaces') shutil.move('/etc/wpa_supplicant/wpa_supplicant.conf.save', '/etc/wpa_supplicant/wpa_supplicant.conf') exit(1) self.logger.error( 'sip_net_config: should have exited above. sip_monitor will restart' ) raise web.seeother('/cn')
def POST(self): global error_msg, been_through_subconfig been_through_subconfig = False self.logger.debug('in Sub POST') save_last_get('Sub POST') error_msg = '' form = web.input() continuation = '/cn' try: gv.sd['master'] = 1 if 'Master Station' in form else 0 gv.sd['slave'] = 1 if 'Substation' in form else 0 gv.sd['subnet_only_substations'] = 0 if 'Enable Remote Substations' in form else 1 form['Radio Only Substation Name'] = form['Radio Only Substation Name'].strip() if 'Radio Only Substation Name' in form else '' radio_only_substation = len(form['Radio Only Substation Name']) > 0 if not radio_only_substation: gv.sd['remote_radio_substation'] = 1 if 'Only Radio Access' in form else 0 if not gv.sd['master'] and not gv.sd['slave'] and not radio_only_substation: error_msg = 'At least one of "Master Substation" or "Substation" must be checked.' raise web.seeother('/su') # back to form for f in ['Master IP', 'Master Port', 'System Network Name', 'Radio Power', 'Radio Network Name', 'Radio Router Number', 'Radio Only Substation Name']: if f in form: form[f] = form[f].strip() if not radio_only_substation and len(form['Master IP']) == 0: error_msg = '"Master IP" must not be blank' raise web.seeother('/su') # back to form gv.sd['master_ip'] = form['Master IP'] gv.sd['substation_network'] = form['System Network Name'] if 'Radio Power' in form: try: power = int(form['Radio Power']) except: power = -1 jsave(gv.sd, 'sd') actual_power = power & ~0x10 # disable the "hard power" bit if actual_power < 0 or actual_power > 5: error_msg = 'Error: "Radio Power" must be integer between 0 and 4 inclusive.' raise web.seeother('/su') # back to form # if len(form['Radio Network Name']) < 1: # error_msg = 'Error: "Radio Network Name" must be non-empty.' # raise web.seeother('/su') # back to form if len(form['Radio Network Name']) > 0: radio_network_hash = password_hash(form['Radio Network Name'], 'notarandomstring')[:16] cmd = ['python', 'substation_proxy.py', '--onetime', '--power='+str(power), '--key='+radio_network_hash] else: cmd = ['python', 'substation_proxy.py', '--onetime', '--power='+str(power)] router_id = 255 type = 'base' if not gv.sd['remote_radio_substation'] else 'remote' self.logger.info('initial radio type: ' + type) if len(form['Radio Router Number']) > 0 and form['Radio Router Number'] != '0': try: router_id = int(form['Radio Router Number']) except: router_id = 254 if router_id < 1 or router_id > 63: error_msg = 'Error: "Radio Router Number" must be between 1 and 63 inclusive.' raise web.seeother('/su') # back to form cmd.append('--radio_routing='+str(router_id)) type = 'router' if radio_only_substation: if len(form['Radio Only Substation Name']) > 12: error_msg = 'Error: "Radio Only Substation Name" must be unique and between 1 and 12 characters.' raise web.seeother('/su') # back to form elif form['Radio Only Substation Name'] == 'localhost': error_msg = 'Error: "Radio Only Substation Name" must not be "localhost".' raise web.seeother('/su') # back to form cmd.append('--radio_name='+form['Radio Only Substation Name']) type = 'remote' # radio only substations are never base radios cmd.append('--type='+type) # get pid of substation_proxy. # Tell sip_monitor to not restart it. # Kill it, then setparameters, then allow sip_monitor to restart it proxy_info = subprocess.check_output("/bin/ps auwx | /bin/grep -e substation_proxy", shell=True) l = proxy_info.split('\n') kill_list = ['kill', '-9'] for e in l: if 'grep -e' not in e and e != '': word_list = re.sub('[^\w]', ' ', e).split() kill_list.append(word_list[1]) subprocess.call(['touch', 'data/substation_proxy_pause']) try: if len(kill_list) > 2: subprocess.call(kill_list) self.logger.info('Executing cmd: ' + " ".join(cmd)) subprocess.call(cmd) self.logger.info('removing substation_proxy_pause') subprocess.call(['rm', 'data/substation_proxy_pause']) except Exception as ex: self.logger.info('removing substation_proxy_pause ex: ' + str(ex)) subprocess.call(['rm', 'data/substation_proxy_pause']) raise if radio_only_substation: continuation = '/cc' else: jsave(gv.sd, 'sd') except Exception as ex: self.logger.info('finish ex: ' + str(ex)) raise web.seeother('/su') # back to form if continuation != '/cc': regenerate_ssh_keys() self.logger.debug('Sub POST been_through True. continuation: ' + continuation) been_through_subconfig = True raise web.seeother(continuation) # configure network parameters
def sms_check(self): """Control and processing SMS""" data = get_sms_options() # Load data from json file tel1 = data["tel1"] tel2 = data["tel2"] comm1 = data["txt1"] comm2 = data["txt2"] comm3 = data["txt3"] comm4 = data["txt4"] comm5 = data["txt5"] comm6 = data["txt6"] sm = gammu.StateMachine() sm.ReadConfig() try: sm.Init() print("Checking SMS...") except: print("Error: SMS modem fault") status = sm.GetSMSStatus() remain = status["SIMUsed"] + status["PhoneUsed"] + status["TemplatesUsed"] sms = [] start = True while remain > 0: if start: cursms = sm.GetNextSMS(Start=True, Folder=0) start = False else: cursms = sm.GetNextSMS(Location=cursms[0]["Location"], Folder=0) remain = remain - len(cursms) sms.append(cursms) data = gammu.LinkSMS(sms) for x in data: v = gammu.DecodeSMS(x) m = x[0] print("%-15s: %s" % ("Sender", m["Number"])) print("%-15s: %s" % ("Date", str(m["DateTime"]))) print("%-15s: %s" % ("State", m["State"])) print("%-15s: %s" % ("SMS command", m["Text"])) if (m["Number"] == tel1) or (m["Number"] == tel2): # If telephone is admin 1 or admin 2 self.add_status( time.strftime("%d.%m.%Y at %H:%M:%S", time.localtime(time.time())) + " SMS from admin") if m["State"] == "UnRead": # If SMS is unread if ( m["Text"] == comm1 ): # If command = comm1 (info - send SMS to admin phone1 and phone2) self.add_status("Command " + comm1 + " is processed") if gv.lrun[1] == 98: pgr = "Run-once" elif gv.lrun[1] == 99: pgr = "Manual" else: pgr = str(gv.lrun[1]) start = time.gmtime(gv.now - gv.lrun[2]) if pgr != "0": logline = ( " {program: " + pgr + ",station: " + str(gv.lrun[0]) + ",duration: " + timestr(gv.lrun[2]) + ",start: " + time.strftime("%H:%M:%S - %Y-%m-%d", start) + "}") else: logline = " Last program none" revision = " Rev: " + gv.ver_date datastr = ("On " + time.strftime( "%d.%m.%Y at %H:%M:%S", time.localtime(time.time())) + ". Run time: " + uptime() + " IP: " + get_ip() + logline + revision) message = { "Text": datastr, "SMSC": { "Location": 1 }, "Number": m["Number"], } sm.SendSMS(message) self.add_status( "Command: " + comm1 + " was processed and confirmation was sent as SMS to: " + m["Number"]) self.add_status("SMS text: " + datastr) sm.DeleteSMS(m["Folder"], m["Location"]) # SMS deleted self.add_status("Received SMS was deleted") elif m["Text"] == comm2: # If command = comm2 (stop - system SIP off) self.add_status("Command " + comm2 + " is processed") gv.sd["en"] = 0 # disable system SIP jsave(gv.sd, "sd") # save en = 0 message = { "Text": "Command: " + comm2 + " was processed", "SMSC": { "Location": 1 }, "Number": m["Number"], } sm.SendSMS(message) self.add_status( "Command: " + comm2 + " was processed and confirmation was sent as SMS to: " + m["Number"]) sm.DeleteSMS(m["Folder"], m["Location"]) self.add_status("Received SMS was deleted") elif m["Text"] == comm3: # If command = comm3 (start - system SIP on) self.add_status("Command " + comm3 + " is processed") gv.sd["en"] = 1 # enable system SIP jsave(gv.sd, "sd") # save en = 1 message = { "Text": "Command: " + comm3 + " was processed", "SMSC": { "Location": 1 }, "Number": m["Number"], } sm.SendSMS(message) self.add_status( "Command: " + comm3 + " was processed and confirmation was sent as SMS to: " + m["Number"]) sm.DeleteSMS(m["Folder"], m["Location"]) self.add_status("Received SMS was deleted") elif m["Text"] == comm4: # If command = comm4 (reboot system) self.add_status("Command " + comm4 + " is processed") message = { "Text": "Command: " + comm4 + " was processed", "SMSC": { "Location": 1 }, "Number": m["Number"], } sm.SendSMS(message) self.add_status( "Command: " + comm4 + " was processed and confirmation was sent as SMS to: " + m["Number"]) sm.DeleteSMS(m["Folder"], m["Location"]) self.add_status( "Received SMS was deleted and system is now reboot") self._sleep(10) reboot() # restart linux system elif m["Text"] == comm5: # If command = comm5 (poweroff system) self.add_status("Command " + comm5 + " is processed") message = { "Text": "Command: " + comm5 + " was processed", "SMSC": { "Location": 1 }, "Number": m["Number"], } sm.SendSMS(message) self.add_status( "Command: " + comm5 + " was processed and confirmation was sent as SMS to: " + m["Number"]) sm.DeleteSMS(m["Folder"], m["Location"]) self.add_status( "Received SMS was deleted and system is now poweroff") self._sleep(10) poweroff() # poweroff linux system elif m["Text"] == comm6: # If command = comm6 (update SIP system) self.add_status("Command " + comm6 + " is processed") message = { "Text": "Command: " + comm6 + " was processed", "SMSC": { "Location": 1 }, "Number": m["Number"], } sm.SendSMS(message) self.add_status( "Command: " + comm6 + " was processed and confirmation was sent as SMS to: " + m["Number"]) try: from plugins.system_update import perform_update perform_update() self.add_status( "Received SMS was deleted, update was performed and program will restart" ) except ImportError: self.add_status( "Received SMS was deleted, but could not perform update" ) sm.DeleteSMS(m["Folder"], m["Location"]) else: # If SMS command is not defined sm.DeleteSMS(m["Folder"], m["Location"]) self.add_status("Received command " + m["Text"] + " is not defined!") else: # If SMS was read sm.DeleteSMS(m["Folder"], m["Location"]) self.add_status("Received SMS was deleted - SMS was read") else: # If telephone number is not admin 1 or admin 2 phone number sm.DeleteSMS(m["Folder"], m["Location"]) self.add_status( "Received SMS was deleted - SMS was not from admin")
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 GET(self): qdict = web.input() try: ddict = json.loads(qdict['data']) except: raise web.unauthorized() validate_remote(ddict) # may raise unauthorized ddict['last_join'] = gv.now ddict['status'] = 'ok' # gv.logger.debug('joining ip: ' + ddict['ip'] + ' name: ' + ddict['name'] + ' proxy: ' + ddict['proxy']) found_slave = 0 for i,d in enumerate(gv.plugin_data['su']['subinfo']): if i == 0: continue if d['name'] == ddict['name']: if d['ip'] != ddict['ip'] or d['port'] != ddict['port'] or d['proxy'] != ddict['proxy']: gv.logger.info('Substation ' + ddict['name'] + ' changed address from: ' + \ d['ip'] + ':' + str(d['port']) + ' to: ' + \ ddict['ip'] + ':' + str(ddict['port']) + \ '; proxy from: ' + d['proxy'] + ' to: ' + ddict['proxy']) su_strip = gv.plugin_data['su'].copy() for p in ['ip', 'port', 'proxy']: su_strip['subinfo'][i][p] = ddict[p] del su_strip['subdesc'] # dont save active data jsave(su_strip, 'substations') for p in ['ip', 'port', 'proxy', 'status', 'last_join']: gv.plugin_data['su']['subinfo'][i][p] = ddict[p] found_slave = i break if found_slave == 0: gv.logger.info('join_master adding substation: ' + ddict['name'] + ' at ip: ' + ddict['ip'] + ' proxy: ' + ddict['proxy']) mkdir_p('./data/imported_logs/'+ddict['name']+'/sensors') # get structure in place for log files gv.plugin_data['su']['subinfo'].append(ddict) found_slave = len(gv.plugin_data['su']['subinfo']) - 1 if gv.substation == '': gv.substation = ddict['name'] gv.substation_index = found_slave gv.plugin_data['su']['subdesc'].append(gv.plugin_data['su']['subdesc'][0].copy()) su_strip = gv.plugin_data['su'].copy() del su_strip['subdesc'] # dont save active data jsave(su_strip, 'substations') result = {'sd':{}, 'other':{}} web.header('Content-Type', 'application/json') for entry in gv.options: f = entry[2] if f in ['name', 'htp', 'nbrd', 'opw', 'npw', 'cpw', 'external_htp', 'enable_upnp', 'remote_support_port']: continue if len(f) > 2 and (f[0:2] == 'te' or f[0:2] == 'et'): # filter out email and et stuff unless explicitly added below continue result['sd'][f] = gv.sd[f] for f in ['tu', 'password', 'salt', 'wl_et_weather', 'teprogramrun', 'teipchange', 'tepoweron']: result['sd'][f] = gv.sd[f] result['other']['websession'] = web.config._session.user # capture login and logout result['other']['datetime'] = time.strftime("%a %d %b %Y %H:%M:%S", time.localtime()) return json.dumps(result)
def sms_check(self): """Control and processing SMS""" data = get_sms_options() # Load data from json file tel1 = data['tel1'] tel2 = data['tel2'] comm1 = data['txt1'] comm2 = data['txt2'] comm3 = data['txt3'] comm4 = data['txt4'] comm5 = data['txt5'] comm6 = data['txt6'] sm = gammu.StateMachine() sm.ReadConfig() try: sm.Init() print "Checking SMS..." except: print "Error: SMS modem fault" status = sm.GetSMSStatus() remain = status['SIMUsed'] + status['PhoneUsed'] + status['TemplatesUsed'] sms = [] start = True while remain > 0: if start: cursms = sm.GetNextSMS(Start=True, Folder=0) start = False else: cursms = sm.GetNextSMS(Location=cursms[0]['Location'], Folder=0) remain = remain - len(cursms) sms.append(cursms) data = gammu.LinkSMS(sms) for x in data: v = gammu.DecodeSMS(x) m = x[0] print '%-15s: %s' % ('Sender', m['Number']) print '%-15s: %s' % ('Date', str(m['DateTime'])) print '%-15s: %s' % ('State', m['State']) print '%-15s: %s' % ('SMS command', m['Text']) if (m['Number'] == tel1) or (m['Number'] == tel2): # If telephone is admin 1 or admin 2 self.add_status( time.strftime("%d.%m.%Y at %H:%M:%S", time.localtime(time.time())) + ' SMS from admin') if m['State'] == "UnRead": # If SMS is unread if m['Text'] == comm1: # If command = comm1 (info - send SMS to admin phone1 and phone2) self.add_status('Command ' + comm1 + ' is processed') if gv.lrun[1] == 98: pgr = 'Run-once' elif gv.lrun[1] == 99: pgr = 'Manual' else: pgr = str(gv.lrun[1]) start = time.gmtime(gv.now - gv.lrun[2]) if pgr != '0': logline = ' {program: ' + pgr + ',station: ' + str( gv.lrun[0]) + ',duration: ' + timestr( gv.lrun[2]) + ',start: ' + time.strftime( "%H:%M:%S - %Y-%m-%d", start) + '}' else: logline = ' Last program none' revision = ' Rev: ' + gv.ver_date datastr = ('On ' + time.strftime( "%d.%m.%Y at %H:%M:%S", time.localtime(time.time())) + '. Run time: ' + uptime() + ' IP: ' + get_ip() + logline + revision) message = { 'Text': datastr, 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm1 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) self.add_status('SMS text: ' + datastr) sm.DeleteSMS(m['Folder'], m['Location']) # SMS deleted self.add_status('Received SMS was deleted') elif m['Text'] == comm2: # If command = comm2 (stop - system OSPi off) self.add_status('Command ' + comm2 + ' is processed') gv.sd['en'] = 0 # disable system OSPi jsave(gv.sd, 'sd') # save en = 0 message = { 'Text': 'Command: ' + comm2 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm2 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted') elif m['Text'] == comm3: # If command = comm3 (start - system ospi on) self.add_status('Command ' + comm3 + ' is processed') gv.sd['en'] = 1 # enable system OSPi jsave(gv.sd, 'sd') # save en = 1 message = { 'Text': 'Command: ' + comm3 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm3 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted') elif m['Text'] == comm4: # If command = comm4 (reboot system) self.add_status('Command ' + comm4 + ' is processed') message = { 'Text': 'Command: ' + comm4 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm4 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status( 'Received SMS was deleted and system is now reboot') self._sleep(10) reboot() # restart linux system elif m['Text'] == comm5: # If command = comm5 (poweroff system) self.add_status('Command ' + comm5 + ' is processed') message = { 'Text': 'Command: ' + comm5 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm5 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) self.add_status( 'Received SMS was deleted and system is now poweroff') self._sleep(10) poweroff() # poweroff linux system elif m['Text'] == comm6: # If command = comm6 (update ospi system) self.add_status('Command ' + comm6 + ' is processed') message = { 'Text': 'Command: ' + comm6 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) self.add_status( 'Command: ' + comm6 + ' was processed and confirmation was sent as SMS to: ' + m['Number']) try: from plugins.system_update import perform_update perform_update() self.add_status( 'Received SMS was deleted, update was performed and program will restart' ) except ImportError: self.add_status( 'Received SMS was deleted, but could not perform update' ) sm.DeleteSMS(m['Folder'], m['Location']) else: # If SMS command is not defined sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received command ' + m['Text'] + ' is not defined!') else: # If SMS was read sm.DeleteSMS(m['Folder'], m['Location']) self.add_status('Received SMS was deleted - SMS was read') else: # If telephone number is not admin 1 or admin 2 phone number sm.DeleteSMS(m['Folder'], m['Location']) self.add_status( 'Received SMS was deleted - SMS was not from admin')
def GET(self): qdict = web.input() try: ddict = json.loads(qdict['data']) except: raise web.unauthorized() force_reboot = False info = {} for l in ['wlog', 'elog', 'slog', 'evlog']: if l in ddict and ddict[l]: end = ddict['end_date'] days = ddict['days_before'] start_after = ddict['start_after'] prefix = '' try: if l in ['slog', 'evlog']: prefix = 'sensors/' + gv.plugin_data['ld'][int(ddict['ldi'])]['name'] + '/logs/' except: pass records = read_log(prefix+l, end, days, start_after) info[l] = records for dlog in ['dlogirricloud', 'dlogirricloud_monitor', 'dlogirricloud_net_config']: if dlog in ddict and ddict[dlog]: records = [] try: with gv.log_lock: with open('./logs/' + dlog[4:] + '.out', 'r') as file: records = file.readlines() except: pass info[dlog] = [] for r in records: info[dlog].append(r) if 'lrun' in ddict and ddict['lrun']: info['lrun'] = gv.lrun if 'programs' in ddict: if ddict['programs'] == 1: info['programs'] = gv.pd else: gv.pd = ddict['programs'] jsave(gv.pd, 'programs') info['programs'] = 1 if 'ps' in ddict and ddict['ps']: info['ps'] = gv.ps if 'sbits' in ddict and ddict['sbits']: info['sbits'] = gv.sbits if 'srvals' in ddict and ddict['srvals']: info['srvals'] = gv.srvals if 'sensors' in ddict and 'ld' in gv.plugin_data: if ddict['sensors'] == 1: info['sensors'] = [] try: if 'ldi' not in ddict or int(ddict['ldi']) == -1: info['sensors'] = gv.plugin_data['ld'] else: info['sensors'] = gv.plugin_data['ld'][int(ddict['ldi'])] except: pass info['sensboards'] = i2c.get_vsb_boards().keys() info['remotesensboards'] = get_remote_sensor_boards() else: try: if 'ldi' not in ddict or int(ddict['ldi']) == -1: gv.plugin_data['ld'] = ddict['sensors'] else: gv.plugin_data['ld'][int(ddict['ldi'])] = ddict['sensors'] except: gv.plugin_data['ld'] = ddict['sensors'] jsave(gv.plugin_data['ld'], 'sensors') info['sensors'] = 1 if 'camera' in ddict and 'ca' in gv.plugin_data: if ddict['camera'] == 1: info['camera'] = gv.plugin_data['ca'] if 'cai' in ddict and ddict['cai']: info['cai'] = '' if gv.plugin_data['ca']['enable_camera'] == 'on': try: with open('./static/images/camera.jpg', mode='rb') as file: # b is important -> binary info['cai'] = base64.b64encode(file.read()) except: pass else: gv.plugin_data['ca'] = ddict['camera'] jsave(gv.plugin_data['ca'], 'camera') info['camera'] = 1 if 'sd' in ddict: if ddict['sd'] == 1: sd = gv.sd.copy() del sd['substation_network'] del sd['salt'] del sd['password'] del sd['pwd'] del sd['enable_upnp'] # stuff from base configuration stays as was del sd['subnet_only_substations'] del sd['external_proxy_port'] kill_keys = [] for k,v in sd.iteritems(): if len(k) > 2 and (k[0:2] == 'te' or k[0:2] == 'et'): kill_keys.append(k) for k in kill_keys: del sd[k] # dont send textemail or et_weather stuff info['sd'] = sd else: for field in ddict['sd']: gv.sd[field] = ddict['sd'][field] update_hostname(gv.sd['name']) update_tza(gv.sd['tza']) jsave(gv.sd, 'sd') info['sd'] = 1 force_reboot = True if 'snames' in ddict: if ddict['snames'] == 1: info['snames'] = gv.snames else: gv.snames = ddict['snames'] jsave(gv.snames, 'snames') info['snames'] = 1 if 'snotes' in ddict: if ddict['snotes'] == 1: info['snotes'] = gv.snotes else: gv.snotes = ddict['snotes'] jsave(gv.snotes, 'snotes') info['snotes'] = 1 if 'update_status' in ddict and ddict['update_status']: updatechecker.update_rev_data() info['update_status'] = updatechecker.status web.header('Content-Type', 'application/json') ret_str = json.dumps(info) if force_reboot: reboot(5) # give a few seconds to reply return ret_str