def didl_parse(xml, xmlpath, xslpath, delimiter, standardtags, tags = None, returnresult = None): "retrieving audio tags from response xml" didl_xml = OHcommons.xml_prepare(xml, xmlpath, 'string') didl_xsl = OHcommons.xsl_prepare('didl', xslpath) returnstring = None if tags == None: for tag in standardtags.split(','): tagvalue = OHcommons.xsl_transform(didl_xml, didl_xsl, tag) if str(tagvalue) == '': tagvalue = '-' if returnstring == None: returnstring = str(tagvalue) else: returnstring = returnstring + delimiter + str(tagvalue) else: for tag in tags: tagvalue = OHcommons.xsl_transform(didl_xml, didl_xsl, tag) if returnstring == None: returnstring = str(tagvalue) else: returnstring = returnstring + delimiter + str(tagvalue) if returnresult == None: print returnstring return else: return returnstring
def device_handler(config, devices, descriptions, available_devices, units_used): logging.info('Device handler started. Entering service loop ...') while True: time.sleep(60) while config['message'] != '': logging.info('Device handler blocked (' + config['message'] + '). Waiting ...') if config['message'] == 'device': logging.warning('Device is blocking itself. Removing block.') config['message'] = '' time.sleep(10) config['message'] = 'device' for product, device in devices: if product == 'product': logging.debug('search for device: ' + device + ' ' + devices[product, device]) args = prepare_arguments('openhab', device, devices[product, device]) logging.debug(args) keep_going = True result = OHcommons.search(args, devices, config, keep_going) if result != None: if device not in available_devices: descriptions[device] = result available_devices.append(device) logging.info('New device ' + device + ' added to list of available devices.') config['message'] = 'newdevice' else: if device in available_devices: available_devices.remove(device) logging.info( 'Device ' + device + ' now offline. Deleting from list of available devices.' ) if device in units_used.keys(): for unit in units_used[device]: try: logging.info('Delete subscription for ' + device + ' and event url ' + unit[1] + '.') del unit[1:] except: logging.warning('Subscription for ' + device + ' was already deleted.') del descriptions[device] logging.info('Service loop done. Available devices: ' + str(available_devices) + '.') if config['message'] == 'device': config['message'] = '' return
def command_handler(config, devices, descriptions, available_devices): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.settimeout(600) sock.bind(('', int(config['cmdport']))) sock.listen(5) logging.debug("command socket is set up") while True: header, command = listen2port(sock) if command != None: logging.info('Command received: ' + command) args_command = command.split(' ') if args_command[0] == 'command': try: args = OHcustoms.set_arguments(args_command) unit = args.unit[0] name = args.name[0] if name in available_devices: if unit != 'Custom': OHcommons.command(args, devices, config, False, descriptions[name]) else: OHcustoms.command(args, devices, config, descriptions[name]) else: logging.warning( 'Command for device ' + name + ' received but not available - skipping.') except Exception as er: logging.error(er) else: logging.warning('Message received was no command - skipping.') else: if header != None: logging.warning('Received None as body - skipping. Header: ' + str(header)) else: logging.warning('Received None as header and body - skipping.')
def search(config, devices): 'search all products in config given and return descriptions' available_devices = [] descriptions = {} for product, device in devices: if product == 'product': logging.debug('search for device: ' + device + ' ' + devices[product, device]) args = prepare_arguments('openhab', device, devices[product, device]) logging.debug(args) keep_going = True result = OHcommons.search(args, devices, config, keep_going) if result != None: descriptions[device] = result available_devices.append(device) logging.info('Devices found: ' + str(available_devices) + '.') return descriptions, available_devices
def parse_event(text, action, state_var, path): xml = OHcommons.xml_prepare(text, '', 'string') xsl = OHcommons.xsl_prepare('OHevent', path) result = OHcommons.xsl_transform(xml, xsl, action, state_var) return str(result)
def subscription_handler(descriptions, available_devices, config, units_used, state_vars): 'initialize subscriptions for all available devices' timeouts = [] for device in available_devices: logging.info('Processing ' + device + ' ...') if device in units_used.keys(): for unit in units_used[device]: xsl = OHcommons.xsl_prepare('description', config['xslpath']) result = OHcommons.xsl_transform(descriptions[device]['xml'], xsl, 'event_url', unit[0]) if str(result) != '': unit.append(descriptions[device]['baseurl'] + str(result)) sid, timeout = subscribe('subscribe', device, descriptions[device]['baseurl'], str(result), \ config['callback'], config['port']) if timeout != None: timeouts.append(int(timeout)) if sid != None: unit.append(sid) logging.info('Processing ' + device + ' finished.') logging.debug('units: ' + str(units_used)) try: timeout = min(timeouts) / 2 except: timeout = 300 logging.debug('timeout: ' + str(timeout)) logging.info( 'Initial device search and subscription done. Entering serice loop ...' ) while True: for counter in xrange(1, 10): time.sleep(int(timeout / 10)) if config['message'] == 'newdevice': config['message'] = '' break while config['message'] != '': logging.info('Subscription handler blocked (' + config['message'] + '). Waiting ...') if config['message'] == 'subscription': logging.warning( 'Subscription is blocking itself. Removing block.') config['message'] = '' if config['message'] == 'newdevice': config['message'] = '' break time.sleep(10) config['message'] = 'subscription' for device in available_devices: logging.info('Processing ' + device + ' ...') if device in units_used.keys(): for unit in units_used[device]: if len(unit) > 1: if subscribe('renew', device, unit[1], '', '', config['port'], unit[2]): logging.info('Subscription for ' + device + ' event url ' + unit[1] + ' renewed.') else: del unit[1:] logging.info('Subscription for ' + device + ' failed. Deleting sid from list.') else: xsl = OHcommons.xsl_prepare('description', config['xslpath']) result = OHcommons.xsl_transform( descriptions[device]['xml'], xsl, 'event_url', unit[0]) if str(result) != '': unit.append(descriptions[device]['baseurl'] + str(result)) sid, timeout = subscribe('subscribe', device, descriptions[device]['baseurl'], str(result), \ config['callback'], config['port']) if timeout != None: timeouts.append(int(timeout)) if sid != None: unit.append(sid) logging.info('Processing ' + device + ' finished.') timeouts = list(set(timeouts)) try: timeout = min(timeouts) / 2 except: timeout = 300 logging.debug('timeout: ' + str(timeout)) logging.info('Subscription loop done. Timeout: ' + str(timeout) + '.') config['message'] = '' return
def command(args, devices, config, description = None): if args.command[0] in ['Fakeradio', 'NextRadiostation', 'Radiostation', 'SetSender', \ 'SourceText', 'Status', 'ToggleMute', 'TogglePlay', 'TrackParse']: "Process custom commands" logging.debug('Running custom command ' + args.command[0]) customcommand = True if args.command[0] == 'TrackParse': "TrackParse" tags = args.output args = prepare_arguments(args, 'Info', [ 'Track', '-o', 'Metadata']) result = OHcommons.command(args, devices, config, customcommand, description) didl_parse(result, config['xmlpath'], config['xslpath'], \ config['xmltagdelimiter'], config['standardtags'], tags) elif args.command[0] == 'TogglePlay': "TogglePlay" args = prepare_arguments(args, 'Playlist', ['TransportState']) result = OHcommons.command(args, devices, config, customcommand, description) logging.debug('-----') if result in ['Paused', 'Stopped']: args = prepare_arguments(args, 'Playlist', ['Play']) elif result == 'Playing': args = prepare_arguments(args, 'Playlist', ['Pause']) OHcommons.command(args, devices, config, customcommand, description) elif args.command[0] in ['SourceText', 'Radiostation', 'NextRadiostation']: "SourceText Radiostation and NextRadiostation" args_backup = args args = prepare_arguments(args, 'Product', ['SourceIndex', '-o', 'Value']) source_id = OHcommons.command(args, devices, config, customcommand, description) logging.debug('-----') if args_backup.command[0] == 'SourceText': args = prepare_arguments(args, 'Product', ['Source', '-i', 'Index=' + source_id, '-o', 'Name']) source = OHcommons.command(args, devices, config, customcommand, description) print source return elif args_backup.command[0] == 'Radiostation': if source_id != '1': args = prepare_arguments(args, 'Product', ['SetSourceIndexByName', '-i', 'Value=Radio']) OHcommons.command(args, devices, config, False, description) args = prepare_arguments(args, 'Radio', ['SetId', '-i', args_backup.input[0], 'Uri=']) OHcommons.command(args, devices, config, False, description) args = prepare_arguments(args, 'Radio', ['Play']) OHcommons.command(args, devices, config, False, description) elif args_backup.command[0] == 'NextRadiostation': args = prepare_arguments(args, 'Radio', ['Id', '-o', 'Value']) station = OHcommons.command(args, devices, config, customcommand, description) logging.debug('Current Station: ' + station) args = prepare_arguments(args, 'Radio', ['TransportState', '-o', 'Value']) state = OHcommons.command(args, devices, config, customcommand, description) if source_id != '1': args = prepare_arguments(args, 'Product', ['SetSourceIndexByName', '-i', 'Value=Radio']) if station == '0': OHcommons.command(args, devices, config, False, description) args = prepare_arguments(args, 'Radio', ['SetId', '-i', 'Value=1', 'Uri=']) OHcommons.command(args, devices, config, False, description) else: if source_id == '1' and state == 'Playing': ind = config['stations'].index(station) if len(config['stations']) <= ind + 1: newstation = config['stations'][0] else: newstation = config['stations'][ind +1] logging.debug('Next Station: ' + newstation) args = prepare_arguments(args, 'Radio', ['SetId', '-i', 'Value=' + newstation, 'Uri=']) OHcommons.command(args, devices, config, False, description) args = prepare_arguments(args, 'Radio', ['Play']) OHcommons.command(args, devices, config, False, description) else: args = prepare_arguments(args, 'Radio', ['Play']) OHcommons.command(args, devices, config, False, description) elif args.command[0] == 'ToggleMute': "Switch Mute on and off" args = prepare_arguments(args, 'Volume', ['Mute', '-o', 'Value']) result = OHcommons.command(args, devices, config, customcommand, description) if result == '1': args = prepare_arguments(args, 'Volume', ['SetMute', '-i', 'Value=0']) OHcommons.command(args, devices, config, customcommand, description) else: args = prepare_arguments(args, 'Volume', ['SetMute', '-i', 'Value=1']) OHcommons.command(args, devices, config, customcommand, description) logging.debug('-----') elif args.command[0] == 'Status': "return modified transport state" args = prepare_arguments(args, 'Playlist', ['TransportState', '-o', 'Value']) result = OHcommons.command(args, devices, config, customcommand, description) if result == 'Playing': print 'Play' elif result == 'Paused': print 'Pause' else: print 'Stop' logging.debug('-----') elif args.command[0] == 'Fakeradio': "emulate Radio Interface" customxml = config['fakeradio', args.input[0].split('=')[1]] args = prepare_arguments(args, 'Playlist', ['DeleteAll']) OHcommons.command(args, devices, config, customcommand, description) args = prepare_arguments(args, 'Playlist', ['Insert']) OHcommons.command(args, devices, config, customcommand, description, customxml) args = prepare_arguments(args, 'Playlist', ['Play']) OHcommons.command(args, devices, config, customcommand, description) logging.debug('-----') elif args.command[0] == 'SetSender': ipt = args.input[0].split('=') if ipt[0] == 'uuid': uuid = ipt[1] elif ipt[0] == 'name': logging.debug('Try to resolve ' + ipt[1]) uuid = devices['sender', ipt[1]] args_backup = args logging.debug(uuid) "add current ds to sender group specified by uuid or name" args = prepare_arguments(args, 'Sender', ['Metadata', '-o', 'Value'], uuid) metadata = OHcommons.command(args, devices, config, customcommand) Uri = didl_parse(metadata, config['xmlpath'], config['xslpath'], \ config['xmltagdelimiter'], config['standardtags'], ['Uri'], 'returnresult') args = prepare_arguments(args_backup, 'Receiver', \ ['SetSender', '-i', 'Uri=' + Uri, 'Metadata=' + metadata]) print args OHcommons.command(args, devices, config, customcommand, description) args = prepare_arguments(args, 'Receiver', ['Play']) OHcommons.command(args, devices, config, customcommand, description) else: logging.error('Custom command ' + args.command[0] + ' is not supported.') sys.exit(5) return
logger = logging.getLogger() logger.setLevel(numeric_level) logger.addHandler(log_handler) logging.debug('logging started') elif args.log == ["systemd"]: from systemd.journal import JournalHandler logger = logging.getLogger() logger.setLevel(numeric_level) logger.addHandler(JournalHandler(SYSLOG_IDENTIFIER='OHsentinel')) logging.debug('logging started') logging.debug('Used configuration: ' + str(config)) logging.debug('Known devices: ' + str(devices)) return args, config, devices args, config, devices = init() logging.debug(args) if args.mode == 'search': OHcommons.search(args, devices, config) elif args.mode == 'command': if args.unit[0] == 'Custom': "Process command in custom unit" OHcustoms.command(args, devices, config) else: "Process standard command" OHcommons.command(args, devices, config) elif args.mode == 'explore': OHcommons.explore(args, devices, config) elif args.mode == 'remote': OHcommons.remote(args, devices, config)