protected void parseDecodedCommand(String itemName, IrCommand theCommand, Command ohCommand) { if (theCommand != null) { // traverse the providers, for each provider, check each binding if it matches theCommand for (IRtransBindingProvider provider : providers) { if (provider.providesBindingFor(itemName)) { List<org.openhab.core.types.Command> commands = provider.getAllCommands(itemName); // first check if commands are defined, and that they have the correct DirectionType Iterator<org.openhab.core.types.Command> listIterator = commands.listIterator(); while (listIterator.hasNext()) { org.openhab.core.types.Command aCommand = listIterator.next(); IrCommand providerCommand = new IrCommand(); providerCommand.remote = provider.getRemote(itemName, aCommand); providerCommand.command = provider.getIrCommand(itemName, aCommand); if (aCommand == ohCommand) { if (providerCommand.matches(theCommand)) { List<Class<? extends State>> stateTypeList = provider.getAcceptedDataTypes(itemName, aCommand); State newState = null; if (aCommand instanceof DecimalType) { newState = createStateFromString( stateTypeList, theCommand.remote + "," + theCommand.command); } else { newState = createStateFromString(stateTypeList, aCommand.toString()); } if (newState != null) { eventPublisher.postUpdate(itemName, newState); } else { logger.warn( "Can not create an Item State to match command {} on item {} ", aCommand, itemName); } } else { logger.info( "The IRtrans command '{},{}' does not match the command '{}' of the binding configuration for item '{}'", new Object[] {theCommand.remote, theCommand.command, ohCommand, itemName}); } } } } } } }
protected void parseIRDBMessage(String itemName, String message, Command ohCommand) { Pattern IRDB_PATTERN = Pattern.compile("RCV_COM (.*),(.*),(.*),(.*)"); Matcher matcher = IRDB_PATTERN.matcher(message); if (matcher.matches()) { IrCommand theCommand = new IrCommand(); theCommand.remote = matcher.group(1); theCommand.command = matcher.group(2); parseDecodedCommand(itemName, theCommand, ohCommand); } else { logger.error( "{} does not match the IRDB IRtrans message format ({})", message, matcher.pattern()); } }
/** * Fetch the IrCommand that corresponds with the given (hex)String. * * @param someString the some string * @return the ir command */ protected IrCommand getIrCommand(String someString) { IrCommand theCommand = null; if (someString != null) { // Run through the dB if IrCommands to see which one is matching, if any, the payload we just // received Iterator<IrCommand> commandIterator = irCommands.iterator(); while (commandIterator.hasNext()) { IrCommand aCommand = commandIterator.next(); if (aCommand.sequenceToHEXString().equals(someString)) { theCommand = aCommand; break; } } } return theCommand; }
/** * "Pack" the infrared command so that it can be sent to the IRTrans device * * @param led the led * @param theCommand the the command * @return a string which is the full command to be sent to the device */ protected String packHexCommand(Leds led, IrCommand theCommand) { String output = new String(); output = "Asndhex "; output += "L"; switch (led) { case ALL: output += "B"; break; case ONE: output += "1"; break; case TWO: output += "2"; break; case THREE: output += "3"; break; case FOUR: output += "4"; break; case FIVE: output += "5"; break; case SIX: output += "6"; break; case SEVEN: output += "7"; break; case EIGHT: output += "8"; break; case INTERNAL: output += "I"; break; case EXTERNAL: output += "E"; break; case DEFAULT: output += "D"; break; } output += ","; output += "H" + theCommand.toHEXString(); output += (char) 13; return output; }
/** {@inheritDoc} */ @Override protected boolean internalReceiveChanneledCommand( String itemName, Command command, Channel sChannel, String commandAsString) { IRtransBindingProvider provider = findFirstMatchingBindingProvider(itemName); String remoteName = null; String irCommandName = null; if (command != null && provider != null) { if (command instanceof DecimalType) { remoteName = StringUtils.substringBefore(commandAsString, ","); irCommandName = StringUtils.substringAfter(commandAsString, ","); IrCommand firstCommand = new IrCommand(); firstCommand.remote = remoteName; firstCommand.command = irCommandName; IrCommand secondCommand = new IrCommand(); secondCommand.remote = provider.getRemote(itemName, command); secondCommand.command = provider.getIrCommand(itemName, command); if (!firstCommand.matches(secondCommand)) { remoteName = null; irCommandName = null; } } else { remoteName = provider.getRemote(itemName, command); irCommandName = provider.getIrCommand(itemName, command); } } if (remoteName != null && irCommandName != null) { Leds led = provider.getLed(itemName, command); IrCommand theCommand = new IrCommand(); theCommand.remote = remoteName; theCommand.command = irCommandName; // construct the string we need to send to the IRtrans device String output = packIRDBCommand(led, theCommand); ByteBuffer outputBuffer = ByteBuffer.allocate(output.getBytes().length); ByteBuffer response = null; try { outputBuffer.put(output.getBytes("ASCII")); response = writeBuffer(outputBuffer, sChannel, true, timeOut); } catch (UnsupportedEncodingException e) { logger.error( "An exception occurred while encoding an infrared command: {}", e.getMessage()); } if (response != null) { String message = stripByteCount(response); if (message != null) { if (message.contains("RESULT OK")) { List<Class<? extends State>> stateTypeList = provider.getAcceptedDataTypes(itemName, command); State newState = createStateFromString(stateTypeList, commandAsString); if (newState != null) { eventPublisher.postUpdate(itemName, newState); } else { logger.warn( "Can not parse " + commandAsString + " to match command {} on item {} ", command, itemName); } } else { logger.warn( "Received an unexpected response {}", StringUtils.substringAfter(message, "RESULT ")); } } } else { logger.warn("Did not receive an answer from the IRtrans device - Parsing is skipped"); } } else { logger.warn( "Invalid command {} for Item {} - Transmission is skipped", commandAsString, itemName); } // we will always return false, because the irBinding itself will postUpdate new values, the // underlying tcp // binding should // not deal with that anymore. return false; }