Search in sources :

Example 1 with ThingDoc

use of io.openems.api.doc.ThingDoc in project openems by OpenEMS.

the class ClassRepository method getThingDoc.

/**
 * Returns the cached ThingDoc or parses the class and adds it to the cache.
 * Field annotations have higher priority than method annotations!
 *
 * @param clazz
 */
public ThingDoc getThingDoc(Class<? extends Thing> clazz) {
    if (this.thingDocs.containsKey(clazz)) {
        // return from cache
        return this.thingDocs.get(clazz);
    }
    ThingDoc thingDoc = new ThingDoc(clazz);
    // get info about thing
    ThingInfo thing = clazz.getAnnotation(ThingInfo.class);
    if (thing == null) {
        log.warn("Thing [" + clazz.getName() + "] has no @ThingInfo annotation");
    } else {
        thingDoc.setThingDescription(thing);
    }
    // parse all methods
    for (Method method : clazz.getMethods()) {
        Class<?> type = null;
        if (method.getReturnType().isArray()) {
            Class<?> rtype = method.getReturnType();
            type = rtype.getComponentType();
        } else {
            type = method.getReturnType();
        }
        if (Channel.class.isAssignableFrom(type)) {
            Optional<ChannelInfo> channelInfoOpt = getAnnotationForMethod(clazz, method.getName());
            String channelId = method.getName();
            ChannelDoc channelDoc = new ChannelDoc(method, channelId, channelInfoOpt);
            thingDoc.addChannelDoc(channelDoc);
            if (ConfigChannel.class.isAssignableFrom(type)) {
                thingDoc.addConfigChannelDoc(channelDoc);
            }
        }
    }
    // parse all fields
    for (Field field : clazz.getFields()) {
        Class<?> type = field.getType();
        if (Channel.class.isAssignableFrom(type)) {
            String channelId = field.getName();
            ChannelDoc channelDoc = new ChannelDoc(field, channelId, Optional.ofNullable(field.getAnnotation(ChannelInfo.class)));
            thingDoc.addChannelDoc(channelDoc);
            if (ConfigChannel.class.isAssignableFrom(type)) {
                thingDoc.addConfigChannelDoc(channelDoc);
            }
        }
    }
    // add to cache
    this.thingDocs.put(clazz, thingDoc);
    return thingDoc;
}
Also used : Field(java.lang.reflect.Field) ChannelInfo(io.openems.api.doc.ChannelInfo) Method(java.lang.reflect.Method) ThingInfo(io.openems.api.doc.ThingInfo) ChannelDoc(io.openems.api.doc.ChannelDoc) ThingDoc(io.openems.api.doc.ThingDoc)

Example 2 with ThingDoc

use of io.openems.api.doc.ThingDoc in project openems by OpenEMS.

the class Config method getJson.

/**
 * Gets the Config as Json in the given format
 *
 * @param format
 * @return
 * @throws NotImplementedException
 */
public synchronized JsonObject getJson(ConfigFormat format, Role role, String language) throws NotImplementedException {
    JsonObject jConfig = new JsonObject();
    if (format == ConfigFormat.FILE) {
        /*
			 * Prepare Json in format for config.json file
			 */
        // Bridge
        jConfig.add("things", getBridgesJson(format, role));
        // Scheduler
        jConfig.add("scheduler", getSchedulerJson(format, role));
        // Persistence
        jConfig.add("persistence", getPersistenceJson(format, role));
        // Users
        jConfig.add("users", getUsersJson());
    } else {
        /*
			 * Prepare Json in format for OpenEMS UI
			 */
        // things...
        JsonObject jThings = new JsonObject();
        Set<Thing> things = ThingRepository.getInstance().getThings();
        for (Thing thing : things) {
            JsonObject jThing = (JsonObject) ConfigUtils.getAsJsonElement(thing, format, role);
            jThings.add(thing.id(), jThing);
        }
        jConfig.add("things", jThings);
        // meta...
        JsonObject jMeta = new JsonObject();
        try {
            Iterable<ThingDoc> availableThings = ClassRepository.getInstance().getAvailableThings();
            for (ThingDoc availableThing : availableThings) {
                jMeta.add(availableThing.getClazz().getName(), availableThing.getAsJsonObject());
            }
        } catch (ReflectionException e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }
        jConfig.add("meta", jMeta);
    }
    return jConfig;
}
Also used : ReflectionException(io.openems.api.exception.ReflectionException) JsonObject(com.google.gson.JsonObject) Thing(io.openems.api.thing.Thing) ThingDoc(io.openems.api.doc.ThingDoc)

Example 3 with ThingDoc

use of io.openems.api.doc.ThingDoc in project openems by OpenEMS.

the class ThingRepository method applyChannelAnnotation.

public void applyChannelAnnotation(Thing thing) {
    ThingDoc thingDoc = classRepository.getThingDoc(thing.getClass());
    for (ChannelDoc channelDoc : thingDoc.getChannelDocs()) {
        try {
            Channel channel = getChannel(thing, channelDoc.getMember());
            channel.setChannelDoc(channelDoc);
        } catch (OpenemsException e) {
            log.debug(e.getMessage());
        }
    }
}
Also used : ReadChannel(io.openems.api.channel.ReadChannel) WriteChannel(io.openems.api.channel.WriteChannel) ConfigChannel(io.openems.api.channel.ConfigChannel) ThingStateChannel(io.openems.api.channel.ThingStateChannel) Channel(io.openems.api.channel.Channel) OpenemsException(io.openems.common.exceptions.OpenemsException) ChannelDoc(io.openems.api.doc.ChannelDoc) ThingDoc(io.openems.api.doc.ThingDoc)

Example 4 with ThingDoc

use of io.openems.api.doc.ThingDoc in project openems by OpenEMS.

the class ChannelExport method main.

public static void main(String[] args) throws OpenemsException {
    String openemsPath = "C:\\Users\\matthias.rossmann\\Dev\\git\\openems-neu\\edge\\src";
    Collection<ThingDoc> deviceNatures;
    HashMap<Path, FileWriter> files = new HashMap<>();
    try {
        deviceNatures = ClassRepository.getInstance().getAvailableDeviceNatures();
        FileWriter devices = new FileWriter(Paths.get(openemsPath, "\\io\\openems\\impl\\device\\Readme.md").toFile());
        devices.write("# List of implemented Devices.\r\n\r\n");
        for (ThingDoc thingDoc : deviceNatures) {
            try {
                System.out.println(thingDoc.getClazz().getName());
                if (thingDoc.getClazz().equals(AsymmetricSymmetricCombinationEssNature.class) || thingDoc.getClazz().equals(EssClusterNature.class) || thingDoc.getClazz().isInterface() || Modifier.isAbstract(thingDoc.getClazz().getModifiers())) {
                    continue;
                }
                Path p = Paths.get(openemsPath, thingDoc.getClazz().getName().replaceAll("[^\\.]*$", "").replace(".", "/"), "Readme.md");
                FileWriter fw;
                if (files.containsKey(p)) {
                    fw = files.get(p);
                } else {
                    fw = new FileWriter(p.toFile());
                    files.put(p, fw);
                    fw.write("");
                }
                fw.append("# " + thingDoc.getTitle() + "\r\n" + thingDoc.getText() + "\r\n\r\nFollowing Values are implemented:\r\n\r\n" + "|ChannelName|Unit|\r\n" + "|---|---|\r\n");
                devices.append("* [" + thingDoc.getTitle() + "](" + Paths.get(thingDoc.getClazz().getName().replaceAll("io.openems.impl.device.", "").replaceAll("[^\\.]*$", "").replace(".", "/"), "Readme.md").toString().replace("\\", "/") + ")\r\n");
                Thing thing = thingDoc.getClazz().getConstructor(String.class, Device.class).newInstance("", null);
                if (thing instanceof ModbusDeviceNature) {
                    ((ModbusDeviceNature) thing).init();
                }
                List<ChannelDoc> channelDocs = new LinkedList<>(thingDoc.getChannelDocs());
                Collections.sort(channelDocs, new Comparator<ChannelDoc>() {

                    @Override
                    public int compare(ChannelDoc arg0, ChannelDoc arg1) {
                        return arg0.getName().compareTo(arg1.getName());
                    }
                });
                for (ChannelDoc channelDoc : channelDocs) {
                    Member member = channelDoc.getMember();
                    try {
                        List<Channel> channels = new ArrayList<>();
                        if (member instanceof Method) {
                            if (((Method) member).getReturnType().isArray()) {
                                Channel[] ch = (Channel[]) ((Method) member).invoke(thing);
                                for (Channel c : ch) {
                                    channels.add(c);
                                }
                            } else {
                                // It's a Method with ReturnType Channel
                                channels.add((Channel) ((Method) member).invoke(thing));
                            }
                        } else if (member instanceof Field) {
                            // It's a Field with Type Channel
                            channels.add((Channel) ((Field) member).get(thing));
                        } else {
                            continue;
                        }
                        if (channels.isEmpty()) {
                            System.out.println("Channel is returning null! Thing [" + thing.id() + "], Member [" + member.getName() + "]");
                            continue;
                        }
                        for (Channel channel : channels) {
                            if (channel != null) {
                                StringBuilder unit = new StringBuilder();
                                if (channel instanceof ReadChannel) {
                                    ReadChannel rchannel = ((ReadChannel) channel);
                                    unit.append(rchannel.unitOptional());
                                    rchannel.getLabels().forEach((key, value) -> {
                                        unit.append(key + ": " + value + "<br/>");
                                    });
                                }
                                fw.append("|" + channel.id() + "|" + unit + "|\r\n");
                            }
                        }
                    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                        System.out.println("Unable to add Channel. Member [" + member.getName() + "]");
                    }
                }
            } catch (NoSuchMethodException e) {
            }
        }
        for (FileWriter fw : files.values()) {
            fw.close();
        }
        devices.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : HashMap(java.util.HashMap) FileWriter(java.io.FileWriter) ArrayList(java.util.ArrayList) ReadChannel(io.openems.api.channel.ReadChannel) Field(java.lang.reflect.Field) EssClusterNature(io.openems.impl.device.system.esscluster.EssClusterNature) Member(java.lang.reflect.Member) Thing(io.openems.api.thing.Thing) ThingDoc(io.openems.api.doc.ThingDoc) Path(java.nio.file.Path) Device(io.openems.api.device.Device) ReadChannel(io.openems.api.channel.ReadChannel) Channel(io.openems.api.channel.Channel) Method(java.lang.reflect.Method) ChannelDoc(io.openems.api.doc.ChannelDoc) LinkedList(java.util.LinkedList) InvocationTargetException(java.lang.reflect.InvocationTargetException) OpenemsException(io.openems.common.exceptions.OpenemsException) InvocationTargetException(java.lang.reflect.InvocationTargetException) AsymmetricSymmetricCombinationEssNature(io.openems.impl.device.system.asymmetricsymmetriccombinationess.AsymmetricSymmetricCombinationEssNature) ModbusDeviceNature(io.openems.impl.protocol.modbus.ModbusDeviceNature)

Example 5 with ThingDoc

use of io.openems.api.doc.ThingDoc in project openems by OpenEMS.

the class ThingRepository method addThing.

/**
 * Add a Thing to the Repository and cache its Channels and other information for later usage.
 *
 * @param thing
 */
public synchronized void addThing(Thing thing) {
    if (thingIds.containsValue(thing)) {
        // Thing was already added
        return;
    }
    // Add to thingIds
    thingIds.forcePut(thing.id(), thing);
    // Add to thingClasses
    thingClasses.put(thing.getClass(), thing);
    // Add to bridges
    if (thing instanceof Bridge) {
        bridges.add((Bridge) thing);
    }
    // Add to schedulers
    if (thing instanceof Scheduler) {
        schedulers.add((Scheduler) thing);
    }
    // Add to persistences
    if (thing instanceof Persistence) {
        persistences.add((Persistence) thing);
    }
    // Add to queryablePersistences
    if (thing instanceof QueryablePersistence) {
        queryablePersistences.add((QueryablePersistence) thing);
    }
    // Add to device natures
    if (thing instanceof DeviceNature) {
        deviceNatures.add((DeviceNature) thing);
    }
    // Add Listener
    thing.addListener(this);
    // Apply channel annotation (this happens now and again after initializing the thing via init()
    this.applyChannelAnnotation(thing);
    // Add Channels thingConfigChannels
    ThingDoc thingDoc = classRepository.getThingDoc(thing.getClass());
    for (ChannelDoc channelDoc : thingDoc.getChannelDocs()) {
        Member member = channelDoc.getMember();
        try {
            List<Channel> channels = new ArrayList<>();
            java.util.function.Consumer<Channel> addToChannels = (c) -> {
                if (c == null) {
                // TODO this error is not handled properly
                // log.error(
                // "Channel is returning null! Thing [" + thing.id() + "], Member [" + member.getName() + "]");
                } else {
                    channels.add(c);
                }
            };
            if (member instanceof Method) {
                if (((Method) member).getReturnType().isArray()) {
                    Channel[] ch = (Channel[]) ((Method) member).invoke(thing);
                    for (Channel c : ch) {
                        addToChannels.accept(c);
                    }
                } else {
                    // It's a Method with ReturnType Channel
                    Channel c = (Channel) ((Method) member).invoke(thing);
                    addToChannels.accept(c);
                    if (c instanceof ThingStateChannels) {
                        ThingStateChannels tsc = (ThingStateChannels) c;
                        for (ThingStateChannel fc : tsc.getFaultChannels()) {
                            addToChannels.accept(fc);
                        }
                        for (ThingStateChannel wc : tsc.getWarningChannels()) {
                            addToChannels.accept(wc);
                        }
                    }
                }
            } else if (member instanceof Field) {
                // It's a Field with Type Channel
                Channel c = (Channel) ((Field) member).get(thing);
                addToChannels.accept(c);
            } else {
                continue;
            }
            if (channels.isEmpty()) {
                continue;
            }
            for (Channel channel : channels) {
                // Add Channel to thingChannels
                thingChannels.put(thing, channel.id(), channel);
                if (channel instanceof ConfigChannel) {
                    // Add Channel to configChannels
                    thingConfigChannels.put(thing, (ConfigChannel<?>) channel);
                }
            }
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            log.warn("Unable to add Channel. Member [" + member.getName() + "]", e);
        }
    }
    for (ThingsChangedListener listener : thingListeners) {
        listener.thingChanged(thing, Action.ADD);
    }
}
Also used : ReadChannel(io.openems.api.channel.ReadChannel) JsonObject(com.google.gson.JsonObject) Controller(io.openems.api.controller.Controller) OpenemsException(io.openems.common.exceptions.OpenemsException) LoggerFactory(org.slf4j.LoggerFactory) WriteChannel(io.openems.api.channel.WriteChannel) HashBasedTable(com.google.common.collect.HashBasedTable) ConfigChannel(io.openems.api.channel.ConfigChannel) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) HashMultimap(com.google.common.collect.HashMultimap) Bridge(io.openems.api.bridge.Bridge) Map(java.util.Map) DeviceNature(io.openems.api.device.nature.DeviceNature) Scheduler(io.openems.api.scheduler.Scheduler) LinkedList(java.util.LinkedList) Method(java.lang.reflect.Method) BiMap(com.google.common.collect.BiMap) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Member(java.lang.reflect.Member) Collection(java.util.Collection) JsonUtils(io.openems.common.utils.JsonUtils) Set(java.util.Set) Thing(io.openems.api.thing.Thing) ThingChannelsUpdatedListener(io.openems.api.thing.ThingChannelsUpdatedListener) Field(java.lang.reflect.Field) QueryablePersistence(io.openems.api.persistence.QueryablePersistence) InvocationTargetException(java.lang.reflect.InvocationTargetException) Device(io.openems.api.device.Device) Action(io.openems.core.ThingsChangedListener.Action) List(java.util.List) HashBiMap(com.google.common.collect.HashBiMap) ThingStateChannels(io.openems.api.channel.thingstate.ThingStateChannels) InjectionUtils(io.openems.core.utilities.InjectionUtils) Entry(java.util.Map.Entry) ConfigUtils(io.openems.core.utilities.ConfigUtils) Optional(java.util.Optional) Persistence(io.openems.api.persistence.Persistence) ChannelAddress(io.openems.common.types.ChannelAddress) ChannelDoc(io.openems.api.doc.ChannelDoc) ThingDoc(io.openems.api.doc.ThingDoc) Collections(java.util.Collections) Table(com.google.common.collect.Table) ThingStateChannel(io.openems.api.channel.ThingStateChannel) Channel(io.openems.api.channel.Channel) Scheduler(io.openems.api.scheduler.Scheduler) ConfigChannel(io.openems.api.channel.ConfigChannel) ArrayList(java.util.ArrayList) ThingStateChannels(io.openems.api.channel.thingstate.ThingStateChannels) ThingStateChannel(io.openems.api.channel.ThingStateChannel) Field(java.lang.reflect.Field) QueryablePersistence(io.openems.api.persistence.QueryablePersistence) DeviceNature(io.openems.api.device.nature.DeviceNature) Member(java.lang.reflect.Member) ThingDoc(io.openems.api.doc.ThingDoc) ReadChannel(io.openems.api.channel.ReadChannel) WriteChannel(io.openems.api.channel.WriteChannel) ConfigChannel(io.openems.api.channel.ConfigChannel) ThingStateChannel(io.openems.api.channel.ThingStateChannel) Channel(io.openems.api.channel.Channel) Method(java.lang.reflect.Method) ChannelDoc(io.openems.api.doc.ChannelDoc) InvocationTargetException(java.lang.reflect.InvocationTargetException) QueryablePersistence(io.openems.api.persistence.QueryablePersistence) Persistence(io.openems.api.persistence.Persistence) Bridge(io.openems.api.bridge.Bridge)

Aggregations

ThingDoc (io.openems.api.doc.ThingDoc)7 ChannelDoc (io.openems.api.doc.ChannelDoc)6 Channel (io.openems.api.channel.Channel)4 ReadChannel (io.openems.api.channel.ReadChannel)4 Thing (io.openems.api.thing.Thing)4 Field (java.lang.reflect.Field)4 Method (java.lang.reflect.Method)4 ConfigChannel (io.openems.api.channel.ConfigChannel)3 ThingStateChannel (io.openems.api.channel.ThingStateChannel)3 WriteChannel (io.openems.api.channel.WriteChannel)3 OpenemsException (io.openems.common.exceptions.OpenemsException)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 Member (java.lang.reflect.Member)3 ArrayList (java.util.ArrayList)3 JsonObject (com.google.gson.JsonObject)2 Device (io.openems.api.device.Device)2 LinkedList (java.util.LinkedList)2 Entry (java.util.Map.Entry)2 BiMap (com.google.common.collect.BiMap)1 HashBasedTable (com.google.common.collect.HashBasedTable)1