Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Market3 #6

Open
wants to merge 65 commits into
base: market3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
bdcfc40
First version of TESS and BESS
shwethanidd Aug 13, 2019
6675ff1
Adding setup.py
shwethanidd Aug 13, 2019
59a557a
Adding AHU participating Chilled Water market
shwethanidd Aug 13, 2019
1baec9e
Reading from config
Aug 13, 2019
3c0466e
BESS and TESS changes and Model class related changes
shwethanidd Oct 2, 2019
fb45519
Adding variable group.py
shwethanidd Oct 2, 2019
043785d
Fixing bess and tess optimization code
shwethanidd Oct 2, 2019
2d1d77c
Moved all the device actuation in transactive base class into separat…
shwethanidd Oct 4, 2019
8b2650e
Merge branch 'develop' of https://github.com/shwethanidd/volttron-GS …
shwethanidd Oct 4, 2019
e00031d
changing to Model
shwethanidd Oct 11, 2019
53bd66f
Updates to Transactive market for market3 type
shwethanidd Oct 18, 2019
031905e
ahu update
shwethanidd Oct 18, 2019
f648748
Store previous minimum and maximum price for use in cleared market an…
Oct 21, 2019
7c4124b
Add lighting schedule for lighting model.
Oct 23, 2019
2a602d9
Modify agent to use previous 24 hour prices for determining Pmin and …
Nov 8, 2019
d896951
Fix last 24 hour prices for first day.
Nov 9, 2019
77536b7
Update for polyline intersection for fixed price (fix) and fixed dema…
Nov 11, 2019
fbc1e75
Regression agent initial commit.
Nov 14, 2019
44b3721
Reworked agent with better code
mwcarlson Dec 19, 2019
ffa9a24
Update E+ and ILC to python3.
Jan 15, 2020
127088c
Latest market changes
shwethanidd Feb 6, 2020
f127174
Initial push for modelica agent.
Feb 19, 2020
bc81228
Typo
Feb 19, 2020
ad63a89
Successful testing with simple PID example model.
Feb 20, 2020
4d6edef
Write .mos file for dymola, update ready for additional testing.
Feb 21, 2020
65c4e95
Modelica and test.
Feb 24, 2020
a229485
Update ModelRegressionAgent.
Mar 7, 2020
714005b
Update ModelRegressionAgent.
Mar 7, 2020
1fb94f7
Model regression automation and agent cleanup.
Mar 11, 2020
5842540
Add simulation time handler.
Mar 11, 2020
8d58b14
Add utils import to __init__.
Mar 13, 2020
e4ad373
fix vav agent import.
Mar 13, 2020
3b80cf7
fix record list subscribe.
Mar 13, 2020
80263a1
Add logging for model validation.
Mar 17, 2020
7a13d2a
Merge branch 'master' of https://github.com/VOLTTRON/volttron-GS
Mar 17, 2020
6d53c3f
Remove print
Mar 18, 2020
c60b50c
VAV model.
Mar 18, 2020
dab7eaa
Add return statement to Model.get_q
Mar 18, 2020
886dcb8
DEBUG statements.
Mar 18, 2020
f790ecb
Fixes from testing.
Mar 18, 2020
db7822c
local bus requires '' for external_plaform not None.
SenHuang19 Mar 20, 2020
8285206
Update TCC for python3.
Mar 20, 2020
38d11b4
Update MixMarketServiceAgent to Python3.
Mar 31, 2020
8ac1be6
Config store for tcc passed initial testing.
Mar 31, 2020
7c52579
fixed merge issues upstream volttron-GS
shwethanidd Apr 3, 2020
121bd87
Standalone TCC.
Apr 7, 2020
7361990
Working on TCC standalone version.?
rlutes May 7, 2020
c20ed3d
Add control for standalone TCC/TESS integration.
May 16, 2020
ca2d831
Merge.
May 16, 2020
e22aca6
Pull tcc out of tess.
Jun 9, 2020
45a573b
add init.
Jun 10, 2020
59a1d39
Remove old subscription.
Jun 10, 2020
1357ec6
Remove import.
Jun 10, 2020
b1aece4
fix publish.
Jun 10, 2020
f6e3c4b
Remove function call.
Jun 10, 2020
ee8b5b9
Change variable name.
Jun 10, 2020
4dde50a
Add check for model being none for tcc (no model), change conflicting…
Jun 10, 2020
992d29e
Move optimization call to offer callback.
Jun 10, 2020
a01167a
Send signal to agents for convergence but do not start mixed market.
Jun 10, 2020
6fbbc91
Debug statements for tcc control
Jun 10, 2020
110f05b
Fix actuation methods.
Jun 10, 2020
df0e70d
fix actuation method.
Jun 10, 2020
e15b56d
fix actuation method.
Jun 10, 2020
df42e36
Fix check_current_schedule.
Jun 10, 2020
109e444
Actuation working and tested.
rlutes Jun 11, 2020
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
14 changes: 7 additions & 7 deletions ILCAgent/ilc/criteria_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def get_score_order(self, state):
if state not in cluster.criteria_labels.keys() or state not in cluster.row_average.keys():
_log.debug("Criteria - Not configured for current state: {}".format(state))
continue

_log.debug("EVAL: {} - {}".format(evaluations.values(), cluster.criteria_labels[state]))
input_arr = input_matrix(evaluations, cluster.criteria_labels[state])
scores = build_score(input_arr, cluster.row_average[state], cluster.priority)
all_scored.extend(scores)
Expand All @@ -154,7 +154,7 @@ def get_device(self, device_name):
# this passes all data coming in to all device criteria
# TODO: rethink this approach. Is there a better way to create the topic map to pass only data needed
def ingest_data(self, time_stamp, data):
for device in self.devices.itervalues():
for device in self.devices.values():
device.ingest_data(time_stamp, data)


Expand Down Expand Up @@ -235,7 +235,7 @@ def numeric_check(self, value):
:param value:
:return:
"""
if not isinstance(value, (int, float, long, numbers.Float, numbers.Integer)):
if not isinstance(value, (int, float, numbers.Float, numbers.Integer)):
if isinstance(value, str):
try:
value = float(value)
Expand Down Expand Up @@ -353,7 +353,7 @@ def fixup_dict_args(self, operation_args):

result = {"always": [], "nc": []}

for key, value in operation_args.iteritems():
for key, value in operation_args.items():
if value != "nc":
result["always"].append(key)
else:
Expand All @@ -367,11 +367,11 @@ def build_ingest_map(self, operation_args):
self.update_points = {}
self.operation_arg_count = 0

for arg_type, arg_list in operation_args.iteritems():
for arg_type, arg_list in operation_args.items():
topic_map, topic_set = create_device_topic_map(arg_list, self.device_topic)
self.device_topic_map.update(topic_map)
self.device_topics |= topic_set
self.update_points[arg_type] = set(topic_map.itervalues())
self.update_points[arg_type] = set(topic_map.values())
self.operation_arg_count += len(topic_map)

def evaluate(self):
Expand All @@ -383,7 +383,7 @@ def evaluate(self):
return value

def ingest_data(self, time_stamp, data):
for topic, point in self.device_topic_map.iteritems():
for topic, point in self.device_topic_map.items():
if topic in data:
if not self.status or point not in self.update_points.get("nc", set()):
value = data[topic]
Expand Down
8 changes: 4 additions & 4 deletions ILCAgent/ilc/curtailment_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def get_devices_status(self, state):
return all_on_devices

def ingest_data(self, time_stamp, data):
for device in self.devices.itervalues():
for device in self.devices.values():
device.ingest_data(time_stamp, data)


Expand All @@ -148,7 +148,7 @@ def __init__(self, logging_topic, parent, device_status_args=[], condition="", d
self.logging_topic = logging_topic

def ingest_data(self, time_stamp, data):
for topic, point in self.device_topic_map.iteritems():
for topic, point in self.device_topic_map.items():
if topic in data:
self.current_device_values[point] = data[topic]
_log.debug("DEVICE_STATUS: {} - {} current device values: {}".format(topic,
Expand Down Expand Up @@ -251,7 +251,7 @@ def __init__(self, device_config, logging_topic, parent, default_device=""):
self.device_topics |= controls.device_topics

def ingest_data(self, time_stamp, data):
for control in self.controls.itervalues():
for control in self.controls.values():
control.ingest_data(time_stamp, data)

def get_control_info(self, device_id, state):
Expand Down Expand Up @@ -395,7 +395,7 @@ def check_condition(self):
return value

def ingest_data(self, time_stamp, data):
for topic, point in self.device_topic_map.iteritems():
for topic, point in self.device_topic_map.items():
if topic in data:
self.current_device_values[point] = data[topic]

Expand Down
20 changes: 9 additions & 11 deletions ILCAgent/ilc/ilc_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ def calculate_average_power(self, current_power, current_time):
power_sort.sort(reverse=True)
exp_power = 0

for n in xrange(len(self.bldg_power)):
for n in range(len(self.bldg_power)):
exp_power += power_sort[n][1] * smoothing_constant * (1.0 - smoothing_constant) ** n

exp_power += power_sort[-1][1] * (1.0 - smoothing_constant) ** (len(self.bldg_power))
Expand Down Expand Up @@ -763,9 +763,6 @@ def load_message_handler(self, peer, sender, bus, topic, headers, message):
# TODO: Refactor this code block. Disparate code paths for simulation and real devices is undesireable
if self.sim_running:
gevent.sleep(0.25)
while self.sim_time >= 15:
_log.debug("HOLDING {}".format(self.sim_time))
gevent.sleep(1)
self.vip.pubsub.publish("pubsub", "applications/ilc/advance", headers={}, message={})

def check_load(self):
Expand All @@ -779,10 +776,10 @@ def check_load(self):

if self.demand_limit is not None:
if self.avg_power > self.demand_limit + self.demand_threshold:
result = "Current load of {} kW exceeds demand limit of {} kW.".format(self.avg_power, self.demand_limit)
result = "Current load of {} kW exceeds demand limit of {} kW.".format(self.avg_power, self.demand_limit+self.demand_threshold)
self.curtail_load()
if self.avg_power < self.demand_limit - self.demand_threshold:
result = "Current load of {} kW is below demand limit of {} kW.".format(self.avg_power, self.demand_limit)
elif self.avg_power < self.demand_limit - self.demand_threshold:
result = "Current load of {} kW is below demand limit of {} kW.".format(self.avg_power, self.demand_limit-self.demand_threshold)
self.augment_load()
else:
result = "Current load of {} kW meets demand goal of {} kW.".format(self.avg_power, self.demand_limit)
Expand Down Expand Up @@ -952,10 +949,11 @@ def determine_curtail_parms(self, control, device_dict):
control_load = 0.0
break
load_point_values.append((load_arg[0], value))
try:
control_load = float(load_equation.subs(load_point_values))
except:
_log.debug("Could not convert expression for load estimation: ")
#try:
_log.debug("LOAD_EQUATION: {} - {} - {}".format(point_to_get, load_equation, load_point_values))
control_load = float(load_equation.subs(load_point_values))
#except:
# _log.debug("Could not convert expression for load estimation: ")

try:
revert_value = self.vip.rpc.call(device_actuator, "get_point", control_pt).get(timeout=30)
Expand Down
3 changes: 2 additions & 1 deletion ILCAgent/ilc/ilc_matrices.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import math
from volttron.platform.agent import utils
from collections import defaultdict
from functools import reduce

utils.setup_logging()
_log = logging.getLogger(__name__)
Expand Down Expand Up @@ -238,7 +239,7 @@ def input_matrix(builder, criteria_labels):
"""
sum_mat = defaultdict(float)
inp_mat = {}
label_check = builder.values()[-1].keys()
label_check = list(list(builder.values())[-1].keys())
if set(label_check) != set(criteria_labels):
raise Exception('Input criteria and data criteria do not match.')
for device_data in builder.values():
Expand Down
2 changes: 1 addition & 1 deletion ILCAgent/ilc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@


def clean_text(text, rep={" ": ""}):
rep = dict((re.escape(k), v) for k, v in rep.iteritems())
rep = dict((re.escape(k), v) for k, v in rep.items())
pattern = re.compile("|".join(rep.keys()))
new_key = pattern.sub(lambda m: rep[re.escape(m.group(0))], text)
return new_key
Expand Down
28 changes: 20 additions & 8 deletions MarketAgents/AHUAgent/ahu/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
from volttron.platform.agent.base_market_agent.poly_line import PolyLine
from volttron.platform.agent.base_market_agent.point import Point

from volttron.pnnl.models.ahuchiller import AHUChiller
from volttron.pnnl.models import Model

# from pnnl.models.firstorderzone import FirstOrderZone

Expand All @@ -72,31 +72,43 @@
__version__ = "0.2"


class AHUAgent(Aggregator, AHUChiller):
# https://stash.pnnl.gov/users/ngoh511/repos/transactivecontrol/raw/MarketAgents/AHUAgent/ahu/agent.py?at=refs%2Fheads%2Fahu_chiller_split


class AHUAgent(Aggregator, Model):
"""
The SampleElectricMeterAgent serves as a sample of an electric meter that
sells electricity for a single building at a fixed price.
The AHUAgent participates in 3 markets:
1. Electricity Market: Consumer of electricity
2. Air Market: Supplier of air
3. Chilled Water Market: Consumer of chilled water
"""

def __init__(self, config_path, **kwargs):
try:
config = utils.load_config(config_path)
except StandardError:
except Exception.StandardError:
config = {}
model_config = config.get("model_parameters")
self.agent_name = config.get("agent_name", "ahu")
Aggregator.__init__(self, config, **kwargs)
AHUChiller.__init__(self, model_config, **kwargs)
Model.__init__(self, model_config, **kwargs)

self.init_markets()

def translate_aggregate_demand(self, air_demand, index):
electric_demand_curve = PolyLine()
coil_load_demand_curve = PolyLine()
oat = self.oat_predictions[index] if self.oat_predictions else None
for point in air_demand.points:
electric_demand_curve.add(Point(price=point.y, quantity=self.model.calculate_load(point.x, oat)))
_log.debug("{}: electric demand : {}".format(self.agent_name, electric_demand_curve.points))
#electric_demand_curve.add(Point(price=point.y, quantity=self.model.calculate_load(point.x, oat)))
self.model.input_zone_load(point.x)
electric_demand_curve.add(Point(price=point.y, quantity=self.model.calculate_electric_load()))
coil_load_demand_curve.add(Point(price=point.y, quantity=self.model.calculate_coil_load(oat)))

# Hard-coding the market names is not ideal. Need to come up with more robust solution
self.consumer_demand_curve["electric"][index] = electric_demand_curve
self.consumer_demand_curve["chilled_water"][index] = coil_load_demand_curve



def main():
Expand Down
2 changes: 1 addition & 1 deletion MarketAgents/AHUAgent/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

# Find the version number from the main module
agent_module = agent_package + '.' + MAIN_MODULE
_temp = __import__(agent_module, globals(), locals(), ['__version__'], -1)
_temp = __import__(agent_module, globals(), locals(), ['__version__'], 0)
__version__ = _temp.__version__

# Setup
Expand Down
Empty file.
Loading