def onact(self): if self.actiontype == 'email': # process email action self.statusmsg += 'Processing email alert. ' email = self.actiondetail message = 'Alert is active for ' + self.name + '. Criterion ' + self.variablename + ' in ' + self.tablename + ' has value ' + str(self.variablevalue) + ' with a criterion of ' + str(self.criterion) + ' with an operator of ' + self.operator + '. This alarm status has been on since ' + self.ontime + '.' subject = 'CuPID Alert : Alarm On - ' + self.name actionmail = pilib.gmail(message=message, subject=subject, recipient=email) actionmail.send() elif self.actiontype == 'indicator': # process indicator action self.statusmsg += 'Processing indicator on action. ' indicatorname = self.actiondetail pilib.sqlitequery(pilib.controldatabase, 'update indicators set status=1 where name = \'' + indicatorname + '\'') elif self.actiontype == 'output': self.statusmsg += 'Processing output on action. ' pilib.setsinglevalue(pilib.controldatabase, 'outputs', 'value', '1', condition='"id"=\'' + self.actiondetail +"'") # This should be the generic handler that we migrate to elif self.actiontype == 'setvalue': # to set a value, we need at minimum: # dbname, tablename, valuename, setmethod and either: # setmethod = increment, incrementvalue=1 # setmethod = value dbvndict = parsedbvn(self.actiondetail) dbpath = pilib.dbnametopath(dbvndict['dbname']) # Special set formula? if 'setvalueformula' in self.actiondatadict: # Stuff that we don't know yet. pilib.setsinglevalue(dbpath, dbvndict['tablename'], dbvndict['valuename'], 'formulastuff here', dbvndict['condition']) else: """ TODO: Fix this hack. We cannot currently single quote in the database entry because it breaks the reinsert. So for now, we have to add quotes on either side of the string literal before executing the sqlite query. """ if dbvndict['condition']: querycondition = dbvndict['condition'].split('=')[0] + "='" + dbvndict['condition'].split('=')[1] + "'" # print('FIXED CONDITION') # print(querycondition) else: querycondition = None pilib.setsinglevalue(dbpath, dbvndict['tablename'], dbvndict['valuename'], '1', querycondition)
def parsedbvn(dbvn): # print('DBVN: ') # print(dbvn) """ databasename:tablename:valuename:condition """ split = dbvn.split(':') dbname = split[0].strip() dbpath = pilib.dbnametopath(dbname) if not dbpath: print("error getting dbpath, for dbname: " + dbname) return None tablename = split[1].strip() valuename = split[2].strip() if len(split) == 4: condition = split[3] else: condition = None return {'dbname':dbname,'dbpath':dbpath,'tablename':tablename,'valuename':valuename,'condition':condition}
def handle_modify_channel_alarm(d, output): import pilib from iiutilities import dblib output['message'] += 'modifychannelalarm keyword found. ' required_keywords = ['database', 'valuename', 'value', 'actionname'] if not all(keyword in d for keyword in required_keywords): output['message'] += 'Not all required keywords were found: ' + str(required_keywords) + '. ' return allowed_valuenames = ['enabled', 'PV_low', 'PV_high', 'actiondetail'] if d['valuename'] not in allowed_valuenames: output['message'] += 'Selected valuename is not allowed for this action. ' return dbpath = pilib.dbnametopath(d['database']) database = pilib.cupidDatabase(dbpath) action_condition = '"name"=\'' + d['actionname'] + "'" if d['valuename'] in ['enabled','actiondetail']: try: if d['valuename'] == 'enabled': set_value = int(d['value']) else: set_value = str(d['value']) except: output['message'] += 'Missing keys or bad value conversion. ' else: output['message'] += 'Setting value' + str(set_value) + ' with condition ' + action_condition + '. ' try: database.set_single_value('actions',d['valuename'],set_value, action_condition) except: output['message'] += 'Query error. ' else: output['message'] += 'That appears to have worked. ' elif d['valuename'] in ['PV_high', 'PV_low']: """ These values have to be set in the options field. So we have to pull it out as a json string, put it into a dict, modify values, and then put it back as a string """ from iiutilities.datalib import parseoptions, dicttojson optionstring = database.get_single_value('actions','actiondata',action_condition) output['message'] += 'Existing options: ' + optionstring + '. ' options = parseoptions(optionstring) try: set_value = float(d['value']) except: output['message'] += 'Bad value conversion. ' return if not d['valuename'] in options: output['message'] += 'Valuename does not exist in options. Creating. ' options[d['valuename']] = set_value # Now rewrite to actions optionstring = dicttojson(options) output['message'] += 'New optionstring: ' + optionstring + '. ' try: database.set_single_value('actions','actiondata',optionstring, action_condition) except: output['message'] += 'Query error. ' else: output['message'] += 'That appears to have worked. ' return
def handle_modify_channel(d, output): import pilib """ This is being replaced by class-based functions """ required_keywords = ['database', 'valuename', 'value', 'channelname'] if not all(keyword in d for keyword in required_keywords): output['message'] += 'Not all required keywords were found: ' + str(required_keywords) + '. ' return allowed_valuenames = ['enabled', 'setpointvalue'] if d['valuename'] not in allowed_valuenames: output['message'] += 'Selected valuename is not allowed for this action. ' return dbpath = pilib.dbnametopath(d['database']) database = pilib.cupidDatabase(dbpath) channel_condition = '"name"=\'' + d['channelname'] + "'" if d['valuename'] in allowed_valuenames: try: if d['valuename'] == 'enabled': set_value = int(d['value']) else: set_value = float(d['value']) except: output['message'] += 'Missing keys or bad value conversion. ' return """ For a channel, we will check type. If remote, we set as pending and then initiate processing the channel. """ from iiutilities.datalib import parseoptions, dicttojson # Handle error here. the_channel = database.read_table('channels',channel_condition)[0] if the_channel['type'] == 'remote': output['message'] += 'Processing remote channel, setting pending value. ' print(output['message']) if the_channel['pending']: pending = parseoptions(the_channel['pending']) else: pending = {} pending[d['valuename']] = set_value pending_string = dicttojson(pending) try: database.set_single_value('channels', 'pending', pending_string, channel_condition) except: output['message'] += 'Query error. ' return else: output['message'] += 'That appears to have worked. Now running channel processing on channel. ' else: output['message'] += 'Setting local setpoint value. ' try: database.set_single_value('channels','setpointvalue',set_value) except: output['message'] += 'Query error. ' return else: output['message'] += 'That appears to have worked. ' # Process channel now from cupid.picontrol import process_channel process_channel(channel_name=d['channelname']) # Let's also update the input while we're at it return
def app_modify_channel(post, output): import pilib """ TODO: 1. Fix all the actions to be methods of the channel object. 2. Make this function a wrapper of a general channel modifier function 3. Optimize so we are not using methods that require queries wherever possible. IOW, if mode hasn't changed since we initialized the object, use channel.mode instead of channel.get_mode() """ chan_action = post['chan_action'] channel_data_query = pilib.dbs.control.read_table_row('channels', condition="name='{}'".format(post['channelname'])) if not channel_data_query: output['message'] += 'Channel {} not found. '.format(post['channel_name']) return else: channel_data = channel_data_query[0] this_channel = channel(channel_data) if chan_action == 'spchange' and 'database' in post: output['message'] += 'Spchanged. ' dbpath = pilib.dbnametopath(post['database']) if dbpath: if 'subaction' in post: if post['subaction'] == 'incup': this_channel.inc_setpoint() output['message'] += 'incup. ' if post['subaction'] == 'incdown': this_channel.dec_setpoint() output['message'] += 'incdown. ' if post['subaction'] == 'setvalue': this_channel.set_setpoint(post['value']) output['message'] += 'Setvalue: {}'.format(post['value']) else: output['message'] += 'subaction not found. ' else: output['message'] += 'Problem translating dbpath from friendly name: ' + post['database'] elif chan_action == 'togglemode' and 'database' in post: this_channel.toggle_mode() elif chan_action == 'setmode' and 'database' in post: this_channel.set_mode(post['mode']) elif chan_action == 'setrecipe': this_channel.set_recipe(post['recipe']) elif chan_action == 'setcontrolinput': this_channel.set_control_input(post['controlinput']) elif chan_action == 'enable': this_channel.enable() elif chan_action == 'disable': this_channel.disable() elif chan_action == 'toggle_enabled': this_channel.toggle_enabled() elif chan_action == 'enable_outputs': this_channel.enable_outputs() elif chan_action == 'disable_outputs': this_channel.disable_outputs() elif chan_action == 'toggle_outputs_enabled': this_channel.toggle_outputs_enabled() elif chan_action == 'manualactionchange' and 'subaction' in post: if this_channel.get_mode() == 'manual': if post['subaction'] == 'poson': this_channel.set_action('100.0') elif post['subaction'] == 'negon': this_channel.set_action('-100.0') else: this_channel.set_action('0.0') elif chan_action == 'setposoutput' and 'outputname' in post: this_channel.set_pos_output(post['outputname']) elif chan_action == 'setnegoutput' and 'channelname' in post: this_channel.set_neg_output(post['outputname']) elif chan_action == 'actiondown' and 'channelname' in post: curchanmode = this_channel.get_mode() if curchanmode == "manual": curaction = this_channel.get_action() if curaction == 100: nextvalue = 0 elif curaction == 0: nextvalue = -100 elif curaction == -100: nextvalue = -100 else: nextvalue = 0 this_channel.set_action(nextvalue) elif chan_action == 'actionup' and 'channelname' in post: curchanmode = this_channel.get_mode() if curchanmode == "manual": curaction = this_channel.get_action() if curaction == 100: nextvalue = 100 elif curaction == 0: nextvalue = 100 elif curaction == -100: nextvalue = 0 else: nextvalue = 0 this_channel.set_action(nextvalue)