/**
* 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.primare.internal.protocol.spa20;
import java.util.Arrays;
import org.openhab.binding.primare.internal.protocol.PrimareResponse;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.DimmerItem;
import org.openhab.core.library.items.NumberItem;
import org.openhab.core.library.items.RollershutterItem;
import org.openhab.core.library.items.StringItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class for Primare SP31.7/SP31/SPA20/SPA21 responses
*
* @author Veli-Pekka Juslin
* @since 1.7.0
*/
public class PrimareSPA20Response extends PrimareResponse {
private static final Logger logger = LoggerFactory.getLogger(PrimareSPA20Response.class);
/**
* Constructor
*
*/
public PrimareSPA20Response(byte[] message) {
this.message = message;
}
/**
* @{inheritDoc}
*/
@Override
public boolean isRelevantFor(String deviceCmdString) {
boolean relevant = false;
switch (PrimareSPA20Command.valueOf(deviceCmdString)) {
// Variable 1 = Power/Standby 0..1, 0=Standby (default), 1=Operate
case POWER_QUERY:
case POWER_TOGGLE:
case POWER_OFF:
case POWER_ON:
relevant = (message[1] == 0x01);
break;
// Variable 2 = Main Input number 1..15
case MAIN_INPUT_QUERY:
case MAIN_INPUT_UP:
case MAIN_INPUT_DOWN:
case MAIN_INPUT_SET:
relevant = (message[1] == 0x02);
break;
// Variable 3 = Volume level 0..99, default:0
case VOLUME_QUERY:
case VOLUME_UP:
case VOLUME_DOWN:
case VOLUME_SET:
relevant = (message[1] == 0x03);
break;
// Variable 4 = Balance -20..+20, default:0
case BALANCE_UP:
case BALANCE_QUERY:
case BALANCE_DOWN:
case BALANCE_SET:
relevant = (message[1] == 0x04);
break;
// Variable 5 = Center -20..+20, default:0
case CENTER_UP:
case CENTER_QUERY:
case CENTER_DOWN:
case CENTER_SET:
relevant = (message[1] == 0x05);
break;
// Variable 6 = Surround -20..+20, default:0
case SURROUND_UP:
case SURROUND_QUERY:
case SURROUND_DOWN:
case SURROUND_SET:
relevant = (message[1] == 0x06);
break;
// Variable 7 = Back -20..+20, default:0
case BACK_QUERY:
case BACK_UP:
case BACK_DOWN:
case BACK_SET:
relevant = (message[1] == 0x07);
break;
// Variable 8 = SUB -20..+20, default:0
case SUB_UP:
case SUB_QUERY:
case SUB_DOWN:
case SUB_SET:
relevant = (message[1] == 0x08);
break;
// Variable 9 = Mute 0..1, 0=inactive (default), 1=active
case MUTE_QUERY:
case MUTE_TOGGLE:
case MUTE_OFF:
case MUTE_ON:
relevant = (message[1] == 0x09);
break;
// Variable 10 = Dim 0..1, 0=display on, 1=display off (default)
case DIM_QUERY:
case DIM_TOGGLE:
case DIM_OFF:
case DIM_ON:
relevant = (message[1] == 0x0A);
break;
// Variable 11 = Record Input number 1..15
case RECORD_INPUT_QUERY:
case RECORD_INPUT_UP:
case RECORD_INPUT_DOWN:
case RECORD_INPUT_SET:
relevant = (message[1] == 0x0B);
break;
// Variable 12 = Surround mode 0..6
case SURROUND_MODE_QUERY:
case SURROUND_MODE_UP:
case SURROUND_MODE_SET:
relevant = (message[1] == 0x0C);
break;
// Variable 13 = Verbose 0..1, 1=verbose on, 2=verbose off (default)
case VERBOSE_QUERY:
case VERBOSE_TOGGLE:
case VERBOSE_OFF:
case VERBOSE_ON:
relevant = (message[1] == 0x0D);
break;
// Variable 14 = Menu 0..2, 0 = Exit menu (default), 1=Menu back, 2=Enter menu
case MENU_QUERY:
case MENU_TOGGLE: // Menu enter / menu back
case MENU_SET:
relevant = (message[1] == 0x0E);
break;
// Variable 16 = Extra surround mode 0..1
case EXTRA_SURROUND_MODE_QUERY:
case EXTRA_SURROUND_MODE_TOGGLE:
case EXTRA_SURROUND_MODE_ON:
case EXTRA_SURROUND_MODE_OFF:
relevant = (message[1] == 0x10);
break;
// Variable 17 = Front panel lock 0..1, 0 = lock off (default), 1 = lock on
case FRONT_PANEL_LOCK_QUERY:
case FRONT_PANEL_LOCK_TOGGLE:
case FRONT_PANEL_LOCK_OFF:
case FRONT_PANEL_LOCK_ON:
relevant = (message[1] == 0x11);
break;
// Variable 18 = IR Input select 0..1, 0 = front ir input (default), other = back ir input
case IR_INPUT_QUERY:
case IR_INPUT_TOGGLE:
case IR_INPUT_FRONT:
case IR_INPUT_BACK:
relevant = (message[1] == 0x12);
break;
// Variable 19 = Recall settings 0..2, 0=factory settings, 1=memory factory settings 2=memory installer
// settings
case RECALL_MEMORY:
case RECALL_MEMORY_DIRECT_USER_SETTINGS:
case RECALL_MEMORY_DIRECT_FACTORY_SETTINGS:
case RECALL_MEMORY_DIRECT_INSTALLER_SETTINGS:
relevant = (message[1] == 0x13);
break;
// Variable 20 = Current input name
case CURRENT_INPUT_NAME_QUERY:
relevant = (message[1] == 0x14);
break;
// Variable 21 = name of productline
case PRODUCTLINE_QUERY:
relevant = (message[1] == 0x15);
break;
// Variable 22 = name of model
case MODEL_QUERY:
relevant = (message[1] == 0x16);
break;
// Variable 23 = software version
case SW_VERSION_QUERY:
relevant = (message[1] == 0x17);
break;
// Variable 25 = Late night mode 0..1, 0=off (default), 1=on
case LATE_NIGHT_MODE_QUERY:
case LATE_NIGHT_MODE_TOGGLE:
case LATE_NIGHT_MODE_OFF:
case LATE_NIGHT_MODE_ON:
relevant = (message[1] == 0x18);
break;
}
return relevant;
}
/**
* Convert received response message containing a Primare device variable value
* to suitable OpenHAB state for the given itemType
*
* @param itemType
*
* @return openHAB state
*/
@Override
public State openHabState(Class<? extends Item> itemType) {
State state = UnDefType.UNDEF;
try {
int index;
String s;
if (itemType == SwitchItem.class) {
index = message[2];
// Documentation and behavior mismatch with MUTE (var 9)
// observed with SPA20, software version 1.50 Nov 2 2003
if (message[1] == 9) {
logger.trace("MUTE (variable 9) converted opposite to documentation");
state = index == 0 ? OnOffType.ON : OnOffType.OFF;
} else {
state = index == 0 ? OnOffType.OFF : OnOffType.ON;
}
} else if (itemType == NumberItem.class) {
index = message[2];
state = new DecimalType(index);
} else if (itemType == DimmerItem.class) {
index = message[2];
state = new PercentType(index);
} else if (itemType == RollershutterItem.class) {
index = message[2];
state = new PercentType(index);
} else if (itemType == StringItem.class) {
s = new String(Arrays.copyOfRange(message, 2, message.length - 2));
state = new StringType(s);
}
} catch (Exception e) {
logger.debug("Cannot convert value '{}' to data type {}", message[1], itemType);
}
return state;
}
}