/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.mochadx10.internal; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openhab.binding.mochadx10.commands.MochadX10Address; import org.openhab.binding.mochadx10.commands.MochadX10BrightCommand; import org.openhab.binding.mochadx10.commands.MochadX10Command; import org.openhab.binding.mochadx10.commands.MochadX10DimCommand; import org.openhab.binding.mochadx10.commands.MochadX10OffCommand; import org.openhab.binding.mochadx10.commands.MochadX10OnCommand; import org.openhab.core.events.EventPublisher; /** * The command parser is used to convert incoming Mochad X10 messages into * MochadX10Commands. Furthermore, it keeps track of the last used house code * and unit code. This is needed because some commands received only specify the * house code and assume the unit code is the same as in the previous command. * * @author Jack Sleuters * @since 1.7.0 */ public class MochadX10CommandParser { /** * Pattern for parsing a Mochad X10 dim command */ static final Pattern DIM_PATTERN = Pattern.compile("dim(\\((?<value>[0-9]*)\\))?"); /** * Pattern for parsing a Mochad X10 bright command */ static final Pattern BRIGHT_PATTERN = Pattern.compile("bright(\\((?<value>[0-9]*)\\))?"); /** * The unit code used by the previous command */ private String previousUnitCode = ""; /** * The house code used by the previous command */ private String previousHouseCode = ""; /** * The pattern to parse a received message containing 'HouseUnit:'. * * For example: * * 02/22 15:50:02 Rx PL HouseUnit: B3 */ private static final Pattern HOUSEUNIT_COMMAND = Pattern .compile("[0-9]{2}/[0-9]{2}\\s[0-9]{2}:[0-9]{2}:[0-9]{2}\\sRx\\s((RF)|(PL))\\sHouseUnit:\\s" + "(?<houseCode>[A-P])(?<unitCode>[0-9]*)(\\sFunc:\\s(?<command>.+))?"); /** * The pattern to parse a received message containing 'House:'. * * For example: * * 02/22 15:50:08 Rx PL House: B Func: Bright(13) */ private Pattern HOUSE_COMMAND = Pattern .compile("[0-9]{2}/[0-9]{2}\\s[0-9]{2}:[0-9]{2}:[0-9]{2}\\sRx\\s((RF)|(PL))\\sHouse:\\s" + "(?<houseCode>[A-P])\\sFunc:\\s(?<command>.+)"); /** * The eventPublisher to be passed to MochadX10Commands so that they can execute * postCommand. */ private EventPublisher eventPublisher; /** * Constructor * * @param eventPublisher required to post an event on the openhab bus */ public MochadX10CommandParser(EventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } /** * Parse the received message and create a corresponding MochadX10Command for it. * * @param msg The message received from the Mochad X10 host * @return A MochadX10Command if parsing was successful, otherwise null */ public MochadX10Command parse(String msg) { String command = null; Matcher huc_matcher = HOUSEUNIT_COMMAND.matcher(msg); if (huc_matcher.matches()) { previousHouseCode = huc_matcher.group("houseCode").toLowerCase(); previousUnitCode = huc_matcher.group("unitCode"); try { command = huc_matcher.group("command"); } catch (IllegalArgumentException e) { } if (command != null) { return parseCommand(new MochadX10Address(previousHouseCode, previousUnitCode), command); } else { return null; } } Matcher hc_matcher = HOUSE_COMMAND.matcher(msg); if (hc_matcher.matches()) { String houseCode = hc_matcher.group("houseCode").toLowerCase(); if (houseCode.equals(previousHouseCode)) { return parseCommand(new MochadX10Address(previousHouseCode, previousUnitCode), hc_matcher.group("command")); } } return null; } @Override public String toString() { return "MochadX10CommandParser [previousUnitCode=" + previousUnitCode + ", previousHouseCode=" + previousHouseCode + "]"; } /** * Parse the command part of the received message. * * @param address The X10 address of the command * @param commandString The string containing the X10 command * @return A MochadX10Command if parsing was successful, otherwise null */ private MochadX10Command parseCommand(MochadX10Address address, String commandString) { if (commandString != null) { String command = commandString.toLowerCase(); Matcher matcher; if (command.equals("on")) { return new MochadX10OnCommand(eventPublisher, address); } else if (command.equals("off")) { return new MochadX10OffCommand(eventPublisher, address); } else if (command.contains("dim")) { matcher = DIM_PATTERN.matcher(command); if (matcher.matches()) { int level = matcher.group("value") == null ? -1 : Integer.parseInt(matcher.group("value")); return new MochadX10DimCommand(eventPublisher, address, level); } } else if (command.contains("bright")) { matcher = BRIGHT_PATTERN.matcher(command); if (matcher.matches()) { int level = matcher.group("value") == null ? -1 : Integer.parseInt(matcher.group("value")); return new MochadX10BrightCommand(eventPublisher, address, level); } } } return null; } }