other/train-to-cloud-city/app/server/simulate_session.py (74 lines of code) (raw):
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import random
import sys
import time
import train_types
from google.cloud import firestore
PROJECT = "train-to-cloud-city-4"
COLLECTION = "global_simulation"
STEP_SEC = 5
if len(sys.argv) > 1:
PROJECT = sys.argv[1]
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
log = logging.info
def sleep(duration):
log(f"sleeping for {duration} seconds")
time.sleep(duration)
def change(doc, data):
log(f'{data}')
doc.update(data)
# ----
cargo_pool = set()
for pattern in train_types.PATTERNS.values():
# print(pattern)
for checkpoint in pattern.checkpoints:
for service in checkpoint.satisfying_services:
# print(service)
cargo_pool.add(service)
print(f"cargo_pool: {cargo_pool}")
pattern_pool = list(train_types.PATTERNS.keys())
print(f"pattern_pool: {pattern_pool}")
log(f"connecting to DB: {COLLECTION} in {PROJECT}")
db = firestore.Client(project=PROJECT)
global_ref = db.collection(COLLECTION)
while True:
log("set starting world state")
global_ref.document("input_mailbox").update({"input" : "reset"})
proposal_doc = global_ref.document("proposal")
cargo_doc = global_ref.document("cargo")
signals_doc = global_ref.document("signals")
session_cargo = set()
# only clear these in simulation
signals_doc.update({"one.actual_state" : "off"})
signals_doc.update({"two.actual_state" : "off"})
signals_doc.update({"three.actual_state" : "off"})
signals_doc.update({"four.actual_state" : "off"})
train_doc = global_ref.document("train")
change(train_doc, {"actual_location" : "station"})
change(train_doc, {"actual_state" : "at_station"})
sleep(STEP_SEC)
log("start simulation activity")
change(proposal_doc, {"pattern_slug":random.choice(pattern_pool)})
# update cargo and signals
for i in range(0, 4):
# choose random cargo
sleep(STEP_SEC)
# add a random cargo slug which is not already in session_cargo
session_cargo.add(random.choice(list(cargo_pool.difference(session_cargo))))
change(cargo_doc, {"actual_cargo" : list(session_cargo)})
# sleep then update signal based on signal.target_state?
sleep(STEP_SEC / 2)
signals_state = signals_doc.get()
if signals_state.exists:
for key, signal in signals_state.to_dict().items():
if signal['target_state'] != signal['actual_state']:
print(f'{key}: {signal}')
change(signals_doc, {f"{key}.actual_state" : signal['target_state']})
#sleep(STEP_SEC)
# check train_mailbox... if do_victory_lap, then ... do it
train_mailbox = global_ref.document("train_mailbox").get()
if train_mailbox.exists:
print(f'train_mailbox: {train_mailbox.to_dict()}')
if train_mailbox.to_dict().get('input', '') == 'do_victory_lap':
change(train_doc, {"actual_state" : "victory_lap"})
sleep(STEP_SEC)
change(train_doc, {"actual_location" : "one"})
sleep(STEP_SEC)
change(train_doc, {"actual_location" : "two"})
sleep(STEP_SEC)
change(train_doc, {"actual_location" : "three"})
sleep(STEP_SEC)
change(train_doc, {"actual_location" : "four"})
sleep(STEP_SEC)
change(train_doc, {"actual_location" : "station"})
sleep(20)