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