mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[yamahamusiccast] Initial contribution (#11880)
* Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org> * Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org> * Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org> * Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org> * Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org> * Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org> * Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org> * Pull Request OH3 Signed-off-by: Lennert Coopman <github@coopman.org>
This commit is contained in:
parent
da59cdd255
commit
60c1eceb96
@ -341,6 +341,7 @@
|
|||||||
/bundles/org.openhab.binding.wolfsmartset/ @BoBiene
|
/bundles/org.openhab.binding.wolfsmartset/ @BoBiene
|
||||||
/bundles/org.openhab.binding.xmltv/ @clinique
|
/bundles/org.openhab.binding.xmltv/ @clinique
|
||||||
/bundles/org.openhab.binding.xmppclient/ @pavel-gololobov
|
/bundles/org.openhab.binding.xmppclient/ @pavel-gololobov
|
||||||
|
/bundles/org.openhab.binding.yamahamusiccast/ @coop-git
|
||||||
/bundles/org.openhab.binding.yamahareceiver/ @davidgraeff @zarusz
|
/bundles/org.openhab.binding.yamahareceiver/ @davidgraeff @zarusz
|
||||||
/bundles/org.openhab.binding.yeelight/ @claell
|
/bundles/org.openhab.binding.yeelight/ @claell
|
||||||
/bundles/org.openhab.binding.yioremote/ @miloit
|
/bundles/org.openhab.binding.yioremote/ @miloit
|
||||||
|
@ -1696,6 +1696,11 @@
|
|||||||
<artifactId>org.openhab.binding.xmppclient</artifactId>
|
<artifactId>org.openhab.binding.xmppclient</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.binding.yamahamusiccast</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openhab.addons.bundles</groupId>
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
<artifactId>org.openhab.binding.yamahareceiver</artifactId>
|
<artifactId>org.openhab.binding.yamahareceiver</artifactId>
|
||||||
|
168
bundles/org.openhab.binding.yamahamusiccast/README.md
Normal file
168
bundles/org.openhab.binding.yamahamusiccast/README.md
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# Yamaha MusicCast Binding
|
||||||
|
|
||||||
|
Binding to control Yamaha models via their MusicCast protocol (aka Yamaha Extended Control).
|
||||||
|
With support for 4 zones : main, zone2, zone3, zone4. Main is always present. Zone2, Zone3, Zone4 are read from the model.
|
||||||
|
|
||||||
|
UDP events are captured to reflect changes in the binding for
|
||||||
|
|
||||||
|
- Power
|
||||||
|
- Mute
|
||||||
|
- Volume
|
||||||
|
- Input
|
||||||
|
- Presets
|
||||||
|
- Sleep
|
||||||
|
- Artist
|
||||||
|
- Track
|
||||||
|
- Album
|
||||||
|
- Album Art
|
||||||
|
- Repeat
|
||||||
|
- Shuffle
|
||||||
|
- Play Time
|
||||||
|
- Total Time
|
||||||
|
- Musiccast Link
|
||||||
|
|
||||||
|
## Supported Things
|
||||||
|
|
||||||
|
Each model (AV Receiver, ...) is a Thing (Thing Type ID: yamahamusiccast:device). Things are linked to a Bridge (Thing Type ID: yamahamusiccast:bridge) for receiving UDP events.
|
||||||
|
|
||||||
|
## Discovery
|
||||||
|
|
||||||
|
No auto discovery
|
||||||
|
|
||||||
|
## Thing Configuration
|
||||||
|
|
||||||
|
| Parameter | Type | Description | Advanced | Required |
|
||||||
|
|--------------------|---------|---------------------------------------------------------|----------|---------------|
|
||||||
|
| host | String | IP address of the Yamaha model (AVR, ...) | false | true |
|
||||||
|
| syncVolume | Boolean | Sync volume across linked models (default=false) | false | false |
|
||||||
|
| defaultAfterMCLink | String | Default Input value for client when MC Link is broken | false | false |
|
||||||
|
|
||||||
|
Default value for *defaultAfterMCLink* is *NET RADIO* as most of the models have this on board.
|
||||||
|
|
||||||
|
## Channels
|
||||||
|
|
||||||
|
| channel | type | description |
|
||||||
|
|----------------|--------|---------------------------------------------------------------------|
|
||||||
|
| power | Switch | Power ON/OFF |
|
||||||
|
| mute | Switch | Mute ON/OFF |
|
||||||
|
| volume | Dimmer | Volume as % (recalculated based on Max Volume Model) |
|
||||||
|
| volumeAbs | Number | Volume as absolute value |
|
||||||
|
| input | String | See below for list |
|
||||||
|
| soundProgram | String | See below for list |
|
||||||
|
| selectPreset | String | Select Netradio/USB preset (fetched from Model) |
|
||||||
|
| sleep | Number | Fixed values for Sleep : 0/30/60/90/120 in minutes |
|
||||||
|
| recallScene | Number | Select a scene (8 defaults scenes are foreseen) |
|
||||||
|
| player | Player | PLAY/PAUSE/NEXT/PREVIOUS/REWIND/FASTFORWARD |
|
||||||
|
| artist | String | Artist |
|
||||||
|
| track | String | Track |
|
||||||
|
| album | String | Album |
|
||||||
|
| albumArt | Image | Album Art |
|
||||||
|
| repeat | String | Toggle Repeat. Available values: Off, One, All |
|
||||||
|
| shuffle | String | Toggle Shuffle. Available values: Off, On, Songs, Album |
|
||||||
|
| playTime | String | Play time of current selection: radio, song, track, ... |
|
||||||
|
| totalTime | String | Total time of current selection: radio, song, track, ... |
|
||||||
|
| mclinkStatus | String | Select your Musiccast Server or set to Standalone, Server or Client |
|
||||||
|
|
||||||
|
|
||||||
|
| Zones | description |
|
||||||
|
|----------------------|------------------------------------------------------|
|
||||||
|
| zone1-4 | Zone 1 to 4 to control Power, Volume, ... |
|
||||||
|
| playerControls | Separate zone for Play, Pause, ... |
|
||||||
|
|
||||||
|
## Input List
|
||||||
|
|
||||||
|
Firmware v1
|
||||||
|
|
||||||
|
cd / tuner / multi_ch / phono / hdmi1 / hdmi2 / hdmi3 / hdmi4 / hdmi5 / hdmi6 / hdmi7 /
|
||||||
|
hdmi8 / hdmi / av1 / av2 / av3 / av4 / av5 / av6 / av7 / v_aux / aux1 / aux2 / aux / audio1 /
|
||||||
|
audio2 / audio3 / audio4 / audio_cd / audio / optical1 / optical2 / optical / coaxial1 / coaxial2 /
|
||||||
|
coaxial / digital1 / digital2 / digital / line1 / line2 / line3 / line_cd / analog / tv / bd_dvd /
|
||||||
|
usb_dac / usb / bluetooth / server / net_radio / rhapsody / napster / pandora / siriusxm /
|
||||||
|
spotify / juke / airplay / radiko / qobuz / mc_link / main_sync / none
|
||||||
|
|
||||||
|
Firmware v2
|
||||||
|
|
||||||
|
cd / tuner / multi_ch / phono / hdmi1 / hdmi2 / hdmi3 / hdmi4 / hdmi5 / hdmi6 / hdmi7 /
|
||||||
|
hdmi8 / hdmi / av1 / av2 / av3 / av4 / av5 / av6 / av7 / v_aux / aux1 / aux2 / aux / audio1 /
|
||||||
|
audio2 / audio3 / audio4 / **audio5** / audio_cd / audio / optical1 / optical2 / optical / coaxial1 / coaxial2 /
|
||||||
|
coaxial / digital1 / digital2 / digital / line1 / line2 / line3 / line_cd / analog / tv / bd_dvd /
|
||||||
|
usb_dac / usb / bluetooth / server / net_radio / ~~rhapsody~~ /napster / pandora / siriusxm /
|
||||||
|
spotify / juke / airplay / radiko / qobuz / **tidal** / **deezer** / mc_link / main_sync / none
|
||||||
|
|
||||||
|
## Sound Program
|
||||||
|
|
||||||
|
munich_a / munich_b / munich / frankfurt / stuttgart / vienna / amsterdam / usa_a / usa_b /
|
||||||
|
tokyo / freiburg / royaumont / chamber / concert / village_gate / village_vanguard /
|
||||||
|
warehouse_loft / cellar_club / jazz_club / roxy_theatre / bottom_line / arena / sports /
|
||||||
|
action_game / roleplaying_game / game / music_video / music / recital_opera / pavilion /
|
||||||
|
disco / standard / spectacle / sci-fi / adventure / drama / talk_show / tv_program /
|
||||||
|
mono_movie / movie / enhanced / 2ch_stereo / 5ch_stereo / 7ch_stereo / 9ch_stereo /
|
||||||
|
11ch_stereo / stereo / surr_decoder / my_surround / target / straight / off
|
||||||
|
|
||||||
|
## Full Example
|
||||||
|
|
||||||
|
### Bridge & Thing(s)
|
||||||
|
|
||||||
|
```
|
||||||
|
Bridge yamahamusiccast:bridge:virtual "YXC Bridge" {
|
||||||
|
Thing yamahamusiccast:device:Living "YXC Living" [host="1.2.3.4"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic setup
|
||||||
|
|
||||||
|
```
|
||||||
|
Switch YamahaPower "" {channel="yamahamusiccast:device:Living:main#power"}
|
||||||
|
Switch YamahaMute "" {channel="yamahamusiccast:device:Living:main#mute"}
|
||||||
|
Dimmer YamahaVolume "" {channel="yamahamusiccast:device:Living:main#volume"}
|
||||||
|
Number YamahaVolumeAbs "" {channel="yamahamusiccast:device:Living:main#volumeAbs"}
|
||||||
|
String YamahaInput "" {channel="yamahamusiccast:device:Living:main#input"}
|
||||||
|
String YamahaSelectPreset "" {channel="yamahamusiccast:device:Living:main#selectPreset"}
|
||||||
|
String YamahaSoundProgram "" {channel="yamahamusiccast:device:Living:main#soundProgram"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Player controls
|
||||||
|
|
||||||
|
```
|
||||||
|
Player YamahaPlayer "" {channel="yamahamusiccast:device:Living:playerControls#player"}
|
||||||
|
String YamahaArt "" {channel="yamahamusiccast:device:Living:playerControls#albumArt"}
|
||||||
|
String YamahaArtist "" {channel="yamahamusiccast:device:Living:playerControls#artist"}
|
||||||
|
String YamahaTrack "" {channel="yamahamusiccast:device:Living:playerControls#track"}
|
||||||
|
String YamahaAlbum "" {channel="yamahamusiccast:device:Living:playerControls#album"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### MusicCast setup
|
||||||
|
|
||||||
|
The idea here is to select what device/model will be the master. This needs to be done per device/model which will then be the slave.
|
||||||
|
If you want the *Living* to be the master for the *Kitchen*, select *Living - zone (IP)* from the thing *Kitchen*.
|
||||||
|
The binding will check if there is already a group active for which *Living* is the master. If yes, this group will be used and *Kitchen* will be added.
|
||||||
|
If not, a new group will be created.
|
||||||
|
|
||||||
|
*Device A*: Living with IP 192.168.1.1
|
||||||
|
*Device B*: Kitchen with IP 192.168.1.2
|
||||||
|
|
||||||
|
Set **mclinkStatus** to *Standalone* to remove the device/model from the current active group. The group will keep on exist with other devices/models.
|
||||||
|
If the device/model is the server, the group will be disbanded.
|
||||||
|
|
||||||
|
```
|
||||||
|
String YamahaMCLinkStatus "" {channel="yamahamusiccast:device:Living:main#mclinkStatus"}
|
||||||
|
```
|
||||||
|
|
||||||
|
During testing with the Yamaha Musiccast app, when removing a slave from the group, the status of the client remained *client* and **input** stayed on *mclink*. Only when changing input, the slave was set to *standalone*. Therefor you can set the parameter **defaultAfterMCLink** to an input value supported by your device to break the whole Musiccast Link in OH.
|
||||||
|
|
||||||
|
#### How to use this in a rule?
|
||||||
|
|
||||||
|
The label uses the format _Thinglabel - zone (IP)_.
|
||||||
|
The value which is sent to OH uses the format _IP***zone_.
|
||||||
|
|
||||||
|
```
|
||||||
|
sendCommand(Kitchen_YamahaMCServer, "192.168.1.1***main")
|
||||||
|
sendCommand(Kitchen_YamahaMCServer, "")
|
||||||
|
sendCommand(Kitchen_YamahaMCServer, "server")
|
||||||
|
sendCommand(Kitchen_YamahaMCServer, "client")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tested Models
|
||||||
|
|
||||||
|
RX-D485 / WX-010 / WX-030 / ISX-80 / YSP-1600 / RX-A860 / R-N303D / EX-A1080 / WXA-050 / HTR-4068 (RX-V479)
|
||||||
|
MusicCast 20 / WCX-50 / RX-V6A / YAS-306 / ISX-18D / WX-021 / YAS-408
|
17
bundles/org.openhab.binding.yamahamusiccast/pom.xml
Normal file
17
bundles/org.openhab.binding.yamahamusiccast/pom.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||||
|
<version>3.3.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>org.openhab.binding.yamahamusiccast</artifactId>
|
||||||
|
|
||||||
|
<name>openHAB Add-ons :: Bundles :: Yamaha Musiccast Binding</name>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<features name="org.openhab.binding.yamahamusiccast-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||||
|
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||||
|
|
||||||
|
<feature name="openhab-binding-yamahamusiccast" description="Yamaha Musiccast Binding" version="${project.version}">
|
||||||
|
<feature>openhab-runtime-base</feature>
|
||||||
|
<feature>openhab-transport-upnp</feature>
|
||||||
|
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.yamahamusiccast/${project.version}</bundle>
|
||||||
|
</feature>
|
||||||
|
</features>
|
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link YamahaMusiccastBindingConstants} class defines common constants, which are
|
||||||
|
* used across the whole binding.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class YamahaMusiccastBindingConstants {
|
||||||
|
|
||||||
|
private static final String BINDING_ID = "yamahamusiccast";
|
||||||
|
|
||||||
|
// List of all Thing Type UIDs
|
||||||
|
public static final ThingTypeUID THING_DEVICE = new ThingTypeUID(BINDING_ID, "device");
|
||||||
|
public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge");
|
||||||
|
|
||||||
|
// List of all Channel Type UIDs
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_POWER = new ChannelTypeUID("system:power");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_MUTE = new ChannelTypeUID("system:mute");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_VOLUME = new ChannelTypeUID("system:volume");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_VOLUMEABS = new ChannelTypeUID(BINDING_ID, "volumeAbs");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_INPUT = new ChannelTypeUID(BINDING_ID, "input");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_SOUNDPROGRAM = new ChannelTypeUID(BINDING_ID, "soundProgram");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_SELECTPRESET = new ChannelTypeUID(BINDING_ID, "selectPreset");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_SLEEP = new ChannelTypeUID(BINDING_ID, "sleep");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_RECALLSCENE = new ChannelTypeUID(BINDING_ID, "recallScene");
|
||||||
|
public static final ChannelTypeUID CHANNEL_TYPE_UID_MCLINKSTATUS = new ChannelTypeUID(BINDING_ID, "mclinkStatus");
|
||||||
|
|
||||||
|
// List of all Channel ids
|
||||||
|
public static final String CHANNEL_POWER = "power";
|
||||||
|
public static final String CHANNEL_MUTE = "mute";
|
||||||
|
public static final String CHANNEL_VOLUME = "volume";
|
||||||
|
public static final String CHANNEL_VOLUMEABS = "volumeAbs";
|
||||||
|
public static final String CHANNEL_INPUT = "input";
|
||||||
|
public static final String CHANNEL_SOUNDPROGRAM = "soundProgram";
|
||||||
|
public static final String CHANNEL_SELECTPRESET = "selectPreset";
|
||||||
|
public static final String CHANNEL_PLAYER = "player";
|
||||||
|
public static final String CHANNEL_SLEEP = "sleep";
|
||||||
|
public static final String CHANNEL_RECALLSCENE = "recallScene";
|
||||||
|
public static final String CHANNEL_ARTIST = "artist";
|
||||||
|
public static final String CHANNEL_TRACK = "track";
|
||||||
|
public static final String CHANNEL_ALBUM = "album";
|
||||||
|
public static final String CHANNEL_ALBUMART = "albumArt";
|
||||||
|
public static final String CHANNEL_REPEAT = "repeat";
|
||||||
|
public static final String CHANNEL_SHUFFLE = "shuffle";
|
||||||
|
public static final String CHANNEL_MCLINKSTATUS = "mclinkStatus";
|
||||||
|
public static final String CHANNEL_PLAYTIME = "playTime";
|
||||||
|
public static final String CHANNEL_TOTALTIME = "totalTime";
|
||||||
|
|
||||||
|
public static final int CONNECTION_TIMEOUT_MILLISEC = 5000;
|
||||||
|
public static final int LONG_CONNECTION_TIMEOUT_MILLISEC = 60000;
|
||||||
|
public static final String HTTP = "http://";
|
||||||
|
public static final String YAMAHA_EXTENDED_CONTROL = "/YamahaExtendedControl/v1/";
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.yamahamusiccast.internal.dto.UdpMessage;
|
||||||
|
import org.openhab.core.common.NamedThreadFactory;
|
||||||
|
import org.openhab.core.thing.Bridge;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingStatus;
|
||||||
|
import org.openhab.core.thing.ThingStatusInfo;
|
||||||
|
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link YamahaMusiccastBridgeHandler} is responsible for dispatching UDP events to linked Things.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class YamahaMusiccastBridgeHandler extends BaseBridgeHandler {
|
||||||
|
private Gson gson = new Gson();
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(YamahaMusiccastBridgeHandler.class);
|
||||||
|
private String threadname = getThing().getUID().getAsString();
|
||||||
|
private @Nullable ExecutorService executor;
|
||||||
|
private @Nullable Future<?> eventListenerJob;
|
||||||
|
private static final int UDP_PORT = 41100;
|
||||||
|
private static final int SOCKET_TIMEOUT_MILLISECONDS = 3000;
|
||||||
|
private static final int BUFFER_SIZE = 5120;
|
||||||
|
private @Nullable DatagramSocket socket;
|
||||||
|
|
||||||
|
private void receivePackets() {
|
||||||
|
try {
|
||||||
|
DatagramSocket s = new DatagramSocket(null);
|
||||||
|
s.setSoTimeout(SOCKET_TIMEOUT_MILLISECONDS);
|
||||||
|
s.setReuseAddress(true);
|
||||||
|
InetSocketAddress address = new InetSocketAddress(UDP_PORT);
|
||||||
|
s.bind(address);
|
||||||
|
socket = s;
|
||||||
|
logger.trace("UDP Listener got socket on port {} with timeout {}", UDP_PORT, SOCKET_TIMEOUT_MILLISECONDS);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
logger.trace("UDP Listener got SocketException: {}", e.getMessage(), e);
|
||||||
|
socket = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DatagramPacket packet = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE);
|
||||||
|
DatagramSocket localSocket = socket;
|
||||||
|
while (localSocket != null) {
|
||||||
|
try {
|
||||||
|
localSocket.receive(packet);
|
||||||
|
String received = new String(packet.getData(), 0, packet.getLength());
|
||||||
|
String trackingID = UUID.randomUUID().toString().replace("-", "").substring(0, 32);
|
||||||
|
logger.trace("Received packet: {} (Tracking: {})", received, trackingID);
|
||||||
|
handleUDPEvent(received, trackingID);
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
// Nothing to do on socket timeout
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.trace("UDP Listener got IOException waiting for datagram: {}", e.getMessage());
|
||||||
|
localSocket = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.trace("UDP Listener exiting");
|
||||||
|
}
|
||||||
|
|
||||||
|
public YamahaMusiccastBridgeHandler(Bridge bridge) {
|
||||||
|
super(bridge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
executor = Executors.newSingleThreadExecutor(new NamedThreadFactory(threadname));
|
||||||
|
Future<?> localEventListenerJob = eventListenerJob;
|
||||||
|
ExecutorService localExecutor = executor;
|
||||||
|
if (localEventListenerJob == null || localEventListenerJob.isCancelled()) {
|
||||||
|
if (localExecutor != null) {
|
||||||
|
localEventListenerJob = localExecutor.submit(this::receivePackets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
Future<?> localEventListenerJob = eventListenerJob;
|
||||||
|
ExecutorService localExecutor = executor;
|
||||||
|
if (localEventListenerJob != null) {
|
||||||
|
localEventListenerJob.cancel(true);
|
||||||
|
localEventListenerJob = null;
|
||||||
|
}
|
||||||
|
if (localExecutor != null) {
|
||||||
|
localExecutor.shutdownNow();
|
||||||
|
localExecutor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleUDPEvent(String json, String trackingID) {
|
||||||
|
String udpDeviceId = "";
|
||||||
|
Bridge bridge = (Bridge) thing;
|
||||||
|
for (Thing thing : bridge.getThings()) {
|
||||||
|
ThingStatusInfo statusInfo = thing.getStatusInfo();
|
||||||
|
switch (statusInfo.getStatus()) {
|
||||||
|
case ONLINE:
|
||||||
|
logger.trace("Thing Status: ONLINE - {}", thing.getLabel());
|
||||||
|
YamahaMusiccastHandler handler = (YamahaMusiccastHandler) thing.getHandler();
|
||||||
|
if (handler != null) {
|
||||||
|
logger.trace("UDP: {} - {} ({} - Tracking: {})", json, handler.getDeviceId(), thing.getLabel(),
|
||||||
|
trackingID);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
UdpMessage targetObject = gson.fromJson(json, UdpMessage.class);
|
||||||
|
if (targetObject != null) {
|
||||||
|
udpDeviceId = targetObject.getDeviceId();
|
||||||
|
if (udpDeviceId.equals(handler.getDeviceId())) {
|
||||||
|
handler.processUDPEvent(json, trackingID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.trace("Thing Status: NOT ONLINE - {} (Tracking: {})", thing.getLabel(), trackingID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link YamahaMusiccastConfiguration} class contains fields mapping thing configuration parameters.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class YamahaMusiccastConfiguration {
|
||||||
|
|
||||||
|
public @Nullable String host;
|
||||||
|
public @Nullable Boolean syncVolume;
|
||||||
|
public @Nullable String defaultAfterMCLink;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal;
|
||||||
|
|
||||||
|
import static org.openhab.binding.yamahamusiccast.internal.YamahaMusiccastBindingConstants.*;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.thing.Bridge;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||||
|
import org.osgi.service.component.annotations.Activate;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link YamahamusiccastHandlerFactory} is responsible for creating things and thing
|
||||||
|
* handlers.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
@Component(configurationPid = "binding.yamahamusiccast", service = ThingHandlerFactory.class)
|
||||||
|
public class YamahaMusiccastHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
|
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set
|
||||||
|
.of(YamahaMusiccastBindingConstants.THING_DEVICE, YamahaMusiccastBindingConstants.THING_TYPE_BRIDGE);
|
||||||
|
|
||||||
|
private final YamahaMusiccastStateDescriptionProvider stateDescriptionProvider;
|
||||||
|
|
||||||
|
@Activate
|
||||||
|
public YamahaMusiccastHandlerFactory(@Reference YamahaMusiccastStateDescriptionProvider stateDescriptionProvider) {
|
||||||
|
this.stateDescriptionProvider = stateDescriptionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||||
|
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||||
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
|
|
||||||
|
if (thingTypeUID.equals(THING_TYPE_BRIDGE)) {
|
||||||
|
return new YamahaMusiccastBridgeHandler((Bridge) thing);
|
||||||
|
} else if (THING_DEVICE.equals(thingTypeUID)) {
|
||||||
|
return new YamahaMusiccastHandler(thing, stateDescriptionProvider);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider;
|
||||||
|
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
|
||||||
|
import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link YamahaMusiccastStateDescriptionProvider} is responsible for handling the state options of a channel.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
@Component(service = { DynamicStateDescriptionProvider.class, YamahaMusiccastStateDescriptionProvider.class })
|
||||||
|
@NonNullByDefault
|
||||||
|
public class YamahaMusiccastStateDescriptionProvider extends BaseDynamicStateDescriptionProvider {
|
||||||
|
|
||||||
|
@Reference
|
||||||
|
protected void setChannelTypeI18nLocalizationService(
|
||||||
|
final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
|
||||||
|
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void unsetChannelTypeI18nLocalizationService(
|
||||||
|
final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
|
||||||
|
this.channelTypeI18nLocalizationService = null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the DeviceInfo request requested from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
public class DeviceInfo {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
@SerializedName("model_name")
|
||||||
|
private String modelName;
|
||||||
|
|
||||||
|
@SerializedName("device_id")
|
||||||
|
private String deviceId;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModelName() {
|
||||||
|
if (modelName == null) {
|
||||||
|
modelName = "";
|
||||||
|
}
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceId() {
|
||||||
|
if (deviceId == null) {
|
||||||
|
deviceId = "";
|
||||||
|
}
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the DistributionInfo request requested from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
public class DistributionInfo {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
@SerializedName("group_id")
|
||||||
|
private String groupId;
|
||||||
|
|
||||||
|
@SerializedName("role")
|
||||||
|
private String role;
|
||||||
|
|
||||||
|
@SerializedName("server_zone")
|
||||||
|
private String serverZone;
|
||||||
|
|
||||||
|
@SerializedName("client_list")
|
||||||
|
private JsonArray clientList;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroupId() {
|
||||||
|
if (groupId == null) {
|
||||||
|
groupId = "";
|
||||||
|
}
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole() {
|
||||||
|
if (role == null) {
|
||||||
|
role = "";
|
||||||
|
}
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerZone() {
|
||||||
|
if (serverZone == null) {
|
||||||
|
serverZone = "";
|
||||||
|
}
|
||||||
|
return serverZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonArray getClientList() {
|
||||||
|
return clientList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClientList {
|
||||||
|
@SerializedName("ip_address")
|
||||||
|
private String ipaddress;
|
||||||
|
|
||||||
|
public String getIpaddress() {
|
||||||
|
if (ipaddress == null) {
|
||||||
|
ipaddress = "";
|
||||||
|
}
|
||||||
|
return ipaddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the Features request requested from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Features {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedName("system")
|
||||||
|
private System system;
|
||||||
|
|
||||||
|
public System getSystem() {
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class System {
|
||||||
|
@SerializedName("zone_num")
|
||||||
|
private int zoneNum = 0;
|
||||||
|
|
||||||
|
public int getZoneNum() {
|
||||||
|
return zoneNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the PlayInfo request requested from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PlayInfo {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
@SerializedName("playback")
|
||||||
|
private String playback;
|
||||||
|
|
||||||
|
@SerializedName("artist")
|
||||||
|
private String artist;
|
||||||
|
|
||||||
|
@SerializedName("track")
|
||||||
|
private String track;
|
||||||
|
|
||||||
|
@SerializedName("album")
|
||||||
|
private String album;
|
||||||
|
|
||||||
|
@SerializedName("albumart_url")
|
||||||
|
private String albumarturl;
|
||||||
|
|
||||||
|
@SerializedName("repeat")
|
||||||
|
private String repeat;
|
||||||
|
|
||||||
|
@SerializedName("shuffle")
|
||||||
|
private String shuffle;
|
||||||
|
|
||||||
|
@SerializedName("play_time")
|
||||||
|
private int playTime = 0;
|
||||||
|
|
||||||
|
@SerializedName("total_time")
|
||||||
|
private int totalTime = 0;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlayback() {
|
||||||
|
if (playback == null) {
|
||||||
|
playback = "";
|
||||||
|
}
|
||||||
|
return playback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArtist() {
|
||||||
|
if (artist == null) {
|
||||||
|
artist = "";
|
||||||
|
}
|
||||||
|
return artist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTrack() {
|
||||||
|
if (track == null) {
|
||||||
|
track = "";
|
||||||
|
}
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlbum() {
|
||||||
|
if (album == null) {
|
||||||
|
album = "";
|
||||||
|
}
|
||||||
|
return album;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlbumArtUrl() {
|
||||||
|
if (albumarturl == null) {
|
||||||
|
albumarturl = "";
|
||||||
|
}
|
||||||
|
return albumarturl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRepeat() {
|
||||||
|
if (repeat == null) {
|
||||||
|
repeat = "";
|
||||||
|
}
|
||||||
|
return repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShuffle() {
|
||||||
|
if (shuffle == null) {
|
||||||
|
shuffle = "";
|
||||||
|
}
|
||||||
|
return shuffle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayTime() {
|
||||||
|
return playTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalTime() {
|
||||||
|
return totalTime;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the PresetInfo request requested from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
public class PresetInfo {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
@SerializedName("preset_info")
|
||||||
|
private JsonArray presetInfo;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonArray getPresetInfo() {
|
||||||
|
return presetInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the RecentInfo request requested from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
public class RecentInfo {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
@SerializedName("recent_info")
|
||||||
|
private JsonArray recentInfo;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonArray getRecentInfo() {
|
||||||
|
return recentInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the response received from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Response {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the Status request requested from the Yamaha model/device via the API.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Status {
|
||||||
|
|
||||||
|
@SerializedName("response_code")
|
||||||
|
private String responseCode;
|
||||||
|
|
||||||
|
@SerializedName("power")
|
||||||
|
private String power;
|
||||||
|
|
||||||
|
@SerializedName("mute")
|
||||||
|
private String mute;
|
||||||
|
|
||||||
|
@SerializedName("volume")
|
||||||
|
private int volume;
|
||||||
|
|
||||||
|
@SerializedName("max_volume")
|
||||||
|
private int maxVolume = 1;
|
||||||
|
|
||||||
|
@SerializedName("input")
|
||||||
|
private String input;
|
||||||
|
|
||||||
|
@SerializedName("sound_program")
|
||||||
|
private String soundProgram;
|
||||||
|
|
||||||
|
@SerializedName("sleep")
|
||||||
|
private int sleep = 0;
|
||||||
|
|
||||||
|
public String getResponseCode() {
|
||||||
|
if (responseCode == null) {
|
||||||
|
responseCode = "";
|
||||||
|
}
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPower() {
|
||||||
|
if (power == null) {
|
||||||
|
power = "";
|
||||||
|
}
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMute() {
|
||||||
|
if (mute == null) {
|
||||||
|
mute = "";
|
||||||
|
}
|
||||||
|
return mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVolume() {
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxVolume() {
|
||||||
|
// if no value is returned, set to 1 to avoid division by zero
|
||||||
|
if (maxVolume == 0) {
|
||||||
|
maxVolume = 1;
|
||||||
|
}
|
||||||
|
return maxVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInput() {
|
||||||
|
if (input == null) {
|
||||||
|
input = "";
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSoundProgram() {
|
||||||
|
if (soundProgram == null) {
|
||||||
|
soundProgram = "";
|
||||||
|
}
|
||||||
|
return soundProgram;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSleep() {
|
||||||
|
return sleep;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.yamahamusiccast.internal.dto;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the UDP event received from the Yamaha model/device.
|
||||||
|
*
|
||||||
|
* @author Lennert Coopman - Initial contribution
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class UdpMessage {
|
||||||
|
|
||||||
|
@SerializedName("device_id")
|
||||||
|
private String deviceId;
|
||||||
|
|
||||||
|
public String getDeviceId() {
|
||||||
|
if (deviceId == null) {
|
||||||
|
deviceId = "";
|
||||||
|
}
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedName("main")
|
||||||
|
private Zone main;
|
||||||
|
@SerializedName("zone2")
|
||||||
|
private Zone zone2;
|
||||||
|
@SerializedName("zone3")
|
||||||
|
private Zone zone3;
|
||||||
|
@SerializedName("zone4")
|
||||||
|
private Zone zone4;
|
||||||
|
@SerializedName("netusb")
|
||||||
|
private NetUSB netusb;
|
||||||
|
@SerializedName("dist")
|
||||||
|
private Dist dist;
|
||||||
|
|
||||||
|
public Zone getMain() {
|
||||||
|
return main;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Zone getZone2() {
|
||||||
|
return zone2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Zone getZone3() {
|
||||||
|
return zone3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Zone getZone4() {
|
||||||
|
return zone4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetUSB getNetUSB() {
|
||||||
|
return netusb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dist getDist() {
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Zone {
|
||||||
|
@SerializedName("power")
|
||||||
|
private String power;
|
||||||
|
@SerializedName("volume")
|
||||||
|
private int volume = 0;
|
||||||
|
@SerializedName("mute")
|
||||||
|
private String mute;
|
||||||
|
@SerializedName("input")
|
||||||
|
private String input;
|
||||||
|
@SerializedName("status_updated")
|
||||||
|
private String statusUpdated;
|
||||||
|
|
||||||
|
public String getPower() {
|
||||||
|
if (power == null) {
|
||||||
|
power = "";
|
||||||
|
}
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMute() {
|
||||||
|
if (mute == null) {
|
||||||
|
mute = "";
|
||||||
|
}
|
||||||
|
return mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInput() {
|
||||||
|
if (input == null) {
|
||||||
|
input = "";
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVolume() {
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getstatusUpdated() {
|
||||||
|
if (statusUpdated == null) {
|
||||||
|
statusUpdated = "";
|
||||||
|
}
|
||||||
|
return statusUpdated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetUSB {
|
||||||
|
@SerializedName("preset_control")
|
||||||
|
private PresetControl presetControl;
|
||||||
|
@SerializedName("play_info_updated")
|
||||||
|
private String playInfoUpdated;
|
||||||
|
@SerializedName("play_time")
|
||||||
|
private int playTime;
|
||||||
|
|
||||||
|
public PresetControl getPresetControl() {
|
||||||
|
return presetControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlayInfoUpdated() {
|
||||||
|
if (playInfoUpdated == null) {
|
||||||
|
playInfoUpdated = "";
|
||||||
|
}
|
||||||
|
return playInfoUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayTime() {
|
||||||
|
return playTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PresetControl {
|
||||||
|
@SerializedName("type")
|
||||||
|
private String type;
|
||||||
|
@SerializedName("num")
|
||||||
|
private int num = 1;
|
||||||
|
@SerializedName("result")
|
||||||
|
private String result;
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
if (type == null) {
|
||||||
|
type = "";
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResult() {
|
||||||
|
if (result == null) {
|
||||||
|
result = "";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNum() {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Dist {
|
||||||
|
@SerializedName("dist_info_updated")
|
||||||
|
private String distInfoUpdated;
|
||||||
|
|
||||||
|
public String getDistInfoUpdated() {
|
||||||
|
if (distInfoUpdated == null) {
|
||||||
|
distInfoUpdated = "";
|
||||||
|
}
|
||||||
|
return distInfoUpdated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<binding:binding id="yamahamusiccast" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||||
|
|
||||||
|
<name>Yamaha Musiccast Binding</name>
|
||||||
|
<description>This is the binding for Yamaha Musiccast</description>
|
||||||
|
|
||||||
|
</binding:binding>
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="yamahamusiccast"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
|
||||||
|
<!-- Bridge -->
|
||||||
|
<bridge-type id="bridge">
|
||||||
|
<label>Virtual Bridge</label>
|
||||||
|
<description>Virtual Bridge to receive updates</description>
|
||||||
|
</bridge-type>
|
||||||
|
|
||||||
|
</thing:thing-descriptions>
|
@ -0,0 +1,193 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="yamahamusiccast"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
|
||||||
|
|
||||||
|
<thing-type id="device">
|
||||||
|
<supported-bridge-type-refs>
|
||||||
|
<bridge-type-ref id="bridge"/>
|
||||||
|
</supported-bridge-type-refs>
|
||||||
|
<label>Yamaha MusicCast Model</label>
|
||||||
|
<description>Your Yamaha model with MusicCast functionality</description>
|
||||||
|
|
||||||
|
<channel-groups>
|
||||||
|
<channel-group id="main" typeId="mainControls"/>
|
||||||
|
<channel-group id="zone2" typeId="zone2Controls"/>
|
||||||
|
<channel-group id="zone3" typeId="zone3Controls"/>
|
||||||
|
<channel-group id="zone4" typeId="zone4Controls"/>
|
||||||
|
<channel-group id="playerControls" typeId="playerControls"/>
|
||||||
|
</channel-groups>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter name="host" type="text" required="true">
|
||||||
|
<label>Address</label>
|
||||||
|
<context>network-address</context>
|
||||||
|
<description>The IP address of the AVR to control.</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="syncVolume" type="boolean">
|
||||||
|
<label>Sync Volume</label>
|
||||||
|
<description>Sync Volume across linked Music Cast models</description>
|
||||||
|
<default>true</default>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="defaultAfterMCLink" type="text">
|
||||||
|
<label>MC Link Default Value</label>
|
||||||
|
<description>Default value for client when MC Link is broken</description>
|
||||||
|
<default>net_radio</default>
|
||||||
|
<options>
|
||||||
|
<option value="none">None</option>
|
||||||
|
<option value="net_radio">Net Radio</option>
|
||||||
|
</options>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
</thing-type>
|
||||||
|
|
||||||
|
<channel-group-type id="mainControls">
|
||||||
|
<label>Main Zone (default)</label>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<channel-group-type id="zone2Controls">
|
||||||
|
<label>Zone 2</label>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<channel-group-type id="zone3Controls">
|
||||||
|
<label>Zone 3</label>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<channel-group-type id="zone4Controls">
|
||||||
|
<label>Zone 4</label>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<channel-group-type id="playerControls">
|
||||||
|
<label>Player Controls</label>
|
||||||
|
<channels>
|
||||||
|
<channel id="player" typeId="player"/>
|
||||||
|
<channel id="artist" typeId="artist"/>
|
||||||
|
<channel id="track" typeId="track"/>
|
||||||
|
<channel id="album" typeId="album"/>
|
||||||
|
<channel id="albumArt" typeId="albumArt"/>
|
||||||
|
<channel id="repeat" typeId="repeat"/>
|
||||||
|
<channel id="shuffle" typeId="shuffle"/>
|
||||||
|
<channel id="playTime" typeId="playTime"/>
|
||||||
|
<channel id="totalTime" typeId="totalTime"/>
|
||||||
|
</channels>
|
||||||
|
</channel-group-type>
|
||||||
|
|
||||||
|
<channel-type id="volumeAbs">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Volume</label>
|
||||||
|
<description>Volume channel - Absolute value</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="input">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Input</label>
|
||||||
|
<description>Input channel</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="soundProgram">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Sound Program</label>
|
||||||
|
<description>SoundProgram channel</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="selectPreset">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>NetRadio/USB Preset</label>
|
||||||
|
<description>Select Net Radio/USB Preset channel</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="player">
|
||||||
|
<item-type>Player</item-type>
|
||||||
|
<label>NetRadio/USB Player</label>
|
||||||
|
<description>Player for Net Radio/USB channel</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="sleep">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Sleep</label>
|
||||||
|
<description>Sleep Time in minutes</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="0">No Sleep</option>
|
||||||
|
<option value="30">30 min</option>
|
||||||
|
<option value="60">60 min</option>
|
||||||
|
<option value="90">90 min</option>
|
||||||
|
<option value="120">120 min</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="recallScene">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Scene Selection</label>
|
||||||
|
<description>Scene selection (if available)</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="1">Scene 1</option>
|
||||||
|
<option value="2">Scene 2</option>
|
||||||
|
<option value="3">Scene 3</option>
|
||||||
|
<option value="4">Scene 4</option>
|
||||||
|
<option value="5">Scene 5</option>
|
||||||
|
<option value="6">Scene 6</option>
|
||||||
|
<option value="7">Scene 7</option>
|
||||||
|
<option value="8">Scene 8</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="artist">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Artist</label>
|
||||||
|
<description>Artist</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="track">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Track</label>
|
||||||
|
<description>Track</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="album">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Album</label>
|
||||||
|
<description>Album</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="albumArt">
|
||||||
|
<item-type>Image</item-type>
|
||||||
|
<label>Album Art</label>
|
||||||
|
<description>Album Art</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="repeat">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Repeat</label>
|
||||||
|
<description>Repeat mode</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="off">Off</option>
|
||||||
|
<option value="one">One</option>
|
||||||
|
<option value="all">All</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="shuffle">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Shuffle</label>
|
||||||
|
<description>Shuffle mode</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="off">Off</option>
|
||||||
|
<option value="on">On</option>
|
||||||
|
<option value="songs">Songs</option>
|
||||||
|
<option value="albums">Albums</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="mclinkStatus">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Status MusicCast</label>
|
||||||
|
<description>MusicCast Status</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="playTime">
|
||||||
|
<item-type>Number:Time</item-type>
|
||||||
|
<label>Play Time</label>
|
||||||
|
<description>Play Time</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="totalTime">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Total Time</label>
|
||||||
|
<description>Total Time</description>
|
||||||
|
</channel-type>
|
||||||
|
</thing:thing-descriptions>
|
@ -373,6 +373,7 @@
|
|||||||
<module>org.openhab.binding.wolfsmartset</module>
|
<module>org.openhab.binding.wolfsmartset</module>
|
||||||
<module>org.openhab.binding.xmltv</module>
|
<module>org.openhab.binding.xmltv</module>
|
||||||
<module>org.openhab.binding.xmppclient</module>
|
<module>org.openhab.binding.xmppclient</module>
|
||||||
|
<module>org.openhab.binding.yamahamusiccast</module>
|
||||||
<module>org.openhab.binding.yamahareceiver</module>
|
<module>org.openhab.binding.yamahareceiver</module>
|
||||||
<module>org.openhab.binding.yioremote</module>
|
<module>org.openhab.binding.yioremote</module>
|
||||||
<module>org.openhab.binding.yeelight</module>
|
<module>org.openhab.binding.yeelight</module>
|
||||||
|
Loading…
Reference in New Issue
Block a user