Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
Signed-off-by: clinique <gael@lhopital.org>
  • Loading branch information
clinique committed Jun 15, 2022
1 parent 56c721a commit 75725c0
Show file tree
Hide file tree
Showing 24 changed files with 424 additions and 502 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
/bundles/org.openhab.binding.mqtt.homie/ @davidgraeff
/bundles/org.openhab.binding.mycroft/ @dalgwen
/bundles/org.openhab.binding.mybmw/ @weymann @ntruchsess
/bundles/org.openhab.binding.mynice/ @clinique
/bundles/org.openhab.binding.myq/ @digitaldan
/bundles/org.openhab.binding.mystrom/ @pail23
/bundles/org.openhab.binding.nanoleaf/ @raepple @stefan-hoehn
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,11 @@
<artifactId>org.openhab.binding.mybmw</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.mynice</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.myq</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ public class MyNiceBindingConstants {
private static final String BINDING_ID = "mynice";

// List of all Channel ids
public static final String DOOR_STATUS = "doorstatus";
public static final String DOOR_STATUS = "status";
public static final String DOOR_OBSTRUCTED = "obstruct";
public static final String DOOR_MOVING = "moving";
public static final String DOOR_COMMAND = "command";

// List of all Thing Type UIDs
public static final ThingTypeUID BRIDGE_TYPE_IT4WIFI = new ThingTypeUID(BINDING_ID, "it4wifi");
public static final ThingTypeUID THING_TYPE_SWING = new ThingTypeUID(BINDING_ID, "swing");

// Configuration element of a portal
public static final String DEVICE_ID = "id";
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
public class It4WifiConfiguration {
public static final String PASSWORD = "password";
public static final String HOSTNAME = "hostname";

public String hostname = "";
public String macAddress = "";
public String password = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.jmdns.ServiceInfo;
Expand Down Expand Up @@ -81,7 +80,6 @@ public String getServiceType() {
}

private boolean validate(String mac) {
Matcher m = MAC_PATTERN.matcher(mac);
return m.find();
return MAC_PATTERN.matcher(mac).find();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
package org.openhab.binding.mynice.internal.discovery;

import static org.openhab.binding.mynice.internal.MyNiceBindingConstants.THING_TYPE_SWING;
import static org.openhab.binding.mynice.internal.MyNiceBindingConstants.*;

import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -41,9 +41,10 @@
@NonNullByDefault
public class MyNiceDiscoveryService extends AbstractDiscoveryService
implements MyNiceDataListener, ThingHandlerService {
private static final int SEARCH_TIME = 5;

private static final int SEARCH_TIME = 5;
private final Logger logger = LoggerFactory.getLogger(MyNiceDiscoveryService.class);

private @Nullable It4WifiHandler bridgeHandler;

/**
Expand Down Expand Up @@ -84,21 +85,35 @@ public void deactivate() {
}

@Override
public void onDataFetched(ThingUID bridge, List<Device> devices) {
devices.forEach(device -> {
ThingUID thingUID = new ThingUID(THING_TYPE_SWING, bridge, device.id);
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(bridge)
.withLabel(device.manuf + " " + device.prod).withRepresentationProperty("id")
.withProperty("id", device.id).build();
thingDiscovered(discoveryResult);
});
public void onDataFetched(List<Device> devices) {
It4WifiHandler handler = bridgeHandler;
if (handler != null) {
ThingUID bridgeUID = handler.getThing().getUID();
devices.stream().filter(device -> device.type != null).forEach(device -> {
ThingUID thingUID = null;
switch (device.type) {
case SWING:
thingUID = new ThingUID(THING_TYPE_SWING, bridgeUID, device.id);
break;
default:
logger.info("`{}` type of device is not yet supported", device.type);
break;
}
if (thingUID != null) {
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID)
.withLabel(String.format("%s %s", device.manuf, device.prod))
.withRepresentationProperty(DEVICE_ID).withProperty(DEVICE_ID, device.id).build();
thingDiscovered(discoveryResult);
}
});
}
}

@Override
protected void startScan() {
It4WifiHandler handler = bridgeHandler;
if (handler != null) {
handler.request(CommandType.INFO);
handler.sendCommand(CommandType.INFO);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import org.openhab.binding.mynice.internal.config.It4WifiConfiguration;
import org.openhab.binding.mynice.internal.discovery.MyNiceDiscoveryService;
import org.openhab.binding.mynice.internal.xml.It4WifiConnector;
import org.openhab.binding.mynice.internal.xml.It4WifiSession;
import org.openhab.binding.mynice.internal.xml.MyNiceXStream;
import org.openhab.binding.mynice.internal.xml.RequestBuilder;
import org.openhab.binding.mynice.internal.xml.dto.CommandType;
import org.openhab.binding.mynice.internal.xml.dto.Device;
import org.openhab.binding.mynice.internal.xml.dto.Event;
Expand Down Expand Up @@ -56,8 +56,8 @@ public class It4WifiHandler extends BaseBridgeHandler {

private @NonNullByDefault({}) It4WifiConfiguration config;
private @NonNullByDefault({}) It4WifiConnector connector;
private @NonNullByDefault({}) RequestBuilder reqBuilder;
private final MyNiceXStream xstream = new MyNiceXStream();
private final It4WifiSession session = new It4WifiSession();
private List<Device> devices = new ArrayList<>();

public It4WifiHandler(Bridge thing) {
Expand All @@ -69,117 +69,106 @@ public Collection<Class<? extends ThingHandlerService>> getServices() {
return Set.of(MyNiceDiscoveryService.class);
}

public boolean registerDataListener(MyNiceDataListener dataListener) {
boolean result = dataListeners.add(dataListener);
notifiyListeners(devices);
return result;
public void registerDataListener(MyNiceDataListener dataListener) {
dataListeners.add(dataListener);
notifyListeners(devices);
}

public boolean unregisterDataListener(MyNiceDataListener dataListener) {
return dataListeners.remove(dataListener);
public void unregisterDataListener(MyNiceDataListener dataListener) {
dataListeners.remove(dataListener);
}

@Override
public void handleCommand(ChannelUID channelUID, Command command) {
// if (CHANNEL_1.equals(channelUID.getId())) {
// if (command instanceof RefreshType) {
// TODO: handle data refresh
// }

// TODO: handle command

// Note: if communication with thing fails for some reason,
// indicate that by setting the status with detail information:
// updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
// "Could not control device at IP address x.x.x.x");
// }
// we do not handle commands
}

@Override
public void initialize() {
updateStatus(ThingStatus.UNKNOWN);
config = getConfigAs(It4WifiConfiguration.class);
connector = new It4WifiConnector(config.hostname, config.macAddress, session, this);
connector = new It4WifiConnector(config.hostname, this);
reqBuilder = new RequestBuilder(config.macAddress);
connector.start();
}

public void received(String command) {
logger.debug("Received : {}", command);
Event event = xstream.deserialize(command);
Response response = null;
if (event instanceof Response) {
response = (Response) event;
}
try {
if (event.error != null) {
logger.warn("Error code {} received : {}", event.error.code, event.error.info);
if (event.error != null) {
logger.warn("Error code {} received : {}", event.error.code, event.error.info);
} else {
if (event instanceof Response) {
handleResponse((Response) event);
} else {
switch (event.type) {
case PAIR:
Configuration thingConfig = editConfiguration();
thingConfig.put(It4WifiConfiguration.PASSWORD, response.authentication.pwd);
updateConfiguration(thingConfig);
logger.info("Pairing key updated in Configuration.");
connector.buildMessage(CommandType.VERIFY);
break;
case VERIFY:
switch (response.authentication.perm) {
case admin:
case user:
connector.buildMessage(CommandType.CONNECT);
break;
case wait:
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.CONFIGURATION_PENDING,
"Please validate the user on the MyNice application");
scheduler.schedule(() -> handShaked(), 5, TimeUnit.SECONDS);
break;
default:
break;
}
boolean notify = response.authentication.notify;
case CONNECT:
String sc = response.authentication.sc;
if (sc != null) {
session.setChallenges(sc, response.authentication.id, config.password);
connector.buildMessage(CommandType.INFO);
}
break;
case INFO:
updateStatus(ThingStatus.ONLINE);
if (thing.getProperties().isEmpty()) {
Map<String, String> properties = Map.of(PROPERTY_VENDOR, response.intf.manuf,
PROPERTY_MODEL_ID, response.intf.prod, PROPERTY_SERIAL_NUMBER,
response.intf.serialNr, PROPERTY_HARDWARE_VERSION, response.intf.versionHW,
PROPERTY_FIRMWARE_VERSION, response.intf.versionFW);
updateProperties(properties);
}
notifiyListeners(event.getDevices());
break;
case CHANGE:
case STATUS:
notifiyListeners(event.getDevices());
break;
}
notifyListeners(event.getDevices());
}
} catch (Exception e) {
// TODO Auto-generated catch block
}
}

private void notifiyListeners(List<Device> list) {
devices = list;
dataListeners.forEach(listener -> listener.onDataFetched(thing.getUID(), devices));
private void handleResponse(Response response) {
switch (response.type) {
case PAIR:
Configuration thingConfig = editConfiguration();
thingConfig.put(It4WifiConfiguration.PASSWORD, response.authentication.pwd);
updateConfiguration(thingConfig);
logger.info("Pairing key updated in Configuration.");
sendCommand(CommandType.VERIFY);
return;
case VERIFY:
switch (response.authentication.perm) {
case admin:
case user:
sendCommand(CommandType.CONNECT);
return;
case wait:
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.CONFIGURATION_PENDING,
"Please validate the user on the MyNice application");
scheduler.schedule(() -> handShaked(), 5, TimeUnit.SECONDS);
return;
default:
return;
}
case CONNECT:
String sc = response.authentication.sc;
if (sc != null) {
reqBuilder.setChallenges(sc, response.authentication.id, config.password);
sendCommand(CommandType.INFO);
}
return;
case INFO:
updateStatus(ThingStatus.ONLINE);
if (thing.getProperties().isEmpty()) {
Map<String, String> properties = Map.of(PROPERTY_VENDOR, response.intf.manuf, PROPERTY_MODEL_ID,
response.intf.prod, PROPERTY_SERIAL_NUMBER, response.intf.serialNr,
PROPERTY_HARDWARE_VERSION, response.intf.versionHW, PROPERTY_FIRMWARE_VERSION,
response.intf.versionFW);
updateProperties(properties);
}
notifyListeners(response.getDevices());
return;
case STATUS:
notifyListeners(response.getDevices());
break;
default:
logger.info("Unhandled response type : {}", response.type);
}
}

public void handShaked() {
request(config.password.isBlank() ? CommandType.PAIR : CommandType.VERIFY);
sendCommand(config.password.isBlank() ? CommandType.PAIR : CommandType.VERIFY);
}

public void request(CommandType command) {
try {
connector.buildMessage(command);
} catch (Exception e) {
// TODO Auto-generated catch block
}
private void notifyListeners(List<Device> list) {
devices = list;
dataListeners.forEach(listener -> listener.onDataFetched(devices));
}

public void sendCommand(CommandType command) {
connector.sendCommand(reqBuilder.buildMessage(command));
}

public void sendCommand(String id, String command) {
connector.sendCommand(reqBuilder.buildMessage(id, command.toLowerCase()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.mynice.internal.xml.dto.Device;
import org.openhab.core.thing.ThingUID;

/**
* The {@link MyNiceDataListener} is notified by the bridge thing handler with updated data from
Expand All @@ -27,5 +26,5 @@
@NonNullByDefault
public interface MyNiceDataListener {

public void onDataFetched(ThingUID bridge, List<Device> devices);
public void onDataFetched(List<Device> devices);
}
Loading

0 comments on commit 75725c0

Please sign in to comment.