Reading and writing data#
Input variables#
A components in a scenario can be configured with input variables, which are configured either with a reference to an input scenario, or with a simple static value.
with JobClient.connect() as job:
my_component = job.scenario.components["my_component"]
input_variable = my_component.input_variables["my_input_variable"]
...
Reading data from inputs#
All input variables in the scenario can be read using
read_inputs(), which returns an iterable that
returns tuples of time values and dictionaries of the data read. At the same time,
value is also updated.
The row dictionaries returned by the iterable, are keyed by the dotted path of the input variable, which are the .-separated component names, and finally the input variable id.
with JobClient.connect() as job:
result = 0.0
for t, data in job.read_inputs(step=3600.0):
my_variable_value = data["my_component_name.my_variable_id"]
another_variable_value = data["another_component_name.another_variable_id"]
result += my_variable_value / 2 + another_variable_value / 2
And using input variables it could be done like this:
with JobClient.connect() as job:
my_component = job.scenario.components["my_component"]
input_variable = my_component.input_variables["my_input_variable"]
result = 0.0
for t, _ in job.read_inputs(step=3600.0):
result += input_variable.value
Reading data from the current scenario#
Sometimes reading data from the current scenario is useful, especially for auxillary jobs that are made to generate reports from the data written by another job (e.g. a simulation).
It is possible with the reader’s methods
range() (for reading a simple range of data),
and data_frame() for reading data into a
pandas.DataFrame object.
Note
Using data_frame() requires pandas
to be installed separately.
with JobClient.connect() as job:
all_data = list(job.reader.range())
data_frame = job.reader.data_frame()
Writing a timeseries of data#
Writing data is quite simple. You can use either
series() and write a whole series of data in
one line, or you can use row() to write a
single row of data. You can also combine the two, but it is important that the time
value is always increasing, and is consistent.
Internally the data is buffered, and only actually uploaded once in a while to improve performance.
with JobClient.connect() as job:
job.writer.row(
job.time.start + timedelta(hours=1), {"tag1": 10.0, "tag2": 1.0}
)
job.writer.series(
[job.time.start + timedelta(hours=h) for h in [2, 3, 4, 5]],
{
"tag1": [20.0, 30.0, 40.0, 50.0],
"tag2": [1.3, 0.8, 10.0, -10.0]
}
)
job.writer.row(
job.time.start + timedelta(hours=6), {"tag1": 60.0, "tag2": -11.0}
)
And instead of manually managing the time values, you can also iterate over
range(), to get all valid time values within
the job runtime.
with JobClient.connect() as job:
for t in job.time.range(step=timedelta(hour=1)):
job.writer.row(t, {"tag1": compute_tag_1(t), "tag2": compute_tag_2(t)})
Combining reading and writing#
Conveniently, it is possible to combine the reading and writing functions, so that it is easy to read data, transform it, and output the transformed values:
with JobClient.connect() as job:
for t, data in job.read_inputs(step=3600.0):
my_variable_value = data["my_component_name.my_variable_id"]
job.writer.row(t, {"with_added_noise": my_variable_value + random.random()})