From ef4ea5743cf444e940f44538fed28990412d5c1d Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Sun, 11 Feb 2018 20:35:17 +0000 Subject: [PATCH 01/13] inital commit --- .../.classpath | 7 + .../.gitignore | 2 + .../.project | 28 ++++ .../.settings/org.eclipse.jdt.core.prefs | 7 + .../.settings/org.eclipse.pde.core.prefs | 4 + .../META-INF/MANIFEST.MF | 26 ++++ .../build.properties | 4 + .../node/openadr/mockven/MockVen.java | 52 ++++++++ .../mockven/MockVenDatumDataSource.java | 89 +++++++++++++ .../node/openadr/mockven/OadrParams.java | 120 ++++++++++++++++++ .../openadr/mockven/OadrPayloadGenerator.java | 17 +++ .../OadrQueryRegistrationGenerator.java | 23 ++++ .../node/openadr/mockven/OadrSubDomains.java | 10 ++ .../openadr/mockven/TopNodeConnection.java | 65 ++++++++++ 14 files changed, 454 insertions(+) create mode 100644 net.solarnetwork.node.openadr.mockven/.classpath create mode 100644 net.solarnetwork.node.openadr.mockven/.gitignore create mode 100644 net.solarnetwork.node.openadr.mockven/.project create mode 100644 net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.jdt.core.prefs create mode 100644 net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.pde.core.prefs create mode 100644 net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF create mode 100644 net.solarnetwork.node.openadr.mockven/build.properties create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java diff --git a/net.solarnetwork.node.openadr.mockven/.classpath b/net.solarnetwork.node.openadr.mockven/.classpath new file mode 100644 index 000000000..2374a41aa --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/net.solarnetwork.node.openadr.mockven/.gitignore b/net.solarnetwork.node.openadr.mockven/.gitignore new file mode 100644 index 000000000..c3dca1b96 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/.gitignore @@ -0,0 +1,2 @@ +/build +/target diff --git a/net.solarnetwork.node.openadr.mockven/.project b/net.solarnetwork.node.openadr.mockven/.project new file mode 100644 index 000000000..382984931 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/.project @@ -0,0 +1,28 @@ + + + net.solarnetwork.node.openadr.mockven + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.jdt.core.prefs b/net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..c537b6306 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.pde.core.prefs b/net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 000000000..e8ff8be0b --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +pluginProject.equinox=false +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF b/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF new file mode 100644 index 000000000..6c03d98ff --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF @@ -0,0 +1,26 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: OpenADR VEN Mock +Bundle-SymbolicName: net.solarnetwork.node.openadr.mockven +Bundle-Version: 1.0.0 +Bundle-Vendor: SolarNetwork +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: net.solarnetwork.node;version="1.23.0", + net.solarnetwork.node.dao;version="1.8.0", + net.solarnetwork.node.domain;version="1.11.0", + net.solarnetwork.node.job;version="1.13.4", + net.solarnetwork.node.settings;version="1.10.0", + net.solarnetwork.node.settings.support;version="1.8.0", + net.solarnetwork.node.support;version="1.14.0", + net.solarnetwork.node.util;version="1.7.2", + net.solarnetwork.util;version="1.28.0", + org.quartz;version="[2.2.3,3.0.0)", + org.quartz.simpl;version="[2.2.3,3.0.0)", + org.slf4j;version="[1.7.24,2.0.0)", + org.springframework.beans;version="[4.2.9.RELEASE,5.0.0)", + org.springframework.context.support;version="[4.2.9.RELEASE,5.0.0)", + org.springframework.core;version="[4.2.9.RELEASE,5.0.0)", + org.springframework.http;version="4.2.9.RELEASE", + org.springframework.scheduling.quartz;version="[4.2.9.RELEASE,5.0.0)", + org.springframework.web.client;version="4.2.9.RELEASE" +Require-Bundle: net.solarnetwork.external.openadr.model diff --git a/net.solarnetwork.node.openadr.mockven/build.properties b/net.solarnetwork.node.openadr.mockven/build.properties new file mode 100644 index 000000000..668f1032f --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = build/eclipse/ +bin.includes = META-INF/,\ + . diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java new file mode 100644 index 000000000..e6432e743 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java @@ -0,0 +1,52 @@ + +package net.solarnetwork.node.openadr.mockven; + +public class MockVen extends OadrParams { + + private boolean registered = false; + private String url; + private TopNodeConnection connection; + + public MockVen() { + connection = new TopNodeConnection(); + } + + @Override + public void setVenID(String venID) { + if ( !getVenID().equals(venID) ) { + registered = false; + } + super.setVenID(venID); + } + + @Override + public void setVenName(String venName) { + if ( !getVenName().equals(venName) ) { + registered = false; + } + super.setVenName(venName); + } + + public boolean isRegisterd() { + + //this should query registration + return registered; + } + + public void setVtnURL(String url) { + this.url = url; + } + + //Polls the VTN and responds to events + public void pollAndRespond() { + if ( registered == false ) { + queryAndRegister(); + } + } + + //asks VTN if we are registered if not register + public void queryAndRegister() { + + } + +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java new file mode 100644 index 000000000..fa8634c8c --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java @@ -0,0 +1,89 @@ + +package net.solarnetwork.node.openadr.mockven; + +import java.util.List; +import net.solarnetwork.node.DatumDataSource; +import net.solarnetwork.node.domain.GeneralNodeDatum; +import net.solarnetwork.node.settings.SettingSpecifier; +import net.solarnetwork.node.settings.SettingSpecifierProvider; +import net.solarnetwork.node.settings.support.BasicTextFieldSettingSpecifier; +import net.solarnetwork.node.support.DatumDataSourceSupport; + +public class MockVenDatumDataSource extends DatumDataSourceSupport + implements DatumDataSource, SettingSpecifierProvider { + + private String venName; + private String venID; + private String vtnAddress; + private String vtnName; + private MockVen mockVen = null; + + @Override + public Class getDatumType() { + return GeneralNodeDatum.class; + } + + @Override + public GeneralNodeDatum readCurrentDatum() { + if ( mockVen == null ) { + mockVen = new MockVen(); + } + mockVen.pollAndRespond(); + + // I don't understand how to configure in OSGI how to do a job so instead we will be using this to summon the MockVen + return null; + } + + @Override + public String getSettingUID() { + return "net.solarnetwork.node.openadr.mockven"; + } + + @Override + public String getDisplayName() { + return "OpenADR Ven Mock"; + } + + @Override + public List getSettingSpecifiers() { + List results = getIdentifiableSettingSpecifiers(); + results.add(new BasicTextFieldSettingSpecifier("venName", null)); + results.add(new BasicTextFieldSettingSpecifier("venID", null)); + results.add(new BasicTextFieldSettingSpecifier("vtnAddress", null)); + results.add(new BasicTextFieldSettingSpecifier("vtnName", null)); + return results; + } + + public String getVenName() { + return venName; + } + + public void setVenName(String venName) { + this.venName = venName; + } + + public String getVenID() { + return venID; + } + + public void setVenID(String venID) { + this.venID = venID; + } + + public String getVtnAddress() { + return vtnAddress; + } + + public void setVtnAddress(String vtnAddress) { + this.vtnAddress = vtnAddress; + } + + public String getVtnName() { + return vtnName; + } + + public void setVtnName(String vtnName) { + this.vtnName = vtnName; + } + +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java new file mode 100644 index 000000000..5bfaddf46 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java @@ -0,0 +1,120 @@ + +package net.solarnetwork.node.openadr.mockven; + +import openadr.model.v20b.OadrTransportType; + +public abstract class OadrParams { + + private String venName; + + //not sure about these constants + private String venID; + private String registrationID; + private String requestID; + + private String vtnID; + private int modificationNumber; + private String eventID; + + private OadrTransportType transportType; + private String profileName; + private Boolean reportOnly; + private Boolean xmlSignature; + private Boolean httpPullModel; + + public String getVenName() { + return venName; + } + + public void setVenName(String venName) { + this.venName = venName; + } + + public String getVenID() { + return venID; + } + + public void setVenID(String venID) { + this.venID = venID; + } + + public String getRegistrationID() { + return registrationID; + } + + public void setRegistrationID(String registrationID) { + this.registrationID = registrationID; + } + + public String getRequestID() { + return requestID; + } + + public void setRequestID(String requestID) { + this.requestID = requestID; + } + + public OadrTransportType getTransportName() { + return transportType; + } + + public void setTransportName(OadrTransportType transportName) { + this.transportType = transportName; + } + + public String getProfileName() { + return profileName; + } + + public void setProfileName(String profileName) { + this.profileName = profileName; + } + + public Boolean isReportOnly() { + return reportOnly; + } + + public void setReportOnly(boolean reportOnly) { + this.reportOnly = reportOnly; + } + + public Boolean isXmlSignature() { + return xmlSignature; + } + + public void setXmlSignature(boolean xmlSignature) { + this.xmlSignature = xmlSignature; + } + + public Boolean isHttpPullModel() { + return httpPullModel; + } + + public void setHttpPullModel(boolean httpPullModel) { + this.httpPullModel = httpPullModel; + } + + public String getVtnID() { + return vtnID; + } + + public void setVtnID(String vtnID) { + this.vtnID = vtnID; + } + + public int getModificationNumber() { + return modificationNumber; + } + + public void setModificationNumber(int modificationNumber) { + this.modificationNumber = modificationNumber; + } + + public String getEventID() { + return eventID; + } + + public void setEventID(String eventID) { + this.eventID = eventID; + } +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java new file mode 100644 index 000000000..495535912 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java @@ -0,0 +1,17 @@ + +package net.solarnetwork.node.openadr.mockven; + +import java.util.Random; + +public abstract class OadrPayloadGenerator { + + String genRandomRequestID() { + Random rand = new Random(); + StringBuffer sb = new StringBuffer(); + for ( int i = 0; i < 10; i++ ) { + //this produces lowercase letters + sb.append(Integer.toHexString(rand.nextInt(16))); + } + return sb.toString(); + } +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java new file mode 100644 index 000000000..6fa3da793 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java @@ -0,0 +1,23 @@ + +package net.solarnetwork.node.openadr.mockven; + +import openadr.model.v20b.OadrPayload; +import openadr.model.v20b.OadrQueryRegistration; +import openadr.model.v20b.OadrSignedObject; + +public class OadrQueryRegistrationGenerator extends OadrPayloadGenerator { + + OadrPayload createPayload(OadrParams params) { + OadrPayload payload = new OadrPayload(); + OadrSignedObject signedObject = new OadrSignedObject(); + OadrQueryRegistration queryReg = new OadrQueryRegistration(); + payload.withOadrSignedObject(signedObject.withOadrQueryRegistration(queryReg)); + + queryReg.setRequestID(genRandomRequestID()); + + //TODO check if profile name and scheme version are the same thing + queryReg.setSchemaVersion(params.getProfileName()); + return null; + + } +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java new file mode 100644 index 000000000..3e1671cbc --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java @@ -0,0 +1,10 @@ + +package net.solarnetwork.node.openadr.mockven; + +public class OadrSubDomains { + + public static final String EiRegisterParty = "EiRegisterParty"; + public static final String EiReport = "EiReport"; + public static final String EiEvent = "EiEvent"; + public static final String OadrPoll = "OadrPoll"; +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java new file mode 100644 index 000000000..985cca495 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java @@ -0,0 +1,65 @@ + +package net.solarnetwork.node.openadr.mockven; + +import java.io.StringReader; +import java.io.StringWriter; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; +import org.xml.sax.InputSource; +import openadr.model.v20b.OadrPayload; + +public class TopNodeConnection { + + private HttpHeaders headers; + private RestTemplate rest; + private JAXBContext jaxbContext; + private Marshaller marshaller; + + public TopNodeConnection() { + headers = new HttpHeaders(); + rest = new RestTemplate(); + headers.setContentType(MediaType.TEXT_XML); + try { + jaxbContext = JAXBContext.newInstance("openadr.model.v20b:" + "openadr.model.v20b.atom:" + + "openadr.model.v20b.currency:" + "openadr.model.v20b.ei:" + + "openadr.model.v20b.emix:" + "openadr.model.v20b.gml:" + + "openadr.model.v20b.greenbutton:" + "openadr.model.v20b.power:" + + "openadr.model.v20b.pyld:" + "openadr.model.v20b.siscale:" + + "openadr.model.v20b.strm:" + "openadr.model.v20b.xcal:" + + "openadr.model.v20b.xmldsig:" + "openadr.model.v20b.xmldsig11"); + + marshaller = jaxbContext.createMarshaller(); + } catch ( JAXBException e ) { + throw new RuntimeException(e); + } + } + + public OadrPayload postPayload(String url, OadrPayload payload) { + StringWriter out = new StringWriter(); + try { + marshaller.marshal(payload, out); + + ResponseEntity response = rest.postForEntity(url, out.toString(), String.class); + + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + + OadrPayload returnPayload = (OadrPayload) jaxbUnmarshaller + .unmarshal(new InputSource(new StringReader(response.getBody()))); + + //TODO remove print statment + System.out.println(response.getBody()); + return returnPayload; + + } catch ( JAXBException e ) { + throw new RuntimeException(e); + } + + } + +} From 16179ab7d746855131c96f451d2b515af82df5a1 Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Mon, 12 Feb 2018 22:28:06 +0000 Subject: [PATCH 02/13] program now polls VTN --- .../.classpath | 2 +- .../META-INF/MANIFEST.MF | 1 + .../OSGI-INF/blueprint/module.xml | 113 +++++++++++++++++ .../node/openadr/mockven/MockVen.java | 117 +++++++++++++++++- .../mockven/MockVenDatumDataSource.java | 18 ++- .../mockven/MockVenDatumDataSource.properties | 3 + .../OadrCreatePartyRegistrationGenerator.java | 27 ++++ .../node/openadr/mockven/OadrParams.java | 10 +- .../OadrQueryRegistrationGenerator.java | 3 +- .../openadr/mockven/TopNodeConnection.java | 10 +- 10 files changed, 289 insertions(+), 15 deletions(-) create mode 100644 net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java diff --git a/net.solarnetwork.node.openadr.mockven/.classpath b/net.solarnetwork.node.openadr.mockven/.classpath index 2374a41aa..aeeaff84d 100644 --- a/net.solarnetwork.node.openadr.mockven/.classpath +++ b/net.solarnetwork.node.openadr.mockven/.classpath @@ -1,7 +1,7 @@ + - diff --git a/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF b/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF index 6c03d98ff..f457aa9e8 100644 --- a/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF +++ b/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Import-Package: net.solarnetwork.node;version="1.23.0", net.solarnetwork.node.support;version="1.14.0", net.solarnetwork.node.util;version="1.7.2", net.solarnetwork.util;version="1.28.0", + openadr.model.v20b;version="2.1.0", org.quartz;version="[2.2.3,3.0.0)", org.quartz.simpl;version="[2.2.3,3.0.0)", org.slf4j;version="[1.7.24,2.0.0)", diff --git a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml new file mode 100644 index 000000000..192ae43f9 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + net.solarnetwork.node.job.ManagedTriggerAndJobDetail + net.solarnetwork.node.job.ServiceProvider + net.solarnetwork.node.settings.SettingSpecifierProvider + + + + + + + + + + + + + + + + + + + + + + + + net.solarnetwork.node.DatumDataSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java index e6432e743..ef2e6d949 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java @@ -1,6 +1,20 @@ package net.solarnetwork.node.openadr.mockven; +import openadr.model.v20b.OadrCreatedEvent; +import openadr.model.v20b.OadrCreatedPartyRegistration; +import openadr.model.v20b.OadrDistributeEvent; +import openadr.model.v20b.OadrPayload; +import openadr.model.v20b.OadrPoll; +import openadr.model.v20b.OadrSignedObject; +import openadr.model.v20b.ei.EiResponse; +import openadr.model.v20b.ei.EventDescriptor; +import openadr.model.v20b.ei.EventResponses.EventResponse; +import openadr.model.v20b.ei.OptTypeType; +import openadr.model.v20b.ei.QualifiedEventID; +import openadr.model.v20b.ei.ResponseCode; +import openadr.model.v20b.pyld.EiCreatedEvent; + public class MockVen extends OadrParams { private boolean registered = false; @@ -13,7 +27,7 @@ public MockVen() { @Override public void setVenID(String venID) { - if ( !getVenID().equals(venID) ) { + if ( !venID.equals(getVenID()) ) { registered = false; } super.setVenID(venID); @@ -21,7 +35,7 @@ public void setVenID(String venID) { @Override public void setVenName(String venName) { - if ( !getVenName().equals(venName) ) { + if ( !venName.equals(getVenName()) ) { registered = false; } super.setVenName(venName); @@ -34,19 +48,118 @@ public boolean isRegisterd() { } public void setVtnURL(String url) { + //ensure the URL ends with a / as we will be needing to call subdomains + if ( !url.endsWith("/") ) { + url = url + "/"; + } this.url = url; } //Polls the VTN and responds to events public void pollAndRespond() { + OadrSignedObject response = pollVTN().getOadrSignedObject(); + if ( response.getOadrDistributeEvent() != null ) { + //would it be better to have the response behavior expendable? + //I would say probably but for now lets hardcode some behavior + //TODO + respondToDistributeEvent(response.getOadrDistributeEvent()); + } + } + + //in a good design I guess this would be modifiable to change response behavior + //I need to figure out the best class structure for not but for now lets hardcode + //TODO + private void respondToDistributeEvent(OadrDistributeEvent event) { + //I should be using a generator but for now leave it here + //I currently don't have a pattern for passing in values to a generator + //TODO + + //NOTE HARDCODED FOR ONE EVENT + EventDescriptor params = event.getOadrEvents().get(0).getEiEvent().getEventDescriptor(); + String eventID = params.getEventID(); + Long modNum = params.getModificationNumber(); + String requestId = event.getRequestID(); + + //we have received and event + OadrPayload payload = new OadrPayload(); + OadrSignedObject signedObject = new OadrSignedObject(); + OadrCreatedEvent createdEvent = new OadrCreatedEvent(); + payload.setOadrSignedObject(signedObject.withOadrCreatedEvent(createdEvent)); + + createdEvent.setSchemaVersion(getProfileName()); + EiCreatedEvent eiCreatedEvent = new EiCreatedEvent(); + eiCreatedEvent.setVenID(getVenID()); + + EiResponse eiResponse = new EiResponse(); + eiResponse.setRequestID(requestId);//check that is not from event + eiResponse.setResponseCode(new ResponseCode().withValue("200")); + + eiCreatedEvent.setEiResponse(eiResponse); + + EventResponse eventResponse = new EventResponse(); + eventResponse.setOptType(OptTypeType.OPT_IN); + eventResponse.setQualifiedEventID( + new QualifiedEventID().withEventID(eventID).withModificationNumber(modNum)); + //eiCreatedEvent.setEventResponses(value); + + } + + //Polls the VTN and does nothing + public void poll() { + //this method returns something but we ignore it + pollVTN(); + } + + //only to be called when ven is registered to VTN + private OadrPayload pollVTN() { if ( registered == false ) { queryAndRegister(); } + + if ( registered == false ) { + throw new RuntimeException("Failed at registering with VTN"); + } + //this should be in its own generator + //TODO move this code + OadrPayload payload = new OadrPayload(); + OadrSignedObject signedObject = new OadrSignedObject(); + OadrPoll poll = new OadrPoll(); + payload.withOadrSignedObject(signedObject.withOadrPoll(poll)); + + //These values should be set from the registration + poll.setVenID(this.getVenID()); + poll.setSchemaVersion(this.getProfileName()); + + OadrPayload response = connection.postPayload(url + OadrSubDomains.OadrPoll, payload); + return response; + } //asks VTN if we are registered if not register public void queryAndRegister() { + OadrQueryRegistrationGenerator payloadGen = new OadrQueryRegistrationGenerator(); + OadrPayload payload = payloadGen.createPayload(this); + + //should have better error handling. + System.out.println(url + OadrSubDomains.EiRegisterParty); + OadrPayload response = connection.postPayload(url + OadrSubDomains.EiRegisterParty, payload); + OadrCreatedPartyRegistration partyReg = response.getOadrSignedObject() + .getOadrCreatedPartyRegistration(); + //Check to see if that the VTN is okay before proceeding + if ( partyReg.getEiResponse().getResponseDescription().equalsIgnoreCase("OK") ) { + setVtnID(partyReg.getVtnID()); + OadrCreatePartyRegistrationGenerator payloadGen2 = new OadrCreatePartyRegistrationGenerator(); + payload = payloadGen2.createPayload(this); + response = connection.postPayload(url + OadrSubDomains.EiRegisterParty, payload); + partyReg = response.getOadrSignedObject().getOadrCreatedPartyRegistration(); + setRegistrationID(partyReg.getRegistrationID()); + setVenID(partyReg.getVenID()); + registered = true; + //skip register report for now + } else { + //something went wrong + } } } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java index fa8634c8c..d049f1c83 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java @@ -25,12 +25,10 @@ public Class getDatumType() { @Override public GeneralNodeDatum readCurrentDatum() { - if ( mockVen == null ) { - mockVen = new MockVen(); - } - mockVen.pollAndRespond(); // I don't understand how to configure in OSGI how to do a job so instead we will be using this to summon the MockVen + runMockVen(); + return null; } @@ -86,4 +84,16 @@ public void setVtnName(String vtnName) { this.vtnName = vtnName; } + // I don't understand how to configure in OSGI how to do a job so instead we will be using this to summon the MockVen + //this gets called when requesting a new datum + private void runMockVen() { + if ( mockVen == null ) { + mockVen = new MockVen(); + } + mockVen.setVenID(venID); + mockVen.setVtnURL(vtnAddress); + mockVen.setVenName(venName); + mockVen.pollAndRespond(); + } + } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties new file mode 100644 index 000000000..fd46d6e94 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties @@ -0,0 +1,3 @@ +title = OpenADR Mock Vitural End Node +venName.key = VEN Name +venName.desc = The human readable name of the VEN to be given to the VTN diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java new file mode 100644 index 000000000..5db2d29fa --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java @@ -0,0 +1,27 @@ + +package net.solarnetwork.node.openadr.mockven; + +import openadr.model.v20b.OadrCreatePartyRegistration; +import openadr.model.v20b.OadrPayload; +import openadr.model.v20b.OadrSignedObject; + +public class OadrCreatePartyRegistrationGenerator extends OadrPayloadGenerator { + + OadrPayload createPayload(OadrParams params) { + OadrPayload payload = new OadrPayload(); + OadrSignedObject signedObject = new OadrSignedObject(); + OadrCreatePartyRegistration partyReg = new OadrCreatePartyRegistration(); + payload.withOadrSignedObject(signedObject.withOadrCreatePartyRegistration(partyReg)); + + partyReg.setSchemaVersion(params.getProfileName()); + partyReg.setRequestID(genRandomRequestID()); + partyReg.setOadrHttpPullModel(params.isHttpPullModel()); + partyReg.setOadrVenName(params.getVenName()); + partyReg.setOadrXmlSignature(params.isXmlSignature()); + partyReg.setOadrReportOnly(params.isReportOnly()); + partyReg.setOadrTransportName(params.getTransportName()); + + return payload; + + } +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java index 5bfaddf46..9949646ca 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java @@ -16,11 +16,11 @@ public abstract class OadrParams { private int modificationNumber; private String eventID; - private OadrTransportType transportType; - private String profileName; - private Boolean reportOnly; - private Boolean xmlSignature; - private Boolean httpPullModel; + private OadrTransportType transportType = OadrTransportType.SIMPLE_HTTP; + private String profileName = "2.0b"; + private Boolean reportOnly = false; + private Boolean xmlSignature = false; + private Boolean httpPullModel = true; public String getVenName() { return venName; diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java index 6fa3da793..c2231e81b 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java @@ -17,7 +17,8 @@ OadrPayload createPayload(OadrParams params) { //TODO check if profile name and scheme version are the same thing queryReg.setSchemaVersion(params.getProfileName()); - return null; + + return payload; } } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java index 985cca495..5daf93daa 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java @@ -13,6 +13,7 @@ import org.springframework.web.client.RestTemplate; import org.xml.sax.InputSource; import openadr.model.v20b.OadrPayload; +import openadr.model.v20b.ObjectFactory; public class TopNodeConnection { @@ -25,6 +26,10 @@ public TopNodeConnection() { headers = new HttpHeaders(); rest = new RestTemplate(); headers.setContentType(MediaType.TEXT_XML); + + //Require a class loader when using OSGI + //https://stackoverflow.com/a/1043807 + ClassLoader cl = ObjectFactory.class.getClassLoader(); try { jaxbContext = JAXBContext.newInstance("openadr.model.v20b:" + "openadr.model.v20b.atom:" + "openadr.model.v20b.currency:" + "openadr.model.v20b.ei:" @@ -32,7 +37,7 @@ public TopNodeConnection() { + "openadr.model.v20b.greenbutton:" + "openadr.model.v20b.power:" + "openadr.model.v20b.pyld:" + "openadr.model.v20b.siscale:" + "openadr.model.v20b.strm:" + "openadr.model.v20b.xcal:" - + "openadr.model.v20b.xmldsig:" + "openadr.model.v20b.xmldsig11"); + + "openadr.model.v20b.xmldsig:" + "openadr.model.v20b.xmldsig11", cl); marshaller = jaxbContext.createMarshaller(); } catch ( JAXBException e ) { @@ -40,7 +45,8 @@ public TopNodeConnection() { } } - public OadrPayload postPayload(String url, OadrPayload payload) { + //I assume I have to synchronize this method to prevent trying to connect at the same time + public synchronized OadrPayload postPayload(String url, OadrPayload payload) { StringWriter out = new StringWriter(); try { marshaller.marshal(payload, out); From 1467b93120db3b1cd1e39a6a3f83f9596b428be1 Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Tue, 13 Feb 2018 01:49:05 +0000 Subject: [PATCH 03/13] removed venID from settings page and refactored some areas of MockVen --- .../node/openadr/mockven/MockVen.java | 119 +++++++----------- .../mockven/MockVenDatumDataSource.java | 10 +- .../mockven/MockVenDatumDataSource.properties | 6 + .../mockven/OadrCreatedEventGenerator.java | 55 ++++++++ .../openadr/mockven/OadrPollGenerator.java | 23 ++++ 5 files changed, 134 insertions(+), 79 deletions(-) create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java index ef2e6d949..40c92d329 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java @@ -1,20 +1,20 @@ package net.solarnetwork.node.openadr.mockven; -import openadr.model.v20b.OadrCreatedEvent; import openadr.model.v20b.OadrCreatedPartyRegistration; import openadr.model.v20b.OadrDistributeEvent; import openadr.model.v20b.OadrPayload; -import openadr.model.v20b.OadrPoll; import openadr.model.v20b.OadrSignedObject; -import openadr.model.v20b.ei.EiResponse; -import openadr.model.v20b.ei.EventDescriptor; -import openadr.model.v20b.ei.EventResponses.EventResponse; -import openadr.model.v20b.ei.OptTypeType; -import openadr.model.v20b.ei.QualifiedEventID; -import openadr.model.v20b.ei.ResponseCode; -import openadr.model.v20b.pyld.EiCreatedEvent; +/** + * + * Class to simulate a Virtual End Node (VEN). This class is designed to talk to + * a VTN via OpenADR 2.0b + * + * + * @author robert + * @version 1.0 + */ public class MockVen extends OadrParams { private boolean registered = false; @@ -25,82 +25,58 @@ public MockVen() { connection = new TopNodeConnection(); } - @Override - public void setVenID(String venID) { - if ( !venID.equals(getVenID()) ) { - registered = false; - } - super.setVenID(venID); - } - @Override public void setVenName(String venName) { + //if this parameter changes we assume we are no longer registered if ( !venName.equals(getVenName()) ) { registered = false; } super.setVenName(venName); } - public boolean isRegisterd() { - - //this should query registration - return registered; - } - public void setVtnURL(String url) { - //ensure the URL ends with a / as we will be needing to call subdomains + //ensure the URL ends with a / as we will be needing to call subdomains from OadrSubDomains if ( !url.endsWith("/") ) { url = url + "/"; } + //if this parameter changes we assume we are no longer registered + if ( !url.equals(this.url) ) { + registered = false; + } + this.url = url; } - //Polls the VTN and responds to events + /** + * sends a OadrPoll message to the VTN and acts according to the message + * sent back + */ public void pollAndRespond() { + + if ( registered == false ) { + queryAndRegister(); + } + OadrSignedObject response = pollVTN().getOadrSignedObject(); + + //currently the only supported response is for a OadrDistrubuteEvent if ( response.getOadrDistributeEvent() != null ) { - //would it be better to have the response behavior expendable? - //I would say probably but for now lets hardcode some behavior - //TODO respondToDistributeEvent(response.getOadrDistributeEvent()); } } - //in a good design I guess this would be modifiable to change response behavior - //I need to figure out the best class structure for not but for now lets hardcode - //TODO - private void respondToDistributeEvent(OadrDistributeEvent event) { - //I should be using a generator but for now leave it here - //I currently don't have a pattern for passing in values to a generator - //TODO - - //NOTE HARDCODED FOR ONE EVENT - EventDescriptor params = event.getOadrEvents().get(0).getEiEvent().getEventDescriptor(); - String eventID = params.getEventID(); - Long modNum = params.getModificationNumber(); - String requestId = event.getRequestID(); - - //we have received and event - OadrPayload payload = new OadrPayload(); - OadrSignedObject signedObject = new OadrSignedObject(); - OadrCreatedEvent createdEvent = new OadrCreatedEvent(); - payload.setOadrSignedObject(signedObject.withOadrCreatedEvent(createdEvent)); - - createdEvent.setSchemaVersion(getProfileName()); - EiCreatedEvent eiCreatedEvent = new EiCreatedEvent(); - eiCreatedEvent.setVenID(getVenID()); - - EiResponse eiResponse = new EiResponse(); - eiResponse.setRequestID(requestId);//check that is not from event - eiResponse.setResponseCode(new ResponseCode().withValue("200")); - - eiCreatedEvent.setEiResponse(eiResponse); - - EventResponse eventResponse = new EventResponse(); - eventResponse.setOptType(OptTypeType.OPT_IN); - eventResponse.setQualifiedEventID( - new QualifiedEventID().withEventID(eventID).withModificationNumber(modNum)); - //eiCreatedEvent.setEventResponses(value); + /** + * The + * + * @param event + */ + public void respondToDistributeEvent(OadrDistributeEvent event) { + + //I don't think it makes sense for the decision to opt in to be in the generator + OadrCreatedEventGenerator generator = new OadrCreatedEventGenerator(); + OadrPayload payload = generator.createPayload(this, event); + + OadrPayload response = connection.postPayload(url + OadrSubDomains.EiEvent, payload); } @@ -116,19 +92,9 @@ private OadrPayload pollVTN() { queryAndRegister(); } - if ( registered == false ) { - throw new RuntimeException("Failed at registering with VTN"); - } - //this should be in its own generator - //TODO move this code - OadrPayload payload = new OadrPayload(); - OadrSignedObject signedObject = new OadrSignedObject(); - OadrPoll poll = new OadrPoll(); - payload.withOadrSignedObject(signedObject.withOadrPoll(poll)); + OadrPollGenerator generator = new OadrPollGenerator(); - //These values should be set from the registration - poll.setVenID(this.getVenID()); - poll.setSchemaVersion(this.getProfileName()); + OadrPayload payload = generator.createPayload(this); OadrPayload response = connection.postPayload(url + OadrSubDomains.OadrPoll, payload); return response; @@ -141,7 +107,6 @@ public void queryAndRegister() { OadrPayload payload = payloadGen.createPayload(this); //should have better error handling. - System.out.println(url + OadrSubDomains.EiRegisterParty); OadrPayload response = connection.postPayload(url + OadrSubDomains.EiRegisterParty, payload); OadrCreatedPartyRegistration partyReg = response.getOadrSignedObject() .getOadrCreatedPartyRegistration(); @@ -158,7 +123,7 @@ public void queryAndRegister() { registered = true; //skip register report for now } else { - //something went wrong + throw new RuntimeException("Failed at registering with VTN"); } } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java index d049f1c83..e23e5b777 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java @@ -9,6 +9,14 @@ import net.solarnetwork.node.settings.support.BasicTextFieldSettingSpecifier; import net.solarnetwork.node.support.DatumDataSourceSupport; +/** + * + * I would prefer is this plugin did not have a datum data source however it was + * the easiest way for me to achieve + * + * @author robert + * @version 1.0 + */ public class MockVenDatumDataSource extends DatumDataSourceSupport implements DatumDataSource, SettingSpecifierProvider { @@ -46,7 +54,6 @@ public String getDisplayName() { public List getSettingSpecifiers() { List results = getIdentifiableSettingSpecifiers(); results.add(new BasicTextFieldSettingSpecifier("venName", null)); - results.add(new BasicTextFieldSettingSpecifier("venID", null)); results.add(new BasicTextFieldSettingSpecifier("vtnAddress", null)); results.add(new BasicTextFieldSettingSpecifier("vtnName", null)); return results; @@ -90,7 +97,6 @@ private void runMockVen() { if ( mockVen == null ) { mockVen = new MockVen(); } - mockVen.setVenID(venID); mockVen.setVtnURL(vtnAddress); mockVen.setVenName(venName); mockVen.pollAndRespond(); diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties index fd46d6e94..bfa4c773c 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties @@ -1,3 +1,9 @@ title = OpenADR Mock Vitural End Node venName.key = VEN Name venName.desc = The human readable name of the VEN to be given to the VTN +venID.key = VEN ID +venID.desc = The ID number this VEN has associated with VTN +vtnAddress.key = VTN URL +vtnAddress.desc = The URL of the VTN to where OpenADR 2.0b messages get sent to. These typically end with /OpenADR2/Simple/2.0b/ +vtnName.key = VTN Name +vtnName.desc = The human readable name of the VTN diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java new file mode 100644 index 000000000..664691613 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java @@ -0,0 +1,55 @@ + +package net.solarnetwork.node.openadr.mockven; + +import openadr.model.v20b.OadrCreatedEvent; +import openadr.model.v20b.OadrDistributeEvent; +import openadr.model.v20b.OadrPayload; +import openadr.model.v20b.OadrSignedObject; +import openadr.model.v20b.ei.EiResponse; +import openadr.model.v20b.ei.EventDescriptor; +import openadr.model.v20b.ei.EventResponses; +import openadr.model.v20b.ei.EventResponses.EventResponse; +import openadr.model.v20b.ei.OptTypeType; +import openadr.model.v20b.ei.QualifiedEventID; +import openadr.model.v20b.ei.ResponseCode; +import openadr.model.v20b.pyld.EiCreatedEvent; + +public class OadrCreatedEventGenerator { + + OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { + //NOTE HARDCODED FOR ONE EVENT + EventDescriptor eventParams = event.getOadrEvents().get(0).getEiEvent().getEventDescriptor(); + String eventID = eventParams.getEventID(); + Long modNum = eventParams.getModificationNumber(); + String requestId = event.getRequestID(); + + //we have received and event + OadrPayload payload = new OadrPayload(); + OadrSignedObject signedObject = new OadrSignedObject(); + OadrCreatedEvent createdEvent = new OadrCreatedEvent(); + payload.setOadrSignedObject(signedObject.withOadrCreatedEvent(createdEvent)); + + createdEvent.setSchemaVersion(params.getProfileName()); + EiCreatedEvent eiCreatedEvent = new EiCreatedEvent(); + eiCreatedEvent.setVenID(params.getVenID()); + + EiResponse eiResponse = new EiResponse(); + eiResponse.setRequestID(requestId);//check that is not from event + eiResponse.setResponseCode(new ResponseCode().withValue("200")); + + eiCreatedEvent.setEiResponse(eiResponse); + + EventResponse eventResponse = new EventResponse(); + eventResponse.setOptType(OptTypeType.OPT_IN); + eventResponse.setQualifiedEventID( + new QualifiedEventID().withEventID(eventID).withModificationNumber(modNum)); + + EventResponses eventResponses = new EventResponses(); + eventResponses.getEventResponses().add(eventResponse); + eiCreatedEvent.setEventResponses(eventResponses); + + createdEvent.setEiCreatedEvent(eiCreatedEvent); + + return payload; + } +} diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java new file mode 100644 index 000000000..f361bd505 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java @@ -0,0 +1,23 @@ + +package net.solarnetwork.node.openadr.mockven; + +import openadr.model.v20b.OadrPayload; +import openadr.model.v20b.OadrPoll; +import openadr.model.v20b.OadrSignedObject; + +public class OadrPollGenerator extends OadrPayloadGenerator { + + OadrPayload createPayload(OadrParams params) { + OadrPayload payload = new OadrPayload(); + OadrSignedObject signedObject = new OadrSignedObject(); + OadrPoll poll = new OadrPoll(); + + payload.withOadrSignedObject(signedObject.withOadrPoll(poll)); + + //These values should be set from the registration + poll.setVenID(params.getVenID()); + poll.setSchemaVersion(params.getProfileName()); + + return payload; + } +} From d1b68a15c73b4a21eab85ccbcd86f1b5dd34ab48 Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Tue, 13 Feb 2018 03:53:37 +0000 Subject: [PATCH 04/13] added default vales to venName and vtnAddress to match the VTN and VEN implementations --- .../node/openadr/mockven/MockVenDatumDataSource.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java index e23e5b777..e01940b74 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java @@ -53,9 +53,13 @@ public String getDisplayName() { @Override public List getSettingSpecifiers() { List results = getIdentifiableSettingSpecifiers(); - results.add(new BasicTextFieldSettingSpecifier("venName", null)); + //default names used by EPRI's VEN and VTN + //see results.add(new BasicTextFieldSettingSpecifier("vtnName", "EPRI")); + //results.add(new BasicTextFieldSettingSpecifier("vtnName", "EPRI")); + results.add(new BasicTextFieldSettingSpecifier("venName", "Test_VEN_Name")); + results.add(new BasicTextFieldSettingSpecifier("vtnName", "EPRI")); + results.add(new BasicTextFieldSettingSpecifier("vtnAddress", null)); - results.add(new BasicTextFieldSettingSpecifier("vtnName", null)); return results; } From 02968558fc2bcf9962992e142e5634149c3df405 Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Tue, 13 Feb 2018 20:43:57 +0000 Subject: [PATCH 05/13] fixed typos and missing visabillity modifiers in generators --- .../OSGI-INF/blueprint/module.xml | 14 +++++++------- .../mockven/MockVenDatumDataSource.properties | 2 +- .../OadrCreatePartyRegistrationGenerator.java | 2 +- .../openadr/mockven/OadrCreatedEventGenerator.java | 4 +++- .../node/openadr/mockven/OadrPayloadGenerator.java | 2 +- .../node/openadr/mockven/OadrPollGenerator.java | 2 +- .../mockven/OadrQueryRegistrationGenerator.java | 2 +- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml index 192ae43f9..c92f12dc0 100644 --- a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml +++ b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml @@ -32,16 +32,16 @@ - + - + - @@ -58,14 +58,14 @@ we define a cron style trigger, that by default runs once/minute --> - + - @@ -90,10 +90,10 @@ + is what MockVenDatumDataSource is! --> - + diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties index bfa4c773c..8c1f8eb80 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties @@ -1,4 +1,4 @@ -title = OpenADR Mock Vitural End Node +title = OpenADR Mock Virtual End Node venName.key = VEN Name venName.desc = The human readable name of the VEN to be given to the VTN venID.key = VEN ID diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java index 5db2d29fa..c506baec2 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatePartyRegistrationGenerator.java @@ -7,7 +7,7 @@ public class OadrCreatePartyRegistrationGenerator extends OadrPayloadGenerator { - OadrPayload createPayload(OadrParams params) { + public OadrPayload createPayload(OadrParams params) { OadrPayload payload = new OadrPayload(); OadrSignedObject signedObject = new OadrSignedObject(); OadrCreatePartyRegistration partyReg = new OadrCreatePartyRegistration(); diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java index 664691613..1572bcd1a 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java @@ -16,7 +16,7 @@ public class OadrCreatedEventGenerator { - OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { + public OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { //NOTE HARDCODED FOR ONE EVENT EventDescriptor eventParams = event.getOadrEvents().get(0).getEiEvent().getEventDescriptor(); String eventID = eventParams.getEventID(); @@ -40,6 +40,7 @@ OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { eiCreatedEvent.setEiResponse(eiResponse); EventResponse eventResponse = new EventResponse(); + eventResponse.setOptType(OptTypeType.OPT_IN); eventResponse.setQualifiedEventID( new QualifiedEventID().withEventID(eventID).withModificationNumber(modNum)); @@ -52,4 +53,5 @@ OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { return payload; } + } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java index 495535912..9ec7e3715 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java @@ -5,7 +5,7 @@ public abstract class OadrPayloadGenerator { - String genRandomRequestID() { + public String genRandomRequestID() { Random rand = new Random(); StringBuffer sb = new StringBuffer(); for ( int i = 0; i < 10; i++ ) { diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java index f361bd505..c211b3960 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java @@ -7,7 +7,7 @@ public class OadrPollGenerator extends OadrPayloadGenerator { - OadrPayload createPayload(OadrParams params) { + public OadrPayload createPayload(OadrParams params) { OadrPayload payload = new OadrPayload(); OadrSignedObject signedObject = new OadrSignedObject(); OadrPoll poll = new OadrPoll(); diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java index c2231e81b..af48c5c67 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java @@ -7,7 +7,7 @@ public class OadrQueryRegistrationGenerator extends OadrPayloadGenerator { - OadrPayload createPayload(OadrParams params) { + public OadrPayload createPayload(OadrParams params) { OadrPayload payload = new OadrPayload(); OadrSignedObject signedObject = new OadrSignedObject(); OadrQueryRegistration queryReg = new OadrQueryRegistration(); From bf58d8d2c75fa66771ca91eed22bc90184e1fd7e Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Wed, 14 Feb 2018 02:15:03 +0000 Subject: [PATCH 06/13] MockVEN now opts out of events that are over or have incorrect signalName signalType combinations --- .../mockven/OadrCreatedEventGenerator.java | 131 +++++++++++++++++- .../mockven/SignalNameEnumeratedType.java | 36 +++++ 2 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java index 1572bcd1a..b98819509 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java @@ -1,10 +1,15 @@ package net.solarnetwork.node.openadr.mockven; +import java.time.Duration; +import java.util.Calendar; +import java.util.GregorianCalendar; import openadr.model.v20b.OadrCreatedEvent; import openadr.model.v20b.OadrDistributeEvent; +import openadr.model.v20b.OadrDistributeEvent.OadrEvent; import openadr.model.v20b.OadrPayload; import openadr.model.v20b.OadrSignedObject; +import openadr.model.v20b.ei.EiEventSignal; import openadr.model.v20b.ei.EiResponse; import openadr.model.v20b.ei.EventDescriptor; import openadr.model.v20b.ei.EventResponses; @@ -12,6 +17,7 @@ import openadr.model.v20b.ei.OptTypeType; import openadr.model.v20b.ei.QualifiedEventID; import openadr.model.v20b.ei.ResponseCode; +import openadr.model.v20b.ei.SignalTypeEnumeratedType; import openadr.model.v20b.pyld.EiCreatedEvent; public class OadrCreatedEventGenerator { @@ -41,7 +47,7 @@ public OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { EventResponse eventResponse = new EventResponse(); - eventResponse.setOptType(OptTypeType.OPT_IN); + eventResponse.setOptType(OptInLogic(params, event.getOadrEvents().get(0))); eventResponse.setQualifiedEventID( new QualifiedEventID().withEventID(eventID).withModificationNumber(modNum)); @@ -54,4 +60,127 @@ public OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { return payload; } + //Feel free to overwrite this method to change opt in behavior. + public OptTypeType OptInLogic(OadrParams params, OadrEvent event) { + + //ensure that the signals are valid if not opt out. This is the behavior of the EPRI VEN + for ( EiEventSignal eventSig : event.getEiEvent().getEiEventSignals().getEiEventSignals() ) { + if ( !validSignalNameAndType(eventSig) ) { + return OptTypeType.OPT_OUT; + } + } + if ( eventOver(event) ) { + return OptTypeType.OPT_OUT; + } + + return OptTypeType.OPT_IN; + } + + public boolean validSignalNameAndType(EiEventSignal event) { + String singalName = event.getSignalName(); + SignalTypeEnumeratedType signalType = event.getSignalType(); + + SignalNameEnumeratedType sigName = SignalNameEnumeratedType.valueOf(singalName); + + switch (sigName) { + case simple: + if ( signalType.equals(SignalTypeEnumeratedType.LEVEL) ) { + break; + } + return false; + case SIMPLE: + if ( signalType.equals(SignalTypeEnumeratedType.LEVEL) ) { + break; + } + return false; + case ELECTRICITY_PRICE: + if ( signalType.equals(SignalTypeEnumeratedType.PRICE) + || signalType.equals(SignalTypeEnumeratedType.PRICE_RELATIVE) + || signalType.equals(SignalTypeEnumeratedType.PRICE_MULTIPLIER) ) { + break; + } + return false; + case ENERGY_PRICE: + if ( signalType.equals(SignalTypeEnumeratedType.PRICE) + || signalType.equals(SignalTypeEnumeratedType.PRICE_RELATIVE) + || signalType.equals(SignalTypeEnumeratedType.PRICE_MULTIPLIER) ) { + break; + } + return false; + case DEMAND_CHARGE: + if ( signalType.equals(SignalTypeEnumeratedType.PRICE) + || signalType.equals(SignalTypeEnumeratedType.PRICE_RELATIVE) + || signalType.equals(SignalTypeEnumeratedType.PRICE_MULTIPLIER) ) { + break; + } + return false; + case BID_PRICE: + if ( signalType.equals(SignalTypeEnumeratedType.PRICE) ) { + break; + } + return false; + case BID_LOAD: + if ( signalType.equals(SignalTypeEnumeratedType.SETPOINT) ) { + break; + } + return false; + case BID_ENERGY: + if ( signalType.equals(SignalTypeEnumeratedType.SETPOINT) ) { + break; + } + return false; + case CHARGE_STATE: + if ( signalType.equals(SignalTypeEnumeratedType.SETPOINT) + || signalType.equals(SignalTypeEnumeratedType.DELTA) + || signalType.equals(SignalTypeEnumeratedType.MULTIPLIER) ) { + break; + } + return false; + case LOAD_DISPATCH: + if ( signalType.equals(SignalTypeEnumeratedType.SETPOINT) + || signalType.equals(SignalTypeEnumeratedType.DELTA) + || signalType.equals(SignalTypeEnumeratedType.MULTIPLIER) + || signalType.equals(SignalTypeEnumeratedType.LEVEL) ) { + break; + } + return false; + case LOAD_CONTROL: + if ( signalType.equals(SignalTypeEnumeratedType.X_LOAD_CONTROL_CAPACITY) + || signalType.equals(SignalTypeEnumeratedType.X_LOAD_CONTROL_LEVEL_OFFSET) + || signalType.equals(SignalTypeEnumeratedType.X_LOAD_CONTROL_PERCENT_OFFSET) + || signalType.equals(SignalTypeEnumeratedType.X_LOAD_CONTROL_SETPOINT) ) { + break; + } + return false; + } + + return true; + } + + //Checks that the event has not already past. + public boolean eventOver(OadrEvent event) { + GregorianCalendar now = (GregorianCalendar) GregorianCalendar.getInstance(); + + String durationString = event.getEiEvent().getEiActivePeriod().getProperties().getDuration() + .getDuration().getValue(); + + GregorianCalendar eventdate = event.getEiEvent().getEiActivePeriod().getProperties().getDtstart() + .getDateTime().getValue().toGregorianCalendar(); + + Duration d = Duration.parse(durationString); + //d.getSeconds(); + + eventdate.add(Calendar.SECOND, (int) d.getSeconds()); + + int dateCompare = eventdate.compareTo(now); + if ( dateCompare > 0 ) { + //event still has some time to go + return true; + } else { + //event has already been compleated + return false; + } + + } + } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java new file mode 100644 index 000000000..1841232e8 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java @@ -0,0 +1,36 @@ + +package net.solarnetwork.node.openadr.mockven; + +public enum SignalNameEnumeratedType { + SIMPLE("SIMPLE"), + simple("simple"), + ELECTRICITY_PRICE("ELECTRICITY_PRICE"), + ENERGY_PRICE("ENERGY_PRICE"), + DEMAND_CHARGE("DEMAND_CHARGE"), + BID_PRICE("BID_PRICE"), + BID_LOAD("BID_LOAD"), + BID_ENERGY("BID_ENERGY"), + CHARGE_STATE("CHARGE_STATE"), + LOAD_DISPATCH("LOAD_DISPATCH"), + LOAD_CONTROL("LOAD_CONTROL"); + + private final String value; + + SignalNameEnumeratedType(String v) { + value = v; + } + + @Override + public String toString() { + return value; + } + + public static SignalNameEnumeratedType fromValue(String v) { + for ( SignalNameEnumeratedType c : SignalNameEnumeratedType.values() ) { + if ( c.value.equals(v) ) { + return c; + } + } + throw new IllegalArgumentException(v); + } +} From 599ad6934b2288969d94f5abc09c32372dfca2a5 Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Wed, 14 Feb 2018 02:57:53 +0000 Subject: [PATCH 07/13] added some comments --- .../openadr/mockven/MockVenDatumDataSource.java | 2 +- .../mockven/OadrCreatedEventGenerator.java | 15 +++++++++++++++ .../mockven/OadrQueryRegistrationGenerator.java | 2 +- .../node/openadr/mockven/OadrSubDomains.java | 7 +++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java index e01940b74..e01ca420a 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java @@ -12,7 +12,7 @@ /** * * I would prefer is this plugin did not have a datum data source however it was - * the easiest way for me to achieve + * the easiest way for me to achieve an event in regular intervals * * @author robert * @version 1.0 diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java index b98819509..60b91513d 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java @@ -20,8 +20,23 @@ import openadr.model.v20b.ei.SignalTypeEnumeratedType; import openadr.model.v20b.pyld.EiCreatedEvent; +/** + * + * Class to generate OadrPayloads containing OadrCreatedEvent. This class is + * different to my other generators as it requires a OadrDistrubuteEvent object. + * This class also has some logic in deciding whether to opt into events or not. + * + * @author robert + * @version 1.0 + */ public class OadrCreatedEventGenerator { + /** + * + * @param params + * @param event + * @return Payload with a OadrCreatedEvent + */ public OadrPayload createPayload(OadrParams params, OadrDistributeEvent event) { //NOTE HARDCODED FOR ONE EVENT EventDescriptor eventParams = event.getOadrEvents().get(0).getEiEvent().getEventDescriptor(); diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java index af48c5c67..442885739 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java @@ -15,7 +15,7 @@ public OadrPayload createPayload(OadrParams params) { queryReg.setRequestID(genRandomRequestID()); - //TODO check if profile name and scheme version are the same thing + //TODO I not sure if profilename and schema version are the same thing from what I saw it is always "2.0b" queryReg.setSchemaVersion(params.getProfileName()); return payload; diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java index 3e1671cbc..3a27ad0cb 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrSubDomains.java @@ -1,6 +1,13 @@ package net.solarnetwork.node.openadr.mockven; +/** + * + * class containing static constants of the URL subdomains in OpenADR requests + * + * @author robert + * @version 1.0 + */ public class OadrSubDomains { public static final String EiRegisterParty = "EiRegisterParty"; From ac9e2f39bb6c4fda7964f1626ba3193ba330c6ca Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Wed, 14 Feb 2018 23:34:42 +0000 Subject: [PATCH 08/13] changed the service type from datum to JobService --- .../META-INF/MANIFEST.MF | 1 + .../OSGI-INF/blueprint/module.xml | 17 +++++++++---- .../node/openadr/mockven/MockVen.java | 2 +- .../mockven/MockVenDatumDataSource.java | 25 ++++++------------- .../node/openadr/mockven/PollTrigger.java | 21 ++++++++++++++++ 5 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java diff --git a/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF b/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF index f457aa9e8..b16c26b90 100644 --- a/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF +++ b/net.solarnetwork.node.openadr.mockven/META-INF/MANIFEST.MF @@ -16,6 +16,7 @@ Import-Package: net.solarnetwork.node;version="1.23.0", net.solarnetwork.util;version="1.28.0", openadr.model.v20b;version="2.1.0", org.quartz;version="[2.2.3,3.0.0)", + org.quartz.impl.triggers;version="2.2.3", org.quartz.simpl;version="[2.2.3,3.0.0)", org.slf4j;version="[1.7.24,2.0.0)", org.springframework.beans;version="[4.2.9.RELEASE,5.0.0)", diff --git a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml index c92f12dc0..1235687b8 100644 --- a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml +++ b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml @@ -15,11 +15,11 @@ http://www.springframework.org/schema/context/spring-context-4.2.xsd"> - + @@ -63,6 +63,12 @@ + + + + + diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java index 40c92d329..15f1d4935 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java @@ -9,7 +9,7 @@ /** * * Class to simulate a Virtual End Node (VEN). This class is designed to talk to - * a VTN via OpenADR 2.0b + * a Virtual Top Node (VTN) via OpenADR 2.0b * * * @author robert diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java index e01ca420a..042054726 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java @@ -2,8 +2,7 @@ package net.solarnetwork.node.openadr.mockven; import java.util.List; -import net.solarnetwork.node.DatumDataSource; -import net.solarnetwork.node.domain.GeneralNodeDatum; +import net.solarnetwork.node.job.JobService; import net.solarnetwork.node.settings.SettingSpecifier; import net.solarnetwork.node.settings.SettingSpecifierProvider; import net.solarnetwork.node.settings.support.BasicTextFieldSettingSpecifier; @@ -18,7 +17,7 @@ * @version 1.0 */ public class MockVenDatumDataSource extends DatumDataSourceSupport - implements DatumDataSource, SettingSpecifierProvider { + implements JobService, SettingSpecifierProvider { private String venName; private String venID; @@ -26,20 +25,6 @@ public class MockVenDatumDataSource extends DatumDataSourceSupport private String vtnName; private MockVen mockVen = null; - @Override - public Class getDatumType() { - return GeneralNodeDatum.class; - } - - @Override - public GeneralNodeDatum readCurrentDatum() { - - // I don't understand how to configure in OSGI how to do a job so instead we will be using this to summon the MockVen - runMockVen(); - - return null; - } - @Override public String getSettingUID() { return "net.solarnetwork.node.openadr.mockven"; @@ -106,4 +91,10 @@ private void runMockVen() { mockVen.pollAndRespond(); } + @Override + public void executeJobService() throws Exception { + // TODO Auto-generated method stub + runMockVen(); + } + } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java new file mode 100644 index 000000000..6343cc5e5 --- /dev/null +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java @@ -0,0 +1,21 @@ + +package net.solarnetwork.node.openadr.mockven; + +import java.util.Date; +import org.quartz.impl.triggers.SimpleTriggerImpl; + +public class PollTrigger extends SimpleTriggerImpl { + + /** + * + */ + private static final long serialVersionUID = 5752379851134828607L; + + public PollTrigger() { + setStartTime(new Date()); + setEndTime(null); + setRepeatInterval(10000L); + setRepeatCount(REPEAT_INDEFINITELY); + + } +} From 510be26e4b5966da9bf4130cb91cb515b6f699d3 Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Thu, 15 Feb 2018 01:22:12 +0000 Subject: [PATCH 09/13] added some documention on future implementation and changed name of MockVenDatumDataSource as it is no longer a datum data source --- .../OSGI-INF/blueprint/module.xml | 4 ++-- .../net/solarnetwork/node/openadr/mockven/MockVen.java | 3 +++ ...kVenDatumDataSource.java => MockVenJobService.java} | 2 +- .../openadr/mockven/OadrCreatedEventGenerator.java | 10 ++++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) rename net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/{MockVenDatumDataSource.java => MockVenJobService.java} (97%) diff --git a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml index 1235687b8..59edae2a8 100644 --- a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml +++ b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml @@ -23,7 +23,7 @@ - + @@ -106,7 +106,7 @@ - + diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java index 15f1d4935..0002213a4 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVen.java @@ -74,6 +74,9 @@ public void respondToDistributeEvent(OadrDistributeEvent event) { //I don't think it makes sense for the decision to opt in to be in the generator OadrCreatedEventGenerator generator = new OadrCreatedEventGenerator(); + + //You can potentially use this location for interacting when a demand response engine or some other mechanism for doing demand reposnse on the solarnetwork + //all of the parameters for the event are inside the OadrDistributeEvent OadrPayload payload = generator.createPayload(this, event); OadrPayload response = connection.postPayload(url + OadrSubDomains.EiEvent, payload); diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenJobService.java similarity index 97% rename from net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java rename to net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenJobService.java index 042054726..99a8ff536 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenJobService.java @@ -16,7 +16,7 @@ * @author robert * @version 1.0 */ -public class MockVenDatumDataSource extends DatumDataSourceSupport +public class MockVenJobService extends DatumDataSourceSupport implements JobService, SettingSpecifierProvider { private String venName; diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java index 60b91513d..732febe91 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrCreatedEventGenerator.java @@ -88,6 +88,16 @@ public OptTypeType OptInLogic(OadrParams params, OadrEvent event) { return OptTypeType.OPT_OUT; } + //proof of concept showing how to select a specific signalName + if ( event.getEiEvent().getEiEventSignals().getEiEventSignals().get(0).getSignalName() + .equals(SignalNameEnumeratedType.LOAD_CONTROL.toString()) ) { + + // One can grab the data from the event and use it for applying a demand response. + //If you were to use my existing demand response framework for solarnetwork here is a good location to talk to a demand response engine and update the demand response. + //see https://github.com/robbierew/solarnetwork-node/tree/demandresponse + + return OptTypeType.OPT_IN; + } return OptTypeType.OPT_IN; } From 1aaf39e25376c1a352d9bed196638b8893094bba Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Thu, 15 Feb 2018 02:59:23 +0000 Subject: [PATCH 10/13] Added some comments --- .../mockven/MockVenDatumDataSource.properties | 4 ++++ .../openadr/mockven/MockVenJobService.java | 21 +++++++------------ .../node/openadr/mockven/OadrParams.java | 11 ++++++++-- .../openadr/mockven/OadrPayloadGenerator.java | 8 +++++++ .../openadr/mockven/OadrPollGenerator.java | 7 +++++++ .../OadrQueryRegistrationGenerator.java | 7 +++++++ .../node/openadr/mockven/PollTrigger.java | 10 +++++++++ .../mockven/SignalNameEnumeratedType.java | 8 +++++++ .../openadr/mockven/TopNodeConnection.java | 16 ++++++++++++-- 9 files changed, 74 insertions(+), 18 deletions(-) diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties index 8c1f8eb80..1c7d1f020 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenDatumDataSource.properties @@ -1,4 +1,8 @@ title = OpenADR Mock Virtual End Node +triggerCronExpression.key = Schedule +triggerCronExpression.desc = A \ + \ + cron expression representing the schedule to sample data at. venName.key = VEN Name venName.desc = The human readable name of the VEN to be given to the VTN venID.key = VEN ID diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenJobService.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenJobService.java index 99a8ff536..d38e573fa 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenJobService.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/MockVenJobService.java @@ -10,8 +10,8 @@ /** * - * I would prefer is this plugin did not have a datum data source however it was - * the easiest way for me to achieve an event in regular intervals + * Setting specifier for the MockVEN it also implements JobService to allow + * periodic polling of the VTN * * @author robert * @version 1.0 @@ -20,7 +20,6 @@ public class MockVenJobService extends DatumDataSourceSupport implements JobService, SettingSpecifierProvider { private String venName; - private String venID; private String vtnAddress; private String vtnName; private MockVen mockVen = null; @@ -56,14 +55,6 @@ public void setVenName(String venName) { this.venName = venName; } - public String getVenID() { - return venID; - } - - public void setVenID(String venID) { - this.venID = venID; - } - public String getVtnAddress() { return vtnAddress; } @@ -80,20 +71,22 @@ public void setVtnName(String vtnName) { this.vtnName = vtnName; } - // I don't understand how to configure in OSGI how to do a job so instead we will be using this to summon the MockVen - //this gets called when requesting a new datum private void runMockVen() { + //create a MockVen instance when we don't have one if ( mockVen == null ) { mockVen = new MockVen(); } + //put the settings into the mock ven mockVen.setVtnURL(vtnAddress); mockVen.setVenName(venName); + + //the poll and respond method will register to the VTN if it is not already registered + //otherwise it will send poll request to the VTN and respond to any events mockVen.pollAndRespond(); } @Override public void executeJobService() throws Exception { - // TODO Auto-generated method stub runMockVen(); } diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java index 9949646ca..d18d8653d 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrParams.java @@ -3,11 +3,18 @@ import openadr.model.v20b.OadrTransportType; -public abstract class OadrParams { +/** + * This abstract class just has a bunch of getters and setters of parameters + * that often go into OadrPayloads. These are used in the generators of the + * various payloads. + * + * @author robert + * @version 1.0 + */ +public class OadrParams { private String venName; - //not sure about these constants private String venID; private String registrationID; private String requestID; diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java index 9ec7e3715..dba933c7d 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPayloadGenerator.java @@ -3,8 +3,16 @@ import java.util.Random; +/** + * Abstract class containing useful functions often used in OadrPayload + * generators + * + * @author robert + * @version 1.0 + */ public abstract class OadrPayloadGenerator { + //returns a hex string 10 characters in length used for generating request IDs public String genRandomRequestID() { Random rand = new Random(); StringBuffer sb = new StringBuffer(); diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java index c211b3960..8e7a5eda2 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrPollGenerator.java @@ -5,6 +5,13 @@ import openadr.model.v20b.OadrPoll; import openadr.model.v20b.OadrSignedObject; +/** + * + * Creates a OadrPayload containing a OadrPoll + * + * @author robert + * @version 1.0 + */ public class OadrPollGenerator extends OadrPayloadGenerator { public OadrPayload createPayload(OadrParams params) { diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java index 442885739..e5713c4df 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/OadrQueryRegistrationGenerator.java @@ -5,6 +5,13 @@ import openadr.model.v20b.OadrQueryRegistration; import openadr.model.v20b.OadrSignedObject; +/** + * + * Creates a OadrPayload with a OadrQueryRegistration + * + * @author solardev + * @version 1.0 + */ public class OadrQueryRegistrationGenerator extends OadrPayloadGenerator { public OadrPayload createPayload(OadrParams params) { diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java index 6343cc5e5..cc682402c 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/PollTrigger.java @@ -4,6 +4,16 @@ import java.util.Date; import org.quartz.impl.triggers.SimpleTriggerImpl; +/** + * + * FIXME + * + * This class currently does not do what I want it to do. I want to be able to + * poll the VTN every 10 seconds. + * + * @author robert + * @version 1.0 + */ public class PollTrigger extends SimpleTriggerImpl { /** diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java index 1841232e8..70d03d95a 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/SignalNameEnumeratedType.java @@ -1,6 +1,14 @@ package net.solarnetwork.node.openadr.mockven; +/** + * + * enum of the OpenADR signal names. perhapes this should be moved into the + * OpenADR package. Followed the design pattern of SignalTypeEnumeratedType + * + * @author robert + * @version 1.0 + */ public enum SignalNameEnumeratedType { SIMPLE("SIMPLE"), simple("simple"), diff --git a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java index 5daf93daa..eb80cd909 100644 --- a/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java +++ b/net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/TopNodeConnection.java @@ -15,6 +15,14 @@ import openadr.model.v20b.OadrPayload; import openadr.model.v20b.ObjectFactory; +/** + * + * Class that handles the connection to the VTN. Supports posting OadrPayloads + * getting the response. + * + * @author robert + * @version 1.0 + */ public class TopNodeConnection { private HttpHeaders headers; @@ -27,7 +35,7 @@ public TopNodeConnection() { rest = new RestTemplate(); headers.setContentType(MediaType.TEXT_XML); - //Require a class loader when using OSGI + //Require a class loader when using OSGI otherwise you get JAXBException //https://stackoverflow.com/a/1043807 ClassLoader cl = ObjectFactory.class.getClassLoader(); try { @@ -41,20 +49,24 @@ public TopNodeConnection() { marshaller = jaxbContext.createMarshaller(); } catch ( JAXBException e ) { + //have no way of recovering from exception. So I turn it into a RuntimeException so I don't have to declare that this class throws and exception throw new RuntimeException(e); } } - //I assume I have to synchronize this method to prevent trying to connect at the same time + //I assume I have to synchronize this method to prevent trying to connect at the same time. Never tested multipal connections. public synchronized OadrPayload postPayload(String url, OadrPayload payload) { StringWriter out = new StringWriter(); try { + //turns the payload into a XML string and writes it to the StringWriter marshaller.marshal(payload, out); + //send the xml to the VTN and get the response ResponseEntity response = rest.postForEntity(url, out.toString(), String.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + //convert the response into a OadrPayload object OadrPayload returnPayload = (OadrPayload) jaxbUnmarshaller .unmarshal(new InputSource(new StringReader(response.getBody()))); From 895ea00f1fe2d3d8d640e00cda43d4b20af8a69a Mon Sep 17 00:00:00 2001 From: SolarNet Developer Date: Thu, 15 Feb 2018 22:52:08 +0000 Subject: [PATCH 11/13] more documentation and fixed localisation after the filename change for the settings specifier --- .../OSGI-INF/blueprint/module.xml | 38 ++++++------- .../node/openadr/mockven/MockVen.java | 53 ++++++++++++++----- ...roperties => MockVenJobService.properties} | 2 + .../openadr/mockven/TopNodeConnection.java | 1 + 4 files changed, 62 insertions(+), 32 deletions(-) rename net.solarnetwork.node.openadr.mockven/src/net/solarnetwork/node/openadr/mockven/{MockVenDatumDataSource.properties => MockVenJobService.properties} (86%) diff --git a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml index 59edae2a8..9598662f4 100644 --- a/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml +++ b/net.solarnetwork.node.openadr.mockven/OSGI-INF/blueprint/module.xml @@ -28,7 +28,7 @@ - + @@ -74,24 +74,24 @@ - - - - - - - net.solarnetwork.node.DatumDataSource - - - - - - - - - - - + + + + + + + + + + + + + + + + + +