]> git.basschouten.com Git - openhab-addons.git/blob
54ea99516b7d0c437d5e44a7ad1920d9d811c1a8
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.yamahareceiver.internal.protocol.xml;
14
15 import static java.util.stream.Collectors.joining;
16 import static org.openhab.binding.yamahareceiver.internal.protocol.xml.XMLConstants.Commands.*;
17
18 import java.io.IOException;
19 import java.util.Collection;
20 import java.util.LinkedList;
21 import java.util.List;
22
23 import org.openhab.binding.yamahareceiver.internal.YamahaReceiverBindingConstants.Zone;
24 import org.openhab.binding.yamahareceiver.internal.protocol.AbstractConnection;
25 import org.openhab.binding.yamahareceiver.internal.protocol.ReceivedMessageParseException;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 import org.w3c.dom.Document;
29 import org.w3c.dom.Node;
30
31 /**
32  * Provides services for XML protocol
33  *
34  * @author Tomasz Maruszak - Initial contribution
35  */
36 public class XMLProtocolService {
37
38     private static final Logger LOGGER = LoggerFactory.getLogger(XMLProtocolService.class);
39
40     /**
41      * Sends a command to the specified zone.
42      *
43      * @param con
44      * @param zone
45      * @param cmd
46      * @return The response XML node (specific to the command sent).
47      * @throws IOException
48      * @throws ReceivedMessageParseException
49      */
50     public static Node getZoneResponse(AbstractConnection con, Zone zone, String cmd)
51             throws IOException, ReceivedMessageParseException {
52         return getResponse(con, XMLUtils.wrZone(zone, cmd), zone.toString());
53     }
54
55     /**
56      * Sends a command to the specified zone.
57      *
58      * @param con
59      * @param zone
60      * @param cmd
61      * @param path XML tree path to extract from the response
62      * @return The response XML node (specific to the command sent).
63      * @throws IOException
64      * @throws ReceivedMessageParseException
65      */
66     public static Node getZoneResponse(AbstractConnection con, Zone zone, String cmd, String path)
67             throws IOException, ReceivedMessageParseException {
68         return getResponse(con, XMLUtils.wrZone(zone, cmd), zone + "/" + path);
69     }
70
71     /**
72      * Send the command and retrieve the node at the specified element path.
73      *
74      * @param cmd
75      * @param path
76      * @return
77      * @throws IOException
78      * @throws ReceivedMessageParseException
79      */
80     public static Node getResponse(AbstractConnection con, String cmd, String path)
81             throws IOException, ReceivedMessageParseException {
82         String response = con.sendReceive(cmd);
83         Document doc = XMLUtils.xml(response);
84         if (doc.getFirstChild() == null) {
85             throw new ReceivedMessageParseException("The command '" + cmd + "' failed: " + response);
86         }
87         Node content = XMLUtils.getNode(doc.getFirstChild(), path);
88         return content;
89     }
90
91     /**
92      * Sends a request to retrieve the input values available for the zone.
93      *
94      * @param con
95      * @param zone
96      * @return
97      * @throws IOException
98      * @throws ReceivedMessageParseException
99      */
100     public static Collection<InputDto> getInputs(AbstractConnection con, Zone zone)
101             throws IOException, ReceivedMessageParseException {
102         Node inputSelItem = getZoneResponse(con, zone, ZONE_INPUT_QUERY, ZONE_INPUT_PATH);
103
104         List<InputDto> inputs = new LinkedList<>();
105         XMLUtils.getChildElements(inputSelItem).forEach(item -> {
106             String param = item.getElementsByTagName("Param").item(0).getTextContent();
107             boolean writable = item.getElementsByTagName("RW").item(0).getTextContent().contains("W");
108             inputs.add(new InputDto(param, writable));
109         });
110
111         if (LOGGER.isTraceEnabled()) {
112             LOGGER.trace("Zone {} - inputs: {}", zone, inputs.stream().map(InputDto::toString).collect(joining(", ")));
113         }
114
115         return inputs;
116     }
117
118     /**
119      * Represents an input source
120      */
121     public static class InputDto {
122
123         private final String param;
124         private final boolean writable;
125
126         public InputDto(String param, boolean writable) {
127             this.param = param;
128             this.writable = writable;
129         }
130
131         public String getParam() {
132             return param;
133         }
134
135         public boolean isWritable() {
136             return writable;
137         }
138
139         @Override
140         public String toString() {
141             return String.format("%s:%s", param, writable ? "RW" : "R");
142         }
143     }
144 }