def action_leave(self, channels): if type(channels) != type([]): channels = [channels] for i in range(len(channels)): channels[i] = self.addChannelPrefix(channels[i]) log.info('Leave %s' % ','.join(channels)) self.connection.part(channels)
def handleDaemonItem(self, type, id): # If item is already offline, do nothing - but (re)start if applicable item = self.orchestrator.data[type][id] if item['online'] == False: if type == 'service': if not item.has_key('offlineTimer'): item['offlineTimer'] = time.time() if item['main'].get('autostart'): if item.get('manuallyStopped'): log.debug('Do not auto-start service %s since manually stopped' % id) else: timeSinceOffline = time.time() - item['offlineTimer'] if timeSinceOffline > self.orchestrator.startInterval: self.orchestrator.data[type][id]['offlineTimer'] = time.time() try: #self.orchestrator.action_startService(id) serviceId, managerId = self.orchestrator.parseServiceParam(id) if self.orchestrator.isOnline('manager', managerId): log.info('Auto-start service %s @ %s after %s secs offline' % (serviceId, managerId, timeSinceOffline)) self.orchestrator.startService(managerId, serviceId) else: log.debug('Do not auto-start service %s since manager %s is offline' % (id,managerId)) except Exception, e: log.error('Error trying to autostart service %s: %s' % (id,e)) else: log.debug('Do not auto-start service %s since %s secs offline is less than startinterval %s' % (id,timeSinceOffline,self.orchestrator.startInterval)) else: log.debug('Do not auto-start service %s since autostart not set in config' % (id,))
def start(self, block=False): ''' Run the service Will start main loop, onStart(), in a separate thread, and then start listening for incoming actions. This function should typically NOT be overridden. Your service's custom main loop code should be implemented in onStart() instead. ''' # Send an event about being online self.sendOnlineEvent() # @todo: shutdown of loop # - how to break loop(s) when shutdown() is called # - up to each service to implement? # Do main loop, i.e. onStart(), in a separate thread # (It will typically do stuff and call onEvent() to # push events to the queue). log.info('Starting thread for onStart') self.eventThread = ServiceThread(self.onStart, 'OnStart', self.config.get('id')) self.eventThread.start() if block: self.listen() else: self.actionThread = ServiceThread(self.listen, 'Actions', self.config.get('id')) self.actionThread.start()
def setOffline(self, type, key): if not type or not key: log.warn('Ignore attempt to set type=%s id=%s as offline' % (type,key)) return # Init dict path if not set if not self.data[type].has_key(key): self.data[type][key] = {'online': None} # If not already offline, set offline and send offline event if self.data[type][key]['online'] != False: log.info('%s %s changed status to offline' % (type, key)) self.data[type][key]['online'] = False self.data[type][key]['offlineTimer'] = time.time() eventTopic = '%s%s.%s.online' % ( self.typeToPrefix(type), amqp.PREFIX_EVENT, key ) event = {'data': {'value': False}, 'key': 'online'} if type == 'service': event['service'] = key else: event['host'] = key self.producer.put(eventTopic, event)
def onStart(self): log.info('Starting PhilipsTV') while not self._shutdown: data_raw = self.ser.readline( ) # Using readline for now since this doesn't need performance data = self._parse_data(data_raw) self.sendEvent('change', data, self.meta)
def onStart(self): log.info('Starting main lifx loop') while not self._shutdown: changes = self.lx.update_unit_info() if not (not changes['new'] and not changes['gone'] and not changes['changed']): self.send_change_events(changes) time.sleep(self.interval)
def onInit(self): self.dataPath = self.config.getDataDir() config = Config(self.config.data(), self.dataPath) self.plots = config.getPlots() self.graphs = config.getGraphs() self.interval = self.determineInterval() log.info('Service started with %s plots, %s graphs, interval %s' % (len(self.plots), len(self.graphs), self.interval))
def _log(self, file, message, key): if file == self.SELF_LOG: log.info(message) else: file = '%s.log' % file logger2 = self.getLogger(file, key) logger2.info(message)
def action_graph(self, id, start=None, end=None): graph = self.getGraph(id) if not graph: raise Exception('No such graph: %s' % id) log.info('graph: %s %s => %s' % (id,start,end)) graph.graph(start, end) return graph.path
def _get_service(self, dev): log.info('Running _get_service') devkey = "%03d:%03d" % (dev.bus, dev.address) devdict = {devkey: {}} for key, value in vars(dev).items(): if not key.startswith('_'): devdict[devkey].update({key: value}) usb_strings = cusb.service_strings(dev.bus, dev.address) devdict[devkey].update(usb_strings) # chainsify the dictionary for key, value in devdict[devkey].items(): devdict[devkey].update({key: {'value': value}}) devconf = { 'conf': { 'bLength': dev[0].bLength, 'bDescriptorType': dev[0].bDescriptorType, 'wTotalLength': dev[0].wTotalLength, 'bNumInterfaces': dev[0].bNumInterfaces, 'bConfigurationValue': dev[0].bConfigurationValue, 'bmAttributes': dev[0].bmAttributes, 'bMaxPower': dev[0].bMaxPower } } devdict[devkey].update(devconf) # dev[0] since we only check first configuration devdict[devkey].update({'interfaces': self._get_all_interfaces(dev[0])}) return devdict
def onInit(self): log.info('IntegraService init.') self.model = self.config.get('model') self.ser_dev = self.config.get('serial') if self.ser_dev and self.model: self.topics, self.cmds = iscp.model_cmds(self.model) else: log.error('Service needs serial service and model to work.') sys.exit(1) self.act_desc = { 'info': 'Integra/Onkyo model %s' % self.model, 'actions': [] } for cmd in self.cmds: for subcmd in self.cmds[cmd]: newcmd = { 'name': cmd + subcmd, 'info': self.cmds[cmd][subcmd]['description'], 'args': [] } # matches non-empty type-dicts: if self.cmds[cmd][subcmd]['type']: param = self._type_desc(self.cmds[cmd][subcmd]['type']) if param: newcmd['args'].append(param) self.act_desc['actions'].append(newcmd) self.ser = serial.Serial( port=self.ser_dev, baudrate=9600, timeout=0.05, # 50ms reponse time according to spec bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, )
def start(self, block=False): ''' Run the service Will start main loop, onStart(), in a separate thread, and then start listening for incoming actions. This function should typically NOT be overridden. Your service's custom main loop code should be implemented in onStart() instead. ''' # Send an event about being online self.sendOnlineEvent() # @todo: shutdown of loop # - how to break loop(s) when shutdown() is called # - up to each service to implement? # Do main loop, i.e. onStart(), in a separate thread # (It will typically do stuff and call onEvent() to # push events to the queue). log.info('Starting thread for onStart') self.eventThread = ServiceThread(self.onStart) self.eventThread.start() if block: self.listen() else: self.actionThread = ServiceThread(self.listen) self.actionThread.start()
def setOnline(self, type, key, force=False): if not type or not key: log.warn('Ignore attempt to set type=%s id=%s as online' % (type,key)) return # Init dict path if not set if not self.data[type].has_key(key): self.data[type][key] = {'online': None} #if type == 'manager': # self.data[type][key]['services'] = None # If not already online (or force [re-]online) # Set online and send online-event if self.data[type][key]['online'] != True or force: log.info('%s %s changed status to online' % (type, key)) self.data[type][key]['online'] = True eventTopic = '%s%s.%s.online' % ( self.typeToPrefix(type), amqp.PREFIX_EVENT, key ) event = {'data': {'value': True}, 'key': 'online'} if type == 'service': event['service'] = key else: event['host'] = key self.producer.put(eventTopic, event) # Update last heartbeat time self.data[type][key]['heartbeat'] = time.time()
def action_graph(self, id, start=None, end=None): graph = self.getGraph(id) if not graph: raise Exception('No such graph: %s' % id) log.info('graph: %s %s => %s' % (id, start, end)) graph.graph(start, end) return graph.path
def waitEventAddData(self, key, data): log.info('waitEventAppendData: %s = %s' % (key, data)) # Just ignore if we are not waiting for this event if not self.waitEvents.has_key(key): return # Add data for k in data: self.waitEvents[key]['data'][k] = data[k]
def action_update_service(self, bus, address): ''' Update information on specific usb service bus / address @param bus int Bus number @param address int Address number ''' log.info('Running action_update_service') self._get_dev_path(bus, address)
def onStart(self): log.info('Starting Ruter service') self.interval = 5 * 60 self.apiUri = 'http://reisapi.ruter.no/Travel/GetTravels' while not self._shutdown: self.updateTravelProposals() time.sleep(self.interval)
def loadServiceConfig(self, path, isReload=False): if isReload: log.info('Reload service config: %s' % path) else: log.info('Load service config: %s' % path) instanceConfig = self.getConfig(path) if not instanceConfig: return instanceData = instanceConfig.data() classDir = '%s/config/service-classes' % self.coreConfig.get('libdir') classFile = '%s/%s.yml' % (classDir, instanceData['main']['class']) classConfig = self.getConfig(classFile) classData = classConfig.data() hasChanges = False if not classData: return if not instanceData['main'].get('id'): id = self.generateUuid() instanceData['main']['id'] = id instanceConfig.set('id', id) hasChanges = True if not instanceData['main'].get('name'): name = instanceData['main']['class'].lower() instanceData['main']['name'] = name instanceConfig.set('name', name) hasChanges = True if not instanceData['main'].get('manager'): manager = 'master' instanceData['main']['manager'] = manager instanceConfig.set('manager', manager) hasChanges = True if hasChanges: instanceConfig.save() data = self.mergeDictionaries(classData, instanceData) data['online'] = False data['heartbeat'] = 0 if isReload and self.data['service'].has_key( data['main']['id'] ): old = self.data['service'][ data['main']['id'] ] data['online'] = old.get('online') data['heartbeat'] = old.get('heartbeat') if not data.get('online'): data['online'] = False if not data.get('heartbeat'): data['heartbeat'] = 0 self.data['service'][ data['main']['id'] ] = data
def _get_all_services(self): log.info('Running _get_all_services') # We only support 1 configuration, mulitple configurations are said to very rare # This saves us from a one level deeper dict which is unnecessary in most cases data = {} self.usb_devs = usb.core.find(find_all=True) for dev in self.usb_devs: devdict = self._get_service(dev) data.update(devdict) return data
def onStart(self): log.info('IntegraService starting.') while not self._shutdown: # TODO: check for self.command variable, and run command here # rather than from runAction()? line = self.ser.readline() if line: self.sendEvent(line[1:4], {'value': line[4:]}) # TODO: sleep probably not needed? time.sleep(0.1)
def updateTravelProposals(self): log.info('Updating travel props') headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36" } url = self.apiUri + '?fromplace=' + self.fromPlace + '&toplace=' + self.toPlace + '&isafter=true&transporttypes=' + self.transportTypes req = urllib2.Request(url, None, headers) try: response = urllib2.urlopen(req) self.parseReponse(response.read()) except urllib2.HTTPError as e: log.error('Error when updating TravelProposals %s: %s' % (e, e.read())) time.sleep(self.interval * 3)
def sendStartupEvents(self): for deviceId in self.devices: log.info('send start ev: %s' % deviceId) tmp = deviceId.split('-') type = tmp.pop(0) id = int(tmp.pop(0)) if type == 'device': self.deviceEventCallback(id, td.TELLSTICK_TURNOFF, 0, 1, True) elif type == 'sensor': dataType = int(tmp.pop(0)) self.sensorEventCallback('', '', id, dataType, 0, time.time(), 0, True)
def arp_monitor_callback(self, pkt): # pkt.show() if pkt.haslayer(ARP): # This is needed since the filter some times lets through non-arp frames if pkt[ARP].op == 1: # who-has (request) t = datetime.datetime.now() log.info("ARP Request: " + pkt[ARP].psrc + " is asking about " + pkt[ARP].pdst) self.sendEvent(pkt.psrc, {'type': 'arp_query'}) # return pkt.psrc if pkt[ARP].op == 2: # is-at (response) log.info("ARP Response: " + pkt[ARP].hwsrc + " has address " + pkt[ARP].psrc) self.sendEvent(pkt[ARP].hwsrc, {'device': 'ARP', 'address': pkt[ARP].psrc, 'type': 'arp_response'})
def onStart(self): while not self._shutdown: now = time.time() for plot in self.plots: if plot.isDue(): value = self.getPlotValue(plot) log.info('Plot %s = %s @ %s' % (plot.id, value, now)) plot.plot(value, now) else: log.debug('Plot %s is not due yet @ %s' % (plot.id, now)) time.sleep(self.interval)
def graph(self, start, end): consolidationFunction = 'AVERAGE' data = [ self.path.encode('utf-8') ] index = 0 for plot in self.plots: index += 1 color = self.getColor(index) stack = '' if self.stack: stack = 'STACK' data.append( # DEF:key=file:datasource:cf 'DEF:data%s=%s:data:%s' % (index, plot.path, consolidationFunction) ) data.append( # AREA:key#color:label:STACK 'AREA:data%s#%s:%s:%s' % (index, color[1], '', stack) ) index = 0 for plot in self.plots: index += 1 color = self.getColor(index) stack = '' if self.stack and index > 1: stack = 'STACK' label = plot.label data.append( # LINE:key#color:label:STACK 'LINE1:data%s#%s:%s:%s' % (index, color[0], label, stack) ) data.append('-w %s' % self.width) data.append('-h %s' % self.height) if start: data.append('-s %s' % int(start)) if end: data.append('-e %s' % int(end)) args = [] for arg in data: if type(arg) == type(u''): arg = arg.encode('utf-8') args.append(arg) #print('data: %s'%(args,)) log.info('graph.args: %s' % (args,)) rrdtool.graph(*args)
def onInit(self): log.info('Zeroconf publish init') self.ip_addr = self._get_ip() self.hostname = socket.gethostname() self.services = [] self.desc = {'Description': 'Chains Home Automation service on rabbitmq'} self.amqp_info = ServiceInfo("_amqp._tcp.local.", "Chains Master AMQP %s._amqp._tcp.local." % self.hostname, socket.inet_aton(self.ip_addr), 5672, 0, 0, self.desc, "%s.local." % self.hostname) self.service.append(self.amqp_info) self.zeroconf = Zeroconf()
def onStart(self): """ start loop """ # let user defined how often to update data log.info('SystemService main loop starting') while not self._shutdown: log.info('Main loop running') self.action_cpuinfo() self.action_meminfo() self.action_netinfo() self.action_sysinfo() self.action_diskinfo() # wait a while before sending system info again time.sleep(self.interval)
def bint(arg): if type(arg) == type(True): if arg: return 1 else: return 0 elif type(arg) == type('') or type(arg) == type(u''): if arg == '1' or arg == 'True': return 1 else: return 0 elif type(arg) == type(1): if arg > 0: return 1 else: return 0 else: log.info('Unknown bint arg converted to 0: %s (%s)' % (arg, type(arg))) return 0
def _get_endpoint(self, endp): log.info('Running _get_endpoint') endpoint = { str(endp.bEndpointAddress): { 'bLength': endp.bLength, 'bDescriptorType': endp.bDescriptorType, 'bEndpointAddress': endp.bEndpointAddress, 'bmAttributes': endp.bmAttributes, 'wMaxPacketSize': endp.wMaxPacketSize, 'bInterval': endp.bInterval, } } return endpoint
def onInit(self): self.adapters = cec.list_adapters() if len(self.adapters) < 1: sys.exit('No CEC adapters found') else: self.adapter = self.adapters[0] log.info('Found adapter(s): %s' % str(self.adapters)) log.info('Using adapter %s' % self.adapter) self.sendEvent('current_adapter', {'id': 0}) cec.init(self.adapter) # Service config self.interval = self.config.get('interval') or 60 self.location = self.config.get('location') self.cur_service = None
def isRunning(serviceId): # Check pidfile pid = getPid(serviceId) if not pid: log.info('Proc no pid: %s' % pid) return False # Check if pid in pidfile actually exists try: os.kill(pid, 0) except OSError: log.info('Proc not running (kill -0): %s' % pid) delPid(serviceId) return False # Check if defunct/zombie process proc = psutil.Process(pid) status = None if type(proc.status) == types.FunctionType: status = proc.status() else: status = proc.status if status == psutil.STATUS_ZOMBIE: log.info('Proc not running (zombie): %s' % pid) delPid(serviceId) return False # Process is running log.info('Proc running with status %s: %s' % (status,pid)) return pid
def main(daemonType, fork=True): conf = config.data(daemonType) conf['id'] = resolveDaemonId(conf['id']) if not conf: raise Exception('No section "daemon_%s" in config' % id) for k in conf: if k[0:4] == 'env_': log.info('Set ENV.%s = %s' % (k[4:],conf[k])) os.environ[k[4:]] = conf[k] d = Daemon(daemonType, conf['id'], getDaemonMainFunction(daemonType)) if fork: d.fork() else: d.main()
def onStart(self): """ start loop """ # let user defined how often to update data log.info('SystemService main loop starting') while not self._shutdown: log.info('Main loop running') self.action_sysinfo() self.action_meminfo() self.action_cpuinfo() self.action_userprocinfo() self.action_diskinfo() self.action_netinfo() # wait a while before sending system info again time.sleep(self.interval)
def listen(self): log.info('Start listening for messages, topics = %s' % self.getConsumeKeys()) actionPrefix = self.getActionPrefix() heartBeatRequestPrefix = self.getHeartBeatRequestPrefix() while not self._shutdown: log.notice('Waiting for messages') try: topic, data, correlationId = self.consumer.get() except socket.error, e: self.reconnect(e) continue except amqplib.client_0_8.exceptions.AMQPConnectionException, e: self.reconnect(e) continue
def isRunning(serviceId): # Check pidfile pid = getPid(serviceId) if not pid: log.info('Proc no pid: %s' % pid) return False # Check if pid in pidfile actually exists try: os.kill(pid, 0) except OSError: log.info('Proc not running (kill -0): %s' % pid) delPid(serviceId) return False # Check if defunct/zombie process proc = psutil.Process(pid) status = None if type(proc.status) == types.FunctionType: status = proc.status() else: status = proc.status if status == psutil.STATUS_ZOMBIE: log.info('Proc not running (zombie): %s' % pid) delPid(serviceId) return False # Process is running log.info('Proc running with status %s: %s' % (status, pid)) return pid
def graph(self, start, end): consolidationFunction = 'AVERAGE' data = [self.path.encode('utf-8')] index = 0 for plot in self.plots: index += 1 color = self.getColor(index) stack = '' if self.stack: stack = 'STACK' data.append( # DEF:key=file:datasource:cf 'DEF:data%s=%s:data:%s' % (index, plot.path, consolidationFunction)) data.append( # AREA:key#color:label:STACK 'AREA:data%s#%s:%s:%s' % (index, color[1], '', stack)) index = 0 for plot in self.plots: index += 1 color = self.getColor(index) stack = '' if self.stack and index > 1: stack = 'STACK' label = plot.label data.append( # LINE:key#color:label:STACK 'LINE1:data%s#%s:%s:%s' % (index, color[0], label, stack)) data.append('-w %s' % self.width) data.append('-h %s' % self.height) if start: data.append('-s %s' % int(start)) if end: data.append('-e %s' % int(end)) args = [] for arg in data: if type(arg) == type(u''): arg = arg.encode('utf-8') args.append(arg) #print('data: %s'%(args,)) log.info('graph.args: %s' % (args, )) rrdtool.graph(*args)
def main(daemonType, fork=True): coreConfig = CoreConfig() conf = coreConfig.data(daemonType) if not conf: raise Exception('No section "daemon_%s" in config' % id) conf['id'] = resolveDaemonId(conf['id']) for k in conf: if k[0:4] == 'env_': log.info('Set ENV.%s = %s' % (k[4:], conf[k])) os.environ[k[4:]] = conf[k] d = Daemon(daemonType, conf['id'], getDaemonMainFunction(daemonType)) if fork: d.fork() else: d.main()
def __init__(self, id): log.info('Starting orchestator') amqp.AmqpDaemon.__init__(self, 'orchestrator', id) self.coreConfig = config.CoreConfig() self.data = { 'manager': {}, 'service': {}, 'reactor': {}, 'orchestrator': {} } self.timeout = 30 self.timeoutInterval = 5 self.startInterval = 15 self.timeoutThread = TimeoutThread(self) self.loadServiceConfigs()
def action_join(self, channel, secret=None, autoSecret=True): # Prefix channel with # if not already prefixed channel = self.addChannelPrefix(channel) # If no secret provided, check if channel has one configured in config if not secret and autoSecret: try: secret = self.secrets[channel] except KeyError: pass # Join channel with secret if secret: log.info('Joining channel %s with secret %s' % (channel, secret)) self.connection.join(channel, secret) # Or without secret else: log.info('Joining channel %s without secret' % channel) self.connection.join(channel)