Skip to content

Commit

Permalink
feat(asset.provider): Now the DataType sent to the driver depends on …
Browse files Browse the repository at this point in the history
…the DataType of the channel and theDataType of the scaleOffsetDataType field and a new ScaleOffsetDataType, LONG, has been added (#5432)

* Now a dependent datatype is forwarded to the driver

* fixed test

* Added test for ChannelRecordHelper

* Added test for dynamic valuetype

* little code cleanup

* Fixed bug on Long scale/offset

* Fixed wrong import

(cherry picked from commit bda665c)
  • Loading branch information
salvatore-coppola authored and MMaiero committed Oct 17, 2024
1 parent f45421e commit 9fd8159
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
@NotThreadSafe
public class ChannelRecord {

private static final String NULL_CHANNEL_NAME_ERROR_MESSAGE = "Channel Name cannot be null";

/**
* Provided channel configuration to perform read or write
* operation.
Expand Down Expand Up @@ -115,7 +117,7 @@ private ChannelRecord() {
* @return the channel record
*/
public static ChannelRecord createReadRecord(final String channelName, final DataType valueType) {
requireNonNull(channelName, "Channel Name cannot be null");
requireNonNull(channelName, NULL_CHANNEL_NAME_ERROR_MESSAGE);
requireNonNull(valueType, "Value Type cannot be null");

ChannelRecord result = new ChannelRecord();
Expand All @@ -131,7 +133,7 @@ public static ChannelRecord createReadRecord(final String channelName, final Dat
*/
public static ChannelRecord createReadRecord(final String channelName, final DataType valueType,
final String unit) {
requireNonNull(channelName, "Channel Name cannot be null");
requireNonNull(channelName, NULL_CHANNEL_NAME_ERROR_MESSAGE);
requireNonNull(valueType, "Value Type cannot be null");

ChannelRecord result = new ChannelRecord();
Expand All @@ -154,7 +156,7 @@ public static ChannelRecord createReadRecord(final String channelName, final Dat
* @return the channel record
*/
public static ChannelRecord createWriteRecord(final String channelName, final TypedValue<?> value) {
requireNonNull(channelName, "Channel Name cannot be null");
requireNonNull(channelName, NULL_CHANNEL_NAME_ERROR_MESSAGE);
requireNonNull(value, "Value cannot be null");

ChannelRecord result = new ChannelRecord();
Expand All @@ -177,7 +179,7 @@ public static ChannelRecord createWriteRecord(final String channelName, final Ty
* @return the channel record
*/
public static ChannelRecord createStatusRecord(final String channelName, final ChannelStatus status) {
requireNonNull(channelName, "Channel Name cannot be null");
requireNonNull(channelName, NULL_CHANNEL_NAME_ERROR_MESSAGE);
requireNonNull(status, "Status cannot be null");

ChannelRecord result = new ChannelRecord();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ public enum ScaleOffsetType {

DEFINED_BY_VALUE_TYPE,

DOUBLE;
DOUBLE,

LONG;

/**
* Converts {@code stringScaleOffsetType}, if possible, to the related {@link ScaleOffsetType}.
Expand All @@ -43,6 +45,10 @@ public static ScaleOffsetType getScaleOffsetType(String stringScaleOffsetType) {
return DOUBLE;
}

if (LONG.name().equalsIgnoreCase(stringScaleOffsetType)) {
return LONG;
}

throw new IllegalArgumentException("Cannot convert to DataType");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.eclipse.kura.driver.PreparedRead;
import org.eclipse.kura.internal.asset.provider.BaseAssetConfiguration;
import org.eclipse.kura.internal.asset.provider.DriverTrackerCustomizer;
import org.eclipse.kura.internal.asset.provider.helper.ChannelRecordHelper;
import org.eclipse.kura.type.DataType;
import org.eclipse.kura.type.TypedValue;
import org.eclipse.kura.type.TypedValues;
Expand Down Expand Up @@ -386,7 +387,8 @@ public List<ChannelRecord> read(final Set<String> channelNames) throws KuraExcep
continue;
}

final ChannelRecord channelRecord = channel.createReadRecord();
final ChannelRecord channelRecord = ChannelRecordHelper.createModifiedChannelRecord(channel);
channel.createReadRecord();
validRecords.add(channelRecord);
channelRecords.add(channelRecord);
}
Expand Down Expand Up @@ -435,8 +437,9 @@ private void applyScaleAndOffset(final ChannelRecord channelRecord, final Channe
newValue = calculateScaleAndOffsetByTypedValue((TypedValue<? extends Number>) channelRecord.getValue(),
channelScale, channelOffset);
} else {
newValue = calculateScaleAndOffset((TypedValue<? extends Number>) channelRecord.getValue(),
channel.getScaleOffsetType(), channelScale, channelOffset);
newValue = calculateScaleAndOffset(channel.getValueType(),
(TypedValue<? extends Number>) channelRecord.getValue(), channel.getScaleOffsetType(),
channelScale, channelOffset);
}

channelRecord.setValue(newValue);
Expand Down Expand Up @@ -479,18 +482,23 @@ private TypedValue<? extends Number> calculateScaleAndOffsetByTypedValue(TypedVa

}

private TypedValue<? extends Number> calculateScaleAndOffset(TypedValue<? extends Number> typedValue,
ScaleOffsetType scaleOffsetType, Number scale, Number offset) {
private TypedValue<? extends Number> calculateScaleAndOffset(DataType outputValueType,
TypedValue<? extends Number> typedValue, ScaleOffsetType scaleOffsetType, Number scale, Number offset) {

Number result = null;

if (ScaleOffsetType.DOUBLE.equals(scaleOffsetType)) {
switch (scaleOffsetType) {
case DOUBLE:
result = scale.doubleValue() * typedValue.getValue().doubleValue() + offset.doubleValue();
} else {
break;
case LONG:
result = scale.longValue() * typedValue.getValue().longValue() + offset.longValue();
break;
default:
throw new IllegalArgumentException("Invalid scale/offset type");
}

return toTypedValue(typedValue.getType(), result);
return toTypedValue(outputValueType, result);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.eclipse.kura.core.configuration.util.ComponentUtil;
import org.eclipse.kura.driver.ChannelDescriptor;
import org.eclipse.kura.driver.Driver;
import org.eclipse.kura.internal.asset.provider.helper.ChannelRecordHelper;
import org.eclipse.kura.type.DataType;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
Expand Down Expand Up @@ -103,7 +104,7 @@ public List<ChannelRecord> getAllReadRecords() {
final Channel channel = e.getValue();
if (channel.isEnabled()
&& (channel.getType() == ChannelType.READ || channel.getType() == ChannelType.READ_WRITE)) {
readRecords.add(channel.createReadRecord());
readRecords.add(ChannelRecordHelper.createModifiedChannelRecord(channel));
}
}

Expand Down Expand Up @@ -409,6 +410,9 @@ private static Number parseScaleOffsetTypedValue(ScaleOffsetType type, String va
case DEFINED_BY_VALUE_TYPE:
case DOUBLE:
return Double.parseDouble(value);
case LONG:
// TODO replace with Long.parseLong(value) once scale and offset are turned in String in the metatype
return (Double.valueOf(value).longValue());
default:
throw new IllegalArgumentException(value + " cannot be converted into a Number of type " + type);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2024 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eurotech
*******************************************************************************/

package org.eclipse.kura.internal.asset.provider.helper;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.kura.asset.provider.AssetConstants;
import org.eclipse.kura.channel.Channel;
import org.eclipse.kura.channel.ChannelRecord;
import org.eclipse.kura.channel.ScaleOffsetType;
import org.eclipse.kura.type.DataType;

public class ChannelRecordHelper {

private ChannelRecordHelper() {
// Private constructor to prevent instantiation
}

public static ChannelRecord createModifiedChannelRecord(Channel channel) {

DataType actualDataType = channel.getScaleOffsetType() == ScaleOffsetType.DEFINED_BY_VALUE_TYPE
? channel.getValueType()
: toDataType(channel.getScaleOffsetType());

ChannelRecord channelRecord = ChannelRecord.createReadRecord(channel.getName(), actualDataType,
channel.getUnit());

Map<String, Object> configMap = new HashMap<>(channel.getConfiguration());
configMap.put(AssetConstants.VALUE_TYPE.value(), actualDataType.name());
channelRecord.setChannelConfig(configMap);

return channelRecord;
}

private static DataType toDataType(ScaleOffsetType scaleOffsetType) {
switch (scaleOffsetType) {
case DOUBLE:
return DataType.DOUBLE;
case LONG:
return DataType.LONG;
default:
throw new IllegalArgumentException("Unsupported scale offset type: " + scaleOffsetType);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.eclipse.kura.asset.provider.helper.test;

import static org.junit.Assert.assertEquals;

import java.util.Collections;

import org.eclipse.kura.channel.Channel;
import org.eclipse.kura.channel.ChannelRecord;
import org.eclipse.kura.channel.ChannelType;
import org.eclipse.kura.channel.ScaleOffsetType;
import org.eclipse.kura.internal.asset.provider.helper.ChannelRecordHelper;
import org.eclipse.kura.type.DataType;
import org.junit.Test;

public class ChannelRecordHelperTest {

private Channel channel;
private ChannelRecord channelRecord;

@Test
public void shouldCreateChannelRecorWithDoubleValueType() {
givenChannel(new Channel("test-channel", ChannelType.READ, DataType.INTEGER, ScaleOffsetType.DOUBLE, 3.3d, 3.1d,
Collections.emptyMap()));

whenCreatedChannelRecord();

thenChannelRecordValueTypeIs(DataType.DOUBLE);
}

@Test
public void shouldCreateChannelRecorWithIntegerValueType() {
givenChannel(new Channel("test-channel", ChannelType.READ, DataType.INTEGER,
ScaleOffsetType.DEFINED_BY_VALUE_TYPE, 3.3d, 3.1d, Collections.emptyMap()));

whenCreatedChannelRecord();

thenChannelRecordValueTypeIs(DataType.INTEGER);
}

@Test
public void shouldCreateChannelRecorWithLongValueType() {
givenChannel(new Channel("test-channel", ChannelType.READ, DataType.INTEGER, ScaleOffsetType.LONG, 3l, 4l,
Collections.emptyMap()));

whenCreatedChannelRecord();

thenChannelRecordValueTypeIs(DataType.LONG);
}

private void thenChannelRecordValueTypeIs(DataType datatype) {
assertEquals(datatype, this.channelRecord.getValueType());

}

private void givenChannel(Channel channel) {
this.channel = channel;

}

private void whenCreatedChannelRecord() {
this.channelRecord = ChannelRecordHelper.createModifiedChannelRecord(this.channel);
}
}
Loading

0 comments on commit 9fd8159

Please sign in to comment.