]> git.basschouten.com Git - openhab-addons.git/blob
50c8fe26b9fb0c51901f80b88db40b06bde397be
[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     /**
112      * Add a device to the device table
113      *
114      * @param udn UDN for the device
115      * @param deviceId A unique device id
116      * @param ipAddress IP address of the receiver
117      * @param handler The corresponding thing handler
118      */
119
120     public void setNotifyServletStatus(boolean newStatus) {
121         logger.debug("NotifyServlet started");
122         servletInitialized = newStatus;
123     }
124
125     public boolean getNotifyServletStatus() {
126         return servletInitialized;
127     }
128
129     /**
130      * We received the pairing result (by the Notify servlet)
131      *
132      * @param notifyDeviceId The unique device id pairing was initiated for
133      * @param pairingCode Pairing code computed by the receiver
134      * @return true: thing handler was called, false: failed, e.g. unknown device
135      */
136     public boolean notifyPairingResult(String notifyDeviceId, String ipAddress, String pairingCode) {
137         try {
138             logger.trace("PairingResult: Check {} devices for id {}, ipAddress {}", manager.numberOfDevices(),
139                     notifyDeviceId, ipAddress);
140             MagentaTVDevice dev = manager.lookupDevice(ipAddress);
141             if ((dev != null) && (dev.thingHandler != null)) {
142                 if (dev.deviceId.isEmpty()) {
143                     logger.trace("deviceId {} assigned for ipAddress {}", notifyDeviceId, ipAddress);
144                     dev.deviceId = notifyDeviceId;
145                 }
146                 if (dev.thingHandler != null) {
147                     dev.thingHandler.onPairingResult(pairingCode);
148                 }
149                 return true;
150             }
151
152             logger.debug("Received pairingCode {} for unregistered device {}!", pairingCode, ipAddress);
153         } catch (MagentaTVException e) {
154             logger.debug("Unable to process pairing result for deviceID {}: {}", notifyDeviceId, e.toString());
155         }
156         return false;
157     }
158
159     /**
160      * A programInfo or playStatus event was received from the receiver
161      *
162      * @param mrMac MR MAC address (used to map the device)
163      * @param jsonEvent Event data in JSON format
164      * @return true: thing handler was called, false: failed, e.g. unknown device
165      */
166     public boolean notifyMREvent(String mrMac, String jsonEvent) {
167         try {
168             logger.trace("Received MR event from MAC {}, JSON={}", mrMac, jsonEvent);
169             MagentaTVDevice dev = manager.lookupDevice(mrMac);
170             if ((dev != null) && (dev.thingHandler != null)) {
171                 dev.thingHandler.onMREvent(jsonEvent);
172                 return true;
173             }
174             logger.debug("Received event for unregistered MR: MAC address {}, JSON={}", mrMac, jsonEvent);
175         } catch (RuntimeException e) {
176             logger.debug("Unable to process MR event! {} ({}), json={}", e.getMessage(), e.getClass(), jsonEvent);
177         }
178         return false;
179     }
180
181     /**
182      * The PowerOff Listener got a byebye message. This comes in when the receiver
183      * was is going to suspend mode.
184      *
185      * @param ipAddress receiver IP
186      */
187     public void onPowerOff(String ipAddress) {
188         try {
189             logger.debug("ByeBye message received for IP {}", ipAddress);
190             MagentaTVDevice dev = manager.lookupDevice(ipAddress);
191             if ((dev != null) && (dev.thingHandler != null)) {
192                 dev.thingHandler.onPowerOff();
193             }
194         } catch (MagentaTVException e) {
195             logger.debug("Unable to process SSDP message for IP {} - {}", ipAddress, e.toString());
196         }
197     }
198 }