Skip to content

Commit

Permalink
add channels when defining thing type
Browse files Browse the repository at this point in the history
Signed-off-by: Dieter Schmidt <[email protected]>
  • Loading branch information
dimalo committed Aug 13, 2017
1 parent e60efd4 commit 8067f57
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import static org.openhab.binding.miio.MiIoBindingConstants.*;

import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
Expand All @@ -20,24 +22,34 @@
import org.eclipse.smarthome.core.cache.ExpiringCache;
import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.library.types.StringType;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.ThingStatusDetail;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
import org.eclipse.smarthome.core.thing.binding.builder.ChannelBuilder;
import org.eclipse.smarthome.core.thing.binding.builder.ThingBuilder;
import org.eclipse.smarthome.core.types.Command;
import org.openhab.binding.miio.MiIoBindingConfiguration;
import org.openhab.binding.miio.MiIoBindingConstants;
import org.openhab.binding.miio.internal.Message;
import org.openhab.binding.miio.internal.MiIoCommand;
import org.openhab.binding.miio.internal.MiIoCommunication;
import org.openhab.binding.miio.internal.MiIoCryptoException;
import org.openhab.binding.miio.internal.MiIoDevices;
import org.openhab.binding.miio.internal.Utils;
import org.openhab.binding.miio.internal.basic.MiIoBasicDevice;
import org.openhab.binding.miio.internal.basic.MiIoBasicProperty;
import org.openhab.binding.miio.internal.basic.MiIoDeviceAction;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonIOException;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
Expand All @@ -54,6 +66,8 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler {
protected ScheduledFuture<?> pollingJob;
protected MiIoBindingConfiguration configuration;
protected MiIoDevices miDevice = MiIoDevices.UNKNOWN;
MiIoBasicDevice miioDevice;
private Map<String, MiIoDeviceAction> actions;
protected boolean isIdentified;

protected JsonParser parser;
Expand Down Expand Up @@ -282,6 +296,7 @@ protected void defineDeviceType() {
if (miioInfo != null) {
updateProperties(miioInfo);
updateThingType(miioInfo);
buildChannelStructure(miioInfo.get("model").getAsString());
}
}

Expand Down Expand Up @@ -342,4 +357,68 @@ protected JsonObject getJsonResultHelper(String response) {
}
return null;
}

private boolean buildChannelStructure(String deviceName) {
// TODO: This still needs significant cleanup but should be functional
try {
Bundle bundle = bundleContext.getBundle();
URL fn = bundle.getEntry(MiIoBindingConstants.DATABASE_PATH + deviceName + ".json");
logger.debug("bundle: {}, {}, {}", bundle, fn.getFile(), fn);
JsonObject deviceMapping = Utils.convertFileToJSON(fn);
logger.debug("Device Mapper: {}, {}, {}", fn.getFile(), deviceMapping.toString());

Gson gson = new GsonBuilder().serializeNulls().create();
miioDevice = gson.fromJson(deviceMapping, MiIoBasicDevice.class);

actions = new HashMap<String, MiIoDeviceAction>();

// make a map of the actions
for (MiIoDeviceAction action : miioDevice.getDevice().getActions()) {
actions.put(action.getChannel(), action);
}

for (Channel ch : getThing().getChannels()) {
logger.debug("Current thing channels {}, type: {}", ch.getUID(), ch.getChannelTypeUID());
}
ThingBuilder thingBuilder = editThing();
int channelsAdded = 0;
for (MiIoBasicProperty miProperty : miioDevice.getDevice().getProperties()) {

logger.debug("properties {}", miProperty);
ChannelUID channelUID = new ChannelUID(getThing().getUID(), miProperty.getChannel());

// TODO: only for testing. This should not be done finally. Channel only to be added when not there
// already
if (getThing().getChannel(miProperty.getChannel()) == null) {
logger.info("Add Channel '{}' for thing {}", miProperty.getChannel(), getThing().getUID());

Channel channel = ChannelBuilder.create(channelUID, miProperty.getType())
.withLabel(miProperty.getFriendlyName()).build();
thingBuilder.withChannel(channel);
channelsAdded += 1;
}
}
// only update if channels were added/removed
if (channelsAdded > 0) {
updateThing(thingBuilder.build());
}

} catch (JsonIOException e) {
logger.debug("Error reading Json", e);
} catch (JsonSyntaxException e) {
logger.debug("Error reading Json", e);
} catch (IOException e) {
logger.debug("Error reading Json", e);
} catch (NullPointerException e) {
logger.debug("Error crreating channel structure", e);
} catch (Exception e) {
logger.debug("Error crreating channel structure", e);
}

return false;
}

Map<String, MiIoDeviceAction> getActions() {
return actions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,24 @@

import static org.openhab.binding.miio.MiIoBindingConstants.CHANNEL_COMMAND;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.library.types.OnOffType;
import org.eclipse.smarthome.core.library.types.StringType;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.binding.builder.ChannelBuilder;
import org.eclipse.smarthome.core.thing.binding.builder.ThingBuilder;
import org.eclipse.smarthome.core.thing.type.ChannelTypeUID;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.RefreshType;
import org.openhab.binding.miio.MiIoBindingConstants;
import org.openhab.binding.miio.internal.MiIoCommand;
import org.openhab.binding.miio.internal.Utils;
import org.openhab.binding.miio.internal.basic.MiIoBasicDevice;
import org.openhab.binding.miio.internal.basic.MiIoBasicProperty;
import org.openhab.binding.miio.internal.basic.MiIoDeviceAction;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonIOException;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

/**
* The {@link MiIoBasicHandler} is responsible for handling commands, which are
Expand All @@ -54,8 +37,6 @@
*/
public class MiIoBasicHandler extends MiIoAbstractHandler {
private final Logger logger = LoggerFactory.getLogger(MiIoBasicHandler.class);
MiIoBasicDevice miioDevice;
private Map<String, MiIoDeviceAction> actions;

public MiIoBasicHandler(Thing thing) {
super(thing);
Expand All @@ -73,9 +54,9 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}
// TODO: cleanup debug stuff & add handling types
logger.debug("Locating action for channel {}:{}", channelUID.getId(), command);
if (actions != null) {
if (actions.containsKey(channelUID.getId())) {
String cmd = actions.get(channelUID.getId()).getCommand();
if (getActions() != null) {
if (getActions().containsKey(channelUID.getId())) {
String cmd = getActions().get(channelUID.getId()).getCommand();
if (command instanceof OnOffType) {
cmd = cmd + "[\"" + command.toString().toLowerCase() + "\"]";
}
Expand All @@ -86,8 +67,8 @@ public void handleCommand(ChannelUID channelUID, Command command) {
sendCommand(cmd);
} else {
logger.debug("Channel Id {} not in mapping. Available:", channelUID.getId());
for (String a : actions.keySet()) {
logger.debug("entries: {} : {}", a, actions.get(a));
for (String a : getActions().keySet()) {
logger.debug("entries: {} : {}", a, getActions().get(a));
}

}
Expand Down Expand Up @@ -159,7 +140,6 @@ protected boolean initializeData() {
initalizeNetworkCache();
// For testing only.. this should load the possible properties & actions per device
// NB, ones working properly, this action should be done once the type is known
buildChannelStructure("zhimi.airpurifier.m1");

this.miioCom = getConnection();
if (miioCom != null) {
Expand All @@ -169,70 +149,4 @@ protected boolean initializeData() {
}
return true;
}

private boolean buildChannelStructure(String deviceName) {
// TODO: This still needs significant cleanup but should be functional
try {
Bundle bundle = bundleContext.getBundle();
URL fn = bundle.getEntry(MiIoBindingConstants.DATABASE_PATH + deviceName + ".json");
logger.debug("bundle: {}, {}, {}", bundle, fn.getFile(), fn);
JsonObject deviceMapping = Utils.convertFileToJSON(fn);
logger.debug("Device Mapper: {}, {}, {}", fn.getFile(), deviceMapping.toString());

Gson gson = new GsonBuilder().serializeNulls().create();
miioDevice = gson.fromJson(deviceMapping, MiIoBasicDevice.class);

actions = new HashMap<String, MiIoDeviceAction>();

// make a map of the actions
for (MiIoDeviceAction action : miioDevice.getDevice().getActions()) {
actions.put(action.getChannel(), action);
}

for (Channel ch : getThing().getChannels()) {
logger.debug("Current thing channels {}, type: {}", ch.getUID(), ch.getChannelTypeUID());
}
ThingBuilder thingBuilder = editThing();
int channelsAdded = 0;
for (MiIoBasicProperty miProperty : miioDevice.getDevice().getProperties()) {

logger.debug("properties {}", miProperty);
ChannelUID channelUID = new ChannelUID(getThing().getUID(), miProperty.getChannel());

// TODO: only for testing. This should not be done finally. Channel only to be added when not there
// already
if (getThing().getChannel(miProperty.getChannel()) != null) {
logger.info("Channel '{}' for thing {} already exist... removing", miProperty.getChannel(),
getThing().getUID());
thingBuilder.withoutChannel(new ChannelUID(getThing().getUID(), miProperty.getChannel()));
}

ChannelTypeUID channelTypeUID = new ChannelTypeUID(MiIoBindingConstants.BINDING_ID,
miProperty.getChannelType());

Channel channel = ChannelBuilder.create(channelUID, miProperty.getType()).withType(channelTypeUID)
.withLabel(miProperty.getFriendlyName()).build();
thingBuilder.withChannel(channel);
channelsAdded += 1;
}
// only update if channels were added/removed
if (channelsAdded > 0) {
updateThing(thingBuilder.build());
}

} catch (JsonIOException e) {
logger.debug("Error reading Json", e);
} catch (JsonSyntaxException e) {
logger.debug("Error reading Json", e);
} catch (IOException e) {
logger.debug("Error reading Json", e);
} catch (NullPointerException e) {
logger.debug("Error crreating channel structure", e);
} catch (Exception e) {
logger.debug("Error crreating channel structure", e);
}

return false;

}
}

0 comments on commit 8067f57

Please sign in to comment.