Coverage for pybeepop/beepop/coldstoragesimulator.py: 42%
100 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 13:34 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 13:34 +0000
1"""
2ColdStorageSimulator class:
3- Simulates cold storage conditions for a bee colony.
4- Can be activated manually or by specifying start/end dates.
5- When active, overrides temperature and disables foraging.
6- Tracks active, starting, and ending phases.
7- All logic and comments from the C++ version are preserved.
8"""
10from datetime import datetime
13class ColdStorageSimulator:
14 DEFAULT_TEMPERATURE = (40.0 - 32.0) / 1.8 # Celsius
15 _instance = None
17 def __init__(self):
18 self.enabled = False
19 self.start_date = None
20 self.end_date = None
21 self.on = False
22 self.temperature = self.DEFAULT_TEMPERATURE
23 self.start_date_str = ""
24 self.end_date_str = ""
25 self.is_active = False
26 self.is_starting = False
27 self.is_ending = False
29 @classmethod
30 def get(cls):
31 if cls._instance is None:
32 cls._instance = ColdStorageSimulator()
33 return cls._instance
35 def set_enabled(self, enabled):
36 self.enabled = enabled
38 def is_enabled(self):
39 return self.enabled
41 def activate(self):
42 self.on = True
44 def deactivate(self):
45 self.on = False
47 def is_on(self):
48 return self.on
50 def is_automatic(self):
51 return not self.start_date_str and not self.end_date_str
53 def get_temp(self, event):
54 temperature = getattr(event, "temp", None)
55 if self.is_active:
56 temperature = self.temperature
57 return temperature
59 def get_max_temp(self, event):
60 temperature = getattr(event, "max_temp", None)
61 if self.is_active:
62 temperature = self.temperature
63 return temperature
65 def get_min_temp(self, event):
66 temperature = getattr(event, "min_temp", None)
67 if self.is_active:
68 temperature = self.temperature
69 return temperature
71 def get_forage_inc(self, event):
72 forage_inc = getattr(event, "forage_inc", None)
73 if self.is_active:
74 forage_inc = 0.0
75 return forage_inc
77 def is_forage_day(self, event):
78 forage_day = getattr(event, "forage_day", None)
79 if self.is_active:
80 forage_day = False
81 return forage_day
83 def set_start_date(self, start_date):
84 self.start_date = start_date
85 self.start_date_str = start_date.strftime("%m%d") if start_date else ""
87 def set_end_date(self, end_date):
88 self.end_date = end_date
89 self.end_date_str = end_date.strftime("%m%d") if end_date else ""
91 def update(self, event, colony):
92 """
93 Updates the state of the cold storage, call once per simulation day.
94 Tracks starting/ending phases based on colony and event state.
95 """
96 is_active = self.enabled and (self.on or self.is_cold_storage_period(event))
97 if not self.is_active and is_active:
98 self.is_starting = True
99 # Starting phase: bees placed in cold storage, brood still present
100 if self.is_starting:
101 starting = (
102 getattr(colony.queen, "teggs", 0) > 0
103 or getattr(colony, "cap_drn", None)
104 and getattr(colony.cap_drn, "quantity", 0) > 0
105 or getattr(colony, "cap_wkr", None)
106 and getattr(colony.cap_wkr, "quantity", 0) > 0
107 )
108 self.is_starting = starting
109 # Ending phase: queen starts to lay eggs again while in cold storage
110 if is_active and not self.is_starting and getattr(colony.queen, "teggs", 0) > 0:
111 self.is_ending = True
112 if not is_active:
113 self.is_starting = False
114 self.is_ending = False
115 self.is_active = is_active
117 def reset(self):
118 self.enabled = False
119 self.start_date = None
120 self.end_date = None
121 self.on = False
122 self.temperature = self.DEFAULT_TEMPERATURE
123 self.start_date_str = ""
124 self.end_date_str = ""
125 self.is_active = False
126 self.is_starting = False
127 self.is_ending = False
129 def is_active_now(self):
130 return self.is_active
132 def is_starting_now(self):
133 return self.is_active and self.is_starting
135 def is_ending_now(self):
136 return self.is_active and self.is_ending
138 def is_cold_storage_period(self, event):
139 """
140 Returns True if the current event is within the cold storage period.
141 """
142 if not self.start_date_str or not self.end_date_str:
143 return False
144 current_date_str = event.time.strftime("%m%d") if hasattr(event, "time") else ""
145 if self.start_date_str >= self.end_date_str:
146 return (
147 current_date_str >= self.start_date_str
148 or current_date_str <= self.end_date_str
149 )
150 else:
151 return self.start_date_str <= current_date_str <= self.end_date_str