[yamahareceiver] Add possiblity to switch HDMI outputs on and off on Yamaha receivers (openhab#6327) (#11063)

* Add possiblity to switch HDMI outputs on and off on Yamaha receivers
(openhab#6327)

Signed-off-by: Bernhard Gruber <b-gruber@gmx.de>
This commit is contained in:
fragger42
2021-07-31 11:52:45 +02:00
committed by GitHub
parent 207dab57b9
commit 882374fbcc
7 changed files with 102 additions and 0 deletions

View File

@@ -48,6 +48,8 @@ public class YamahaReceiverBindingConstants {
public static final String CHANNEL_MUTE = "mute";
public static final String CHANNEL_SCENE = "scene";
public static final String CHANNEL_DIALOGUE_LEVEL = "dialogueLevel";
public static final String CHANNEL_HDMI1OUT = "hdmi1Out";
public static final String CHANNEL_HDMI2OUT = "hdmi2Out";
public static final String CHANNEL_PARTY_MODE = "party_mode";
public static final String CHANNEL_PARTY_MODE_MUTE = "party_mode_mute";

View File

@@ -305,6 +305,14 @@ public class YamahaZoneThingHandler extends BaseThingHandler
zoneControl.setDialogueLevel(((DecimalType) command).intValue());
break;
case CHANNEL_HDMI1OUT:
zoneControl.setHDMI1Out(((OnOffType) command) == OnOffType.ON);
break;
case CHANNEL_HDMI2OUT:
zoneControl.setHDMI2Out(((OnOffType) command) == OnOffType.ON);
break;
case CHANNEL_NAVIGATION_MENU:
if (inputWithNavigationControl == null) {
logger.warn("Channel {} not working with {} input!", id, zoneState.inputID);
@@ -491,6 +499,10 @@ public class YamahaZoneThingHandler extends BaseThingHandler
// no state updates available
} else if (id.equals(grpZone(CHANNEL_DIALOGUE_LEVEL))) {
updateState(channelUID, new DecimalType(zoneState.dialogueLevel));
} else if (id.equals(grpZone(CHANNEL_HDMI1OUT))) {
updateState(channelUID, zoneState.hdmi1Out ? OnOffType.ON : OnOffType.OFF);
} else if (id.equals(grpZone(CHANNEL_HDMI2OUT))) {
updateState(channelUID, zoneState.hdmi2Out ? OnOffType.ON : OnOffType.OFF);
} else if (id.equals(grpPlayback(CHANNEL_PLAYBACK))) {
updateState(channelUID, new StringType(playInfoState.playbackMode));
@@ -536,6 +548,8 @@ public class YamahaZoneThingHandler extends BaseThingHandler
updateState(grpZone(CHANNEL_VOLUME), new PercentType((int) zoneConfig.getVolumePercentage(zoneState.volumeDB)));
updateState(grpZone(CHANNEL_MUTE), zoneState.mute ? OnOffType.ON : OnOffType.OFF);
updateState(grpZone(CHANNEL_DIALOGUE_LEVEL), new DecimalType(zoneState.dialogueLevel));
updateState(grpZone(CHANNEL_HDMI1OUT), zoneState.hdmi1Out ? OnOffType.ON : OnOffType.OFF);
updateState(grpZone(CHANNEL_HDMI2OUT), zoneState.hdmi2Out ? OnOffType.ON : OnOffType.OFF);
// If the input changed
if (inputChanged) {

View File

@@ -64,6 +64,26 @@ public interface ZoneControl extends IStateUpdatable {
void setDialogueLevel(int level) throws IOException, ReceivedMessageParseException;
/**
* Switches the HDMI1 output on or off.
*
* @param on The new state
*
* @throws IOException
* @throws ReceivedMessageParseException
*/
void setHDMI1Out(boolean on) throws IOException, ReceivedMessageParseException;
/**
* Switches the HDMI2 output on or off.
*
* @param on The new state
*
* @throws IOException
* @throws ReceivedMessageParseException
*/
void setHDMI2Out(boolean on) throws IOException, ReceivedMessageParseException;
/**
* Sets the active scene for the zone.
*

View File

@@ -77,7 +77,15 @@ public class ZoneControlXML implements ZoneControl {
protected CommandTemplate dialogueLevel = new CommandTemplate(
"<Sound_Video><Dialogue_Adjust><Dialogue_Lvl>%d</Dialogue_Lvl></Dialogue_Adjust></Sound_Video>",
"Sound_Video/Dialogue_Adjust/Dialogue_Lvl");
protected CommandTemplate hdmi1Out = new CommandTemplate(
"<System><Sound_Video><HDMI><Output><OUT_1>%s</OUT_1></Output></HDMI></Sound_Video></System>",
"Sound_Video/HDMI/Output/OUT_1");
protected CommandTemplate hdmi2Out = new CommandTemplate(
"<System><Sound_Video><HDMI><Output><OUT_2>%s</OUT_2></Output></HDMI></Sound_Video></System>",
"Sound_Video/HDMI/Output/OUT_2");
protected boolean dialogueLevelSupported = false;
protected boolean hdmi1OutSupported = false;
protected boolean hdmi2OutSupported = false;
public ZoneControlXML(AbstractConnection con, Zone zone, YamahaZoneConfig zoneSettings,
ZoneControlStateListener observer, DeviceInformationState deviceInformationState,
@@ -118,6 +126,12 @@ public class ZoneControlXML implements ZoneControl {
logger.debug("Zone {} - the {} channel is not supported on your model", getZone(), CHANNEL_DIALOGUE_LEVEL);
}
hdmi1OutSupported = zoneDescriptor.hasCommandEnding("Sound_Video,HDMI,Output,OUT_1", () -> logger
.debug("Zone {} - the {} channel is not supported on your model", getZone(), CHANNEL_HDMI1OUT));
hdmi2OutSupported = zoneDescriptor.hasCommandEnding("Sound_Video,HDMI,Output,OUT_2", () -> logger
.debug("Zone {} - the {} channel is not supported on your model", getZone(), CHANNEL_HDMI2OUT));
// Note: Detection for RX-V3900, which uses <Vol> instead of <Volume>
if (zoneDescriptor.hasCommandEnding("Vol,Lvl")) {
volume = volume.replace("Volume", "Vol");
@@ -153,6 +167,10 @@ public class ZoneControlXML implements ZoneControl {
comReference.get().send(XMLUtils.wrZone(zone, message));
}
protected void sendCommandWithoutZone(String message) throws IOException {
comReference.get().send(message);
}
/**
* Return the zone
*/
@@ -253,6 +271,24 @@ public class ZoneControlXML implements ZoneControl {
update();
}
@Override
public void setHDMI1Out(boolean on) throws IOException, ReceivedMessageParseException {
if (!hdmi1OutSupported) {
return;
}
sendCommandWithoutZone(hdmi1Out.apply(on ? ON : OFF));
update();
}
@Override
public void setHDMI2Out(boolean on) throws IOException, ReceivedMessageParseException {
if (!hdmi2OutSupported) {
return;
}
sendCommandWithoutZone(hdmi2Out.apply(on ? ON : OFF));
update();
}
@Override
public void setScene(String scene) throws IOException, ReceivedMessageParseException {
if (!sceneSelSupported) {
@@ -290,6 +326,12 @@ public class ZoneControlXML implements ZoneControl {
throw new ReceivedMessageParseException("Expected inputID. Failed to read Input/Input_Sel");
}
value = getNodeContentOrEmpty(statusNode, hdmi1Out.getPath());
state.hdmi1Out = ON.equalsIgnoreCase(value);
value = getNodeContentOrEmpty(statusNode, hdmi1Out.getPath());
state.hdmi2Out = ON.equalsIgnoreCase(value);
// Some receivers may use Src_Name instead?
value = getNodeContentOrEmpty(statusNode, inputSelNamePath);
state.inputName = value;

View File

@@ -30,4 +30,6 @@ public class ZoneControlState {
public float volumeDB = 0.0f; // volume in dB
public boolean mute = false;
public int dialogueLevel = 0;
public boolean hdmi1Out = false;
public boolean hdmi2Out = false;
}

View File

@@ -130,6 +130,8 @@
<channel id="volume" typeId="volume"/>
<channel id="volumeDB" typeId="volumeDB"/>
<channel id="dialogueLevel" typeId="dialogueLevel"/>
<channel id="hdmi1Out" typeId="hdmi1Out"/>
<channel id="hdmi2Out" typeId="hdmi2Out"/>
<channel id="mute" typeId="mute"/>
<channel id="scene" typeId="scene"/>
</channels>
@@ -231,6 +233,20 @@
<state min="0" max="2" step="1" pattern="%d"/>
</channel-type>
<channel-type id="hdmi1Out">
<item-type>Switch</item-type>
<label>HDMI1 Output</label>
<description>Switch the HDMI1 Output ON/OFF</description>
<category>switch</category>
</channel-type>
<channel-type id="hdmi2Out">
<item-type>Switch</item-type>
<label>HDMI2 Output</label>
<description>Switch the HDMI2 Output ON/OFF</description>
<category>switch</category>
</channel-type>
<channel-type id="scene">
<item-type>String</item-type>
<label>Scene</label>