use of io.openems.api.channel.ConfigChannel in project openems by OpenEMS.
the class ChannelRestlet method setValue.
/**
* handle HTTP POST request
*
* @param thingId
* @param channelId
* @param jHttpPost
*/
private void setValue(Channel channel, JsonObject jHttpPost) {
// check for writable channel
if (!(channel instanceof WriteChannel<?>)) {
throw new ResourceException(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
}
// parse value
JsonElement jValue;
if (jHttpPost.has("value")) {
jValue = jHttpPost.get("value");
} else {
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Value is missing");
}
// set channel value
if (channel instanceof ConfigChannel<?>) {
// is a ConfigChannel
ConfigChannel<?> configChannel = (ConfigChannel<?>) channel;
try {
configChannel.updateValue(jValue, true);
log.info("Updated Channel [" + channel.address() + "] to value [" + jValue.toString() + "].");
} catch (NotImplementedException e) {
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Conversion not implemented");
}
} else if (channel instanceof WriteChannel<?>) {
/*
* WriteChannel
*/
WriteChannel<?> writeChannel = (WriteChannel<?>) channel;
WriteObject writeObject = new WriteJsonObject(jValue).onFirstSuccess(() -> {
Notification.EDGE_CHANNEL_UPDATE_SUCCESS.writeToLog(log, "set " + channel.address() + " => " + jValue);
}).onFirstError((e) -> {
Notification.EDGE_CHANNEL_UPDATE_FAILED.writeToLog(log, "set " + channel.address() + " => " + jValue);
}).onTimeout(() -> {
Notification.EDGE_CHANNEL_UPDATE_TIMEOUT.writeToLog(log, "set " + channel.address() + " => " + jValue);
});
this.apiWorker.addValue(writeChannel, writeObject);
}
}
use of io.openems.api.channel.ConfigChannel in project openems by OpenEMS.
the class InjectionUtils method getThingMapsFromConfig.
public static Object getThingMapsFromConfig(ConfigChannel<?> channel, JsonElement j) throws ReflectionException {
/*
* Get "Field" in Channels parent class
*/
Field field;
try {
field = channel.parent().getClass().getField(channel.id());
} catch (NoSuchFieldException | SecurityException e) {
throw new ReflectionException("Field for ConfigChannel [" + channel.address() + "] is not named [" + channel.id() + "] in [" + channel.getClass().getSimpleName() + "]");
}
/*
* Get expected Object Type (List, Set, simple Object)
*/
Type expectedObjectType = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
if (expectedObjectType instanceof ParameterizedType) {
expectedObjectType = ((ParameterizedType) expectedObjectType).getRawType();
}
Class<?> expectedObjectClass = (Class<?>) expectedObjectType;
/*
* Get the ThingMap class
*/
Class<?> thingMapClass = channel.type().get();
/*
* Get the referenced Thing class
*/
IsThingMap isThingMapAnnotation = thingMapClass.getAnnotation(IsThingMap.class);
Class<? extends Thing> thingClass = isThingMapAnnotation.type();
/*
* Prepare filter for matching Things
* - Empty filter: accept nothing
* - Asterisk: accept everything
* - Otherwise: accept only exact string matches on the thing id
*/
Set<String> filter = new HashSet<>();
if (j.isJsonPrimitive()) {
String id = j.getAsJsonPrimitive().getAsString();
filter.add(id);
} else if (j.isJsonArray()) {
j.getAsJsonArray().forEach(id -> filter.add(id.getAsString()));
}
/*
* Create ThingMap instance(s) for each matching Thing
*/
ThingRepository thingRepository = ThingRepository.getInstance();
Set<Thing> matchingThings = thingRepository.getThingsAssignableByClass(thingClass);
Set<ThingMap> thingMaps = new HashSet<>();
for (Thing thing : matchingThings) {
if (filter.contains(thing.id()) || filter.contains("*")) {
ThingMap thingMap = (ThingMap) InjectionUtils.getInstance(thingMapClass, thing);
thingMaps.add(thingMap);
}
}
/*
* Prepare return
*/
if (thingMaps.isEmpty() && !filter.isEmpty()) {
throw new ReflectionException("No matching ThingMap found for ConfigChannel [" + channel.address() + "]");
}
if (Collection.class.isAssignableFrom(expectedObjectClass)) {
if (Set.class.isAssignableFrom(expectedObjectClass)) {
return thingMaps;
} else if (List.class.isAssignableFrom(expectedObjectClass)) {
return new ArrayList<>(thingMaps);
} else {
throw new ReflectionException("Only List and Set ConfigChannels are currently implemented, not [" + expectedObjectClass + "]. ConfigChannel [" + channel.address() + "]");
}
} else {
// No collection
if (thingMaps.size() > 1) {
throw new ReflectionException("Field for ConfigChannel [" + channel.address() + "] is no collection, but more than one ThingMaps [" + thingMaps + "] is fitting for [" + channel.id() + "] in [" + channel.getClass().getSimpleName() + "]");
} else {
return thingMaps.iterator().next();
}
}
}
Aggregations