Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="build/eclipse"/>
</classpath>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build
/target
28 changes: 28 additions & 0 deletions net.solarnetwork.node.demandresponse.dresimplestrategy/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>net.solarnetwork.node.demandresponse.dresimplestrategy</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
eclipse.preferences.version=1
pluginProject.equinox=false
pluginProject.extensions=false
resolve.requirebundle=false
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Mimumum DR Engine
Bundle-SymbolicName: net.solarnetwork.node.demandresponse.dresimplestrategy
Bundle-Version: 1.0.0
Bundle-Vendor: SolarNetwork
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: build.eclipse.net.solarnetwork.node.demandresponse.dretargetcost,
net.solarnetwork.node;version="1.23.0",
net.solarnetwork.node.dao;version="1.8.0",
net.solarnetwork.node.demandresponse.dretargetcost,
net.solarnetwork.node.domain;version="1.11.0",
net.solarnetwork.node.job;version="1.13.4",
net.solarnetwork.node.reactor;version="1.3.0",
net.solarnetwork.node.reactor.support;version="1.3.0",
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.test;version="1.3.0",
net.solarnetwork.node.util;version="1.7.2",
net.solarnetwork.util;version="1.28.0",
org.junit;version="[4.12.0,5.0.0)",
org.junit.runner;version="[4.12.0,5.0.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;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.scheduling.quartz;version="[4.2.9.RELEASE,5.0.0)"
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ctx="http://www.springframework.org/schema/context"
xmlns:osgix="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">

<reference-list id="feedbackInstructionHandlers"
availability="optional"
interface="net.solarnetwork.node.reactor.FeedbackInstructionHandler" />

<!-- provides access to local database storage for our datum -->
<bean id="generalNodeDatumDao" class="net.solarnetwork.util.DynamicServiceTracker">
<property name="bundleContext" ref="bundleContext" />
<property name="serviceClassName" value="net.solarnetwork.node.dao.DatumDao" />
<property name="serviceFilter"
value="(datumClassName=net.solarnetwork.node.domain.GeneralNodeDatum)" />
</bean>

<!-- support localized strings for the settings in the GUI -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames"
value="net.solarnetwork.node.demandresponse.dresimplestrategy.DRESimpleStrategyDatumDataSource" />
</bean>

<!-- support localized strings for the periodic job settings in the GUI -->
<bean id="jobMessageSource" class="net.solarnetwork.node.util.PrefixedMessageSource">
<property name="prefix" value="datumDataSource." />
<property name="delegate" ref="messageSource" />
</bean>

<bean id="eventAdmin" class="net.solarnetwork.util.DynamicServiceTracker">
<property name="bundleContext" ref="bundleContext" />
<property name="serviceClassName" value="org.osgi.service.event.EventAdmin" />
</bean>

<!-- publish a "component factory" so our Foobar Inverter appears in the
settings GUI -->
<service
interface="net.solarnetwork.node.settings.SettingSpecifierProviderFactory">
<bean
class="net.solarnetwork.node.settings.support.BasicSettingSpecifierProviderFactory">
<property name="displayName" value="Min DR Engine" />
<property name="factoryUID"
value="net.solarnetwork.node.demandresponse.dresimplestrategy" />
<property name="messageSource" ref="messageSource" />
</bean>
</service>

<!-- publish a "service factory" that each Foobar Inverter component instance
can be configured in the GUI, along with a periodic job to collect datum
from it -->
<osgix:managed-service-factory
factory-pid="net.solarnetwork.node.demandresponse.dresimplestrategy"
autowire-on-update="true">
<osgix:interfaces>
<beans:value>net.solarnetwork.node.job.ManagedTriggerAndJobDetail</beans:value>
<beans:value>net.solarnetwork.node.job.ServiceProvider</beans:value>
<beans:value>net.solarnetwork.node.settings.SettingSpecifierProvider</beans:value>
</osgix:interfaces>
<osgix:service-properties>
<beans:entry key="settingPid"
value="net.solarnetwork.node.demandresponse.dresimplestrategy" />
</osgix:service-properties>
<bean class="net.solarnetwork.node.job.SimpleManagedTriggerAndJobDetail">

<!-- the trigger defines when the periodic job runs; in this case we define
a cron style trigger, that by default runs once/minute -->
<property name="trigger">
<bean class="net.solarnetwork.node.job.RandomizedCronTriggerFactoryBean">
<property name="name" value="dPowerDatumLoggerTrigger" />
<property name="cronExpression" value="5 * * * * ?" />
<property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_DO_NOTHING" />
<property name="randomSecond" value="true" />
</bean>
</property>

<!-- we can also publish the FoobarDatumDataSource instance itself as
a service by configuring serviceProviderConfigurations here... this is optional
but generally a good idea -->
<property name="serviceProviderConfigurations">
<map>
<entry key="datumDataSource">
<bean
class="net.solarnetwork.node.job.SimpleServiceProviderConfiguration">
<property name="interfaces">
<list>
<value>net.solarnetwork.node.DatumDataSource</value>
</list>
</property>
<property name="properties">
<map>
<entry key="datumClassName" value="net.solarnetwork.node.domain.EnergyDatum" />
</map>
</property>
</bean>
</entry>
</map>
</property>

<!-- the jobDetail defines what job should be executed periodically by
the trigger; here we define a net.solarnetwork.node.job.DatumDataSourceManagedLoggerJob
job which will invoke the readCurrentDatum() method on a DatumDataSource,
which is what FoobarDatumDataSource is! -->
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="name" value="drbatteryPowerDatumLoggerJob" />
<property name="jobClass"
value="net.solarnetwork.node.job.DatumDataSourceManagedLoggerJob" />
<property name="jobDataAsMap">
<map>
<entry key="datumDao" value-ref="generalNodeDatumDao" />
<entry key="datumDataSource">
<bean
class="net.solarnetwork.node.demandresponse.dresimplestrategy.DRESimpleStrategyDatumDataSource">
<property name="linkedInstance">
<bean
class="net.solarnetwork.node.demandresponse.dresimplestrategy.DRESimpleStrategy">
<property name="feedbackInstructionHandlers" ref="feedbackInstructionHandlers" />
</bean>
</property>
<property name="messageSource" ref="messageSource" />
</bean>
</entry>



</map>
</property>
</bean>
</property>
</bean>
</osgix:managed-service-factory>

</blueprint>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source.. = src/
output.. = build/eclipse/
bin.includes = META-INF/,\
.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package net.solarnetwork.node.demandresponse.dresimplestrategy;

import java.util.Collection;
import java.util.Date;
import java.util.Map;

import net.solarnetwork.node.demandresponse.dretargetcost.DRSupportTools;
import net.solarnetwork.node.reactor.FeedbackInstructionHandler;
import net.solarnetwork.node.reactor.Instruction;
import net.solarnetwork.node.reactor.InstructionHandler;
import net.solarnetwork.node.reactor.support.BasicInstruction;

/**
* Expirimental class looking into how a demand responce system my look like.
* Method names and API use will probably change in refactoring into a propper
* implementation.
*
*
* This class is very simple it turns off as many devices as it can and controls
* batterys via a mode textbox
*
*
* @author robert
*
*/
public class DRESimpleStrategy {
private DRESimpleStrategyDatumDataSource settings;
private Collection<FeedbackInstructionHandler> feedbackInstructionHandlers;

// status variables for the datum source
private Integer numdrdevices = 0;

public DRESimpleStrategyDatumDataSource getSettings() {
return settings;
}

// configured in OSGI
public void setSettings(DRESimpleStrategyDatumDataSource settings) {
this.settings = settings;

}

protected void drupdate() {
numdrdevices = 0;
for (FeedbackInstructionHandler handler : feedbackInstructionHandlers) {
if (handler.handlesTopic(DRSupportTools.DRPARAMS_INSTRUCTION)) {

BasicInstruction instr = new BasicInstruction(DRSupportTools.DRPARAMS_INSTRUCTION, new Date(),
Instruction.LOCAL_INSTRUCTION_ID, Instruction.LOCAL_INSTRUCTION_ID, null);

// The devices want to know where the instruction came from for
// verification
instr.addParameter(settings.getUID(), "");

Map<String, ?> params = handler.processInstructionWithFeedback(instr).getResultParameters();
if (DRSupportTools.isDRCapable(params)) {
numdrdevices++;
Integer watts = DRSupportTools.readWatts(params);
Integer minwatts = DRSupportTools.readMinWatts(params);
Integer maxwatts = DRSupportTools.readMaxWatts(params);
if (DRSupportTools.isChargeable(params)) {
String mode = settings.getBatteryMode();
if (mode.equalsIgnoreCase("DISCHARGE")) {
// Tell the battery to discharge as much as it can
sendDRtoBattery(true, handler, maxwatts);
} else if (mode.equalsIgnoreCase("CHARGE")) {
// Tell the battery to charge as much as it can. For
// that we need the max charging watts param
sendDRtoBattery(false, handler, DRSupportTools.readMaxChargingWatts(params));
} else {
// Assume idle tell battery to not discharge and set
// draw to 0 watts
// it should be the case for batterys to have
// minwatts at 0 but check anyways
if (minwatts.equals(0)) {
sendDRtoBattery(false, handler, 0);
}
}
} else if (watts > minwatts) {
Integer shedamount = watts - minwatts;
// in this strategy we just lower power of all devices
// as much as we can
instr = new BasicInstruction(InstructionHandler.TOPIC_SHED_LOAD, new Date(),
Instruction.LOCAL_INSTRUCTION_ID, Instruction.LOCAL_INSTRUCTION_ID, null);

instr.addParameter(settings.getUID(), shedamount.toString());
handler.processInstruction(instr);
}
}
}
}

}

private void sendDRtoBattery(Boolean discharge, FeedbackInstructionHandler handler, Integer wattValue) {
BasicInstruction instr = new BasicInstruction(InstructionHandler.TOPIC_SET_CONTROL_PARAMETER, new Date(),
Instruction.LOCAL_INSTRUCTION_ID, Instruction.LOCAL_INSTRUCTION_ID, null);
instr.addParameter(settings.getUID(), "");
instr.addParameter(DRSupportTools.WATTS_PARAM, wattValue.toString());
instr.addParameter(DRSupportTools.DISCHARGING_PARAM, discharge.toString());
handler.processInstruction(instr);
}

public Collection<FeedbackInstructionHandler> getFeedbackInstructionHandlers() {
return feedbackInstructionHandlers;
}

// configured in OSGI
public void setFeedbackInstructionHandlers(Collection<FeedbackInstructionHandler> feedbackInstructionHandlers) {
this.feedbackInstructionHandlers = feedbackInstructionHandlers;
}

public Integer getNumdrdevices() {
return numdrdevices;
}
}
Loading