/**
* 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.lcn.mappingtarget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openhab.binding.lcn.common.LcnAddr;
import org.openhab.binding.lcn.common.LcnAddrMod;
import org.openhab.binding.lcn.common.LcnDefs;
import org.openhab.binding.lcn.common.PckGenerator;
import org.openhab.binding.lcn.connection.Connection;
import org.openhab.binding.lcn.connection.ModInfo;
import org.openhab.binding.lcn.input.ModStatusBinSensors;
import org.openhab.binding.lcn.input.ModStatusKeyLocks;
import org.openhab.binding.lcn.input.ModStatusLedsAndLogicOps;
import org.openhab.binding.lcn.input.ModStatusOutput;
import org.openhab.binding.lcn.input.ModStatusRelays;
import org.openhab.binding.lcn.input.ModStatusVar;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.items.Item;
import org.openhab.core.types.Command;
/**
* Locks keys temporary.
*
* @author Tobias J�ttner
*/
public class LockKeysTemporary extends TargetWithLcnAddr {
/** Pattern to parse lock-keys temporary commands. */
private static final Pattern PATTERN_LOCKKEYS_TEMPORARY = Pattern.compile(
"(?<keys>([ABCD][12345678])*)\\.(?<time>\\d+)(?<timeUnit>.+)",
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
/** Lock-flags for the 4x8 keys. */
private final boolean[][] keys;
/** Period to lock. */
private final int time;
/** The period's unit. */
private final LcnDefs.TimeUnit timeUnit;
/**
* Constructor.
*
* @param addr the target LCN address
* @param keys the lock-flags for 4x8 keys
* @param time the lock period
* @param timeUnit the period's unit
*/
LockKeysTemporary(LcnAddr addr, boolean[][] keys, int time, LcnDefs.TimeUnit timeUnit) {
super(addr);
this.keys = keys;
this.time = time;
this.timeUnit = timeUnit;
}
/**
* Tries to parse the given input text.
*
* @param input the text to parse
* @return the parsed {@link LockKeysTemporary} or null
*/
static Target tryParseTarget(String input) {
CmdAndAddressRet header = CmdAndAddressRet.parse(input, true);
if (header != null) {
try {
Matcher matcher;
switch (header.getCmd().toUpperCase()) {
case "LOCK":
if ((matcher = PATTERN_LOCKKEYS_TEMPORARY.matcher(header.getRestInput())).matches()) {
boolean[][] keys = new boolean[][] { new boolean[8], new boolean[8], new boolean[8],
new boolean[8] };
String s = matcher.group("keys");
for (int i = 0; i < s.length(); i += 2) {
String key = s.substring(i, i + 2).toUpperCase();
int tableId;
switch (key.charAt(0)) {
case 'A':
tableId = 0;
break;
case 'B':
tableId = 1;
break;
case 'C':
tableId = 2;
break;
case 'D':
tableId = 3;
break;
default:
throw new Error();
}
int keyId = Integer.parseInt(key.substring(1, 2)) - 1;
keys[tableId][keyId] = true;
}
LcnDefs.TimeUnit timeUnit = LcnDefs.TimeUnit.parse(matcher.group("timeUnit"));
return new LockKeysTemporary(header.getAddr(), keys,
Integer.parseInt(matcher.group("time")), timeUnit);
}
break;
}
} catch (IllegalArgumentException ex) {
}
}
return null;
}
/** {@inheritDoc} */
@Override
public void send(Connection conn, Item item, Command cmd) {
boolean sent = false;
for (int tableId = 0; tableId < 4; ++tableId) {
for (int keyId = 0; keyId < 8; ++keyId) {
if (this.keys[tableId][keyId]) { // Lock if at least one key should be locled
if (tableId == 0) { // Only table A is currently supported
conn.queue(this.addr, !this.addr.isGroup(),
PckGenerator.lockKeyTabATemporary(this.time, this.timeUnit, this.keys[tableId]));
sent = true;
} else {
logger.error(String.format("Locking keys from table %s (temporary) is not supported.",
tableId == 1 ? "B" : tableId == 2 ? "C" : "D"));
}
break;
}
}
}
// Force status update (status is polled and should be updated now)
if (sent && !this.addr.isGroup()) {
ModInfo info = conn.getModInfo((LcnAddrMod) this.addr);
if (info != null) {
info.requestStatusLockedKeys.nextRequestIn(ModInfo.STATUS_REQUEST_DELAY_AFTER_COMMAND_MSEC,
System.nanoTime());
}
}
}
/** {@inheritDoc} */
@Override
public void register(Connection conn) {
}
/** {@inheritDoc} */
@Override
public boolean visualizationHandleOutputStatus(ModStatusOutput pchkInput, Command cmd, Item item,
EventPublisher eventPublisher) {
return false;
}
/** {@inheritDoc} */
@Override
public boolean visualizationHandleRelaysStatus(ModStatusRelays pchkInput, Command cmd, Item item,
EventPublisher eventPublisher) {
return false;
}
/** {@inheritDoc} */
@Override
public boolean visualizationBinSensorsStatus(ModStatusBinSensors pchkInput, Command cmd, Item item,
EventPublisher eventPublisher) {
return false;
}
/** {@inheritDoc} */
@Override
public boolean visualizationVarStatus(ModStatusVar pchkInput, Command cmd, Item item,
EventPublisher eventPublisher) {
return false;
}
/** {@inheritDoc} */
@Override
public boolean visualizationLedsAndLogicOpsStatus(ModStatusLedsAndLogicOps pchkInput, Command cmd, Item item,
EventPublisher eventPublisher) {
return false;
}
/** {@inheritDoc} */
@Override
public boolean visualizationKeyLocksStatus(ModStatusKeyLocks pchkInput, Command cmd, Item item,
EventPublisher eventPublisher) {
return false;
}
}