diff --git a/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoAbstractHandler.java b/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoAbstractHandler.java index 3128a3f411390..57847c8b70043 100644 --- a/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoAbstractHandler.java +++ b/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoAbstractHandler.java @@ -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; @@ -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; @@ -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 actions; protected boolean isIdentified; protected JsonParser parser; @@ -282,6 +296,7 @@ protected void defineDeviceType() { if (miioInfo != null) { updateProperties(miioInfo); updateThingType(miioInfo); + buildChannelStructure(miioInfo.get("model").getAsString()); } } @@ -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(); + + // 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 getActions() { + return actions; + } } diff --git a/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoBasicHandler.java b/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoBasicHandler.java index 4e30aa6bd14ee..401ae23369ffd 100644 --- a/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoBasicHandler.java +++ b/addons/binding/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/handler/MiIoBasicHandler.java @@ -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 @@ -54,8 +37,6 @@ */ public class MiIoBasicHandler extends MiIoAbstractHandler { private final Logger logger = LoggerFactory.getLogger(MiIoBasicHandler.class); - MiIoBasicDevice miioDevice; - private Map actions; public MiIoBasicHandler(Thing thing) { super(thing); @@ -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() + "\"]"; } @@ -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)); } } @@ -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) { @@ -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(); - - // 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; - - } }