From 16e2ccbe39e413a440078d57e4ab4383f3ab51ec Mon Sep 17 00:00:00 2001 From: nxi Date: Wed, 29 May 2024 16:24:28 +1000 Subject: [PATCH] add access to property of SICS controllers --- .../src/ch/psi/sics/hipadaba/Property.java | 13 ++++ .../psi/sics/hipadaba/impl/PropertyImpl.java | 7 ++ .../batch/ui/buffer/BatchBufferManager.java | 8 ++- .../controllers/ComponentController.java | 14 ++++ .../controllers/IComponentController.java | 10 +++ .../gumtree/gumnix/sics/core/SicsUtils.java | 22 ++++++ .../sics/widgets/swt/DeviceStatusWidget.java | 34 ++++++++- .../widgets/swt/EnvironmentControlWidget.java | 62 ++++++++++++++--- .../gumtree/sics/control/ISicsController.java | 6 ++ .../sics/control/support/SicsController.java | 26 +++++++ .../org/gumtree/sics/util/SicsModelUtils.java | 24 +++++++ .../sics/server/restlet/SicsRestlet.java | 69 ++++++++++++++++++- .../restlet/SicsRestletApplication.java | 1 + 13 files changed, 284 insertions(+), 12 deletions(-) diff --git a/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/Property.java b/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/Property.java index 229dc5422..401fb3f37 100644 --- a/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/Property.java +++ b/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/Property.java @@ -41,6 +41,19 @@ public interface Property { */ List getValue(); + /** + * Set a String value to the first attribute of the property. + * + *

+ * Only change the first item of the list. + *

+ * + * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String" + * extendedMetaData="kind='element' name='value'" + * @generated + */ + void setValue(String stringValue); + /** * Returns the value of the 'Id' attribute. * diff --git a/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/impl/PropertyImpl.java b/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/impl/PropertyImpl.java index 3844ec4d9..3104e8555 100644 --- a/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/impl/PropertyImpl.java +++ b/framework/sics/ch.psi.sics.hipadaba/src/ch/psi/sics/hipadaba/impl/PropertyImpl.java @@ -99,6 +99,13 @@ public List getValue() { return value; } + public void setValue(String stringValue) { + if (value == null) { + value = new EDataTypeEList(String.class, this, HipadabaPackageImpl.PROPERTY__VALUE); + } + value.set(0, stringValue); + } + /** * * diff --git a/framework/sics/org.gumtree.gumnix.sics.batch.ui/src/org/gumtree/gumnix/sics/batch/ui/buffer/BatchBufferManager.java b/framework/sics/org.gumtree.gumnix.sics.batch.ui/src/org/gumtree/gumnix/sics/batch/ui/buffer/BatchBufferManager.java index 21e6617f3..432685355 100644 --- a/framework/sics/org.gumtree.gumnix.sics.batch.ui/src/org/gumtree/gumnix/sics/batch/ui/buffer/BatchBufferManager.java +++ b/framework/sics/org.gumtree.gumnix.sics.batch.ui/src/org/gumtree/gumnix/sics/batch/ui/buffer/BatchBufferManager.java @@ -302,8 +302,8 @@ private void execute(IBatchBuffer buffer) throws IOException { // Modified by nxi. Change the uploading strategy. Save the script in the mounted folder instead. // // Ready to upload -// asyncSend("exe clear", null, ISicsProxy.CHANNEL_RAW_BATCH); -// asyncSend("exe clearupload", null, ISicsProxy.CHANNEL_RAW_BATCH); + asyncSend("exe clear", null, ISicsProxy.CHANNEL_RAW_BATCH); + asyncSend("exe clearupload", null, ISicsProxy.CHANNEL_RAW_BATCH); // asyncSend("exe upload", null, ISicsProxy.CHANNEL_RAW_BATCH); // // Upload // BufferedReader reader = new BufferedReader(new StringReader(buffer.getContent())); @@ -369,6 +369,10 @@ private void execute(IBatchBuffer buffer) throws IOException { // Enqueue (due to the delay in general channel, wait until it is ready) final boolean[] enqueued = new boolean[] { false }; + try { + Thread.sleep(500); + } catch (InterruptedException e1) { + } asyncSend("exe enqueue {" + filename + "}", new SicsCallbackAdapter() { public void receiveReply(ISicsReplyData data) { enqueued[0] = true; diff --git a/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/ComponentController.java b/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/ComponentController.java index 023478e49..fec7ac305 100644 --- a/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/ComponentController.java +++ b/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/ComponentController.java @@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory; import ch.psi.sics.hipadaba.Component; +import ch.psi.sics.hipadaba.Property; public abstract class ComponentController implements IComponentController { @@ -106,6 +107,19 @@ public String getDeviceId() { return deviceId; } + @Override + public List getPropertyValue(String propId) { + List propList = getComponent().getProperty(); + if (propList != null) { + for (Property prop : propList) { + if (propId.equals(prop.getId())) { + return prop.getValue(); + } + } + } + return new ArrayList(); + } + public ControllerStatus getStatus() { return status; } diff --git a/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/IComponentController.java b/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/IComponentController.java index b2335e79d..040284560 100644 --- a/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/IComponentController.java +++ b/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/control/controllers/IComponentController.java @@ -12,6 +12,8 @@ package org.gumtree.gumnix.sics.control.controllers; +import java.util.List; + import org.gumtree.gumnix.sics.control.ControllerStatus; import org.gumtree.gumnix.sics.control.events.IComponentControllerListener; @@ -99,5 +101,13 @@ public interface IComponentController { * @param listener */ public void removeComponentListener(IComponentControllerListener listener); + + /** + * Return the value of a specific property ID. Return null if not found. + * + * @param propId in List of String type + * @return + */ + public List getPropertyValue(String propId); } diff --git a/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/core/SicsUtils.java b/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/core/SicsUtils.java index cfd4af849..7403d9d38 100644 --- a/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/core/SicsUtils.java +++ b/framework/sics/org.gumtree.gumnix.sics.core/src/org/gumtree/gumnix/sics/core/SicsUtils.java @@ -47,6 +47,10 @@ public class SicsUtils { private static List drivableIdCache; + private static final String PROP_NXALIAS = "nxalias"; + + private static final String PREFIX_SAMPLE = "sample"; + public static List getSicsDrivableIdList() { if (drivableIdCache == null) { // SICS proxy is not yet ready @@ -423,4 +427,22 @@ private SicsUtils() { super(); } + public static IComponentController getNicknameController(IComponentController seItem) { + List prop = seItem.getPropertyValue(PROP_NXALIAS); + if (prop.size() > 0) { + String alias = prop.get(0); + String[] path = alias.split("_"); + String nickPath = null; + if (!PREFIX_SAMPLE.equals(path[0])) { + nickPath = "/" + PREFIX_SAMPLE; + } + for (int i = 0; i < path.length - 1; i++) { + nickPath += "/" + path[i]; + } + nickPath += "/nick"; + return SicsCore.getSicsController().findComponentController(nickPath); + } + return null; + } + } diff --git a/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/DeviceStatusWidget.java b/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/DeviceStatusWidget.java index d80bc9d57..669e3e444 100644 --- a/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/DeviceStatusWidget.java +++ b/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/DeviceStatusWidget.java @@ -3,6 +3,7 @@ import java.net.URI; import java.text.Normalizer.Form; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -86,6 +87,7 @@ protected void handleRender() { label = getWidgetFactory().createLabel(this, deviceContext.label + ": "); label.setFont(UIResources.getDefaultFont(SWT.BOLD)); + deviceContext.widget = label; // Part 3: Value label = createDeviceLabel(this, deviceContext.path, "--", SWT.RIGHT, deviceContext.converter, deviceContext.showSoftLimits); @@ -269,6 +271,10 @@ public void run() throws Exception { }); } + protected void sortDevices() { + Collections.sort(deviceContexts); + } + @Override protected void disposeWidget() { if (deviceContexts != null) { @@ -381,14 +387,23 @@ public void setDelayEventExecutor(IDelayEventExecutor delayEventExecutor) { * Utilities *************************************************************************/ - private class DeviceContext { + private class DeviceContext implements Comparable { String path; Image icon; String label; String unit; + Label widget; boolean isSeparator; LabelConverter converter; boolean showSoftLimits; + + @Override + public int compareTo(DeviceContext arg0) { + if (label == null) { + return -1; + } + return label.compareTo(arg0.label); + } } private class LabelContext { @@ -683,4 +698,21 @@ protected void checkSicsConnection() { } catch (InterruptedException e) { } } + + public void setDeviceTitle(String path, String newTitle) { + for (final DeviceContext device : deviceContexts) { + if (device.path.equals(path)) { + device.label = newTitle; + SafeUIRunner.asyncExec(new SafeRunnable() { + @Override + public void run() throws Exception { + if (device.widget != null && !device.widget.isDisposed()) { + device.widget.setText(device.label); + device.widget.pack(); + } + } + }); + } + } + } } diff --git a/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/EnvironmentControlWidget.java b/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/EnvironmentControlWidget.java index d7176c866..01853680e 100644 --- a/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/EnvironmentControlWidget.java +++ b/framework/sics/org.gumtree.gumnix.sics.widgets/src/org/gumtree/gumnix/sics/widgets/swt/EnvironmentControlWidget.java @@ -8,8 +8,14 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; +import org.gumtree.gumnix.sics.control.ControllerStatus; import org.gumtree.gumnix.sics.control.controllers.IComponentController; +import org.gumtree.gumnix.sics.control.controllers.IComponentData; +import org.gumtree.gumnix.sics.control.controllers.IDynamicController; +import org.gumtree.gumnix.sics.control.events.DynamicControllerListenerAdapter; +import org.gumtree.gumnix.sics.control.events.IComponentControllerListener; import org.gumtree.gumnix.sics.core.SicsCore; +import org.gumtree.gumnix.sics.core.SicsUtils; public class EnvironmentControlWidget extends DeviceStatusWidget { @@ -35,9 +41,24 @@ public int compare(IComponentController o1, return o1.getId().compareTo(o2.getId()); } }); - for (IComponentController item : itemList) { + for (final IComponentController item : itemList) { String id = item.getId(); String label = id; + String nickname = null; + List nickList = item.getPropertyValue("nick"); + if (nickList != null && nickList.size() > 0) { + nickname = nickList.get(0); + } + String aliasName = null; + List aliasList = item.getPropertyValue("nxalias"); + if (aliasList != null && aliasList.size() > 0) { + aliasName = aliasList.get(0); + } + String units = null; + List unitsList = item.getPropertyValue("units"); + if (unitsList != null && unitsList.size() > 0) { + units = unitsList.get(0); + } // String units = ""; // if (id.startsWith("T")) { // units = "K"; @@ -50,18 +71,43 @@ public int compare(IComponentController o1, // } else if (id.startsWith("I")) { // units = "A"; // } - if (label.contains("SP")) { - label = id.replace("SP", " SetPoint"); - } else if (label.contains("S")) { - label = id.replace("S", " Sensor"); + if (aliasName != null) { + label = aliasName; + } else { + if (label.contains("SP")) { + label = id.replace("SP", " SetPoint"); + } else if (label.contains("S")) { + label = id.replace("S", " Sensor"); + } + } + String fullname = null; + if (nickname != null) { + fullname = label + "(" + nickname + ")"; + } else { + fullname = label; } try { - addDevice(item.getPath(), label, null, null); -// addDevice(item.getPath(), label, null, null); + addDevice(item.getPath(), fullname, null, units); } catch (Exception e) { - // TODO: handle exception + } + + final String labelPrefix = label; + IComponentController nickController = SicsUtils.getNicknameController(item); + if (nickController != null) { + if (nickController instanceof IDynamicController) { + ((IDynamicController) nickController).addComponentListener(new DynamicControllerListenerAdapter() { + + private String prefix = labelPrefix; + @Override + public void valueChanged(IDynamicController controller, IComponentData newValue) { + String newTitle = prefix + "(" + newValue.getStringData() + ")"; + setDeviceTitle(item.getPath(), newTitle); + } + }); + } } } + sortDevices(); Display.getDefault().asyncExec(new Runnable() { @Override diff --git a/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/ISicsController.java b/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/ISicsController.java index e52a55d2e..b539bb8db 100644 --- a/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/ISicsController.java +++ b/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/ISicsController.java @@ -11,6 +11,8 @@ package org.gumtree.sics.control; +import java.util.List; + import org.gumtree.core.object.IDisposable; import org.gumtree.sics.io.ISicsProxy; @@ -76,4 +78,8 @@ public interface ISicsController extends IDisposable { public ISicsController findChildByDeviceId(String deviceId); + public List getPropertyValue(String propId); + + public void setPropertyValue(String propId, String newValue); + } diff --git a/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/support/SicsController.java b/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/support/SicsController.java index 21d15fb47..026f110dc 100644 --- a/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/support/SicsController.java +++ b/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/control/support/SicsController.java @@ -18,6 +18,7 @@ import org.gumtree.util.string.StringUtils; import ch.psi.sics.hipadaba.Component; +import ch.psi.sics.hipadaba.Property; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; @@ -66,6 +67,31 @@ public void setDeviceId(String deviceId) { this.deviceId = deviceId; } + @Override + public List getPropertyValue(String propId) { + List propList = componentModel.getProperty(); + if (propList != null) { + for (Property prop : propList) { + if (propId.equals(prop.getId())) { + return prop.getValue(); + } + } + } + return null; + } + + @Override + public void setPropertyValue(String propId, String newValue) { + List propList = componentModel.getProperty(); + if (propList != null) { + for (Property prop : propList) { + if (propId.equals(prop.getId())) { + prop.setValue(newValue); + } + } + } + } + @Override public String getPath() { if (path == null) { diff --git a/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/util/SicsModelUtils.java b/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/util/SicsModelUtils.java index 5460488e2..7ad4ef526 100644 --- a/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/util/SicsModelUtils.java +++ b/framework/sics/org.gumtree.sics.core/src/org/gumtree/sics/util/SicsModelUtils.java @@ -18,6 +18,8 @@ import org.eclipse.emf.ecore.sdo.util.SDOUtil; import org.gumtree.sics.core.PropertySelectionCriterion; import org.gumtree.sics.core.PropertySelectionType; +import org.gumtree.sics.control.ISicsController; +import org.gumtree.sics.core.ISicsManager; import org.gumtree.sics.core.PropertyConstants.ComponentType; import org.gumtree.sics.core.PropertyConstants.Privilege; import org.gumtree.sics.core.PropertyConstants.PropertyType; @@ -32,6 +34,10 @@ public final class SicsModelUtils { + private static final String PROP_NXALIAS = "nxalias"; + + private static final String PREFIX_SAMPLE = "sample"; + public static SICS deserialiseSICSModel(byte[] data) throws IOException { return loadSICSModel(new ByteArrayInputStream(data)); } @@ -321,4 +327,22 @@ private SicsModelUtils() { super(); } + public static ISicsController getNicknameController(ISicsManager sicsManager, ISicsController seItem) { + List prop = seItem.getPropertyValue(PROP_NXALIAS); + if (prop.size() > 0) { + String alias = prop.get(0); + String[] path = alias.split("_"); + String nickPath = null; + if (!PREFIX_SAMPLE.equals(path[0])) { + nickPath = "/" + PREFIX_SAMPLE; + } + for (int i = 0; i < path.length - 1; i++) { + nickPath += "/" + path[i]; + } + nickPath += "/nick"; + return sicsManager.getServerController().findChild(nickPath); + } + return null; + } + } diff --git a/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestlet.java b/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestlet.java index a48f79be9..68753b93e 100644 --- a/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestlet.java +++ b/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestlet.java @@ -18,14 +18,20 @@ import org.gumtree.sics.control.ISicsController; import org.gumtree.sics.control.ServerStatus; import org.gumtree.sics.core.ISicsManager; +import org.gumtree.sics.core.ISicsMonitor; import org.gumtree.sics.io.ISicsData; +import org.gumtree.sics.io.SicsEventHandler; +import org.gumtree.sics.io.SicsLogManager; +import org.gumtree.sics.io.ISicsLogManager.LogType; import org.gumtree.sics.util.SicsComponentUtils; +import org.gumtree.sics.util.SicsModelUtils; import org.gumtree.util.ILoopExitCondition; import org.gumtree.util.LoopRunner; import org.gumtree.util.LoopRunnerStatus; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.osgi.service.event.Event; import org.restlet.Request; import org.restlet.Response; import org.restlet.Restlet; @@ -61,6 +67,12 @@ public class SicsRestlet extends Restlet implements IDisposable { private static final String QUERY_COMPONENTS = "components"; + private static final String CONTROL_GROUP = "/control"; + + private static final String PROP_NICK = "nick"; + + private static final String[] PROP_COLLECTED = new String[] {PROP_NICK, "nxalias", "units"}; + private static Logger logger = LoggerFactory.getLogger(SicsRestlet.class); private ISicsManager sicsManager; @@ -148,7 +160,7 @@ public int compare(ISicsController o1, ISicsController o2) { }); for (ISicsController child : childList){ try { - JSONObject controllerValues = createComponentJSONRepresentation( + JSONObject controllerValues = createComponentJSONRepresentationWithProp( request, child, false); array.put(controllerValues); } catch (Exception e) { @@ -400,6 +412,28 @@ public boolean getExitCondition() { return result; } + private JSONObject createComponentJSONRepresentationWithProp(Request request, + ISicsController controller, boolean detailed) throws Exception { + JSONObject result = createComponentJSONRepresentation(request, controller, detailed); + for (String name : PROP_COLLECTED) { + String value = null; + List valueList = controller.getPropertyValue(name); + if (valueList != null && valueList.size() > 0) { + value = valueList.get(0); + } + if (value != null) { + result.put(name, value); + } + } +// ISicsController nickController = SicsModelUtils.getNicknameController(getSicsManager(), controller); +// if (nickController != null) { +// if (nickController instanceof IDynamicController) { +// ((IDynamicController) nickController).addChild(child); +// } +// } + return result; + } + private void writeJSONObject(Response response, Form queryForm, JSONObject jsonObject) { // Use content-type in header to resolve representation (see http://restlet.tigris.org/issues/show_bug.cgi?id=385) // TODO: fix this will Restlet 1.1 @@ -422,6 +456,39 @@ private void writeJSONObject(Response response, Form queryForm, JSONObject jsonO } } + public void initControlListener() { + ISicsController controller = getSicsManager() + .getServerController().findChild(CONTROL_GROUP); + if (controller != null) { + ISicsController[] children = controller.getChildren(); + List childList = Arrays.asList(children); + for (final ISicsController child : childList){ + ISicsController nickController = SicsModelUtils.getNicknameController(getSicsManager(), child); + if (nickController != null) { + ((IDynamicController) nickController).getCurrentValue(new ControllerCallbackAdapter() { + + @Override + public void getCurrentValue(ISicsData data) { + super.getCurrentValue(data); + child.setPropertyValue(PROP_NICK, data.getString()); + } + }); + String path = nickController.getPath(); + final SicsEventHandler eventHandler = new SicsEventHandler(ISicsMonitor.EVENT_TOPIC_HNOTIFY + + path) { + @Override + public void handleSicsEvent(Event event) { + String newValue = getString(event, + ISicsMonitor.EVENT_PROP_VALUE); + child.setPropertyValue(PROP_NICK, newValue); + } + }; + eventHandler.setProxyId(getSicsManager().getProxy().getId()).activate(); + } + } + } + } + public ISicsManager getSicsManager() { return sicsManager; } diff --git a/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestletApplication.java b/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestletApplication.java index 36c80be35..1ca9dde55 100644 --- a/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestletApplication.java +++ b/framework/sics/org.gumtree.sics.server/src/org/gumtree/sics/server/restlet/SicsRestletApplication.java @@ -36,6 +36,7 @@ public synchronized Restlet createRoot() { SicsRestlet restlet = ContextInjectionFactory.make(SicsRestlet.class, context); + restlet.initControlListener(); // // Temp: login here // try { // restlet.getSicsManager()