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