From 2037f01bf3e807100f53cb0d264f9e5e1c6318c4 Mon Sep 17 00:00:00 2001 From: gwen-soleil Date: Wed, 22 Jul 2020 15:00:50 +0200 Subject: [PATCH] add method to fill polling history from device code --- .../tango/server/attribute/AttributeImpl.java | 57 ++++++++++++++- .../tango/server/device/DeviceManager.java | 15 +++- .../tango/server/testserver/JTangoTest.java | 15 +++- .../tango/server/testserver/HistoryTest.java | 73 ++++++++++++------- 4 files changed, 129 insertions(+), 31 deletions(-) diff --git a/server/src/main/java/org/tango/server/attribute/AttributeImpl.java b/server/src/main/java/org/tango/server/attribute/AttributeImpl.java index 1739a8d1..abb7b33c 100644 --- a/server/src/main/java/org/tango/server/attribute/AttributeImpl.java +++ b/server/src/main/java/org/tango/server/attribute/AttributeImpl.java @@ -642,10 +642,64 @@ public IAttributeBehavior getBehavior() { return behavior; } + /** + * Add current attribute data to attribute history + */ public void addToHistory() { history.addToHistory(readValue, writeValue, new DevError[0]); } + /** + * Set all data of attribute history + * + * @param readValues read value + * @param writeValues write value + * @throws DevFailed + */ + public void fillHistory(final AttributeValue[] readValues, final AttributeValue[] writeValues, final DevFailed[] errors) throws DevFailed { + history.clear(); + if (readValues == null) { + if (errors != null && errors.length != writeValues.length) { + throw DevFailedUtils.newDevFailed("write and errors values must have the same size"); + } + logger.debug("filling attribute {} history with {} write values", name, writeValues.length); + for (int i = 0; i < writeValues.length; i++) { + DevError[] error = new DevError[0]; + if (errors != null && errors[i] != null) { + error = errors[i].errors; + } + history.addToHistory(writeValues[i], null, error); + } + } else if (writeValues == null) { + if (errors != null && errors.length != readValues.length) { + throw DevFailedUtils.newDevFailed("read and errors values must have the same size"); + } + logger.debug("filling attribute {} history with {} read values", name, readValues.length); + for (int i = 0; i < readValues.length; i++) { + DevError[] error = new DevError[0]; + if (errors != null && errors[i] != null) { + error = errors[i].errors; + } + history.addToHistory(readValues[i], null, error); + } + } else { + if (readValues.length != writeValues.length) { + throw DevFailedUtils.newDevFailed("read and write values must have the same size"); + } + if (errors != null && errors.length != readValues.length) { + throw DevFailedUtils.newDevFailed("read and errors values must have the same size"); + } + logger.debug("filling attribute {} history with {} read and write values", name, readValues.length); + for (int i = 0; i < readValues.length; i++) { + DevError[] error = new DevError[0]; + if (errors != null && errors[i] != null) { + error = errors[i].errors; + } + history.addToHistory(readValues[i], writeValues[i], error); + } + } + } + public void addErrorToHistory(final DevFailed e) throws DevFailed { history.addToHistory(readValue, writeValue, e.errors); } @@ -821,7 +875,8 @@ public double getDeltaTime() { } @Override - public void setPollingStats(final double executionDuration, final double lastUpdateTime, final double deltaTime) { + public void setPollingStats(final double executionDuration, final double lastUpdateTime, + final double deltaTime) { this.executionDuration = executionDuration; this.lastUpdateTime = lastUpdateTime; this.deltaTime = deltaTime; diff --git a/server/src/main/java/org/tango/server/device/DeviceManager.java b/server/src/main/java/org/tango/server/device/DeviceManager.java index 122d82ad..4db616e4 100644 --- a/server/src/main/java/org/tango/server/device/DeviceManager.java +++ b/server/src/main/java/org/tango/server/device/DeviceManager.java @@ -134,7 +134,7 @@ public void removeAttributeProperties(final String attributeName) throws DevFail * @throws DevFailed */ public void clearAttributeProperties() throws DevFailed { - for(AttributeImpl attr: device.getAttributeList()) { + for (AttributeImpl attr : device.getAttributeList()) { attr.removeProperties(); } } @@ -231,6 +231,19 @@ public void triggerPolling(final String polledObject) throws DevFailed { device.triggerPolling(polledObject); } + /** + * Set all value of an attribute's history + * + * @param attributeName attribute name + * @param readValues read value, can be null for Write only attribute + * @param writeValues write value, can be null for Read only attribute + * @throws DevFailed + */ + public void fillAttributeHistory(String attributeName, AttributeValue[] readValues, AttributeValue[] writeValues, DevFailed[] errors) throws DevFailed { + final AttributeImpl attr = AttributeGetterSetter.getAttribute(attributeName, device.getAttributeList()); + attr.fillHistory(readValues, writeValues, errors); + } + /** * Push an event if some client had register it. The method will perform a read on the requested attribute before * sending the event diff --git a/server/src/main/java/org/tango/server/testserver/JTangoTest.java b/server/src/main/java/org/tango/server/testserver/JTangoTest.java index ca2a5493..4576acdf 100644 --- a/server/src/main/java/org/tango/server/testserver/JTangoTest.java +++ b/server/src/main/java/org/tango/server/testserver/JTangoTest.java @@ -389,7 +389,7 @@ public void delete() throws DevFailed { * * @return shortScalar attribute */ - @Attribute + @Attribute(isPolled = true, pollingPeriod = 0) public short getShortScalar() { return shortScalar; } @@ -783,6 +783,19 @@ public int[] testPollingArray() { public void testState() { } + @Command + public void fillHistory() throws DevFailed { + AttributeValue[] values = new AttributeValue[3]; + // FIXME client API does not support null values in history even with errors + //DevFailed[] errors = new DevFailed[3]; + for (int i = 0; i < values.length; i++) { + values[i] = new AttributeValue(); + values[i].setValue((short)i); + // errors[i] = DevFailedUtils.newDevFailed("test"); + } + deviceManager.fillAttributeHistory("shortScalar", values, values, null); + } + /** * * @param myProp diff --git a/server/src/test/java/org/tango/server/testserver/HistoryTest.java b/server/src/test/java/org/tango/server/testserver/HistoryTest.java index 4c7d47cd..37155042 100644 --- a/server/src/test/java/org/tango/server/testserver/HistoryTest.java +++ b/server/src/test/java/org/tango/server/testserver/HistoryTest.java @@ -1,24 +1,24 @@ /** * Copyright (C) : 2012 - * - * Synchrotron Soleil - * L'Orme des merisiers - * Saint Aubin - * BP48 - * 91192 GIF-SUR-YVETTE CEDEX - * + *

+ * Synchrotron Soleil + * L'Orme des merisiers + * Saint Aubin + * BP48 + * 91192 GIF-SUR-YVETTE CEDEX + *

* This file is part of Tango. - * + *

* Tango is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* Tango is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with Tango. If not, see . */ @@ -61,14 +61,31 @@ public static void disconnect() throws DevFailed { ServerManager.getInstance().stop(); } + @Test + public void fillHistory() throws DevFailed { + try { + DeviceProxy dev = new DeviceProxy(deviceName); + TangoCommand cmd = new TangoCommand(deviceName, "fillHistory"); + cmd.execute(); + DeviceDataHistory[] history = dev.attribute_history("shortScalar"); + for (int i = 0; i < history.length; i++) { + // System.out.println(history[i].getErrStack()); + assertThat(history[i].extractShort(), equalTo((short) i)); + } + } catch (DevFailed e) { + DevFailedUtils.printDevFailed(e); + throw e; + } + } + @Test public void attributeHistory() throws DevFailed { // install polling final String adminName = Constants.ADMIN_DEVICE_DOMAIN + "/" + ServerManager.getInstance().getServerName(); try { final TangoCommand cmd = new TangoCommand(adminName, "AddObjPolling"); - final int[] param1 = new int[] { 10 }; - final String[] param2 = new String[] { deviceName, PolledObjectType.ATTRIBUTE.toString(), "shortScalar" }; + final int[] param1 = new int[]{10}; + final String[] param2 = new String[]{deviceName, PolledObjectType.ATTRIBUTE.toString(), "shortScalar"}; cmd.insertMixArgin(param1, param2); cmd.execute(); @@ -96,8 +113,8 @@ public void stateHistory() throws DevFailed { final String adminName = Constants.ADMIN_DEVICE_DOMAIN + "/" + ServerManager.getInstance().getServerName(); try { final TangoCommand cmd = new TangoCommand(adminName, "AddObjPolling"); - final int[] param1 = new int[] { 10 }; - final String[] param2 = new String[] { deviceName, PolledObjectType.ATTRIBUTE.toString(), "State" }; + final int[] param1 = new int[]{10}; + final String[] param2 = new String[]{deviceName, PolledObjectType.ATTRIBUTE.toString(), "State"}; cmd.insertMixArgin(param1, param2); cmd.execute(); @@ -125,8 +142,8 @@ public void stateCommandHistory() throws DevFailed { final String adminName = Constants.ADMIN_DEVICE_DOMAIN + "/" + ServerManager.getInstance().getServerName(); try { final TangoCommand cmd = new TangoCommand(adminName, "AddObjPolling"); - final int[] param1 = new int[] { 10 }; - final String[] param2 = new String[] { deviceName, PolledObjectType.ATTRIBUTE.toString(), "State" }; + final int[] param1 = new int[]{10}; + final String[] param2 = new String[]{deviceName, PolledObjectType.ATTRIBUTE.toString(), "State"}; cmd.insertMixArgin(param1, param2); cmd.execute(); @@ -154,8 +171,8 @@ public void stateSpectrumHistory() throws DevFailed { final String adminName = Constants.ADMIN_DEVICE_DOMAIN + "/" + ServerManager.getInstance().getServerName(); try { final TangoCommand cmd = new TangoCommand(adminName, "AddObjPolling"); - final int[] param1 = new int[] { 10 }; - final String[] param2 = new String[] { deviceName, PolledObjectType.ATTRIBUTE.toString(), "stateSpectrum" }; + final int[] param1 = new int[]{10}; + final String[] param2 = new String[]{deviceName, PolledObjectType.ATTRIBUTE.toString(), "stateSpectrum"}; cmd.insertMixArgin(param1, param2); cmd.execute(); try { @@ -174,8 +191,8 @@ public void stateSpectrumHistory() throws DevFailed { System.out.println(DeviceState.toString(element2)); } System.out.println(Arrays.toString(element.extractDevStateArray())); - assertThat(element.extractDevStateArray(), equalTo(new DevState[] { DevState.ON, DevState.OFF, - DevState.UNKNOWN })); + assertThat(element.extractDevStateArray(), equalTo(new DevState[]{DevState.ON, DevState.OFF, + DevState.UNKNOWN})); } @@ -196,8 +213,8 @@ public void attributeSpectrumHistory() throws DevFailed { final String adminName = Constants.ADMIN_DEVICE_DOMAIN + "/" + ServerManager.getInstance().getServerName(); try { final TangoCommand cmd = new TangoCommand(adminName, "AddObjPolling"); - final int[] param1 = new int[] { 10 }; - final String[] param2 = new String[] { deviceName, PolledObjectType.ATTRIBUTE.toString(), "pollSpectrum" }; + final int[] param1 = new int[]{10}; + final String[] param2 = new String[]{deviceName, PolledObjectType.ATTRIBUTE.toString(), "pollSpectrum"}; cmd.insertMixArgin(param1, param2); cmd.execute(); try { @@ -213,7 +230,7 @@ public void attributeSpectrumHistory() throws DevFailed { for (final DeviceDataHistory element : hist) { if (!element.failed) { System.out.println(Arrays.toString(element.extractLong64Array())); - assertThat(element.extractLong64Array(), equalTo(new long[] { 1, 2, 0 })); + assertThat(element.extractLong64Array(), equalTo(new long[]{1, 2, 0})); } else { assertThat(element.getErrStack()[0].desc, equalTo("error pollSpectrum")); System.out.println(element.getErrStack()[0].desc); @@ -238,8 +255,8 @@ public void commandHistory() throws DevFailed { try { final TangoCommand cmd = new TangoCommand(adminName, "AddObjPolling"); - final int[] param1 = new int[] { 100 }; - final String[] param2 = new String[] { deviceName, PolledObjectType.COMMAND.toString(), "testPolling" }; + final int[] param1 = new int[]{100}; + final String[] param2 = new String[]{deviceName, PolledObjectType.COMMAND.toString(), "testPolling"}; cmd.insertMixArgin(param1, param2); cmd.execute(); // sleep to allow history to be filled @@ -275,14 +292,14 @@ public void commandHistoryArray() throws DevFailed { try { final TangoCommand cmd = new TangoCommand(adminName, "AddObjPolling"); - final int[] param1 = new int[] { 100 }; - final String[] param2 = new String[] { deviceName, PolledObjectType.COMMAND.toString(), "testPollingArray" }; + final int[] param1 = new int[]{100}; + final String[] param2 = new String[]{deviceName, PolledObjectType.COMMAND.toString(), "testPollingArray"}; cmd.insertMixArgin(param1, param2); cmd.execute(); final DeviceProxy dev = new DeviceProxy(deviceName); final DeviceDataHistory[] hist = dev.command_history("testPollingArray"); for (final DeviceDataHistory element : hist) { - assertThat(element.extractLongArray(), equalTo(new int[] { 1, 2 })); + assertThat(element.extractLongArray(), equalTo(new int[]{1, 2})); } } catch (final DevFailed e) {