Пример #1
0
 def onStart(self):
     if not self.hosts:
         log.warn('No hosts to ping')
         return
     started = False
     while not self._shutdown:
         for name in self.hosts:
             host = self.hosts[name]
             if self.ping(host):
                 if self.isDown(host) or not started:
                     self.sendEvent(name, {
                         'value': 'up',
                         'address': host
                     })
                     try: del self.down[host]
                     except: pass
             else:
                 if not self.isDown(host):
                     self.sendEvent(name, {
                         'value': 'down',
                         'address': host
                     })
                     self.down[host] = True
         started = True
         time.sleep(self.interval)
Пример #2
0
    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()
Пример #3
0
    def poll(self):

        data = {}

        keys = [
            'firmware_version',
            'power_loss',
            'battery_voltage',
            'rpi_voltage',
            'sot23_temperature',
            'to92_temperature',
            'shutdown_time',
            'battery_temperature_on_error',
            'ad1',
            'ad2'
        ]

        for key in keys:
            func = 'get_%s' % key
            try:
                func = getattr(self, func)
                value = func()
            except Exception, e:
                log.warn("Ignoring error on get %s: %s" % (key, utils.e2str(e)))
                continue
            data[key] = value
Пример #4
0
    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)
Пример #5
0
 def on_pubmsg(self, c, e):
     try:
         nick = NickMask(e.source()).nick
         a = e.arguments()[0].split(":", 1)
         #print "pub_msg: %s" % a
         #print "pub_msg first char: '%s'" % a[0][0]
         # parse first word as a command if pre'ed by <botname:>
         if len(a) > 1 and irc_lower(a[0]) == irc_lower(self.connection.get_nickname()):
             #self.command_switch(e, a[1].strip())
             a2 = e.arguments()[0].split(" ")
             if len(a2[0][1:]) > 0:
                 self.command_switch(nick,e,a2[1],a2[2:])
         # parse first word as a command if pre'ed by "!"
         elif e.arguments()[0][0] == '!':
             a2 = e.arguments()[0].split(" ")
             if len(a2[0][1:]) > 0:
                 self.command_switch(nick,e,a2[0][1:],a2[1:])
         # else: send as generic pubmessage event
         else:
             a2 = e.arguments()[0]
             data = {'key':'pubmessage', 'value':a2, 'extra': {'nick':nick}}
             self.botEvent(data)
         return
     except Exception, e:
         self.say_public('Exception in on_pubmsg: %s' % e)
         log.warn('Exception in on_privmsg: %s' % utils.e2str(e))
Пример #6
0
 def onInit(self):
     self.from_addr = self.config.get('from_addr')
     self.to_addr = self.config.get('to_addr')
     if not self.to_addr:
         self.to_addr = self.from_addr
     self.username = self.config.get('username')
     self.password = self.config.get('password')
     self.polldelay = self.config.get('polldelay')
     if not self.polldelay:
         self.polldelay = 600
     self.mailserver = self.config.get('mailserver')
     if not self.mailserver:
         self.mailserver = '127.0.0.1'
     self.smtpserver = self.config.get('smtpserver')
     self.deletemail = self.config.get('deletemail')
     if not self.deletemail or not self.deletemail.lower() == 'yes' or not self.deletemail.lower() == 'true':
         self.deletemail = False
     self.maxheaders = self.config.get('maxheader')
     if not self.maxheaders:
         self.maxheaders = 10
     self.maxsize = self.config.get('maxsize')
     if not self.maxsize:
         self.maxsize = 12000
     if not self.smtpserver:
         self.smtpserver = '127.0.0.1'
     if not self.from_addr:
         log.warn('Service needs senders email address to work.')
         sys.exit(1)
Пример #7
0
 def onInit(self):
     self.button_events = [
         array('B', [1, 0, 0, 0, 0, 0, 0]), 'button_release',
         array('B', [1, 1, 0, 0, 0, 0, 0]), 'button_left',
         array('B', [1, 2, 0, 0, 0, 0, 0]), 'button_right',
         array('B', [1, 4, 0, 0, 0, 0, 0]), 'button_middle',
         array('B', [1, 8, 0, 0, 0, 0, 0]), 'button_3',
         array('B', [1, 16, 0, 0, 0, 0, 0]), 'button_4',
         array('B', [1, 32, 0, 0, 0, 0, 0]), 'button_5',
         array('B', [1, 64, 0, 0, 0, 0, 0]), 'button_6',
         array('B', [1, 128, 0, 0, 0, 0, 0]), 'button_7',
         array('B', [1, 255, 0, 0, 0, 0, 0]), 'button_8',
         array('B', [1, 0, 0, 0, 0, 0, 1]), 'wheel_up',
         array('B', [1, 0, 0, 0, 0, 0, 255]), 'wheel_down',
         # mouse button combinations
         # TODO: do this by using bitwise operator to generate all combinations
         array('B', [1, 3, 0, 0, 0, 0, 0]), 'button_left_right',
         array('B', [1, 5, 0, 0, 0, 0, 0]), 'button_left_middle',
         array('B', [1, 6, 0, 0, 0, 0, 0]), 'button_right_middle',
         array('B', [1, 7, 0, 0, 0, 0, 0]), 'button_left_right_middle',
     ]
     # "slow" mouse movements
     self.move_events = [
         array('B', [1, 0, 0, 0, 1, 0, 0]), 'down',
         array('B', [1, 0, 255, 255, 1, 0, 0]), 'down-left',
         array('B', [1, 0, 1, 0, 1, 0, 0]), 'down-right',
         array('B', [1, 0, 0, 0, 255, 255, 0]), 'up',
         array('B', [1, 0, 255, 255, 255, 255, 0]), 'up-left',
         array('B', [1, 0, 1, 0, 255, 255, 0]), 'up-right',
         array('B', [1, 0, 255, 255, 0, 0, 0]), 'left',
         array('B', [1, 0, 1, 0, 0, 0, 0]), 'right',
     ]
     # ## Service config
     self.interval = int(self.config.get('interval')) or 600 # milliseconds
     self.vendorid = int(self.config.get('vendorid'))
     self.productid = int(self.config.get('productid'))
     self.search_params = {}
     if self.vendorid and self.productid:
         self.search_params.update({'idVendor': self.vendorid, 'idProduct': self.productid})
         mousedevs = cusb.find_mouse(self.search_params)
     else:
         log.warn("No config, using first found mouse service")
         mousedevs = cusb.find_mouse()
     if not mousedevs:
         log.error("Can't find mouse service")
         sys.exit("Can't find mouse service")
     # Use first matching mouse
     mouse = mousedevs[0]
     # ## vendor and product ids
     self.dev = usb.core.find(address=mouse['address'], bus=mouse['bus'])
     self.interface = mouse['interface']
     # use the first endpoint
     # dev[configuration][(interface, alt_config)][endpoint]
     self.endpoint = self.dev[mouse['configuration']][(mouse['interface'], 0)][0]
Пример #8
0
    def onMessage(self, topic, data, correlationId):
        topic = topic.split('.')

        # Heartbeats
        if topic[0][1] == amqp.PREFIX_HEARTBEAT_RESPONSE:
            if data == amqp.HEARTBEAT_VALUE_OFFLINE:
                self.setOffline(self.prefixToType(topic[0][0]), topic[1])
            elif data == amqp.HEARTBEAT_VALUE_ONLINE:
                self.setOnline(self.prefixToType(topic[0][0]), topic[1], force=True)
            elif data == amqp.HEARTBEAT_VALUE_RESPONSE:
                self.setOnline(self.prefixToType(topic[0][0]), topic[1])
            else:
                log.warn('Unknown heartbeat event: %s' % (topic,))
Пример #9
0
    def getBluetoothServices(self):
        log.debug('Getting bluetooth services')
        result = []

        if self.config.getBool('discover'):
            log.debug('Using services_discover() to find services')
            try:
                for addr in bluetooth.discover_services(flush_cache=True):
                    log.debug('Found service: %s' % addr)
                    result.append(addr)
            # This happens from time to time, and we don't want to die because of it:
            # BluetoothError: error communicating with local bluetooth adapter
            except bluetooth.btcommon.BluetoothError, e:
                log.warn('BluetoothError ignored: %s' % e)
Пример #10
0
    def getBluetoothServices(self):
        log.debug('Getting bluetooth services')
        result = []

        if self.config.getBool('discover'):
            log.debug('Using services_discover() to find services')
            try:
                for addr in bluetooth.discover_services(flush_cache=True):
                    log.debug('Found service: %s' % addr)
                    result.append(addr)
            # This happens from time to time, and we don't want to die because of it:
            # BluetoothError: error communicating with local bluetooth adapter
            except bluetooth.btcommon.BluetoothError,e:
                log.warn('BluetoothError ignored: %s' % e)
Пример #11
0
 def action_power_toggle(self, cecdev=None):
     '''
     Toggle CEC service power
     @param  adapter  int  CEC service ID
     '''
     if not cecdev:
         cecdev = self.cur_service
     dev = cec.Service(cecdev)
     if dev.is_on:
         dev.power_off()
     elif not dev.is_on:
         dev.power_on()
     else:
         log.warn('powertoggle failed because power status could not be determined')
Пример #12
0
 def on_privmsg(self, c, e):
     nick = NickMask(e.source()).nick
     try:
         if e.arguments()[0][0] == '!':
             a2 = e.arguments()[0].split(" ")
             if len(a2[0][1:]) > 0:
                 self.command_switch(nick,e,a2[0][1:],a2[1:])
         else:
             a2 = e.arguments()[0].split(" ")
             data = {'key':'privmsg', 'value':e.arguments()[0], 'extra': {'nick':nick, 'type':e.eventtype(),'source':e.source(), 'target':e.target()}}
             #data = {'key':'privmessage', 'value':e.arguments()[0], 'extra': {'nick':nick}}
             self.botEvent(data)
     except Exception, e:
         self.say_private(nick, 'Exception: %s' % e)
         log.warn('Exception in on_privmsg: %s' % utils.e2str(e))
Пример #13
0
 def shutdown(self):
     AmqpDaemon.shutdown(self)
     #log.info('Shutdown called')
     #self._shutdown = True
     # Send an action message to ourself to make sure
     # we break out of the wait-loop for actions asap.
     #log.info('Send _shutdown action')
     #self.sendShutdownAction()
     #log.info('Wait 0.5')
     time.sleep(0.5)
     log.info('Joining actionThread')
     if self.actionThread:
         try:
             self.actionThread.join()
         except RuntimeError, e:
             log.warn('Ignoring exception about joining actionThread: %s' % e)
Пример #14
0
 def action_power_toggle(self, cecdev=None):
     '''
     Toggle CEC service power
     @param  adapter  int  CEC service ID
     '''
     if not cecdev:
         cecdev = self.cur_service
     dev = cec.Service(cecdev)
     if dev.is_on:
         dev.power_off()
     elif not dev.is_on:
         dev.power_on()
     else:
         log.warn(
             'powertoggle failed because power status could not be determined'
         )
Пример #15
0
 def shutdown(self):
     AmqpDaemon.shutdown(self)
     #log.info('Shutdown called')
     #self._shutdown = True
     # Send an action message to ourself to make sure
     # we break out of the wait-loop for actions asap.
     #log.info('Send _shutdown action')
     #self.sendShutdownAction()
     #log.info('Wait 0.5')
     time.sleep(0.5)
     log.info('Joining actionThread')
     if self.actionThread:
         try:
             self.actionThread.join()
         except RuntimeError, e:
             log.warn('Ignoring exception about joining actionThread: %s' % e)
Пример #16
0
 def close(self):
     items = []
     if self.channels:
         for item in self.channels:
             items.append(('channel', item))
     if self.conn:
         items.append(('connection', self.conn))
     if self.conn.transport and self.conn.transport.sock:
         items.append(('socket', self.conn.transport.sock))
     for type, obj in items:
         # log.info('Try close %s: %s' % (type,obj))
         try:
             obj.close()
         except Exception as e:
             log.warn('Ignoring fail on close %s: %s' % (type, repr(e)))
     self.channels = []
     self.conn = None
Пример #17
0
 def close(self):
     items = []
     if self.channels:
         for item in self.channels:
             items.append(('channel', item))
     if self.conn:
         items.append(('connection', self.conn))
     if self.conn.transport and self.conn.transport.sock:
         items.append(('socket', self.conn.transport.sock))
     for type, obj in items:
         # log.info('Try close %s: %s' % (type,obj))
         try:
             obj.close()
         except Exception as e:
             log.warn('Ignoring fail on close %s: %s' % (type, repr(e)))
     self.channels = []
     self.conn = None
Пример #18
0
    def onInit(self):
        # Required parameters for pushover
        self.token = self.config.get('token')
        self.username = self.config.get('username')
        if not self.token or self.username:
            log.warn('Service needs token and username to work.')
            sys.exit(1)
        # Optional parameters for pushover
        #  TODO: optionally set default values for these in config
        self.pushurl = 'https://api.pushover.net/1/messages.json'

        self.message = self.config.get('message') or "Chains calling!"
        self.targetdevice = self.config.get('targetdevice')
        self.title = self.config.get('title')
        self.url = self.config.get('url')
        self.urltitle = self.config.get('urltitle')
        self.priority = self.config.getInt('priority') or 1  # "-2" no notification, -1 quiet notification, 1 - high priority, 2 requires confirmation by user
        self.sound = self.config.get('sound') or "bike" # https://pushover.net/api#sounds
Пример #19
0
 def getBridgeConfig(self):
     address = self.config.get('address')
     username = self.config.get('username')
     if not address:
         raise Exception('Must configure address = <ip> or "auto" under [main] in config')
     if not username:
         raise Exception('Must configure username = <username-for-hue-bridge> under [main] in config')
     if address == 'auto':
         from chains.services.philipshue import discovery
         info = discovery.discover()
         if info:
             info = info[0] # todo: handle multiple bridges? 
         if info and info.has_key('internalipaddress'):
             address = info['internalipaddress']
             log.info('discovered bridge-address: %s' % address)
         else:
             log.warn('could not find bridge-address by auto-discovery')
     else:
         log.info('got bridge-address from config: %s' % address)
     return (address, username)
Пример #20
0
    def poll(self):

        data = {}

        keys = [
            'firmware_version', 'power_loss', 'battery_voltage', 'rpi_voltage',
            'sot23_temperature', 'to92_temperature', 'shutdown_time',
            'battery_temperature_on_error', 'ad1', 'ad2'
        ]

        for key in keys:
            func = 'get_%s' % key
            try:
                func = getattr(self, func)
                value = func()
            except Exception, e:
                log.warn("Ignoring error on get %s: %s" %
                         (key, utils.e2str(e)))
                continue
            data[key] = value
Пример #21
0
    def onInit(self):
        # Required parameters for pushover
        self.token = self.config.get('token')
        self.username = self.config.get('username')
        if not self.token or self.username:
            log.warn('Service needs token and username to work.')
            sys.exit(1)
        # Optional parameters for pushover
        #  TODO: optionally set default values for these in config
        self.pushurl = 'https://api.pushover.net/1/messages.json'

        self.message = self.config.get('message') or "Chains calling!"
        self.targetdevice = self.config.get('targetdevice')
        self.title = self.config.get('title')
        self.url = self.config.get('url')
        self.urltitle = self.config.get('urltitle')
        self.priority = self.config.getInt(
            'priority'
        ) or 1  # "-2" no notification, -1 quiet notification, 1 - high priority, 2 requires confirmation by user
        self.sound = self.config.get(
            'sound') or "bike"  # https://pushover.net/api#sounds
Пример #22
0
 def action_op(self, nick, channel=None):
     if not channel: channel = self.channel
     channel = self.addChannelPrefix(channel)
     log.info('do_op1: %s' % channel)
     chanobj = None
     for cn, co in self.channels.items():
         if cn == channel:
             chanobj = co
             break
     if not chanobj:
         msg = 'Cannot op %s on %s because I am not joined to that channel' % (nick, channel)
         self.connection.notice(self.channel, msg)
         log.warn(msg)
         return
     if not self.connection.get_nickname() in chanobj.opers():
         msg = 'Cannot op %s on %s because I am not op on that channel' % (nick, channel)
         self.connection.notice(self.channel, msg)
         log.warn(msg)
         return
     cmd = '+o %s' % nick
     #log.info('do_op: MODE %s %s' % (channel,cmd))
     self.connection.mode(channel, cmd)
Пример #23
0
 def reconnect(self, e):
     if self.connection:
         self.connection.close()
     self.producer = None
     self.consumer = None
     self.connection = None
     delay = 2
     retry = 0
     while True:
         retry += 1
         log.error(
             'Attempting to reconnect #%s and continue in %s sec after socket error: %s'
             % (retry, delay, e))
         time.sleep(delay)
         try:
             self._connect()
             log.error(
                 'Successfully reconnected (after %s retries) - back to work!'
                 % (retry))
             return
         except socket.error as e2:
             log.info(
                 'Ignoring expected exception on reconnect and will soon try again: %s'
                 % repr(e2))
         except amqplib.client_0_8.exceptions.AMQPConnectionException as e2:
             log.info(
                 'Ignoring expected exception on reconnect and will soon try again: %s'
                 % repr(e2))
         except ConnectionNotReadyException as e2:
             log.info(
                 'Ignoring expected exception on reconnect and will soon try again: %s'
                 % repr(e2))
         except Exception as e2:
             log.warn(
                 'Ignoring unexpected exception on reconnect and will soon try again: %s'
                 % repr(e2))
Пример #24
0
 def getBridgeConfig(self):
     address = self.config.get('address')
     username = self.config.get('username')
     if not address:
         raise Exception(
             'Must configure address = <ip> or "auto" under [main] in config'
         )
     if not username:
         raise Exception(
             'Must configure username = <username-for-hue-bridge> under [main] in config'
         )
     if address == 'auto':
         from chains.services.philipshue import discovery
         info = discovery.discover()
         if info:
             info = info[0]  # todo: handle multiple bridges?
         if info and info.has_key('internalipaddress'):
             address = info['internalipaddress']
             log.info('discovered bridge-address: %s' % address)
         else:
             log.warn('could not find bridge-address by auto-discovery')
     else:
         log.info('got bridge-address from config: %s' % address)
     return (address, username)
Пример #25
0
 def onStart(self):
     if not self.hosts:
         log.warn('No hosts to ping')
         return
     started = False
     while not self._shutdown:
         for name in self.hosts:
             host = self.hosts[name]
             if self.ping(host):
                 if self.isDown(host) or not started:
                     self.sendEvent(name, {'value': 'up', 'address': host})
                     try:
                         del self.down[host]
                     except:
                         pass
             else:
                 if not self.isDown(host):
                     self.sendEvent(name, {
                         'value': 'down',
                         'address': host
                     })
                     self.down[host] = True
         started = True
         time.sleep(self.interval)
Пример #26
0
 def reconnect(self, e):
     if self.connection:
         self.connection.close()
     self.producer = None
     self.consumer = None
     self.connection = None
     delay = 2
     retry = 0
     while True:
         retry += 1
         log.error('Attempting to reconnect #%s and continue in %s sec after socket error: %s' % (retry, delay, e))
         time.sleep(delay)
         try:
             self._connect()
             log.error('Successfully reconnected (after %s retries) - back to work!' % (retry))
             return
         except socket.error as e2:
             log.info('Ignoring expected exception on reconnect and will soon try again: %s' % repr(e2))
         except amqplib.client_0_8.exceptions.AMQPConnectionException as e2:
             log.info('Ignoring expected exception on reconnect and will soon try again: %s' % repr(e2))
         except ConnectionNotReadyException as e2:
             log.info('Ignoring expected exception on reconnect and will soon try again: %s' % repr(e2))
         except Exception as e2:
             log.warn('Ignoring unexpected exception on reconnect and will soon try again: %s' % repr(e2))
Пример #27
0
    def closeTelldus(self):

        log.info('Closing telldus')

        try:
            td.unregisterCallback(self.deviceCallbackId)
        except:
            log.warn('ignored error unregistering device callback')

        try:
            td.unregisterCallback(self.sensorCallbackId)
        except:
            log.warn('ignored error unregistering sensor callback')

        try:
            td.close()
        except:
            log.warn('ignored error closing td')
Пример #28
0
    def closeTelldus(self):

        log.info('Closing telldus')

        try:
            td.unregisterCallback(self.deviceCallbackId)
        except:
            log.warn('ignored error unregistering device callback')

        try:
            td.unregisterCallback(self.sensorCallbackId)
        except:
            log.warn('ignored error unregistering sensor callback')

        try:
            td.close()
        except:
            log.warn('ignored error closing td')
Пример #29
0
    def onInit(self):
        self.keymaps = {
            'en_US': [
                '', '', '', '',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
                'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\n', '^]', '^H',
                '^I', ' ', '-', '=', '[', ']', '\\', '>', ';', "'", '`', ',', '.',
                '/', 'CapsLock', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12',
                'PS', 'SL', 'Pause', 'Ins', 'Home', 'PU', '^D', 'End', 'PD', '->', '<-', '-v', '-^', 'NL',
                'KP/', 'KP*', 'KP-', 'KP+', 'KPE', 'KP1', 'KP2', 'KP3', 'KP4', 'KP5', 'KP6', 'KP7', 'KP8',
                'KP9', 'KP0', '\\', 'App', 'Pow', 'KP=', 'F13', 'F14'
            ]
        }

        self.shiftmaps = {
            'en_US': [
                '', '', '', '',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
                'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '\n', '^]', '^H',
                '^I', ' ', '_', '+', '{', '}', '|', '<', ':', '"', '~', '<', '>',
                '?', 'CapsLock', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12',
                'PS', 'SL', 'Pause', 'Ins', 'Home', 'PU', '^D', 'End', 'PD', '->', '<-', '-v', '-^', 'NL',
                'KP/', 'KP*', 'KP-', 'KP+', 'KPE', 'KP1', 'KP2', 'KP3', 'KP4', 'KP5', 'KP6', 'KP7', 'KP8',
                'KP9', 'KP0', '|', 'App', 'Pow', 'KP=', 'F13', 'F14'
            ]
        }

        self.mods = {
            1: 'control_left',  # Left control
            2: 'shift_left',  # Left shift
            4: 'alt_left',  # Left alt
            8: 'super_left',  # Left super
            16: 'control_right',  # Right control
            32: 'shift_right',  # Right shift
            64: 'alt_right',  # Right alt
            128: 'super_right',  # Right super
        }
        # ## Service config
        self.interval = int(self.config.get('interval')) or 10
        self.max_word = int(self.config.get('max_word')) or 50
        self.max_line = int(self.config.get('max_line')) or 250
        self.vendorid = int(self.config.get('vendorid'))
        self.productid = int(self.config.get('productid'))

        self.search_params = {}
        if self.vendorid and self.productid:
            self.search_params.update({'idVendor': self.vendorid, 'idProduct': self.productid})
            kbdevs = cusb.find_keyboard(self.search_params)
        else:
            log.warn("No config, using first found usb keyboard")
            kbdevs = cusb.find_keyboard()
        if not kbdevs:
            log.error("Can't find keyboard")
            sys.exit("Can't find keyboard")
        # Use first matching keyboard
        keyboard = kbdevs[0]
        # ## vendor and product ids
        self.dev = usb.core.find(address=keyboard['address'], bus=keyboard['bus'])
        self.interface = keyboard['interface']
        # use the first endpoint
        # dev[configuration][(interface, alt_config)][endpoint]
        self.endpoint = self.dev[keyboard['configuration']][(keyboard['interface'], 0)][0]
Пример #30
0
    def onInit(self):

        # Channel(s) from config
        defaultChannel = 'chains'
        channels = []
        try:
            channels = self.config['main']['channel'].split(',')
        except KeyError:
            pass
        if not channels:
            channels = ['chains']
            log.warn('Missing or empty "channel" in %s service config, using %s' % (self.config['id'], defaultChannel))
        for i in range(len(channels)):
            channels[i] = self.addChannelPrefix(channels[i].strip())

        # Secret(s)
        secrets = {}
        for k in self.config['main']:
            tmp = k.split('.')
            if len(tmp) == 2 and tmp[0] == 'secret':
                secret[tmp[1]] = self.config['main'][k]

        # Nick
        nickname = 'chainsbot'
        try:
            nickname = self.config['main']['nickname']
        except KeyError:
            log.warn('No "nickname" in %s service config, using %s' % (self.config['id'], nickname))

        # Realname
        realname = 'chainsbot'
        try: realname = self.config['main']['realname']
        except KeyError:
            realname = nickname
            log.info('No "realname" in %s service config, using nickname: %s' % (self.config['id'], nickname))

        # Server
        server = 'localhost'
        try: server = self.config['main']['server']
        except KeyError:
            log.warn('No "server" in %s service config, using %s' % (self.config['id'], server))

        # Port
        port = 6667
        try: port = int(self.config['main']['port'])
        except KeyError:
            log.warn('No "port" in %s service config, using %s' % (self.config['id'], str(port)))

        def onStart(self):
        # For handelig async stuff
        self.waitEvents = {}

        SingleServerIRCBot.__init__(self, [(server, port)], nickname, realname)
        self.allChannels = channels
        self.channel = channels[0] # first chan is default chan
        log.info('all configured channels: %s' % self.allChannels)
        log.info('configured main channel: %s' % self.channel)
        self.secrets = secrets
        self.help_hash = {'help':('This menu',{}),
                        }
        self.queue = OutputManager(self.connection, .9)
        self.queue.start()
        try:
            self.start()
        except KeyboardInterrupt:
            self.connection.quit("Ctrl-C at console")
            print "Quit IRC."
        except Exception, e:
            self.connection.quit("%s: %s" % (e.__class__.__name__, e.args))
        raise
Пример #31
0
                'Not configured to use services_discover() to find services')

        if self.config.getBool('lookup'):
            log.debug('Using lookup_name() to find services')
            try:
                for addr in self.guests:
                    name = bluetooth.lookup_name(addr)
                    if name:
                        log.debug('Found service: %s' % addr)
                        result.append(addr)
                    else:
                        log.debug('Did not find service: %s' % addr)
            # This happens from time to time, and we don't want to die because of it:
            # BluetoothError: error communicating with local bluetooth adapter
            except bluetooth.btcommon.BluetoothError, e:
                log.warn('BluetoothError ignored: %s' % e)
        else:
            log.debug('Not configured to use lookup_name() to find services')

        log.debug('Finished getting blueooth services')

        return result

    def guestsToState(self):
        for mac, nick in self.guests.iteritems():
            self.addToState(mac, False, nick)

    def addToState(self, address, present, nick=None):
        self.state[address] = {
            'name':
            None,  # name that service identifies itself by via bluetooth
Пример #32
0
    def onInit(self):
        self.keymaps = {
            'en_US': [
                '', '', '', '', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7',
                '8', '9', '0', '\n', '^]', '^H', '^I', ' ', '-', '=', '[', ']',
                '\\', '>', ';', "'", '`', ',', '.', '/', 'CapsLock', 'F1',
                'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11',
                'F12', 'PS', 'SL', 'Pause', 'Ins', 'Home', 'PU', '^D', 'End',
                'PD', '->', '<-', '-v', '-^', 'NL', 'KP/', 'KP*', 'KP-', 'KP+',
                'KPE', 'KP1', 'KP2', 'KP3', 'KP4', 'KP5', 'KP6', 'KP7', 'KP8',
                'KP9', 'KP0', '\\', 'App', 'Pow', 'KP=', 'F13', 'F14'
            ]
        }

        self.shiftmaps = {
            'en_US': [
                '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
                'V', 'W', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '^', '&',
                '*', '(', ')', '\n', '^]', '^H', '^I', ' ', '_', '+', '{', '}',
                '|', '<', ':', '"', '~', '<', '>', '?', 'CapsLock', 'F1', 'F2',
                'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12',
                'PS', 'SL', 'Pause', 'Ins', 'Home', 'PU', '^D', 'End', 'PD',
                '->', '<-', '-v', '-^', 'NL', 'KP/', 'KP*', 'KP-', 'KP+',
                'KPE', 'KP1', 'KP2', 'KP3', 'KP4', 'KP5', 'KP6', 'KP7', 'KP8',
                'KP9', 'KP0', '|', 'App', 'Pow', 'KP=', 'F13', 'F14'
            ]
        }

        self.mods = {
            1: 'control_left',  # Left control
            2: 'shift_left',  # Left shift
            4: 'alt_left',  # Left alt
            8: 'super_left',  # Left super
            16: 'control_right',  # Right control
            32: 'shift_right',  # Right shift
            64: 'alt_right',  # Right alt
            128: 'super_right',  # Right super
        }
        # ## Service config
        self.interval = int(self.config.get('interval')) or 10
        self.max_word = int(self.config.get('max_word')) or 50
        self.max_line = int(self.config.get('max_line')) or 250
        self.vendorid = int(self.config.get('vendorid'))
        self.productid = int(self.config.get('productid'))

        self.search_params = {}
        if self.vendorid and self.productid:
            self.search_params.update({
                'idVendor': self.vendorid,
                'idProduct': self.productid
            })
            kbdevs = cusb.find_keyboard(self.search_params)
        else:
            log.warn("No config, using first found usb keyboard")
            kbdevs = cusb.find_keyboard()
        if not kbdevs:
            log.error("Can't find keyboard")
            sys.exit("Can't find keyboard")
        # Use first matching keyboard
        keyboard = kbdevs[0]
        # ## vendor and product ids
        self.dev = usb.core.find(address=keyboard['address'],
                                 bus=keyboard['bus'])
        self.interface = keyboard['interface']
        # use the first endpoint
        # dev[configuration][(interface, alt_config)][endpoint]
        self.endpoint = self.dev[keyboard['configuration']][(
            keyboard['interface'], 0)][0]
Пример #33
0
            log.debug('Not configured to use services_discover() to find services')

        if self.config.getBool('lookup'):
            log.debug('Using lookup_name() to find services')
            try:
                for addr in self.guests:
                    name = bluetooth.lookup_name(addr)
                    if name:
                        log.debug('Found service: %s' % addr)
                        result.append(addr)
                    else:
                        log.debug('Did not find service: %s' % addr)
            # This happens from time to time, and we don't want to die because of it:
            # BluetoothError: error communicating with local bluetooth adapter
            except bluetooth.btcommon.BluetoothError,e:
                log.warn('BluetoothError ignored: %s' % e)
        else:
            log.debug('Not configured to use lookup_name() to find services')

        log.debug('Finished getting blueooth services')

        return result

    def guestsToState(self):
        for mac, nick in self.guests.iteritems():
            self.addToState(mac, False, nick)

    def addToState(self, address, present, nick=None):
        self.state[address] = {
            'name': None,         # name that service identifies itself by via bluetooth
            'nick': nick,         # friendly name for guest from config
Пример #34
0
                self.actionThread.join()
            except RuntimeError, e:
                log.warn('Ignoring exception about joining actionThread: %s' % e)
        log.info('actionThread done')
        log.info('Running onShutdown()')
        try:
            self.onShutdown()
        except Exception, e:
            log.warn('Ignoring exception during onShutdown: %s' % e)
        log.info('Finished running onShutdown()')
        log.info('Joining eventThread')
        if self.eventThread:
            try:
                self.eventThread.join()
            except RuntimeError, e:
                log.warn('Ignoring exception about joining eventThread: %s' % e)
        log.info('eventThread done')
        # Send an event about being online
        log.info('Send offline event')
        try:
            self.sendOfflineEvent()
        except Exception, e:
            log.warn('Ignoring exception during sendOfflineEvent: %s' % e)
        time.sleep(1)
        log.info('Shutdown complete')

    # =============================================
    # Lifecycle functions,
    # that can be implemented as needed.
    # None of these are required.
    # =============================================
Пример #35
0
 def action_setLogLevel(self, level):
     log.setLevel(level)
     log.warn('Changed loglevel to "%s" during runtime' % level)
Пример #36
0
 def onInit(self):
     self.button_events = [
         array('B', [1, 0, 0, 0, 0, 0, 0]),
         'button_release',
         array('B', [1, 1, 0, 0, 0, 0, 0]),
         'button_left',
         array('B', [1, 2, 0, 0, 0, 0, 0]),
         'button_right',
         array('B', [1, 4, 0, 0, 0, 0, 0]),
         'button_middle',
         array('B', [1, 8, 0, 0, 0, 0, 0]),
         'button_3',
         array('B', [1, 16, 0, 0, 0, 0, 0]),
         'button_4',
         array('B', [1, 32, 0, 0, 0, 0, 0]),
         'button_5',
         array('B', [1, 64, 0, 0, 0, 0, 0]),
         'button_6',
         array('B', [1, 128, 0, 0, 0, 0, 0]),
         'button_7',
         array('B', [1, 255, 0, 0, 0, 0, 0]),
         'button_8',
         array('B', [1, 0, 0, 0, 0, 0, 1]),
         'wheel_up',
         array('B', [1, 0, 0, 0, 0, 0, 255]),
         'wheel_down',
         # mouse button combinations
         # TODO: do this by using bitwise operator to generate all combinations
         array('B', [1, 3, 0, 0, 0, 0, 0]),
         'button_left_right',
         array('B', [1, 5, 0, 0, 0, 0, 0]),
         'button_left_middle',
         array('B', [1, 6, 0, 0, 0, 0, 0]),
         'button_right_middle',
         array('B', [1, 7, 0, 0, 0, 0, 0]),
         'button_left_right_middle',
     ]
     # "slow" mouse movements
     self.move_events = [
         array('B', [1, 0, 0, 0, 1, 0, 0]),
         'down',
         array('B', [1, 0, 255, 255, 1, 0, 0]),
         'down-left',
         array('B', [1, 0, 1, 0, 1, 0, 0]),
         'down-right',
         array('B', [1, 0, 0, 0, 255, 255, 0]),
         'up',
         array('B', [1, 0, 255, 255, 255, 255, 0]),
         'up-left',
         array('B', [1, 0, 1, 0, 255, 255, 0]),
         'up-right',
         array('B', [1, 0, 255, 255, 0, 0, 0]),
         'left',
         array('B', [1, 0, 1, 0, 0, 0, 0]),
         'right',
     ]
     # ## Service config
     self.interval = int(self.config.get('interval')) or 600  # milliseconds
     self.vendorid = int(self.config.get('vendorid'))
     self.productid = int(self.config.get('productid'))
     self.search_params = {}
     if self.vendorid and self.productid:
         self.search_params.update({
             'idVendor': self.vendorid,
             'idProduct': self.productid
         })
         mousedevs = cusb.find_mouse(self.search_params)
     else:
         log.warn("No config, using first found mouse service")
         mousedevs = cusb.find_mouse()
     if not mousedevs:
         log.error("Can't find mouse service")
         sys.exit("Can't find mouse service")
     # Use first matching mouse
     mouse = mousedevs[0]
     # ## vendor and product ids
     self.dev = usb.core.find(address=mouse['address'], bus=mouse['bus'])
     self.interface = mouse['interface']
     # use the first endpoint
     # dev[configuration][(interface, alt_config)][endpoint]
     self.endpoint = self.dev[mouse['configuration']][(mouse['interface'],
                                                       0)][0]
Пример #37
0
class Service(AmqpDaemon):
    '''
    Service - base class for all services

    A Service's mission is to send events and respond to actions.
    Typical approach for a service is this:

    == Init ==
    In onInit(), do any setup-tasks that does not block forever,
    like making sure relevant config settings are okay, opening
    a serial port, checking for needed files etc.

    == Run ==
    In onStart(), do any "while true do this" tasks that block forever,
    like polling values from an external interface and sending events,
    or running a webserver that listens forever, or reading from the
    serial port etc.

    == Actions ==
    Implement a number of cmd_xxx() functions, one for each action
    that the service can perform.

    == Shutdown ==
    In onShutdown() do any cleanup tasks if necceceary.
    Note however that this is not guaranteed to be run!

    == Describe ==
    In onDescribe() describe the various events that the service
    can send. You can also describe the actions, but if you use
    the cmd_xxx() approach, you should not need to.
    Implementing onDescribe() is optional, but should be done
    (eventually) to lay the grounds for a nice rules-creation-gui
    in the future.

    See documentation of each method below for more info.
    '''

    # Signals that shutdown is in progress.
    # If this is changed to True (by shutdown()),
    # then any "while forever do this and that" loops
    # should shop doing whatever they're doing.
    _shutdown = False

    # =============================================
    # Core functions,
    # that should (usually) not be overriden.
    # =============================================

    def __init__(self, config):
        AmqpDaemon.__init__(self, 'service', config.get('id')) #, sendHeartBeat=True)
        self.config = config
        self.eventThread = None
        self.actionThread = None
        self.onInit()

    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 shutdown(self):
        AmqpDaemon.shutdown(self)
        #log.info('Shutdown called')
        #self._shutdown = True
        # Send an action message to ourself to make sure
        # we break out of the wait-loop for actions asap.
        #log.info('Send _shutdown action')
        #self.sendShutdownAction()
        #log.info('Wait 0.5')
        time.sleep(0.5)
        log.info('Joining actionThread')
        if self.actionThread:
            try:
                self.actionThread.join()
            except RuntimeError, e:
                log.warn('Ignoring exception about joining actionThread: %s' % e)
        log.info('actionThread done')
        log.info('Running onShutdown()')
        try:
            self.onShutdown()
        except Exception, e:
            log.warn('Ignoring exception during onShutdown: %s' % e)
Пример #38
0
 def action_setLogLevel(self, level):
     log.setLevel(level)
     log.warn('Changed loglevel to "%s" during runtime' % level)
Пример #39
0
        while True:
            retry += 1
            log.error('Attempting to reconnect #%s and continue in %s sec after socket error: %s' % (retry,delay,e))
            time.sleep(delay)
            try:
                self._connect()
                log.error('Successfully reconnected (after %s retries) - back to work!' % (retry))
                return
            except socket.error, e2:
                log.info('Ignoring expected exception on reconnect and will soon try again: %s' % e2)
            except amqplib.client_0_8.exceptions.AMQPConnectionException, e2:
                log.info('Ignoring expected exception on reconnect and will soon try again: %s' % e2)
            except ConnectionNotReadyException, e2:
                log.info('Ignoring expected exception on reconnect and will soon try again: %s' % e2)
            except Exception, e2:
                log.warn('Ignoring unexpected exception on reconnect and will soon try again: %s' % e2)

    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
Пример #40
0
                self.actionThread.join()
            except RuntimeError, e:
                log.warn('Ignoring exception about joining actionThread: %s' % e)
        log.info('actionThread done')
        log.info('Running onShutdown()')
        try:
            self.onShutdown()
        except Exception, e:
            log.warn('Ignoring exception during onShutdown: %s' % e)
        log.info('Finished running onShutdown()')
        log.info('Joining eventThread')
        if self.eventThread:
            try:
                self.eventThread.join()
            except RuntimeError, e:
                log.warn('Ignoring exception about joining eventThread: %s' % e)
        log.info('eventThread done')
        # Send an event about being online
        log.info('Send offline event')
        try:
            self.sendOfflineEvent()
        except Exception, e:
            log.warn('Ignoring exception during sendOfflineEvent: %s' % e)
        time.sleep(1)
        log.info('Shutdown complete')

    # =============================================
    # Lifecycle functions,
    # that can be implemented as needed.
    # None of these are required.
    # =============================================