Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/output/aggregateBatteryOutput.py
169674 views
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
4
# Copyright (C) 2008-2025 German Aerospace Center (DLR) and others.
5
# This program and the accompanying materials are made available under the
6
# terms of the Eclipse Public License 2.0 which is available at
7
# https://www.eclipse.org/legal/epl-2.0/
8
# This Source Code may also be made available under the following Secondary
9
# Licenses when the conditions for such availability set forth in the Eclipse
10
# Public License 2.0 are satisfied: GNU General Public License, version 2
11
# or later which is available at
12
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
13
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
14
15
# @file aggregateBatteryOutput.py
16
# @author Pablo Alvarez Lopez
17
# @date 2022-04-25
18
19
import os
20
import sys
21
from collections import OrderedDict
22
if "SUMO_HOME" in os.environ:
23
sys.path += [os.path.join(os.environ["SUMO_HOME"], "tools")]
24
import sumolib # noqa
25
26
27
def parseTimeSteps(inputFile):
28
# create matrix for result
29
result = {}
30
# iterate over timeSteps
31
for timeStep in sumolib.xml.parse(inputFile, 'timestep'):
32
timestepFloat = float(timeStep.time)
33
# create substructure
34
result[timestepFloat] = {}
35
for vehicle in timeStep.vehicle or []:
36
# add vehicle
37
result[timestepFloat][vehicle.id] = {}
38
# add vehicle values
39
result[timestepFloat][vehicle.id]["energyConsumed"] = float(vehicle.energyConsumed)
40
result[timestepFloat][vehicle.id]["totalEnergyConsumed"] = float(vehicle.totalEnergyConsumed)
41
result[timestepFloat][vehicle.id]["totalEnergyRegenerated"] = float(vehicle.totalEnergyRegenerated)
42
result[timestepFloat][vehicle.id]["energyChargedInTransit"] = float(vehicle.energyChargedInTransit)
43
result[timestepFloat][vehicle.id]["energyChargedStopped"] = float(vehicle.energyChargedStopped)
44
result[timestepFloat][vehicle.id]["timeStopped"] = float(vehicle.timeStopped)
45
# return result
46
return result
47
48
49
def writeTimeSteps(result, outputFile):
50
with open(outputFile, "w") as f:
51
sumolib.xml.writeHeader(f)
52
f.write("<battery-export>\n")
53
Step = sumolib.xml.compound_object('timestep', ['interval'])
54
for timeStep in result:
55
# create ET subElement (node) for timeStep
56
step = Step([str(timeStep[0]) + "-" + str(timeStep[1])])
57
# iterate over timeStep's vehicles
58
for vehicleID in timeStep[2]:
59
vehicleAttributes = timeStep[2][vehicleID]
60
attrs = ("energyConsumed", "totalEnergyConsumed", "totalEnergyRegenerated",
61
"energyChargedInTransit", "energyChargedStopped", "timeStopped", "aggregateNumber")
62
attrValues = OrderedDict([("id", vehicleID)] + [(a, str(vehicleAttributes[a])) for a in attrs])
63
# create ET sub element (node) for vehicle
64
step.addChild('vehicle', attrValues, sortAttrs=False)
65
# write Output
66
f.write(step.toXML(" "))
67
f.write("</battery-export>\n")
68
69
70
def processMatrix(matrix, timeToSplit):
71
# create matrix for result
72
result = []
73
# get last
74
lastValue = int(list(matrix.keys())[-1])
75
# fill timesteps
76
for timeStep in range(0, lastValue, timeToSplit):
77
# check if this is the last interval
78
if ((timeStep + timeToSplit - 1) > lastValue):
79
result.append([timeStep, lastValue, {}])
80
else:
81
result.append([timeStep, timeStep + timeToSplit - 1, {}])
82
# declare timeStep counter
83
timeStepCounter = 0
84
# now copy values from matrix to result
85
for timeStep in matrix:
86
# check if update counter
87
if (result[timeStepCounter][1] < timeStep):
88
timeStepCounter += 1
89
# copy vehicle information
90
for vehicleID in matrix[timeStep]:
91
# get vehicle from Matrix
92
vehicleMatrix = matrix[timeStep][vehicleID]
93
# declare flag for find
94
found = False
95
# iterate over all vehicle IDs that there is already in result
96
for vehicleIDResult in result[timeStepCounter][2]:
97
# check if was already inserted and we have only to update
98
if ((vehicleIDResult == vehicleID) and not found):
99
# get vehicle from Result
100
vehicleResult = result[timeStepCounter][2][vehicleIDResult]
101
# declare new vehicle attributes
102
newVehicleAttributes = {}
103
# update vehicle attributes
104
newVehicleAttributes["energyConsumed"] = float(
105
vehicleResult["energyConsumed"]) + float(vehicleMatrix["energyConsumed"])
106
newVehicleAttributes["totalEnergyConsumed"] = float(
107
vehicleResult["totalEnergyConsumed"]) + float(vehicleMatrix["totalEnergyConsumed"])
108
newVehicleAttributes["totalEnergyRegenerated"] = float(
109
vehicleResult["totalEnergyRegenerated"]) + float(vehicleMatrix["totalEnergyRegenerated"])
110
newVehicleAttributes["energyChargedInTransit"] = float(
111
vehicleResult["energyChargedInTransit"]) + float(vehicleMatrix["energyChargedInTransit"])
112
newVehicleAttributes["energyChargedStopped"] = float(
113
vehicleResult["energyChargedStopped"]) + float(vehicleMatrix["energyChargedStopped"])
114
newVehicleAttributes["timeStopped"] = float(
115
vehicleResult["timeStopped"]) + float(vehicleMatrix["timeStopped"])
116
newVehicleAttributes["aggregateNumber"] = float(vehicleResult["aggregateNumber"]) + 1
117
# add new vehicle attributes in result
118
result[timeStepCounter][2][vehicleIDResult] = newVehicleAttributes
119
# update flag
120
found = True
121
# if vehicle wasn't found add it
122
if not found:
123
# declare new vehicle attributes
124
newVehicleAttributes = {}
125
# add vehicle attributes
126
newVehicleAttributes["energyConsumed"] = float(vehicleMatrix["energyConsumed"])
127
newVehicleAttributes["totalEnergyConsumed"] = float(vehicleMatrix["totalEnergyConsumed"])
128
newVehicleAttributes["totalEnergyRegenerated"] = float(vehicleMatrix["totalEnergyRegenerated"])
129
newVehicleAttributes["energyChargedInTransit"] = float(vehicleMatrix["energyChargedInTransit"])
130
newVehicleAttributes["energyChargedStopped"] = float(vehicleMatrix["energyChargedStopped"])
131
newVehicleAttributes["timeStopped"] = float(vehicleMatrix["timeStopped"])
132
newVehicleAttributes["aggregateNumber"] = 1.0
133
# add new vehicle attributes in result
134
result[timeStepCounter][2][vehicleID] = newVehicleAttributes
135
136
# return matrix
137
return result
138
139
140
def main():
141
op = sumolib.options.ArgumentParser()
142
op.add_argument("-i", "--input", type=op.file, category="input", help="battery input file")
143
op.add_argument("-o", "--output", type=op.file, category="output", help="battery merged output file")
144
op.add_argument("-t", "--time", type=op.time, help="time to merge")
145
opts = op.parse_args()
146
matrix = parseTimeSteps(opts.input)
147
matrix = processMatrix(matrix, int(opts.time))
148
writeTimeSteps(matrix, opts.output)
149
150
151
if __name__ == "__main__":
152
main()
153
154