commit | author | age
|
425bf7
|
1 |
import datetime |
JK |
2 |
|
|
3 |
import gym |
|
4 |
import gym.spaces |
|
5 |
import matplotlib.dates |
|
6 |
import matplotlib.pyplot as plot |
|
7 |
import numpy |
|
8 |
|
|
9 |
from .ArgParser import get_sliding_window_from_config |
|
10 |
from .Cost import NegativeCost |
|
11 |
|
|
12 |
|
|
13 |
class CentralHeatingHistoryEnv(gym.Env): |
|
14 |
metadata = {'render.modes': ['human']} |
|
15 |
|
|
16 |
def __init__(self): |
|
17 |
self.config = None |
|
18 |
self.model = None |
|
19 |
|
|
20 |
self.sliding_window_adapter = None |
|
21 |
self.window = None |
|
22 |
|
|
23 |
self.cost_class = NegativeCost |
|
24 |
self.cost = None |
|
25 |
|
|
26 |
# Required by OpenAI Gym |
|
27 |
self.action_space = gym.spaces.Discrete(2) |
|
28 |
|
|
29 |
def reset(self): |
|
30 |
if not self.config or not self.model: |
|
31 |
raise Exception("config and model must be set before use!") |
|
32 |
|
|
33 |
self.cost = self.cost_class() |
|
34 |
|
|
35 |
self.sliding_window_adapter = get_sliding_window_from_config(self.config) |
|
36 |
self.window = next(self.sliding_window_adapter) |
|
37 |
|
|
38 |
observation_min = numpy.array([-50.] * self.window.get_window_size()) |
|
39 |
observation_max = numpy.array([50.] * self.window.get_window_size()) |
|
40 |
|
|
41 |
# Required by OpenAI Gym |
|
42 |
self.observation_space = gym.spaces.Box(observation_min, observation_max, dtype=numpy.float32) |
|
43 |
|
|
44 |
return numpy.array(self.window.get_window_values()) |
|
45 |
|
|
46 |
def step(self, action): |
|
47 |
return_observation = None |
|
48 |
return_cost = None |
|
49 |
return_done = False |
|
50 |
return_info = None |
|
51 |
|
|
52 |
try: |
|
53 |
self.window.set_current_value('mode', action) |
|
54 |
next_temp_in = self.model.get_temperature(self.window.get_model_values()) |
|
55 |
self.window.set_next_value('temp_in', next_temp_in) |
|
56 |
|
|
57 |
if next_temp_in > 27 or next_temp_in < 15: |
|
58 |
raise StopIteration() |
|
59 |
|
|
60 |
self.window = next(self.sliding_window_adapter) |
|
61 |
return_observation = self.window.get_window_values() |
|
62 |
|
|
63 |
partial_cost = self.cost.add_partial_cost(self.window) |
|
64 |
return_cost = sum(partial_cost.values()) |
|
65 |
except StopIteration: |
|
66 |
return_observation = self.window.get_window_values(offset=1) |
|
67 |
return_done = True |
|
68 |
|
|
69 |
return numpy.array(return_observation), return_cost, return_done, return_info |
|
70 |
|
|
71 |
def render(self, mode='human', close=False): |
|
72 |
if close or not self.window.plot: |
|
73 |
return |
|
74 |
|
|
75 |
x = matplotlib.dates.date2num([datetime.datetime.fromtimestamp(i) for i in self.window.get_plot_data('time')]) |
|
76 |
for i in self.window.plot.keys(): |
|
77 |
if i == "time": |
|
78 |
continue |
|
79 |
plot.plot_date(x, self.window.get_plot_data(i), '-', label=i) |
|
80 |
|
|
81 |
plot.grid(True) |
|
82 |
plot.legend() |
|
83 |
plot.xlabel('date') |
|
84 |
plot.ylabel('temperature/state') |
|
85 |
plot.show(block=True) |
|
86 |
|
|
87 |
|
|
88 |
class CentralHeatingInfiniteEnv(CentralHeatingHistoryEnv): |
|
89 |
def __init__(self): |
|
90 |
super().__init__() |
|
91 |
|
|
92 |
def step(self, action): |
|
93 |
try: |
|
94 |
return super().step(action) |
|
95 |
except KeyboardInterrupt: |
|
96 |
return None, 0, True, None |