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

SMHE-832 Object config #867

Open
wants to merge 29 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6b0e7f3
SMHE-832: first steps config objects
Jun 24, 2022
57f3fd8
SMHE-832: Lombok data objects
Jun 24, 2022
ca42496
SMHE-832: pom added
Jun 24, 2022
de72dc0
SMHE-832: CosemObject
Jun 24, 2022
3281100
Add ObjectListCreator to simulator
stefanermens Jun 24, 2022
0cc89dd
SMHE-832: MeterConfig Test and ToString
Jun 24, 2022
d29f962
SMHE-832: osgp-domain-smartmetering added to super-osgp and platform …
Jun 27, 2022
2e985ce
SMHE-832: junit-jupiter dependency instead of api engine and params b…
Jun 27, 2022
11cb4f2
SMHE-832: restore junit api engine and params because of maven warnings
Jun 27, 2022
d273fdf
Add clock
stefanermens Jun 27, 2022
2ff09fa
SMHE-832: check-in osgp-domain-smartmetering basic
Jun 28, 2022
d07d3be
SMHE-832: check-in config files added
Jun 28, 2022
12cc6ac
Use objectlist in protocol adapter
stefanermens Jun 28, 2022
3413b03
SMHE-832: GetActualMeterRead file and test added
Jun 28, 2022
a23d013
SMHE-832 Object Registration
natasja-n Jun 29, 2022
4a94c2d
SMHE-832 Object Registration
natasja-n Jun 29, 2022
9dd0cab
SMHE-832: ValueType as enum and lombok version the same as in osgp
Jun 29, 2022
e195c46
SMHE-832 Object Registration
natasja-n Jun 29, 2022
fe2f492
SMHE-832: Use dots in obis code
stefanermens Jun 30, 2022
0be14a4
SMHE-832: Added DlmsObjectService bean to DlmsConfig
Jun 30, 2022
62a82f1
Merge remote-tracking branch 'origin/feature/SMHE-832_Object_config' …
Jun 30, 2022
ba52b60
SMHE-832: Add function to get one cosemObject
stefanermens Jun 30, 2022
a0f3fbc
SMHE-832: Add function to get one cosemObject
stefanermens Jun 30, 2022
4f14e89
SMHE-832: Load resources from inside the jar with a stream instead of…
Jul 1, 2022
820e33c
SMHE-832: Working demo
stefanermens Jul 1, 2022
bda8d32
SMHE-832: Log error instead of stacktrace and use version 5.0.0 for SMR
Jul 4, 2022
8f43a15
SMHE-673: base-ws-smartmetering accessible by providing the correct b…
Jul 5, 2022
3d8969f
rollback change
Jul 5, 2022
f5076d0
Merge branch 'feature/SMHE-832_Object_config' of github.com:OSGP/open…
Jul 5, 2022
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
1 change: 1 addition & 0 deletions osgp/platform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Domain Layer
- osgp-domain-logging, Logging domain classes
- osgp-domain-distributionautomation, Distribution Automation domain classes
- osgp-domain-microgrids, Microgrids domain classes
- osgp-domain-smartmetering, smartmetering domain classes e.g.: device config objects
- osgp-domain-tariff-switching, Tariff Switching domain classes
- osgp-logging, Logging incoming requests and outgoing responses of the
Web Service Layer and logging calls to and from devices
Expand Down
23 changes: 23 additions & 0 deletions osgp/platform/osgp-domain-smartmetering/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Domain Smartmetering


### Component Description
Config objects for smart meters.

### Usage

1. Add dependency
```xml
<dependency>
<groupId>org.opensmartgridplatform</groupId>
<artifactId>osgp-domain-smartmetering</artifactId>
</dependency>
```
2. Add the DlmsObjectService bean to the spring config file
```java
@Bean
public DlmsObjectService dlmsObjectService() {
return new DlmsObjectService();
}
```

136 changes: 136 additions & 0 deletions osgp/platform/osgp-domain-smartmetering/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<!--

Copyright 2015 Smart Society Services B.V.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>osgp-domain-smartmetering</artifactId>
<name>osgp-domain-smartmetering</name>
<packaging>jar</packaging>
<!-- Description element is needed for the maven-jxr-plugin to generate a maven site -->
<description>Domain entities for Smart Metering configs.</description>

<parent>
<groupId>org.opensmartgridplatform</groupId>
<artifactId>parent-platform</artifactId>
<version>5.27.0-SNAPSHOT</version>
<relativePath>../parent-platform/pom.xml</relativePath>
</parent>

<properties>
<display.version>${project.version}-${BUILD_TAG}</display.version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven.jar.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
<configuration>
<excludes>
<exclude>%regex[.*integrationtests.*class]</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<!-- Spring Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<!-- Jackson (JSON) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>

<!-- Utils -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<!-- Testing dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.opensmartgridplatform.domain.smartmetering.config;

import lombok.Data;

@Data
public class Attribute {
public int id;
public String description;
public String datatype;
public ValueType valuetype;
public String value;
public String access;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.opensmartgridplatform.domain.smartmetering.config;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.Data;

@Data
public class CosemObject {
public String tag;
public String description;

@JsonProperty("class-id")
public int classId;

public int version;
public String obis;
public String group;
public List<String> meterTypes;
public List<Attribute> attributes;

public Attribute getAttribute(final int id) {
return this.attributes.stream()
.filter(attribute -> attribute.id == id)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Attribute " + id + " not found"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.opensmartgridplatform.domain.smartmetering.config;

import java.util.List;
import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class MeterConfig {
public String profile;
public String version;
public String description;
public List<Setting> settings;
public List<CosemObject> cosemObjects;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.opensmartgridplatform.domain.smartmetering.config;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

@Data
public class Setting {
@JsonProperty("firmware update type")
public String firmwareUpdateType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2022 Alliander N.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/

package org.opensmartgridplatform.domain.smartmetering.config;

public enum ValueType {
FIXED_IN_PROFILE,
FIXED_IN_METER,
DYNAMIC
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright 2019 Smart Society Services B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
package org.opensmartgridplatform.domain.smartmetering.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
import org.opensmartgridplatform.domain.smartmetering.config.CosemObject;
import org.opensmartgridplatform.domain.smartmetering.config.MeterConfig;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class DlmsObjectService {

private List<MeterConfig> meterConfigList;

public DlmsObjectService() {}

public DlmsObjectService(final List<MeterConfig> meterConfigList) {
this.meterConfigList = meterConfigList;
}

public CosemObject getCosemObject(
final String protocolName, final String protocolVersion, final DlmsObjectType dlmsObjectType)
throws IllegalArgumentException {
final Map<DlmsObjectType, CosemObject> cosemObjects =
this.getCosemObjects(protocolName, protocolVersion);
if (cosemObjects.containsKey(dlmsObjectType)) {
return cosemObjects.get(dlmsObjectType);
} else {
throw new IllegalArgumentException(
String.format(
"No object found of type %s in profile %s version %s",
dlmsObjectType.value(), protocolName, protocolVersion));
}
}

public Map<DlmsObjectType, CosemObject> getCosemObjects(
final String protocolName, final String protocolVersion) {

try {
if (this.meterConfigList == null || this.meterConfigList.isEmpty()) {
this.meterConfigList = this.getMeterConfigListFromResources();
}

final Optional<MeterConfig> meterConfig =
this.meterConfigList.stream()
.filter(config -> protocolVersion.equalsIgnoreCase(config.version))
.filter(config -> protocolName.equalsIgnoreCase(config.profile))
.findAny();
if (!meterConfig.isPresent()) {
return new EnumMap<>(DlmsObjectType.class);
}
return this.getCosemObjectFromMeterConfig(meterConfig.get())
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"no config found for protocol '%s' version '%s' ",
protocolName, protocolVersion)));

} catch (final IOException exception) {
throw new IllegalArgumentException(
String.format(
"no config found for protocol '%s' version '%s' ", protocolName, protocolVersion));
}
}

private Optional<Map<DlmsObjectType, CosemObject>> getCosemObjectFromMeterConfig(
final MeterConfig meterConfig) {
final Map<DlmsObjectType, CosemObject> cosemObjectMap = new EnumMap<>(DlmsObjectType.class);
meterConfig
.getCosemObjects()
.forEach(
cosemObject ->
cosemObjectMap.put(DlmsObjectType.fromValue(cosemObject.getTag()), cosemObject));
return Optional.of(cosemObjectMap);
}

private List<MeterConfig> getMeterConfigListFromResources() throws IOException {
final String scannedPackage = "meter_config/*";
final PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
final Resource[] resources = scanner.getResources(scannedPackage);

final ObjectMapper objectMapper = new ObjectMapper();

final List<MeterConfig> meterConfigs = new ArrayList<>();

Stream.of(resources)
.filter(
resource -> resource.getFilename() != null && resource.getFilename().endsWith(".json"))
.forEach(
resource -> {
try {
final MeterConfig meterConfig =
objectMapper.readValue(resource.getInputStream(), MeterConfig.class);
meterConfigs.add(meterConfig);
} catch (final IOException e) {
log.error(String.format("Cannot read config file %s", resource.getFilename()), e);
}
});

return meterConfigs;
}
}
Loading