]> git.basschouten.com Git - openhab-addons.git/blob
787822e859a49242282e19ba8812ee8252e1b735
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.magentatv.internal;
14
15 import static org.openhab.binding.magentatv.internal.MagentaTVBindingConstants.*;
16
17 import java.io.IOException;
18 import java.util.Map;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.magentatv.internal.MagentaTVDeviceManager.MagentaTVDevice;
23 import org.openhab.binding.magentatv.internal.handler.MagentaTVHandler;
24 import org.openhab.binding.magentatv.internal.network.MagentaTVNetwork;
25 import org.openhab.binding.magentatv.internal.network.MagentaTVPoweroffListener;
26 import org.openhab.core.net.HttpServiceUtil;
27 import org.openhab.core.net.NetworkAddressService;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingTypeUID;
30 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
31 import org.openhab.core.thing.binding.ThingHandler;
32 import org.openhab.core.thing.binding.ThingHandlerFactory;
33 import org.osgi.service.component.ComponentContext;
34 import org.osgi.service.component.annotations.Activate;
35 import org.osgi.service.component.annotations.Component;
36 import org.osgi.service.component.annotations.Reference;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link MagentaTVHandlerFactory} is responsible for creating things and thing
42  * handlers.
43  *
44  * @author Markus Michels - Initial contribution
45  */
46 @NonNullByDefault
47 @Component(service = { ThingHandlerFactory.class, MagentaTVHandlerFactory.class }, configurationPid = "binding."
48         + BINDING_ID)
49 public class MagentaTVHandlerFactory extends BaseThingHandlerFactory {
50     private final Logger logger = LoggerFactory.getLogger(MagentaTVHandlerFactory.class);
51
52     private final MagentaTVNetwork network = new MagentaTVNetwork();
53     private final MagentaTVDeviceManager manager;
54     private @Nullable MagentaTVPoweroffListener upnpListener;
55     private boolean servletInitialized = false;
56
57     /**
58      * Activate the bundle: save properties
59      *
60      * @param componentContext
61      * @param configProperties set of properties from cfg (use same names as in
62      *            thing config)
63      */
64
65     @Activate
66     public MagentaTVHandlerFactory(@Reference NetworkAddressService networkAddressService,
67             @Reference MagentaTVDeviceManager manager, ComponentContext componentContext,
68             Map<String, String> configProperties) throws IOException {
69         super.activate(componentContext);
70         this.manager = manager;
71
72         try {
73             logger.debug("Initialize network access");
74             System.setProperty("java.net.preferIPv4Stack", "true");
75             String lip = networkAddressService.getPrimaryIpv4HostAddress();
76             Integer port = HttpServiceUtil.getHttpServicePort(componentContext.getBundleContext());
77             if (port == -1) {
78                 port = 8080;
79             }
80             network.initLocalNet(lip != null ? lip : "", port.toString());
81             upnpListener = new MagentaTVPoweroffListener(this, network.getLocalInterface());
82         } catch (MagentaTVException e) {
83             logger.warn("Initialization failed: {}", e.toString());
84         }
85     }
86
87     @Override
88     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
89         return SUPPORTED_THING_TYPES.contains(thingTypeUID);
90     }
91
92     @Override
93     protected @Nullable ThingHandler createHandler(Thing thing) {
94         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
95
96         if (upnpListener != null) {
97             upnpListener.start();
98         }
99
100         logger.debug("Create thing type {}", thing.getThingTypeUID().getAsString());
101         if (THING_TYPE_RECEIVER.equals(thingTypeUID)) {
102             return new MagentaTVHandler(manager, thing, network);
103         }
104
105         return null;
106     }
107
108     /**
109      * Add a device to the device table
110      *
111      * @param udn UDN for the device
112      * @param deviceId A unique device id
113      * @param ipAddress IP address of the receiver
114      * @param handler The corresponding thing handler
115      */
116
117     public void setNotifyServletStatus(boolean newStatus) {
118         logger.debug("NotifyServlet started");
119         servletInitialized = newStatus;
120     }
121
122     public boolean getNotifyServletStatus() {
123         return servletInitialized;
124     }
125
126     /**
127      * We received the pairing result (by the Notify servlet)
128      *
129      * @param notifyDeviceId The unique device id pairing was initiated for
130      * @param pairingCode Pairing code computed by the receiver
131      * @return true: thing handler was called, false: failed, e.g. unknown device
132      */
133     public boolean notifyPairingResult(String notifyDeviceId, String ipAddress, String pairingCode) {
134         try {
135             logger.trace("PairingResult: Check {} devices for id {}, ipAddress {}", manager.numberOfDevices(),
136                     notifyDeviceId, ipAddress);
137             MagentaTVDevice dev = manager.lookupDevice(ipAddress);
138             if ((dev != null) && (dev.thingHandler != null)) {
139                 if (dev.deviceId.isEmpty()) {
140                     logger.trace("deviceId {} assigned for ipAddress {}", notifyDeviceId, ipAddress);
141                     dev.deviceId = notifyDeviceId;
142                 }
143                 if (dev.thingHandler != null) {
144                     dev.thingHandler.onPairingResult(pairingCode);
145                 }
146                 return true;
147             }
148
149             logger.debug("Received pairingCode {} for unregistered device {}!", pairingCode, ipAddress);
150         } catch (MagentaTVException e) {
151             logger.debug("Unable to process pairing result for deviceID {}: {}", notifyDeviceId, e.toString());
152         }
153         return false;
154     }
155
156     /**
157      * A programInfo or playStatus event was received from the receiver
158      *
159      * @param mrMac MR MAC address (used to map the device)
160      * @param jsonEvent Event data in JSON format
161      * @return true: thing handler was called, false: failed, e.g. unknown device
162      */
163     public boolean notifyMREvent(String mrMac, String jsonEvent) {
164         try {
165             logger.trace("Received MR event from MAC {}, JSON={}", mrMac, jsonEvent);
166             MagentaTVDevice dev = manager.lookupDevice(mrMac);
167             if ((dev != null) && (dev.thingHandler != null)) {
168                 dev.thingHandler.onMREvent(jsonEvent);
169                 return true;
170             }
171             logger.debug("Received event for unregistered MR: MAC address {}, JSON={}", mrMac, jsonEvent);
172         } catch (RuntimeException e) {
173             logger.debug("Unable to process MR event! {} ({}), json={}", e.getMessage(), e.getClass(), jsonEvent);
174         }
175         return false;
176     }
177
178     /**
179      * The PowerOff Listener got a byebye message. This comes in when the receiver
180      * was is going to suspend mode.
181      *
182      * @param ipAddress receiver IP
183      */
184     public void onPowerOff(String ipAddress) {
185         try {
186             logger.debug("ByeBye message received for IP {}", ipAddress);
187             MagentaTVDevice dev = manager.lookupDevice(ipAddress);
188             if ((dev != null) && (dev.thingHandler != null)) {
189                 dev.thingHandler.onPowerOff();
190             }
191         } catch (MagentaTVException e) {
192             logger.debug("Unable to process SSDP message for IP {} - {}", ipAddress, e.toString());
193         }
194     }
195 }