Open Awii0709 opened 9 months ago
Hi @Awii0709,
The data for offline training are generated by follows:
import opendssdirect as dss
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from tqdm import tqdm
from env_123_utils import load_base, load_node
from collections import OrderedDict
# the reference of this code is at:
# https://dss-extensions.org/OpenDSSDirect.py/index.html
# load circuit model
dss.run_command('Redirect IEEE_123dss/IEEE123Master.dss')
dss.run_command('Set Controlmode=STATIC')
all_transformer_names = dss.Transformers.AllNames()
all_regulator_names = dss.RegControls.AllNames()
all_capacitor_names = dss.Capacitors.AllNames()
print('Num of LTC: {}'.format(len(all_regulator_names)))
print('Num of CAP: {}'.format(len(all_capacitor_names)))
# load london dataset
skip_first = 0 # ignoring rows which contain too many nan's
df = pd.read_csv('../data/processed/first_2897_ami_aggto_580.csv', index_col=0)
df = df.iloc[skip_first:, :]
df = df / (df.mean() * 1.0) # normalize each column
# plt.figure(1)
# for i, k in enumerate(load_base.keys()):
# plt.plot(df.iloc[:2000, i].to_numpy(), label=k)
# plt.legend()
# plt.grid()
# plt.title('normalized profile')
volt_all = []
load_all = []
tap_all = []
status_all = []
load_mode = 'I'
model = {'PQ': 1,
'Z': 2,
'I': 5}
def tappu_to_tap(tap_pu):
pu_per_ltc_tap = 5 / 8 / 100
tap = (tap_pu - 1.0) / pu_per_ltc_tap + 16
return tap
for t in tqdm(range(df.shape[0])):
# change some load
# hint: https://githubmemory.com/repo/dss-extensions/OpenDSSDirect.py/issues/86
load_kw = [val[0] * df.iloc[t, i] for i, (key, val) in enumerate(load_base.items())]
load_kvar = [val[1] * df.iloc[t, i] for i, (key, val) in enumerate(load_base.items())]
for i, (key, val) in enumerate(load_base.items()):
dss.run_command('Load.{}.kW={}'.format(key, load_kw[i]))
for i, (key, val) in enumerate(load_base.items()):
dss.run_command('Load.{}.kvar={}'.format(key, load_kvar[i]))
# solve power flow and get results
dss.Solution.Solve()
converged = dss.Solution.Converged()
if not converged:
print('Non-converging power flow')
break
# network loss
ll = dss.Circuit.Losses()
# get voltage magnitude by bus name:
# ref.1: https://sourceforge.net/p/electricdss/discussion/861977/thread/a53badb5/
# ref.2: https://github.com/dss-extensions/OpenDSSDirect.py/issues/15
v_all = []
for bus in load_node.keys():
dss.Circuit.SetActiveBus(bus)
# https: // github.com / dss - extensions / OpenDSSDirect.py / blob / master / opendssdirect / Bus.py
v_mag_angle = dss.Bus.puVmagAngle()
# (read-only) Array of doubles containing voltage magnitude, angle pairs in per unit
v = v_mag_angle[::2]
if load_node[bus]:
for i in range(len(load_node[bus])):
v_all.append(v[i])
else:
v_all.append(v[0])
# LTC taps in per unit
tap = []
dss.Transformers.First() # activate the first transformer
dss.Transformers.Next() # our LTC starts from the second one
tap_pu = dss.Transformers.Tap()
tap.append(tappu_to_tap(tap_pu))
dss.Transformers.Next() # our LTC starts from the second one
tap_pu = dss.Transformers.Tap()
tap.append(tappu_to_tap(tap_pu))
dss.Transformers.Next() # our LTC starts from the second one
tap_pu = dss.Transformers.Tap()
tap.append(tappu_to_tap(tap_pu))
dss.Transformers.Next() # our LTC starts from the second one
tap_pu = dss.Transformers.Tap()
tap.append(tappu_to_tap(tap_pu))
dss.Transformers.Next() # our LTC starts from the second one
tap_pu = dss.Transformers.Tap()
tap.append(tappu_to_tap(tap_pu))
# capacitor status
dss.Capacitors.First()
cap1_state = dss.Capacitors.States()
dss.Capacitors.Next()
cap2_state = dss.Capacitors.States()
dss.Capacitors.Next()
cap3_state = dss.Capacitors.States()
dss.Capacitors.Next()
cap4_state = dss.Capacitors.States()
volt_all.append(np.around(np.array(v_all) * 120.0, decimals=1))
load_all.append(np.around(np.array(load_kw + load_kvar), decimals=1))
tap_all.append(np.array(tap).astype(int))
status_all.append(np.array(cap1_state + cap2_state + cap3_state + cap4_state).astype(int))
volt_all = np.array(volt_all)
load_all = np.array(load_all)
tap_all = np.array(tap_all)
status_all = np.array(status_all)
np.savetxt('../data/processed/IEEE_123/volt.csv', volt_all, delimiter=",")
np.savetxt('../data/processed/IEEE_123/load.csv', load_all, delimiter=",")
np.savetxt('../data/processed/IEEE_123/tap.csv', tap_all, delimiter=",")
np.savetxt('../data/processed/IEEE_123/status.csv', status_all, delimiter=",")
np.savetxt('../data/processed/IEEE_123/timestamp.csv', np.arange(df.shape[0])[:, None], delimiter=",")
and env_123_utils
:
from collections import OrderedDict
# load_base: key=name of load object in the dss script
# value=(kw, k-var)
# the actual load in each timestamp will be load_base multiplied by the scaled London AMI data-set
load_base = OrderedDict([
('S1a', (40.0, 20.0)), #load name: (kw, k-var)
('S2b', (20.0, 10.0)),
('S4c', (40.0, 20.0)),
('S5c', (20.0, 10.0)),
('S6c', (40.0, 20.0)),
('S7a', (20.0, 10.0)),
('S9a', (40.0, 20.0)),
('S10a', (20.0, 10.0)),
('S11a', (40.0, 20.0)),
('S12b', (20.0, 10.0)),
('S16c', (40.0, 20.0)),
('S17c', (20.0, 10.0)),
('S19a', (40.0, 20.0)),
('S20a', (40.0, 20.0)),
('S22b', (40.0, 20.0)),
('S24c', (40.0, 20.0)),
('S28a', (40.0, 20.0)),
('S29a', (40.0, 20.0)),
('S30c', (40.0, 20.0)),
('S31c', (20.0, 10.0)),
('S32c', (20.0, 10.0)),
('S33a', (40.0, 20.0)),
('S34c', (40.0, 20.0)),
('S35a', (40.0, 20.0)),
('S37a', (40.0, 20.0)),
('S38b', (20.0, 10.0)),
('S39b', (20.0, 10.0)),
('S41c', (20.0, 10.0)),
('S42a', (20.0, 10.0)),
('S43b', (40.0, 20.0)),
('S45a', (20.0, 10.0)),
('S46a', (20.0, 10.0)),
('S47', (105.0, 75.0)),
('S48', (210.0, 150.0)),
('S49a', (35.0, 25.0)),
('S49b', (70.0, 50.0)),
('S49c', (35.0, 20.0)),
('S50c', (40.0, 20.0)),
('S51a', (20.0, 10.0)),
('S52a', (40.0, 20.0)),
('S53a', (40.0, 20.0)),
('S55a', (20.0, 10.0)),
('S56b', (20.0, 10.0)),
('S58b', (20.0, 10.0)),
('S59b', (20.0, 10.0)),
('S60a', (20.0, 10.0)),
('S62c', (40.0, 20.0)),
('S63a', (40.0, 20.0)),
('S64b', (75.0, 35.0)),
('S65a', (35.0, 25.0)),
('S65b', (35.0, 25.0)),
('S65c', (70.0, 50.0)),
('S66c', (75.0, 35.0)),
('S68a', (20.0, 10.0)),
('S69a', (40.0, 20.0)),
('S70a', (20.0, 10.0)),
('S71a', (40.0, 20.0)),
('S73c', (40.0, 20.0)),
('S74c', (40.0, 20.0)),
('S75c', (40.0, 20.0)),
('S76a', (105.0, 80.0)),
('S76b', (70.0, 50.0)),
('S76c', (70.0, 50.0)),
('S77b', (40.0, 20.0)),
('S79a', (40.0, 20.0)),
('S80b', (40.0, 20.0)),
('S82a', (40.0, 20.0)),
('S83c', (20.0, 10.0)),
('S84c', (20.0, 10.0)),
('S85c', (40.0, 20.0)),
('S86b', (20.0, 10.0)),
('S87b', (40.0, 20.0)),
('S88a', (40.0, 20.0)),
('S90b', (40.0, 20.0)),
('S92c', (40.0, 20.0)),
('S94a', (40.0, 20.0)),
('S95b', (20.0, 10.0)),
('S96b', (20.0, 10.0)),
('S98a', (40.0, 20.0)),
('S99b', (40.0, 20.0)),
('S100c', (40.0, 20.0)),
('S102c', (20.0, 10.0)),
('S103c', (40.0, 20.0)),
('S104c', (40.0, 20.0)),
('S106b', (40.0, 20.0)),
('S107b', (40.0, 20.0)),
('S109a', (40.0, 20.0)),
('S111a', (20.0, 10.0)),
('S112a', (20.0, 10.0)),
('S113a', (40.0, 20.0)),
('S114a', (20.0, 10.0)),
])
# load_node: key=name of load object in the dss script
# value= phases of the load. Must be in the order (a,b,c)
load_node = OrderedDict([
('1', 'a'), # (kw, k-var)
('2', 'b'),
('4', 'c'),
('5', 'c'),
('6', 'c'),
('7', 'a'),
('9', 'a'),
('10', 'a'),
('11', 'a'),
('12', 'b'),
('16', 'c'),
('17', 'c'),
('19', 'a'),
('20', 'a'),
('22', 'b'),
('24', 'c'),
('28', 'a'),
('29', 'a'),
('30', 'c'),
('31', 'c'),
('32', 'c'),
('33', 'a'),
('34', 'c'),
('35', 'a'),
('37', 'a'),
('38', 'b'),
('39', 'b'),
('41', 'c'),
('42', 'a'),
('43', 'b'),
('45', 'a'),
('46', 'a'),
('47', ''),
('48', ''),
('49', 'a'),
('49', 'b'),
('49', 'c'),
('50', 'c'),
('51', 'a'),
('52', 'a'),
('53', 'a'),
('55', 'a'),
('56', 'b'),
('58', 'b'),
('59', 'b'),
('60', 'a'),
('62', 'c'),
('63', 'a'),
('64', 'b'),
('65', 'a'),
('65', 'b'),
('65', 'c'),
('66', 'c'),
('68', 'a'),
('69', 'a'),
('70', 'a'),
('71', 'a'),
('73', 'c'),
('74', 'c'),
('75', 'c'),
('76', 'a'),
('76', 'b'),
('76', 'c'),
('77', 'b'),
('79', 'a'),
('80', 'b'),
('82', 'a'),
('83', 'c'),
('84', 'c'),
('85', 'c'),
('86', 'b'),
('87', 'b'),
('88', 'a'),
('90', 'b'),
('92', 'c'),
('94', 'a'),
('95', 'b'),
('96', 'b'),
('98', 'a'),
('99', 'b'),
('100', 'c'),
('102', 'c'),
('103', 'c'),
('104', 'c'),
('106', 'b'),
('107', 'b'),
('109', 'a'),
('111', 'a'),
('112', 'a'),
('113', 'a'),
('114', 'a'),
])
Dear @yg-smile,
Can you describe how you generated data for offline training. It would be much appreciated if you could share how you solved the opendss script for offline training with relevant modes.
Thank you.