def run(self): if log.m(log.LEVEL_START_STOP_THREADS): log.l('<'+str(self.threadID)+'> starting Thread: ' + self.name) self.state = constants.CMD_STATE_STARTED self.task.start() self.stop() if log.m(log.LEVEL_START_STOP_THREADS): log.l('<'+str(self.threadID)+'> exiting:' + self.name)
def run(self): if log.m(log.LEVEL_TRIGGER): log.l('starting trigger manager...') while self.active: self.mutex.acquire() try: for k,v in self.triggers.items(): if v.isTrue(): v.action() except: if log.m(log.LEVEL_ERRORS): log.l('ERROR in trigger run method: ' + str(sys.exc_info()[0]) + ': '+str(sys.exc_info()[1])) self.mutex.release() time.sleep(config.DELAY) if log.m(log.LEVEL_TRIGGER): log.l('stopping trigger manager...')
def execute(self): """ executes the request and returns an answer according to the protocol @return: answer as JSON object """ if log.m(log.LEVEL_REQUESTS): log.l('executing request of type: ' + self.type) return None
def start(self): self.state = constants.CMD_STATE_STARTED if self.thread is not None and self.thread.state != constants.CMD_STATE_STARTED: #raise RuntimeError('the CommandThread of this task needs to be in CMD_STATE_STARTED-state to start child tasks!') return False if log.m(log.LEVEL_START_STOP_THREADS): log.l('<'+str(self.getThreadID())+'> starting ' + self.type) return True
def __init__(self, trigger): self.trigger = trigger self.name = trigger['name'] self.condition = datatypes.TriggerCondition(trigger['condition']) self.onAction = trigger['action'] self.repeat = int(trigger['repeat']) if trigger.has_key('repeat') else 0 if log.m(log.LEVEL_FILTERS): log.l('trigger initialized: ' + self.name)
def onChangeColor(self, newColor): if self.finishTrigger.isFalse(): self.finish() filteredColor = utils.interpolateColor(newColor, self.black, self.finishTrigger.progress()) if log.m(log.LEVEL_FILTER_ACTIONS): log.l(self.type+'-filter color ('+str(self.finishTrigger.progress()*100)+'%) from '+str(newColor)+' to '+str(filteredColor)) self.finishTrigger.step() return filteredColor
def __init__(self, threadID, name): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.daemon = True self.active = True self.triggers = {} self.mutex = threading.BoundedSemaphore() if log.m(log.LEVEL_TRIGGER): log.l('trigger manager initialized')
def start(self): if super(Loop, self).start(): self.condition = datatypes.Condition(self.command['condition']) if log.m(log.LEVEL_COMMAND_DETAIL): log.l('<'+str(self.getThreadID())+'> starting loop with condition: ' + str(self.condition)) while self.isStarted(): for t in self.tasks: t.start() self.condition.step() self.stop()
def finish(self): if self.onfinish == constants.FILTER_ONFINISH_REMOVE: server.CurrentFilters.remove(self) if self.onfinish == constants.FILTER_ONFINISH_STOP: if server.CurrentCMD is not None: server.CurrentCMD.stop() server.CurrentCMD = None server.CurrentFilters = [] if log.m(log.LEVEL_FILTER_ACTIONS): log.l(self.type+'-filter finished...')
def __init__(self, type, request): # takes a command as json encoded object """ initializes a new Request object @param type: type of the request (see protocol) @param request: JSON object with the request @return: instance of Request """ self.request = request self.type = type if log.m(log.LEVEL_REQUESTS): log.l('request received: ' + self.request)
def start(self): if super(Fade, self).start(): if self.command.has_key('start'): self.startColor = datatypes.Color(self.command['start']) self.endColor = datatypes.Color(self.command['end']) self.time = datatypes.Time(self.command['time']) if log.m(log.LEVEL_COMMAND_DETAIL): log.l('<'+str(self.getThreadID())+'> fading from '+str(self.startColor if self.startColor is not None else 'current color')+' to '+str(self.endColor)+' over ' + str(self.time) + ' seconds') corefunctions.fade(self, self.time.seconds, self.endColor, self.startColor) self.stop()
def addTrigger(self, trigger): exception = None self.mutex.acquire() try: self.triggers[trigger.name] = trigger if log.m(log.LEVEL_TRIGGER): log.l('trigger added with key=' + trigger.name) except: exception = StandardError(str(sys.exc_info()[0]) + ': '+str(sys.exc_info()[1])) self.mutex.release() if exception is not None: raise exception
def removeTrigger(self, name): exception = None self.mutex.acquire() try: self.triggers.pop(name) if log.m(log.LEVEL_TRIGGER): log.l('trigger removed with key=' + name) except: exception = StandardError(str(sys.exc_info()[0]) + ': '+str(sys.exc_info()[1])) self.mutex.release() if exception is not None: raise exception
def start(self): if super(CC, self).start(): self.color = datatypes.Color(self.command['color']) if self.command.has_key('operator'): self.operator = self.command['operator'] if log.m(log.LEVEL_COMMAND_CC): log.l('<'+str(self.getThreadID())+'> color=' + str(led.COLOR[0]) + ' ' + self.operator + ' ' + str(self.color)) for i in range(0, len(config.LED_PINS)): if ((i + 1) & self.color.Address) != 0: newColor = led.COLOR[i] if self.operator == '*': newColor = newColor * self.color if self.operator == '/': newColor = newColor / self.color if self.operator == '+': newColor = newColor + self.color if self.operator == '-': newColor = newColor - self.color led.setColor(newColor) else: if log.m(log.LEVEL_COMMAND_CC): log.l('<'+str(self.getThreadID())+'> color=' + str(self.color)) led.setColor(self.color) self.stop()
def __init__(self, type, filter): # takes a filter type and a filter as json encoded object """ initializes a new Request object @param type: type of the request (see protocol) @param request: JSON object with the request @return: instance of Request """ self.active = True #TODO: not used yet self.filter = filter self.onfinish = filter['onfinish'] if filter.has_key('onfinish') else 'remove' self.type = type self.finishTrigger = self.finishTrigger = datatypes.Condition(filter['finish']) if filter.has_key('finish') else None if log.m(log.LEVEL_FILTERS): log.l('filter initialized: ' + self.type)
def execute(self): super(RemoveRequest, self).execute() count = 0 if self.item == 'filter': i = 0 while i < len(server.CurrentFilters): if server.CurrentFilters[i].type == self.id: filter = server.CurrentFilters.pop(i) if log.m(log.LEVEL_FILTERS): log.l('removing ' + filter.type+' filter') count = count + 1 else: i += 1 if self.item == 'trigger': try: server.triggerManager.removeTrigger(self.id) count = 1 except: count = 0 answer = {"type":self.type, "item":self.item, "id":self.id, "count":count} return answer
def readcommands(threadName, intervall): #print the config parameters configure.cls() configure.printConfig() print '\n... starting server (',intervall,')...\n\n' #globals global ID global serversocket #create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #bind the socket to a public host, # and a well-known port success = False while not success: try: log.l('trying to bind on port '+str(config.SERVER_PORT)+'...', log.LEVEL_UI) serversocket.bind(('', config.SERVER_PORT)) # socket.gethostname() # for getting own address success = True log.l('successfully bound server to port '+str(config.SERVER_PORT)+'...', log.LEVEL_UI) except: log.l('port is already in use. Trying to reconnect in 5 seconds', log.LEVEL_ERRORS) time.sleep(5) #become a server socket serversocket.listen(5) while RUN: try: (clientsocket, address) = serversocket.accept() global CurrentCMD global CurrentFilters global CommandHistory global CommandCount rcvString = '' clientsocket.setblocking(1) # recv() waits til data comes or timeout is reached clientsocket.settimeout(config.CONNECTION_TIMEOUT) # timeout for receiving and sending kilobyte = str(clientsocket.recv(1024)) try: while(kilobyte): rcvString += kilobyte try: json.loads(rcvString) kilobyte = None except: kilobyte = str(clientsocket.recv(1024)) except: pass #flag which is true if the received command comes from a http request isHTTPRequest = False mutex.acquire() try: answer = {} answer['error'] = [] if rcvString.startswith('GET') or rcvString.startswith('OPTIONS') or rcvString.startswith('POST') or rcvString.startswith('PUT'): isHTTPRequest = True indexOfLineBreak = rcvString.find('\n\n') if indexOfLineBreak < 0: indexOfLineBreak = rcvString.find('\r\n\r\n') rcvString = rcvString[indexOfLineBreak:] rcvString = urllib.unquote(rcvString) if log.m(log.LEVEL_SOCKET_COMMUNICATION): log.l('RECEIVED HTTP ('+str(rcvString)+'): '+rcvString+'\n\n') startIndex = rcvString.find('{') endIndex = rcvString.rfind('}') if startIndex >= 0 and endIndex >= 0: rcvString = rcvString[rcvString.find('{'):rcvString.rfind('}')+1] if log.m(log.LEVEL_SOCKET_COMMUNICATION): log.l('RECEIVED Command ('+str(len(rcvString))+'): '+rcvString+'\n\n') else: if log.m(log.LEVEL_SOCKET_COMMUNICATION): log.l('no valid command found in ('+str(len(rcvString))+'): '+rcvString+'\n\n') else: isHTTPRequest = False if log.m(log.LEVEL_SOCKET_COMMUNICATION): log.l('RECEIVED Command ('+str(len(rcvString))+'): '+rcvString+'\n\n') r = json.loads(rcvString) CommandCount += 1 CommandHistory.append(r) #limit command history to the last 10 commands (client request messages) if len(CommandHistory) > 10: CommandHistory = CommandHistory[len(CommandHistory)-10:len(CommandHistory)] # execute commands if isinstance(r, dict) and r.has_key('commands') and len(r['commands']) > 0: try: if log.m(log.LEVEL_COMMANDS): log.l( 'commands: '+ str(len(r['commands']))) if CurrentCMD is not None: CurrentCMD.stop() CurrentCMD.join() CurrentCMD = None ID = ID + 1 CurrentCMD = CommandThread(ID, 'command thread', r) CurrentFilters = [] answer['commands'] = 1 except: answer['error'].append('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1])) answer['commands'] = 0 log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #add new filters if a command is running if isinstance(r, dict) and r.has_key('filters') and len(r['filters']) > 0 and CurrentCMD is not None and CurrentCMD.state != constants.CMD_STATE_STOPPED: try: for f in r['filters']: CurrentFilters.append(filters.Filter.createFilter(f)) answer['filters'] = 1 except: answer['error'].append('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1])) answer['filters'] = 0 log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #answer request if isinstance(r, dict) and r.has_key('request'): try: req = requests.Request.createRequest(r['request']) answer['request'] = req.execute() except: answer['error'].append('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1])) answer['request'] = None log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #add new triggers if isinstance(r, dict) and r.has_key('triggers') and len(r['triggers']) > 0: try: for t in r['triggers']: triggerManager.addTrigger(trigger.Trigger(t)) answer['triggers'] = 1 except: answer['error'].append('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1])) answer['triggers'] = 0 log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #starting a new command if a new arrived and could be correctly decoded if answer.has_key('commands') and answer['commands'] == 1: CurrentCMD.start() if log.m(log.LEVEL_SOCKET_COMMUNICATION): log.l('---ANSWER---') log.l(str(answer)) except: log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) answer['error'].append(str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1])) #clientsocket.send(json.dumps(answer, separators=(',',':'))) mutex.release() if isHTTPRequest: answerString = json.dumps(answer, separators=(',',':')) httpResponse = 'HTTP/1.1 200 OK\n' httpResponse = httpResponse + 'Content-Type: application/json;charset=utf-8\n' httpResponse = httpResponse + 'Access-Control-Allow-Origin: *\n' httpResponse = httpResponse + 'Content-Length: '+str(len(answerString))+'\n\n' httpResponse = httpResponse + answerString clientsocket.send(httpResponse) log.l('answer sent (http response)', log.LEVEL_SOCKET_COMMUNICATION) else: clientsocket.send(json.dumps(answer, separators=(',',':'))) log.l('answer sent (normal socket)', log.LEVEL_SOCKET_COMMUNICATION) clientsocket.close() except: log.l('ERROR: ' + str(sys.exc_info()[0])+ ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS)
def stop(self): if log.m(log.LEVEL_START_STOP_THREADS): log.l('<'+str(self.threadID)+'> stopping ' + self.name) self.state = constants.CMD_STATE_STOPPED self.task.stop()
def stop(self): if log.m(log.LEVEL_COMMAND_DETAIL): log.l('<'+str(self.getThreadID())+'> stopping loop with condition: ' + str(self.condition)) for t in self.tasks: if t.state != constants.CMD_STATE_STOPPED: t.stop() super(Loop, self).stop()
def applyCommand(r): """ This method can be used from other scripts like triggers.py to apply commands to the server :param r: json object with command :return: None """ global ID global serversocket global CurrentCMD global CurrentFilters global CommandHistory global CommandCount answer = {} mutex.acquire() try: answer['error'] = [] CommandCount += 1 CommandHistory.append(r) #limit command history to the last 10 commands (client request messages) if len(CommandHistory) > 10: CommandHistory = CommandHistory[len(CommandHistory)-10:len(CommandHistory)] contains_cmd = False # execute commands if isinstance(r, dict) and r.has_key('commands') and len(r['commands']) > 0: try: if log.m(log.LEVEL_COMMANDS): log.l( 'commands: '+ str(len(r['commands']))) if CurrentCMD is not None: CurrentCMD.stop() CurrentCMD.join() CurrentCMD = None ID = ID + 1 CurrentCMD = CommandThread(ID, 'command thread', r) CurrentFilters = [] contains_cmd = True except: log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #add new filters if a command is running if isinstance(r, dict) and r.has_key('filters') and len(r['filters']) > 0 and CurrentCMD is not None and CurrentCMD.state != constants.CMD_STATE_STOPPED: try: for f in r['filters']: CurrentFilters.append(filters.Filter.createFilter(f)) except: log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #answer request if isinstance(r, dict) and r.has_key('request'): try: req = requests.Request.createRequest(r['request']) req.execute() except: log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #add new triggers if isinstance(r, dict) and r.has_key('triggers') and len(r['triggers']) > 0: try: for t in r['triggers']: triggerManager.addTrigger(trigger.Trigger(t)) except: log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) #starting a new command if a new arrived and could be correctly decoded if contains_cmd: CurrentCMD.start() except: log.l('ERROR: ' + str(sys.exc_info()[0]) + ": "+ str(sys.exc_info()[1]), log.LEVEL_ERRORS) mutex.release() return answer
def start(self): if super(NOP, self).start(): if log.m(log.LEVEL_COMMAND_DETAIL): log.l('<'+str(self.getThreadID())+'> doing nothing') self.stop()
def __init__(self, command, thread=None): # takes a command as json encoded object self.command = command self.thread = thread self.threadID = -1 self.state = constants.CMD_STATE_INIT if log.m(log.LEVEL_INIT_COMMAND): log.l('<'+str(self.getThreadID())+'> initialized: ' + self.type)
def stop(self): self.state = constants.CMD_STATE_STOPPED if log.m(log.LEVEL_START_STOP_THREADS): log.l('<'+str(self.getThreadID())+'> stopping ' + self.type)
def start(self): if super(Wait, self).start(): self.time = datatypes.Time(self.command['time']) if log.m(log.LEVEL_COMMAND_DETAIL): log.l('<'+str(self.getThreadID())+'> waiting for ' + str(self.time) + ' seconds') corefunctions.wait(self, self.time.seconds) self.stop()