Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Freebox binding: fix initialization and add thing properties #1127

Merged
merged 1 commit into from
Jul 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,19 @@
<channel id="bytes_down" typeId="bytes_down" />
</channels>

<properties>
<property name="vendor">Freebox SAS</property>
</properties>

<config-description>
<parameter name="ipAddress" type="text">
<label>Freebox Network Address</label>
<parameter name="fqdn" type="text">
<label>Freebox Server FQDN</label>
<context>network_address</context>
<description>The IP address / FQDN of the Freebox Server (can include port number)</description>
<default>mafreebox.freebox.fr</default>
<required>false</required>
</parameter>

<parameter name="apiBaseUrl" type="text">
<label>API base URL</label>
<description>The base URL to use the Freebox Server API</description>
<default>/api/</default>
<required>false</required>
</parameter>

<parameter name="apiVersion" type="text">
<label>API version</label>
<description>The Freebox Server API version</description>
<default>3.0</default>
<required>false</required>
</parameter>

<parameter name="appToken" type="text">
<label>Application token</label>
<description>Token generated by the Freebox server</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Import-Package: com.google.common.base,
javax.jmdns,
javax.net,
javax.net.ssl,
org.apache.commons.lang,
org.apache.commons.logging,
org.eclipse.smarthome.config.core,
org.eclipse.smarthome.config.discovery,
Expand All @@ -26,6 +27,7 @@ Import-Package: com.google.common.base,
org.eclipse.smarthome.core.thing,
org.eclipse.smarthome.core.thing.binding,
org.eclipse.smarthome.core.types,
org.eclipse.smarthome.io.net.http,
org.eclipse.smarthome.io.transport.mdns.discovery,
org.osgi.framework,
org.slf4j
Expand Down
6 changes: 2 additions & 4 deletions addons/binding/org.openhab.binding.freebox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ The _server_ bridge thing requires the following configuration parameters:

| Parameter Label | Parameter ID | Description | Required | Default |
|--------------------------|-----------------|---------------------------------------------------------|----------|---------|
| Freebox Network Address | ipAddress | The IP address / FQDN of the Freebox Server (can include port number).| false | mafreebox.freebox.fr |
| API base URL | apiBaseUrl | The base URL to use the Freebox Server API. | false | /api/ |
| API version | apiVersion | The Freebox Server API version. | false | 3.0 |
| Freebox Network Address | fqdn | The IP address / FQDN of the Freebox Server (can include port number).| false | mafreebox.freebox.fr |
| Application token | appToken | Token generated by the Freebox Server. | false | |
| Refresh Interval | refreshInterval | The refresh interval in seconds which is used to poll given Freebox Server.| false | 30 |

Expand Down Expand Up @@ -154,7 +152,7 @@ Bridge freebox:server:fb "Freebox Revolution" [ appToken="xxxxxxxxxxxxxxxxxxxxxx
Here is another example overwritting default configuration parameters:

```
Bridge freebox:server:fb "Freebox Revolution" [ ipAddress="192.168.0.254", appToken="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", refreshInterval=20 ] {
Bridge freebox:server:fb "Freebox Revolution" [ fqdn="192.168.0.254", appToken="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", refreshInterval=20 ] {
Thing phone Phone "Phone" [ refreshPhoneInterval=10, refreshPhoneCallsInterval=120 ]
Thing net_device tv1 "TV living room" [ macAddress="XX:XX:XX:XX:XX:XX" ]
Thing net_interface tv2 "TV bedroom" [ ipAddress="192.168.0.100" ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public class FreeboxBindingConstants {
public final static Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = ImmutableSet.of(FREEBOX_THING_TYPE_PHONE,
FREEBOX_THING_TYPE_NET_DEVICE, FREEBOX_THING_TYPE_NET_INTERFACE);

// List of properties
public final static String API_BASE_URL = "apiBaseUrl";
public final static String API_VERSION = "apiVersion";

// List of all Group Channel ids
public final static String STATE = "state";
public final static String ANY = "any";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@
*/
public class FreeboxServerConfiguration {

public static final String IP_ADDRESS = "ipAddress";
public static final String API_BASE_URL = "apiBaseUrl";
public static final String API_VERSION = "apiVersion";
public static final String FQDN = "fqdn";
public static final String APP_TOKEN = "appToken";
public static final String REFRESH_INTERVAL = "refreshInterval";

public String ipAddress;
public String apiBaseUrl;
public String apiVersion;
public String fqdn;
public String appToken;
public Integer refreshInterval;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService;
import org.eclipse.smarthome.config.discovery.DiscoveryResult;
import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingUID;
import org.matmaul.freeboxos.FreeboxException;
import org.matmaul.freeboxos.lan.LanHostConfig;
Expand Down Expand Up @@ -99,6 +100,9 @@ public void onDataFetched(ThingUID bridge, LanHostsConfig hostsConfig) {
if (thingUID != null) {
logger.trace("Adding new Freebox Network Device {} to inbox", thingUID);
Map<String, Object> properties = new HashMap<>(1);
if ((hostConfig.getVendorName() != null) && !hostConfig.getVendorName().isEmpty()) {
properties.put(Thing.PROPERTY_VENDOR, hostConfig.getVendorName());
}
properties.put(FreeboxNetDeviceConfiguration.MAC_ADDRESS, mac);
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID)
.withProperties(properties).withBridge(bridge).withLabel(name).build();
Expand All @@ -120,6 +124,9 @@ public void onDataFetched(ThingUID bridge, LanHostsConfig hostsConfig) {
if (thingUID != null) {
logger.trace("Adding new Freebox Network Interface {} to inbox", thingUID);
Map<String, Object> properties = new HashMap<>(1);
if ((hostConfig.getVendorName() != null) && !hostConfig.getVendorName().isEmpty()) {
properties.put(Thing.PROPERTY_VENDOR, hostConfig.getVendorName());
}
properties.put(FreeboxNetInterfaceConfiguration.IP_ADDRESS, addr);
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID)
.withProperties(properties).withBridge(bridge).withLabel(name).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import org.eclipse.smarthome.config.discovery.DiscoveryResult;
import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.ThingUID;
import org.eclipse.smarthome.io.transport.mdns.discovery.MDNSDiscoveryParticipant;
Expand Down Expand Up @@ -71,12 +72,15 @@ public DiscoveryResult createResult(ServiceInfo service) {
if (thingUID != null && ip != null) {
logger.info("Created a DiscoveryResult for Freebox Server {} on IP {}", thingUID, ip);
Map<String, Object> properties = new HashMap<>(1);
properties.put(FreeboxServerConfiguration.IP_ADDRESS, ip);
properties.put(FreeboxServerConfiguration.FQDN, ip + ":" + service.getPort());
if (service.getPropertyString("device_type") != null) {
properties.put(Thing.PROPERTY_HARDWARE_VERSION, service.getPropertyString("device_type"));
}
if (service.getPropertyString("api_base_url") != null) {
properties.put(FreeboxServerConfiguration.API_BASE_URL, service.getPropertyString("api_base_url"));
properties.put(FreeboxBindingConstants.API_BASE_URL, service.getPropertyString("api_base_url"));
}
if (service.getPropertyString("api_version") != null) {
properties.put(FreeboxServerConfiguration.API_VERSION, service.getPropertyString("api_version"));
properties.put(FreeboxBindingConstants.API_VERSION, service.getPropertyString("api_version"));
}
result = DiscoveryResultBuilder.create(thingUID).withProperties(properties).withLabel(service.getName())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
import static org.openhab.binding.freebox.FreeboxBindingConstants.*;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType;
import org.eclipse.smarthome.core.library.types.OnOffType;
Expand All @@ -29,6 +31,7 @@
import org.eclipse.smarthome.core.thing.ThingStatusDetail;
import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.io.net.http.HttpUtil;
import org.matmaul.freeboxos.FreeboxException;
import org.matmaul.freeboxos.FreeboxOsClient;
import org.matmaul.freeboxos.airmedia.AirMediaConfig;
Expand All @@ -45,6 +48,7 @@
import org.matmaul.freeboxos.system.SystemConfiguration;
import org.matmaul.freeboxos.upnpav.UPnPAVConfig;
import org.matmaul.freeboxos.wifi.WifiGlobalConfig;
import org.openhab.binding.freebox.FreeboxBindingConstants;
import org.openhab.binding.freebox.config.FreeboxServerConfiguration;
import org.openhab.binding.freebox.internal.FreeboxDataListener;
import org.osgi.framework.Bundle;
Expand All @@ -63,6 +67,7 @@ public class FreeboxHandler extends BaseBridgeHandler {

private Logger logger = LoggerFactory.getLogger(FreeboxHandler.class);

private ScheduledFuture<?> authorizeJob;
private ScheduledFuture<?> globalJob;
private FreeboxOsClient fbClient;
private long uptime;
Expand All @@ -71,6 +76,7 @@ public class FreeboxHandler extends BaseBridgeHandler {
public FreeboxHandler(Bridge bridge) {
super(bridge);

authorizeJob = null;
globalJob = null;
fbClient = null;
uptime = -1;
Expand Down Expand Up @@ -128,7 +134,7 @@ private boolean authorize() {
Bundle bundle = FrameworkUtil.getBundle(getClass());

fbClient = new FreeboxOsClient(bundle.getSymbolicName(), /* org.openhab.binding.freebox */
configuration.ipAddress);
configuration.fqdn);

LoginManager loginManager = fbClient.getLoginManager();
TrackAuthorizeStatus authorizeStatus = TrackAuthorizeStatus.UNKNOWN;
Expand Down Expand Up @@ -175,18 +181,73 @@ private boolean authorize() {
@Override
public void initialize() {
logger.debug("initializing Freebox Server handler.");
if (authorize()) {
updateStatus(ThingStatus.ONLINE);

if (globalJob == null || globalJob.isCancelled()) {
long polling_interval = getConfigAs(FreeboxServerConfiguration.class).refreshInterval;
globalJob = scheduler.scheduleAtFixedRate(globalRunnable, 1, polling_interval, TimeUnit.SECONDS);
String apiBaseUrl = null;
String apiVersion = null;
String hardwareVersion = null;
FreeboxServerConfiguration configuration = getConfigAs(FreeboxServerConfiguration.class);
String result = HttpUtil.executeUrl("GET", "http://" + configuration.fqdn + "/api_version", 5000);
if (result != null) {
apiBaseUrl = StringUtils.trim(
StringUtils.replace(StringUtils.substringBetween(result, "\"api_base_url\":\"", "\""), "\\/", "/"));
apiVersion = StringUtils.trim(StringUtils.substringBetween(result, "\"api_version\":\"", "\""));
hardwareVersion = StringUtils.trim(StringUtils.substringBetween(result, "\"device_type\":\"", "\""));
}

if ((apiBaseUrl != null) && (apiVersion != null) && (hardwareVersion != null)) {
updateStatus(ThingStatus.OFFLINE);

logger.debug("Server OK, binding will schedule a job to establish a connection...");
if (authorizeJob == null || authorizeJob.isCancelled()) {
authorizeJob = scheduler.schedule(authorizeRunnable, 1, TimeUnit.SECONDS);
}
} else {
updateStatus(ThingStatus.OFFLINE);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
}

Map<String, String> properties = editProperties();
boolean update = false;
if ((apiBaseUrl != null) && !apiBaseUrl.isEmpty()
&& ((properties.get(FreeboxBindingConstants.API_BASE_URL) == null)
|| !properties.get(FreeboxBindingConstants.API_BASE_URL).equals(apiBaseUrl))) {
update = true;
properties.put(FreeboxBindingConstants.API_BASE_URL, apiBaseUrl);
}
if ((apiVersion != null) && !apiVersion.isEmpty()
&& ((properties.get(FreeboxBindingConstants.API_VERSION) == null)
|| !properties.get(FreeboxBindingConstants.API_VERSION).equals(apiVersion))) {
update = true;
properties.put(FreeboxBindingConstants.API_VERSION, apiVersion);
}
if ((hardwareVersion != null) && !hardwareVersion.isEmpty()
&& ((properties.get(Thing.PROPERTY_HARDWARE_VERSION) == null)
|| !properties.get(Thing.PROPERTY_HARDWARE_VERSION).equals(hardwareVersion))) {
update = true;
properties.put(Thing.PROPERTY_HARDWARE_VERSION, hardwareVersion);
}
if (update) {
updateProperties(properties);
}
}

private Runnable authorizeRunnable = new Runnable() {
@Override
public void run() {
logger.debug("Authorize job...");
if (authorize()) {
updateStatus(ThingStatus.ONLINE);

if (globalJob == null || globalJob.isCancelled()) {
long polling_interval = getConfigAs(FreeboxServerConfiguration.class).refreshInterval;
logger.debug("Scheduling server state update every {} seconds...", polling_interval);
globalJob = scheduler.scheduleAtFixedRate(globalRunnable, 1, polling_interval, TimeUnit.SECONDS);
}
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
}
}
};

private Runnable globalRunnable = new Runnable() {
@Override
public void run() {
Expand Down Expand Up @@ -214,10 +275,12 @@ public void run() {
}

} catch (Throwable t) {
if (t instanceof Exception) {
logger.error(((Exception) t).getMessage());
if (t instanceof FreeboxException) {
logger.error("FreeboxException: {}", ((FreeboxException) t).getMessage());
} else if (t instanceof Exception) {
logger.error("Exception: {}", ((Exception) t).getMessage());
} else if (t instanceof Error) {
logger.error(((Error) t).getMessage());
logger.error("Error: {}", ((Error) t).getMessage());
} else {
logger.error("Unexpected error");
}
Expand All @@ -232,6 +295,10 @@ public void run() {
@Override
public void dispose() {
logger.debug("Disposing Freebox Server handler.");
if (authorizeJob != null && !authorizeJob.isCancelled()) {
authorizeJob.cancel(true);
authorizeJob = null;
}
if (globalJob != null && !globalJob.isCancelled()) {
globalJob.cancel(true);
globalJob = null;
Expand Down Expand Up @@ -327,6 +394,23 @@ private void fetchLCDConfig() throws FreeboxException {
private void fetchSystemConfig() throws FreeboxException {
SystemConfiguration systemConfiguration = fbClient.getSystemManager().getConfiguration();

Map<String, String> properties = editProperties();
boolean update = false;
if (!systemConfiguration.getSerial().isEmpty() && ((properties.get(Thing.PROPERTY_SERIAL_NUMBER) == null)
|| !properties.get(Thing.PROPERTY_SERIAL_NUMBER).equals(systemConfiguration.getSerial()))) {
update = true;
properties.put(Thing.PROPERTY_SERIAL_NUMBER, systemConfiguration.getSerial());
}
if (!systemConfiguration.getFirmware_version().isEmpty()
&& ((properties.get(Thing.PROPERTY_FIRMWARE_VERSION) == null) || !properties
.get(Thing.PROPERTY_FIRMWARE_VERSION).equals(systemConfiguration.getFirmware_version()))) {
update = true;
properties.put(Thing.PROPERTY_FIRMWARE_VERSION, systemConfiguration.getFirmware_version());
}
if (update) {
updateProperties(properties);
}

updateState(new ChannelUID(getThing().getUID(), FWVERSION),
new StringType(systemConfiguration.getFirmware_version()));

Expand All @@ -346,8 +430,9 @@ private synchronized LanHostsConfig fetchLanHostsConfig() throws FreeboxExceptio

// The update of channels is delegated to each thing handler
for (Thing thing : getThing().getThings()) {
FreeboxThingHandler handler = (FreeboxThingHandler) thing.getHandler();
handler.updateNetInfo(lanHostsConfiguration);
if (thing.getHandler() != null) {
((FreeboxThingHandler) thing.getHandler()).updateNetInfo(lanHostsConfiguration);
}
}

return lanHostsConfiguration;
Expand Down
Loading