pycityagent 2.0.0a52__cp311-cp311-macosx_11_0_arm64.whl → 2.0.0a54__cp311-cp311-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. pycityagent/agent/agent.py +83 -62
  2. pycityagent/agent/agent_base.py +81 -54
  3. pycityagent/cityagent/bankagent.py +5 -7
  4. pycityagent/cityagent/blocks/__init__.py +0 -2
  5. pycityagent/cityagent/blocks/cognition_block.py +149 -172
  6. pycityagent/cityagent/blocks/economy_block.py +90 -129
  7. pycityagent/cityagent/blocks/mobility_block.py +56 -29
  8. pycityagent/cityagent/blocks/needs_block.py +163 -145
  9. pycityagent/cityagent/blocks/other_block.py +17 -9
  10. pycityagent/cityagent/blocks/plan_block.py +45 -57
  11. pycityagent/cityagent/blocks/social_block.py +70 -51
  12. pycityagent/cityagent/blocks/utils.py +2 -0
  13. pycityagent/cityagent/firmagent.py +6 -7
  14. pycityagent/cityagent/governmentagent.py +7 -9
  15. pycityagent/cityagent/memory_config.py +48 -48
  16. pycityagent/cityagent/message_intercept.py +99 -0
  17. pycityagent/cityagent/nbsagent.py +6 -29
  18. pycityagent/cityagent/societyagent.py +325 -127
  19. pycityagent/cli/wrapper.py +4 -0
  20. pycityagent/economy/econ_client.py +0 -2
  21. pycityagent/environment/__init__.py +7 -1
  22. pycityagent/environment/sim/client.py +10 -1
  23. pycityagent/environment/sim/clock_service.py +2 -2
  24. pycityagent/environment/sim/pause_service.py +61 -0
  25. pycityagent/environment/sim/sim_env.py +34 -46
  26. pycityagent/environment/simulator.py +18 -14
  27. pycityagent/llm/embeddings.py +0 -24
  28. pycityagent/llm/llm.py +18 -10
  29. pycityagent/memory/faiss_query.py +29 -26
  30. pycityagent/memory/memory.py +733 -247
  31. pycityagent/message/__init__.py +8 -1
  32. pycityagent/message/message_interceptor.py +322 -0
  33. pycityagent/message/messager.py +42 -11
  34. pycityagent/pycityagent-sim +0 -0
  35. pycityagent/simulation/agentgroup.py +137 -96
  36. pycityagent/simulation/simulation.py +184 -38
  37. pycityagent/simulation/storage/pg.py +2 -2
  38. pycityagent/tools/tool.py +7 -9
  39. pycityagent/utils/__init__.py +7 -2
  40. pycityagent/utils/pg_query.py +1 -0
  41. pycityagent/utils/survey_util.py +26 -23
  42. pycityagent/workflow/block.py +14 -7
  43. {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a54.dist-info}/METADATA +2 -2
  44. {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a54.dist-info}/RECORD +48 -46
  45. pycityagent/cityagent/blocks/time_block.py +0 -116
  46. {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a54.dist-info}/LICENSE +0 -0
  47. {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a54.dist-info}/WHEEL +0 -0
  48. {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a54.dist-info}/entry_points.txt +0 -0
  49. {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a54.dist-info}/top_level.txt +0 -0
@@ -16,7 +16,7 @@ from langchain_core.embeddings import Embeddings
16
16
 
17
17
  from ..agent import Agent, InstitutionAgent
18
18
  from ..economy.econ_client import EconomyClient
19
- from ..environment.simulator import Simulator
19
+ from ..environment import Simulator
20
20
  from ..llm.llm import LLM
21
21
  from ..llm.llmconfig import LLMConfig
22
22
  from ..memory import FaissQuery, Memory
@@ -39,12 +39,13 @@ class AgentGroup:
39
39
  list[Callable[[], tuple[dict, dict, dict]]],
40
40
  ],
41
41
  config: dict,
42
- exp_id: str | UUID,
43
42
  exp_name: str,
43
+ exp_id: str | UUID,
44
44
  enable_avro: bool,
45
45
  avro_path: Path,
46
46
  enable_pgsql: bool,
47
47
  pgsql_writer: ray.ObjectRef,
48
+ message_interceptor: ray.ObjectRef,
48
49
  mlflow_run_id: str,
49
50
  embedding_model: Embeddings,
50
51
  logging_level: int,
@@ -80,6 +81,18 @@ class AgentGroup:
80
81
  }
81
82
  if self.enable_pgsql:
82
83
  pass
84
+ # Mlflow
85
+ _mlflow_config = config.get("metric_request", {}).get("mlflow")
86
+ if _mlflow_config:
87
+ logger.info(f"-----Creating Mlflow client in AgentGroup {self._uuid} ...")
88
+ self.mlflow_client = MlflowClient(
89
+ config=_mlflow_config,
90
+ mlflow_run_name=f"{exp_name}_{1000*int(time.time())}",
91
+ experiment_name=exp_name,
92
+ run_id=mlflow_run_id,
93
+ )
94
+ else:
95
+ self.mlflow_client = None
83
96
 
84
97
  # prepare Messager
85
98
  if "mqtt" in config["simulator_request"]:
@@ -94,6 +107,7 @@ class AgentGroup:
94
107
 
95
108
  self.message_dispatch_task = None
96
109
  self._pgsql_writer = pgsql_writer
110
+ self._message_interceptor = message_interceptor
97
111
  self._last_asyncio_pg_task = None # 将SQL写入的IO隐藏到计算任务后
98
112
  self.initialized = False
99
113
  self.id2agent = {}
@@ -116,19 +130,6 @@ class AgentGroup:
116
130
  else:
117
131
  self.economy_client = None
118
132
 
119
- # Mlflow
120
- _mlflow_config = config.get("metric_request", {}).get("mlflow")
121
- if _mlflow_config:
122
- logger.info(f"-----Creating Mlflow client in AgentGroup {self._uuid} ...")
123
- self.mlflow_client = MlflowClient(
124
- config=_mlflow_config,
125
- mlflow_run_name=f"EXP_{exp_name}_{1000*int(time.time())}",
126
- experiment_name=exp_name,
127
- run_id=mlflow_run_id,
128
- )
129
- else:
130
- self.mlflow_client = None
131
-
132
133
  # set FaissQuery
133
134
  if self.embedding_model is not None:
134
135
  self.faiss_query = FaissQuery(
@@ -144,27 +145,25 @@ class AgentGroup:
144
145
  extra_attributes, profile, base = memory_config_function_group_i()
145
146
  memory = Memory(config=extra_attributes, profile=profile, base=base)
146
147
  agent = agent_class_i(
147
- name=f"{agent_class_i.__name__}_{i}",
148
+ name=f"{agent_class_i.__name__}_{i}", # type: ignore
148
149
  memory=memory,
149
150
  llm_client=self.llm,
150
151
  economy_client=self.economy_client,
151
152
  simulator=self.simulator,
152
153
  )
153
154
  agent.set_exp_id(self.exp_id) # type: ignore
154
- if self.mlflow_client is not None:
155
- agent.set_mlflow_client(self.mlflow_client)
156
155
  if self.messager is not None:
157
156
  agent.set_messager(self.messager)
157
+ if self.mlflow_client is not None:
158
+ agent.set_mlflow_client(self.mlflow_client) # type: ignore
158
159
  if self.enable_avro:
159
160
  agent.set_avro_file(self.avro_file) # type: ignore
160
161
  if self.enable_pgsql:
161
162
  agent.set_pgsql_writer(self._pgsql_writer)
162
- if self.faiss_query is not None:
163
- agent.memory.set_faiss_query(self.faiss_query)
164
- if self.embedding_model is not None:
165
- agent.memory.set_embedding_model(self.embedding_model)
166
163
  if self.agent_config_file is not None and self.agent_config_file[i]:
167
164
  agent.load_from_file(self.agent_config_file[i])
165
+ if self._message_interceptor is not None:
166
+ agent.set_message_interceptor(self._message_interceptor)
168
167
  self.agents.append(agent)
169
168
  self.id2agent[agent._uuid] = agent
170
169
 
@@ -193,11 +192,21 @@ class AgentGroup:
193
192
  self.message_dispatch_task.cancel() # type: ignore
194
193
  await asyncio.gather(self.message_dispatch_task, return_exceptions=True) # type: ignore
195
194
 
195
+ async def insert_agents(self):
196
+ bind_tasks = []
197
+ for agent in self.agents:
198
+ bind_tasks.append(agent.bind_to_simulator()) # type: ignore
199
+ await asyncio.gather(*bind_tasks)
200
+
196
201
  async def init_agents(self):
197
202
  logger.debug(f"-----Initializing Agents in AgentGroup {self._uuid} ...")
198
203
  logger.debug(f"-----Binding Agents to Simulator in AgentGroup {self._uuid} ...")
199
- for agent in self.agents:
200
- await agent.bind_to_simulator() # type: ignore
204
+ while True:
205
+ day = await self.simulator.get_simulator_day()
206
+ if day == 0:
207
+ break
208
+ await asyncio.sleep(1)
209
+ await self.insert_agents()
201
210
  self.id2agent = {agent._uuid: agent for agent in self.agents}
202
211
  logger.debug(f"-----Binding Agents to Messager in AgentGroup {self._uuid} ...")
203
212
  assert self.messager is not None
@@ -221,7 +230,7 @@ class AgentGroup:
221
230
  with open(filename, "wb") as f:
222
231
  profiles = []
223
232
  for agent in self.agents:
224
- profile = await agent.memory._profile.export()
233
+ profile = await agent.status.profile.export()
225
234
  profile = profile[0]
226
235
  profile["id"] = agent._uuid
227
236
  profiles.append(profile)
@@ -252,7 +261,7 @@ class AgentGroup:
252
261
  if not issubclass(type(self.agents[0]), InstitutionAgent):
253
262
  profiles: list[Any] = []
254
263
  for agent in self.agents:
255
- profile = await agent.memory._profile.export()
264
+ profile = await agent.status.profile.export()
256
265
  profile = profile[0]
257
266
  profile["id"] = agent._uuid
258
267
  profiles.append(
@@ -271,7 +280,7 @@ class AgentGroup:
271
280
  else:
272
281
  profiles: list[Any] = []
273
282
  for agent in self.agents:
274
- profile = await agent.memory._profile.export()
283
+ profile = await agent.status.profile.export()
275
284
  profile = profile[0]
276
285
  profile["id"] = agent._uuid
277
286
  profiles.append(
@@ -290,6 +299,18 @@ class AgentGroup:
290
299
  await self._pgsql_writer.async_write_profile.remote( # type:ignore
291
300
  profiles
292
301
  )
302
+ if self.faiss_query is not None:
303
+ logger.debug(f"-----Initializing embeddings in AgentGroup {self._uuid} ...")
304
+ embedding_tasks = []
305
+ for agent in self.agents:
306
+ embedding_tasks.append(agent.memory.initialize_embeddings())
307
+ agent.memory.set_search_components(
308
+ self.faiss_query, self.embedding_model
309
+ )
310
+ agent.memory.set_simulator(self.simulator)
311
+ await asyncio.gather(*embedding_tasks)
312
+ logger.debug(f"-----Embedding initialized in AgentGroup {self._uuid} ...")
313
+
293
314
  self.initialized = True
294
315
  logger.debug(f"-----AgentGroup {self._uuid} initialized")
295
316
 
@@ -307,7 +328,7 @@ class AgentGroup:
307
328
  if keys:
308
329
  for key in keys:
309
330
  assert values is not None
310
- if not agent.memory.get(key) == values[keys.index(key)]:
331
+ if not agent.status.get(key) == values[keys.index(key)]:
311
332
  add = False
312
333
  break
313
334
  if add:
@@ -315,18 +336,23 @@ class AgentGroup:
315
336
  elif keys:
316
337
  for key in keys:
317
338
  assert values is not None
318
- if not agent.memory.get(key) == values[keys.index(key)]:
339
+ if not agent.status.get(key) == values[keys.index(key)]:
319
340
  add = False
320
341
  break
321
342
  if add:
322
343
  filtered_uuids.append(agent._uuid)
323
344
  return filtered_uuids
324
345
 
325
- async def gather(self, content: str):
346
+ async def gather(
347
+ self, content: str, target_agent_uuids: Optional[list[str]] = None
348
+ ):
326
349
  logger.debug(f"-----Gathering {content} from all agents in group {self._uuid}")
327
350
  results = {}
351
+ if target_agent_uuids is None:
352
+ target_agent_uuids = self.agent_uuids
328
353
  for agent in self.agents:
329
- results[agent._uuid] = await agent.memory.get(content)
354
+ if agent._uuid in target_agent_uuids:
355
+ results[agent._uuid] = await agent.status.get(content)
330
356
  return results
331
357
 
332
358
  async def update(self, target_agent_uuid: str, target_key: str, content: Any):
@@ -334,7 +360,7 @@ class AgentGroup:
334
360
  f"-----Updating {target_key} for agent {target_agent_uuid} in group {self._uuid}"
335
361
  )
336
362
  agent = self.id2agent[target_agent_uuid]
337
- await agent.memory.update(target_key, content)
363
+ await agent.status.update(target_key, content)
338
364
 
339
365
  async def message_dispatch(self):
340
366
  logger.debug(f"-----Starting message dispatch for group {self._uuid}")
@@ -394,7 +420,7 @@ class AgentGroup:
394
420
  if not issubclass(type(self.agents[0]), InstitutionAgent):
395
421
  for agent in self.agents:
396
422
  _date_time = datetime.now(timezone.utc)
397
- position = await agent.memory.get("position")
423
+ position = await agent.status.get("position")
398
424
  x = position["xy_position"]["x"]
399
425
  y = position["xy_position"]["y"]
400
426
  lng, lat = self.projector(x, y, inverse=True)
@@ -404,8 +430,11 @@ class AgentGroup:
404
430
  parent_id = position["lane_position"]["lane_id"]
405
431
  else:
406
432
  parent_id = -1
407
- needs = await agent.memory.get("needs")
408
- action = await agent.memory.get("current_step")
433
+ hunger_satisfaction = await agent.status.get("hunger_satisfaction")
434
+ energy_satisfaction = await agent.status.get("energy_satisfaction")
435
+ safety_satisfaction = await agent.status.get("safety_satisfaction")
436
+ social_satisfaction = await agent.status.get("social_satisfaction")
437
+ action = await agent.status.get("current_step")
409
438
  action = action["intention"]
410
439
  avro = {
411
440
  "id": agent._uuid,
@@ -415,10 +444,10 @@ class AgentGroup:
415
444
  "lat": lat,
416
445
  "parent_id": parent_id,
417
446
  "action": action,
418
- "hungry": needs["hungry"],
419
- "tired": needs["tired"],
420
- "safe": needs["safe"],
421
- "social": needs["social"],
447
+ "hungry": hunger_satisfaction,
448
+ "tired": energy_satisfaction,
449
+ "safe": safety_satisfaction,
450
+ "social": social_satisfaction,
422
451
  "created_at": int(_date_time.timestamp() * 1000),
423
452
  }
424
453
  avros.append(avro)
@@ -429,54 +458,54 @@ class AgentGroup:
429
458
  for agent in self.agents:
430
459
  _date_time = datetime.now(timezone.utc)
431
460
  try:
432
- nominal_gdp = await agent.memory.get("nominal_gdp")
461
+ nominal_gdp = await agent.status.get("nominal_gdp")
433
462
  except:
434
463
  nominal_gdp = []
435
464
  try:
436
- real_gdp = await agent.memory.get("real_gdp")
465
+ real_gdp = await agent.status.get("real_gdp")
437
466
  except:
438
467
  real_gdp = []
439
468
  try:
440
- unemployment = await agent.memory.get("unemployment")
469
+ unemployment = await agent.status.get("unemployment")
441
470
  except:
442
471
  unemployment = []
443
472
  try:
444
- wages = await agent.memory.get("wages")
473
+ wages = await agent.status.get("wages")
445
474
  except:
446
475
  wages = []
447
476
  try:
448
- prices = await agent.memory.get("prices")
477
+ prices = await agent.status.get("prices")
449
478
  except:
450
479
  prices = []
451
480
  try:
452
- inventory = await agent.memory.get("inventory")
481
+ inventory = await agent.status.get("inventory")
453
482
  except:
454
483
  inventory = 0
455
484
  try:
456
- price = await agent.memory.get("price")
485
+ price = await agent.status.get("price")
457
486
  except:
458
487
  price = 0.0
459
488
  try:
460
- interest_rate = await agent.memory.get("interest_rate")
489
+ interest_rate = await agent.status.get("interest_rate")
461
490
  except:
462
491
  interest_rate = 0.0
463
492
  try:
464
- bracket_cutoffs = await agent.memory.get("bracket_cutoffs")
493
+ bracket_cutoffs = await agent.status.get("bracket_cutoffs")
465
494
  except:
466
495
  bracket_cutoffs = []
467
496
  try:
468
- bracket_rates = await agent.memory.get("bracket_rates")
497
+ bracket_rates = await agent.status.get("bracket_rates")
469
498
  except:
470
499
  bracket_rates = []
471
500
  try:
472
- employees = await agent.memory.get("employees")
501
+ employees = await agent.status.get("employees")
473
502
  except:
474
503
  employees = []
475
504
  avro = {
476
505
  "id": agent._uuid,
477
506
  "day": _day,
478
507
  "t": _t,
479
- "type": await agent.memory.get("type"),
508
+ "type": await agent.status.get("type"),
480
509
  "nominal_gdp": nominal_gdp,
481
510
  "real_gdp": real_gdp,
482
511
  "unemployment": unemployment,
@@ -514,12 +543,17 @@ class AgentGroup:
514
543
  ]:
515
544
  if key not in _status_dict:
516
545
  _status_dict[key] = ""
546
+ for key in [
547
+ "friend_ids",
548
+ ]:
549
+ if key not in _status_dict:
550
+ _status_dict[key] = []
517
551
  _status_dict["created_at"] = _date_time
518
552
  else:
519
553
  if not issubclass(type(self.agents[0]), InstitutionAgent):
520
554
  for agent in self.agents:
521
555
  _date_time = datetime.now(timezone.utc)
522
- position = await agent.memory.get("position")
556
+ position = await agent.status.get("position")
523
557
  x = position["xy_position"]["x"]
524
558
  y = position["xy_position"]["y"]
525
559
  lng, lat = self.projector(x, y, inverse=True)
@@ -528,10 +562,21 @@ class AgentGroup:
528
562
  elif "lane_position" in position:
529
563
  parent_id = position["lane_position"]["lane_id"]
530
564
  else:
531
- # BUG: 需要处理
532
565
  parent_id = -1
533
- needs = await agent.memory.get("needs")
534
- action = await agent.memory.get("current_step")
566
+ hunger_satisfaction = await agent.status.get(
567
+ "hunger_satisfaction"
568
+ )
569
+ energy_satisfaction = await agent.status.get(
570
+ "energy_satisfaction"
571
+ )
572
+ safety_satisfaction = await agent.status.get(
573
+ "safety_satisfaction"
574
+ )
575
+ social_satisfaction = await agent.status.get(
576
+ "social_satisfaction"
577
+ )
578
+ friend_ids = await agent.status.get("friends")
579
+ action = await agent.status.get("current_step")
535
580
  action = action["intention"]
536
581
  _status_dict = {
537
582
  "id": agent._uuid,
@@ -540,11 +585,14 @@ class AgentGroup:
540
585
  "lng": lng,
541
586
  "lat": lat,
542
587
  "parent_id": parent_id,
588
+ "friend_ids": [
589
+ str(_friend_id) for _friend_id in friend_ids
590
+ ],
543
591
  "action": action,
544
- "hungry": needs["hungry"],
545
- "tired": needs["tired"],
546
- "safe": needs["safe"],
547
- "social": needs["social"],
592
+ "hungry": hunger_satisfaction,
593
+ "tired": energy_satisfaction,
594
+ "safe": safety_satisfaction,
595
+ "social": social_satisfaction,
548
596
  "created_at": _date_time,
549
597
  }
550
598
  _statuses_time_list.append((_status_dict, _date_time))
@@ -552,56 +600,60 @@ class AgentGroup:
552
600
  # institution
553
601
  for agent in self.agents:
554
602
  _date_time = datetime.now(timezone.utc)
555
- position = await agent.memory.get("position")
603
+ position = await agent.status.get("position")
556
604
  x = position["xy_position"]["x"]
557
605
  y = position["xy_position"]["y"]
558
606
  lng, lat = self.projector(x, y, inverse=True)
559
607
  # ATTENTION: no valid position for an institution
560
608
  parent_id = -1
561
609
  try:
562
- nominal_gdp = await agent.memory.get("nominal_gdp")
610
+ nominal_gdp = await agent.status.get("nominal_gdp")
563
611
  except:
564
612
  nominal_gdp = []
565
613
  try:
566
- real_gdp = await agent.memory.get("real_gdp")
614
+ real_gdp = await agent.status.get("real_gdp")
567
615
  except:
568
616
  real_gdp = []
569
617
  try:
570
- unemployment = await agent.memory.get("unemployment")
618
+ unemployment = await agent.status.get("unemployment")
571
619
  except:
572
620
  unemployment = []
573
621
  try:
574
- wages = await agent.memory.get("wages")
622
+ wages = await agent.status.get("wages")
575
623
  except:
576
624
  wages = []
577
625
  try:
578
- prices = await agent.memory.get("prices")
626
+ prices = await agent.status.get("prices")
579
627
  except:
580
628
  prices = []
581
629
  try:
582
- inventory = await agent.memory.get("inventory")
630
+ inventory = await agent.status.get("inventory")
583
631
  except:
584
632
  inventory = 0
585
633
  try:
586
- price = await agent.memory.get("price")
634
+ price = await agent.status.get("price")
587
635
  except:
588
636
  price = 0.0
589
637
  try:
590
- interest_rate = await agent.memory.get("interest_rate")
638
+ interest_rate = await agent.status.get("interest_rate")
591
639
  except:
592
640
  interest_rate = 0.0
593
641
  try:
594
- bracket_cutoffs = await agent.memory.get("bracket_cutoffs")
642
+ bracket_cutoffs = await agent.status.get("bracket_cutoffs")
595
643
  except:
596
644
  bracket_cutoffs = []
597
645
  try:
598
- bracket_rates = await agent.memory.get("bracket_rates")
646
+ bracket_rates = await agent.status.get("bracket_rates")
599
647
  except:
600
648
  bracket_rates = []
601
649
  try:
602
- employees = await agent.memory.get("employees")
650
+ employees = await agent.status.get("employees")
603
651
  except:
604
652
  employees = []
653
+ try:
654
+ friend_ids = await agent.status.get("friends")
655
+ except:
656
+ friend_ids = []
605
657
  _status_dict = {
606
658
  "id": agent._uuid,
607
659
  "day": _day,
@@ -609,8 +661,11 @@ class AgentGroup:
609
661
  "lng": lng,
610
662
  "lat": lat,
611
663
  "parent_id": parent_id,
664
+ "friend_ids": [
665
+ str(_friend_id) for _friend_id in friend_ids
666
+ ],
612
667
  "action": "",
613
- "type": await agent.memory.get("type"),
668
+ "type": await agent.status.get("type"),
614
669
  "nominal_gdp": nominal_gdp,
615
670
  "real_gdp": real_gdp,
616
671
  "unemployment": unemployment,
@@ -634,6 +689,7 @@ class AgentGroup:
634
689
  "lng",
635
690
  "lat",
636
691
  "parent_id",
692
+ "friend_ids",
637
693
  "action",
638
694
  "created_at",
639
695
  ]
@@ -653,33 +709,18 @@ class AgentGroup:
653
709
  )
654
710
 
655
711
  async def step(self):
656
- if not self.initialized:
657
- await self.init_agents()
658
-
659
- tasks = [agent.run() for agent in self.agents]
660
- await asyncio.gather(*tasks)
661
- await self.save_status()
712
+ try:
713
+ tasks = [agent.run() for agent in self.agents]
714
+ await asyncio.gather(*tasks)
715
+ except Exception as e:
716
+ import traceback
662
717
 
663
- async def run(self, day: int = 1):
664
- """运行模拟器
718
+ logger.error(f"模拟器运行错误: {str(e)}\n{traceback.format_exc()}")
719
+ raise RuntimeError(str(e)) from e
665
720
 
666
- Args:
667
- day: 运行天数,默认为1天
668
- """
721
+ async def save(self, day: int, t: int):
669
722
  try:
670
- # 获取开始时间
671
- start_time = await self.simulator.get_time()
672
- start_time = int(start_time)
673
- # 计算结束时间(秒)
674
- end_time = start_time + day * 24 * 3600 # 将天数转换为秒
675
-
676
- while True:
677
- current_time = await self.simulator.get_time()
678
- current_time = int(current_time)
679
- if current_time >= end_time:
680
- break
681
- await self.step()
682
-
723
+ await self.save_status(day, t)
683
724
  except Exception as e:
684
725
  import traceback
685
726