]> git.basschouten.com Git - openhab-addons.git/blob
8b092d8fb0e2e04a22ff4aadeb871b3f9ec95111
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.freeboxos.internal.handler;
14
15 import static org.openhab.binding.freeboxos.internal.FreeboxOsBindingConstants.*;
16 import static org.openhab.core.library.unit.Units.*;
17
18 import java.math.BigDecimal;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.openhab.binding.freeboxos.internal.action.ServerActions;
27 import org.openhab.binding.freeboxos.internal.api.FreeboxException;
28 import org.openhab.binding.freeboxos.internal.api.rest.AfpManager;
29 import org.openhab.binding.freeboxos.internal.api.rest.AirMediaManager;
30 import org.openhab.binding.freeboxos.internal.api.rest.ConnectionManager;
31 import org.openhab.binding.freeboxos.internal.api.rest.ConnectionManager.Status;
32 import org.openhab.binding.freeboxos.internal.api.rest.FtpManager;
33 import org.openhab.binding.freeboxos.internal.api.rest.LanBrowserManager.Source;
34 import org.openhab.binding.freeboxos.internal.api.rest.LanManager;
35 import org.openhab.binding.freeboxos.internal.api.rest.LanManager.LanConfig;
36 import org.openhab.binding.freeboxos.internal.api.rest.SambaManager;
37 import org.openhab.binding.freeboxos.internal.api.rest.SambaManager.Samba;
38 import org.openhab.binding.freeboxos.internal.api.rest.SystemManager;
39 import org.openhab.binding.freeboxos.internal.api.rest.SystemManager.Config;
40 import org.openhab.binding.freeboxos.internal.api.rest.UPnPAVManager;
41 import org.openhab.binding.freeboxos.internal.api.rest.WifiManager;
42 import org.openhab.core.library.types.QuantityType;
43 import org.openhab.core.library.unit.SIUnits;
44 import org.openhab.core.library.unit.Units;
45 import org.openhab.core.thing.Channel;
46 import org.openhab.core.thing.ChannelUID;
47 import org.openhab.core.thing.Thing;
48 import org.openhab.core.thing.binding.ThingHandlerService;
49 import org.openhab.core.thing.binding.builder.ChannelBuilder;
50 import org.openhab.core.thing.type.ChannelTypeUID;
51 import org.openhab.core.types.Command;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 /**
56  * The {@link ServerHandler} handle common parts of Freebox bridges.
57  *
58  * @author Gaël L'hopital - Initial contribution
59  */
60 @NonNullByDefault
61 public class ServerHandler extends ApiConsumerHandler implements FreeDeviceIntf {
62     private static final BigDecimal HUNDRED = BigDecimal.valueOf(100);
63
64     private final Logger logger = LoggerFactory.getLogger(ServerHandler.class);
65     private final ChannelUID eventChannelUID;
66
67     private long uptime = -1;
68
69     public ServerHandler(Thing thing) {
70         super(thing);
71         eventChannelUID = new ChannelUID(getThing().getUID(), GROUP_SYS_INFO, BOX_EVENT);
72     }
73
74     @Override
75     void initializeProperties(Map<String, String> properties) throws FreeboxException {
76         LanConfig lanConfig = getManager(LanManager.class).getConfig();
77         Config config = getManager(SystemManager.class).getConfig();
78         properties.put(Thing.PROPERTY_SERIAL_NUMBER, config.serial());
79         properties.put(Thing.PROPERTY_FIRMWARE_VERSION, config.firmwareVersion());
80         properties.put(Thing.PROPERTY_HARDWARE_VERSION, config.modelInfo().prettyName());
81         properties.put(Thing.PROPERTY_MAC_ADDRESS, config.mac().toColonDelimitedString());
82         properties.put(Source.UPNP.name(), lanConfig.name());
83
84         List<Channel> channels = new ArrayList<>(getThing().getChannels());
85         int nbInit = channels.size();
86         config.sensors().forEach(sensor -> {
87             ChannelUID sensorId = new ChannelUID(thing.getUID(), GROUP_SENSORS, sensor.id());
88             if (getThing().getChannel(sensorId) == null) {
89                 String label = sensor.name();
90                 // For revolution, API returns only "Disque dur" so we patch it to have naming consistency with other
91                 // temperature sensors
92                 if ("Disque dur".equals(label)) {
93                     label = "Température " + label;
94                 }
95                 channels.add(ChannelBuilder.create(sensorId).withLabel(label).withAcceptedItemType("Number:Temperature")
96                         .withType(new ChannelTypeUID(BINDING_ID, "temperature")).build());
97             }
98         });
99         config.fans().forEach(sensor -> {
100             ChannelUID sensorId = new ChannelUID(thing.getUID(), GROUP_FANS, sensor.id());
101             if (getThing().getChannel(sensorId) == null) {
102                 channels.add(ChannelBuilder.create(sensorId).withLabel(sensor.name())
103                         .withAcceptedItemType("Number:Frequency").withType(new ChannelTypeUID(BINDING_ID, "fanspeed"))
104                         .build());
105             }
106         });
107         if (nbInit != channels.size()) {
108             updateThing(editThing().withChannels(channels).build());
109         }
110     }
111
112     @Override
113     protected void internalPoll() throws FreeboxException {
114         logger.debug("Polling server state...");
115         fetchConnectionStatus();
116         fetchSystemConfig();
117
118         if (anyChannelLinked(GROUP_ACTIONS, Set.of(WIFI_STATUS))) {
119             updateChannelOnOff(GROUP_ACTIONS, WIFI_STATUS, getManager(WifiManager.class).getStatus());
120         }
121         if (anyChannelLinked(GROUP_ACTIONS, Set.of(AIRMEDIA_STATUS))) {
122             updateChannelOnOff(GROUP_ACTIONS, AIRMEDIA_STATUS, getManager(AirMediaManager.class).getStatus());
123         }
124         if (anyChannelLinked(GROUP_ACTIONS, Set.of(UPNPAV_STATUS))) {
125             updateChannelOnOff(GROUP_ACTIONS, UPNPAV_STATUS, getManager(UPnPAVManager.class).getStatus());
126         }
127
128         if (anyChannelLinked(GROUP_FILE_SHARING, Set.of(SAMBA_FILE_STATUS, SAMBA_PRINTER_STATUS))) {
129             Samba response = getManager(SambaManager.class).getConfig();
130             updateChannelOnOff(GROUP_FILE_SHARING, SAMBA_FILE_STATUS, response.fileShareEnabled());
131             updateChannelOnOff(GROUP_FILE_SHARING, SAMBA_PRINTER_STATUS, response.printShareEnabled());
132         }
133         if (anyChannelLinked(GROUP_FILE_SHARING, Set.of(FTP_STATUS))) {
134             updateChannelOnOff(GROUP_FILE_SHARING, FTP_STATUS, getManager(FtpManager.class).getStatus());
135         }
136         if (anyChannelLinked(GROUP_FILE_SHARING, Set.of(AFP_FILE_STATUS))) {
137             updateChannelOnOff(GROUP_FILE_SHARING, AFP_FILE_STATUS, getManager(AfpManager.class).getStatus());
138         }
139     }
140
141     private void fetchSystemConfig() throws FreeboxException {
142         Config config = getManager(SystemManager.class).getConfig();
143
144         config.sensors().forEach(s -> updateChannelQuantity(GROUP_SENSORS, s.id(), s.value(), SIUnits.CELSIUS));
145         config.fans().forEach(f -> updateChannelQuantity(GROUP_FANS, f.id(), f.value(), Units.RPM));
146
147         uptime = checkUptimeAndFirmware(config.uptimeVal(), uptime, config.firmwareVersion());
148         updateChannelQuantity(GROUP_SYS_INFO, UPTIME, uptime, Units.SECOND);
149
150         if (anyChannelLinked(GROUP_SYS_INFO, Set.of(IP_ADDRESS))) {
151             LanConfig lanConfig = getManager(LanManager.class).getConfig();
152             updateChannelString(GROUP_SYS_INFO, IP_ADDRESS, lanConfig.ip());
153         }
154     }
155
156     private void fetchConnectionStatus() throws FreeboxException {
157         if (anyChannelLinked(GROUP_CONNECTION_STATUS,
158                 Set.of(LINE_STATUS, LINE_TYPE, LINE_MEDIA, IP_ADDRESS, IPV6_ADDRESS, BYTES_UP, BYTES_DOWN, RATE + "-up",
159                         BW + "-up", PCT_BW + "-up", RATE + "-down", BW + "-down", PCT_BW + "-down"))) {
160             Status status = getManager(ConnectionManager.class).getConfig();
161             updateChannelString(GROUP_CONNECTION_STATUS, LINE_STATUS, status.state());
162             updateChannelString(GROUP_CONNECTION_STATUS, LINE_TYPE, status.type());
163             updateChannelString(GROUP_CONNECTION_STATUS, LINE_MEDIA, status.media());
164             updateChannelString(GROUP_CONNECTION_STATUS, IP_ADDRESS, status.ipv4());
165             updateChannelString(GROUP_CONNECTION_STATUS, IPV6_ADDRESS, status.ipv6());
166
167             updateRateBandwidth(status.rateUp(), status.bandwidthUp(), "up");
168             updateRateBandwidth(status.rateDown(), status.bandwidthDown(), "down");
169
170             updateChannelQuantity(GROUP_CONNECTION_STATUS, BYTES_UP, new QuantityType<>(status.bytesUp(), OCTET),
171                     GIBIOCTET);
172             updateChannelQuantity(GROUP_CONNECTION_STATUS, BYTES_DOWN, new QuantityType<>(status.bytesDown(), OCTET),
173                     GIBIOCTET);
174         }
175     }
176
177     private void updateRateBandwidth(long rate, long bandwidth, String orientation) {
178         QuantityType<?> rateUp = new QuantityType<>(rate * 8, Units.BIT_PER_SECOND);
179         QuantityType<?> bandwidthUp = new QuantityType<>(bandwidth, BIT_PER_SECOND);
180         updateChannelQuantity(GROUP_CONNECTION_STATUS, RATE + "-" + orientation, rateUp, KILOBIT_PER_SECOND);
181         updateChannelQuantity(GROUP_CONNECTION_STATUS, BW + "-" + orientation, bandwidthUp, KILOBIT_PER_SECOND);
182         updateChannelQuantity(GROUP_CONNECTION_STATUS, PCT_BW + "-" + orientation,
183                 !bandwidthUp.equals(QuantityType.ZERO) ? rateUp.multiply(HUNDRED).divide(bandwidthUp)
184                         : QuantityType.ZERO,
185                 Units.PERCENT);
186     }
187
188     @Override
189     protected boolean internalHandleCommand(String channelId, Command command) throws FreeboxException {
190         if (ON_OFF_CLASSES.contains(command.getClass())) {
191             boolean enable = TRUE_COMMANDS.contains(command);
192             switch (channelId) {
193                 case WIFI_STATUS:
194                     updateChannelOnOff(GROUP_ACTIONS, WIFI_STATUS, getManager(WifiManager.class).setStatus(enable));
195                     return true;
196                 case FTP_STATUS:
197                     updateChannelOnOff(GROUP_FILE_SHARING, FTP_STATUS, getManager(FtpManager.class).setStatus(enable));
198                     return true;
199                 case SAMBA_FILE_STATUS:
200                     updateChannelOnOff(GROUP_FILE_SHARING, SAMBA_FILE_STATUS,
201                             getManager(SambaManager.class).setFileShare(enable));
202                     return true;
203                 case SAMBA_PRINTER_STATUS:
204                     updateChannelOnOff(GROUP_FILE_SHARING, SAMBA_PRINTER_STATUS,
205                             getManager(SambaManager.class).setPrintShare(enable));
206                     return true;
207                 case UPNPAV_STATUS:
208                     updateChannelOnOff(GROUP_ACTIONS, UPNPAV_STATUS, getManager(UPnPAVManager.class).setStatus(enable));
209                     return true;
210                 case AFP_FILE_STATUS:
211                     updateChannelOnOff(GROUP_FILE_SHARING, AFP_FILE_STATUS,
212                             getManager(AfpManager.class).setStatus(enable));
213                     return true;
214                 case AIRMEDIA_STATUS:
215                     updateChannelOnOff(GROUP_ACTIONS, AIRMEDIA_STATUS,
216                             getManager(AirMediaManager.class).setStatus(enable));
217                     return true;
218                 default:
219                     break;
220             }
221         }
222         return super.internalHandleCommand(channelId, command);
223     }
224
225     public void reboot() {
226         processReboot(() -> {
227             try {
228                 getManager(SystemManager.class).reboot();
229             } catch (FreeboxException e) {
230                 logger.warn("Error rebooting: {}", e.getMessage());
231             }
232         });
233     }
234
235     @Override
236     public Collection<Class<? extends ThingHandlerService>> getServices() {
237         return Set.of(ServerActions.class);
238     }
239
240     @Override
241     public ChannelUID getEventChannelUID() {
242         return eventChannelUID;
243     }
244
245     @Override
246     public void triggerChannel(ChannelUID channelUID, String event) {
247         super.triggerChannel(channelUID, event);
248     }
249 }