Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/configuration assets #17

Merged
merged 8 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions model/src/main/java/org/openremote/model/custom/CarAsset.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ public class CarAsset extends Asset<CarAsset> {
public static final AttributeDescriptor<String> IMEI = new AttributeDescriptor<>("IMEI", ValueType.TEXT);
public static final AttributeDescriptor<Date> LAST_CONTACT = new AttributeDescriptor<>("lastContact", ValueType.DATE_AND_TIME);
public static final AttributeDescriptor<String> MAKE_AND_MODEL = new AttributeDescriptor<>("makeAndModel", ValueType.TEXT).withOptional(true);
public static final AttributeDescriptor<String> MODEL_NUMBER = new AttributeDescriptor<>("modelNumber", ValueType.TEXT).withOptional(true);
public static final AttributeDescriptor<Integer> MODEL_YEAR = new AttributeDescriptor<>("modelYear", ValueType.INTEGER).withOptional(true);
/**
* If Rich sees this, sorry for the American spelling!
*/
public static final AttributeDescriptor<ColourRGB> COLOR = new AttributeDescriptor<>("color", ValueType.COLOUR_RGB).withOptional(true);
public static final AttributeDescriptor<String> LICENSE_PLATE = new AttributeDescriptor<>("licensePlate", ValueType.TEXT).withOptional(true);

// Figure out a way to use the colour parameter for the color of the car on the map
public static final AssetDescriptor<CarAsset> DESCRIPTOR = new AssetDescriptor<>("car", null, CarAsset.class);


Expand All @@ -42,5 +42,10 @@ public Optional<Integer> getModelYear() {
public Optional<ColourRGB> getColor() {
return getAttributes().getValue(COLOR);
}
public Optional<String> getModelNumber(){return getAttributes().getValue(MODEL_NUMBER);}

public CarAsset setModelNumber(String value){
getAttributes().getOrCreate(MODEL_NUMBER).setValue(value);
return this;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package org.openremote.model.custom;

import org.openremote.model.teltonika.TeltonikaParameter;
import org.openremote.model.value.ValueDescriptor;

import java.util.HashMap;

public class CustomValueTypes {
public static final ValueDescriptor<AssetStateDuration> ASSET_STATE_DURATION = new ValueDescriptor<>("AssetStateDuration", AssetStateDuration.class);
public static final ValueDescriptor<TeltonikaParameter> TELTONIKA_PARAMETER = new ValueDescriptor<>("TeltonikaParameter", TeltonikaParameter.class);
public static class TeltonikaParameterMap extends HashMap<Integer, TeltonikaParameter> {}

public static final ValueDescriptor<TeltonikaParameterMap> TELTONIKA_PARAMETER_MAP = new ValueDescriptor<>("TeltonikaParameterMap", TeltonikaParameterMap.class);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.openremote.model.custom;

import jakarta.persistence.Entity;
import org.openremote.model.asset.Asset;
import org.openremote.model.asset.AssetDescriptor;
import org.openremote.model.geo.GeoJSONPoint;
import org.openremote.model.value.AttributeDescriptor;
import org.openremote.model.value.ValueType;

@Entity
public class TeltonikaConfigurationAsset extends Asset<TeltonikaConfigurationAsset> {
public static final AttributeDescriptor<String[]> WHITELIST = new AttributeDescriptor<>("deviceIMEIWhitelist", ValueType.TEXT.asArray()).withOptional(true);
public static final AttributeDescriptor<Boolean> ENABLED = new AttributeDescriptor<>("Enabled", ValueType.BOOLEAN);
public static final AttributeDescriptor<Boolean> CHECK_FOR_IMEI = new AttributeDescriptor<>("CheckForValidIMEI", ValueType.BOOLEAN);
public static final AttributeDescriptor<String> DEFAULT_MODEL_NUMBER = new AttributeDescriptor<>("defaultModelNumber", ValueType.TEXT);

public static final AssetDescriptor<TeltonikaConfigurationAsset> DESCRIPTOR = new AssetDescriptor<>("gear", null, TeltonikaConfigurationAsset.class);

protected TeltonikaConfigurationAsset(){

}

public TeltonikaConfigurationAsset(String name){
super(name);
super.setLocation(new GeoJSONPoint(0,0,0));
super.setNotes("");
}

public TeltonikaConfigurationAsset setWhitelist(String[] whitelist) {
getAttributes().getOrCreate(WHITELIST).setValue(whitelist);
return this;
}
public TeltonikaConfigurationAsset setEnabled(boolean enabled) {
getAttributes().getOrCreate(ENABLED).setValue(enabled);
return this;
}

public TeltonikaConfigurationAsset setCheckForImei(boolean enabled) {
getAttributes().getOrCreate(CHECK_FOR_IMEI).setValue(enabled);
return this;
}

public TeltonikaConfigurationAsset setDefaultModelNumber(String value) {
getAttributes().getOrCreate(DEFAULT_MODEL_NUMBER).setValue(value);
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.openremote.model.custom;

import jakarta.persistence.Entity;
import org.openremote.model.asset.Asset;
import org.openremote.model.asset.AssetDescriptor;
import org.openremote.model.attribute.Attribute;
import org.openremote.model.attribute.MetaItem;
import org.openremote.model.attribute.MetaMap;
import org.openremote.model.geo.GeoJSONPoint;
import org.openremote.model.teltonika.TeltonikaParameter;
import org.openremote.model.value.AttributeDescriptor;
import org.openremote.model.value.MetaItemType;
import org.openremote.model.value.ValueType;

import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Entity
public class TeltonikaModelConfigurationAsset extends Asset<TeltonikaModelConfigurationAsset> {
public static final AttributeDescriptor<String> MODEL_NUMBER = new AttributeDescriptor<>("modelNumber", ValueType.TEXT);
public static final AttributeDescriptor<TeltonikaParameter[]> PARAMETER_DATA = new AttributeDescriptor<>("TeltonikaParameterData", CustomValueTypes.TELTONIKA_PARAMETER.asArray());

public static final AttributeDescriptor<CustomValueTypes.TeltonikaParameterMap> PARAMETER_MAP = new AttributeDescriptor<>("TeltonikaParameterMap", CustomValueTypes.TELTONIKA_PARAMETER_MAP)
.withMeta(new MetaMap(Map.of(MetaItemType.READ_ONLY.getName(), new MetaItem<>(MetaItemType.READ_ONLY, true))));
public static final AssetDescriptor<TeltonikaModelConfigurationAsset> DESCRIPTOR = new AssetDescriptor<>("switch", null, TeltonikaModelConfigurationAsset.class);

protected TeltonikaModelConfigurationAsset(){}

public TeltonikaModelConfigurationAsset(String name){
super(name);
super.setLocation(new GeoJSONPoint(0,0,0));
super.setNotes("");
}

public TeltonikaModelConfigurationAsset setModelNumber(String name) {
getAttributes().getOrCreate(MODEL_NUMBER).setValue(name);
return this;
}

public TeltonikaModelConfigurationAsset setParameterData(TeltonikaParameter[] data) {
//Get TeltonikaParameter array, cast to Map with parameter ID as key, save to PARAMETER_MAP, remove from PARAMETER_DATA
getAttributes().getOrCreate(PARAMETER_DATA).setValue(data);
CustomValueTypes.TeltonikaParameterMap map = Arrays.stream(data).collect(Collectors.toMap(
TeltonikaParameter::getPropertyId, // Key Mapper
param -> param, // Value Mapper
(existing, replacement) -> replacement, // Merge Function
CustomValueTypes.TeltonikaParameterMap::new
));

getAttributes().getOrCreate(PARAMETER_MAP).setValue(map);

//



return this;
}

public Optional<String> getModelNumber(){
return getAttributes().getValue(MODEL);
}

public CustomValueTypes.TeltonikaParameterMap getParameterMap() {
Optional<Attribute<CustomValueTypes.TeltonikaParameterMap>> map = getAttributes().get(PARAMETER_MAP);

return map.flatMap(Attribute::getValue)
.orElse(null); // or provide a default value other than null, if appropriate
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.openremote.model.teltonika;

import org.openremote.model.custom.CustomValueTypes;
import org.openremote.model.custom.TeltonikaConfigurationAsset;
import org.openremote.model.custom.TeltonikaModelConfigurationAsset;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

public class TeltonikaConfiguration {
public TeltonikaConfigurationAsset getMasterAsset() {
return masterAsset;
}

TeltonikaConfigurationAsset masterAsset;
/**
* Maps Model Number to Map of parameters: {@code [{"FMCOO3": {<map of parameters>}...]}}
*/
HashMap<String, CustomValueTypes.TeltonikaParameterMap> parameterMap;

public List<TeltonikaModelConfigurationAsset> getModelAssets() {
return modelAssets;
}

private List<TeltonikaModelConfigurationAsset> modelAssets;

public TeltonikaConfiguration(TeltonikaConfigurationAsset master, List<TeltonikaModelConfigurationAsset> models){
if (master == null) return;
if (models.isEmpty()) return;

masterAsset = master;

parameterMap = models.stream().collect(Collectors.toMap(
val ->val.getAttributes().get(TeltonikaModelConfigurationAsset.MODEL_NUMBER).get().getValue().get(), // Key Mapper
TeltonikaModelConfigurationAsset::getParameterMap, // Value Mapper
(existing, replacement) -> replacement, // Merge Function
HashMap::new
));

modelAssets = models;

}

@Override
public String toString() {
return "TeltonikaConfiguration{" +
"masterAsset=" + masterAsset +
", parameterMap=" + parameterMap +
", modelAssets=" + modelAssets +
'}';
}

public List<String> getChildModelIDs(){
return modelAssets.stream().map(TeltonikaModelConfigurationAsset::getId).collect(Collectors.toList());
}

public Boolean getEnabled(){
return masterAsset.getAttribute(TeltonikaConfigurationAsset.ENABLED).get().getValue().get();
}

public boolean getCheckForImei() {
return masterAsset.getAttribute(TeltonikaConfigurationAsset.CHECK_FOR_IMEI).get().getValue().get();
}

public String getDefaultModelNumber() {
return masterAsset.getAttribute(TeltonikaConfigurationAsset.DEFAULT_MODEL_NUMBER).get().getValue().get();
}

public HashMap<String, CustomValueTypes.TeltonikaParameterMap> getParameterMap() {
return parameterMap;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

package org.openremote.model.teltonika;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
Expand All @@ -26,7 +27,7 @@
"hwSupport",
"parameterGroup"
})
public class TeltonikaParameter {
public class TeltonikaParameter implements Serializable {

@JsonProperty("propertyIdInAvlPacket")
public Integer propertyId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.openremote.model.asset.agent.ConnectionStatus
import org.openremote.model.attribute.Attribute
import org.openremote.model.attribute.AttributeEvent
import org.openremote.model.attribute.AttributeRef
import org.openremote.model.custom.CarAsset
import org.openremote.model.teltonika.TeltonikaParameter
import org.openremote.model.util.ValueUtil
import org.openremote.model.value.MetaItemType
Expand Down Expand Up @@ -325,7 +326,7 @@ class TeltonikaMQTTProtocolTest extends Specification implements ManagerContaine
conditions.eventually {
asset = assetStorageService.find(UniqueIdentifierGenerator.generateId(getTELTONIKA_DEVICE_IMEI()))
assert asset != null;
assert asset.getAttribute("IMEI").get().getValue().get() == (getTELTONIKA_DEVICE_IMEI());
assert asset.getAttribute(CarAsset.IMEI).get().getValue().get() == (getTELTONIKA_DEVICE_IMEI());
//Make sure that it parsed the attributes, since there is an issue of parsing the FMC003.json file
assert asset.getAttributes().size() > 5;

Expand Down Expand Up @@ -411,7 +412,7 @@ class TeltonikaMQTTProtocolTest extends Specification implements ManagerContaine
conditions.eventually {
asset = assetStorageService.find(UniqueIdentifierGenerator.generateId(getTELTONIKA_DEVICE_IMEI()))
assert asset != null;
assert asset.getAttribute("IMEI").get().getValue().get() == (getTELTONIKA_DEVICE_IMEI());
assert asset.getAttribute(CarAsset.IMEI).get().getValue().get() == (getTELTONIKA_DEVICE_IMEI());
}

when: "the send message attribute is created and then updated"
Expand Down
Loading