def test_register_schedule_callback(self): """ Testing whether registering scheduling works """ sim = BaseSimulation("template_service", SharedStorageSchemas.TEMPLATE_STORAGE) @sim.schedule_callback(3) async def test_func(nats, shared_storage, logger): pass self.assertEqual(len(sim._registered_callbacks), 3)
def test_register_startup_callback(self): """ Testing whether the startup callback registration works """ sim = BaseSimulation("template_service", SharedStorageSchemas.TEMPLATE_STORAGE) @sim.startup_callback async def startup(nats, shared_storage, logger): pass self.assertEqual(sim._startup_callback, startup)
def test_register_nats_data(self): """ Testing whether registering a NATS data route works """ sim = BaseSimulation("template_service", SharedStorageSchemas.TEMPLATE_STORAGE) @sim.subscribe_data_callback("data.test", MessageSchemas.TEST_MESSAGE) async def test_two(msg, nats, shared_storage, logger): pass self.assertEqual(len(sim._nats_routes), 2) self.assertEqual(len(sim._unsubscribe_nats_routes), 2)
def test_register_request_nats_callback(self): """ Testing whether registering requests works """ sim = BaseSimulation("template_service", SharedStorageSchemas.TEMPLATE_STORAGE) @sim.request_nats_callback("data.test", MessageSchemas.TEST_MESSAGE) async def test_func(msg, nats, shared_storage, logger): pass self.assertEqual(len(sim._registered_callbacks), 3) self.assertEqual(len(sim._unsubscribe_nats_routes), 3)
def test_register_schedule(self): """ Testing whether scheduling a callback """ sim = BaseSimulation("template_service", SharedStorageSchemas.TEMPLATE_STORAGE) @sim.schedule_callback(3) async def test_two(nats, shared_storage, logger): pass self.assertEqual(len(sim._nats_routes), 2) self.assertEqual(len(sim._unsubscribe_nats_routes), 1)
import kubesat.orekit as orekit_utils from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes from kubesat.validation import check_omni_in_range, MessageSchemas, check_internal, SharedStorageSchemas simulation = BaseSimulation(ServiceTypes.Orbits, SharedStorageSchemas.ORBIT_SERVICE_STORAGE) @simulation.subscribe_nats_callback("state", MessageSchemas.STATE_MESSAGE) @check_omni_in_range async def cubesat_state(message, nats_handler, shared_storage, logger): """ Update the state of a cubesat in the shared dictionary Args: message (natsmessage): message message.data dictionary with structure as described in message_structure.json message.data["state"] is a dictionary containing telematry data of a satellite nats_handler (natsHandler): distributes callbacks according to the message subject shared_storage: dictionary containing information on on the entire swarm, the time, and the particular satellites phonebook """ state = message.data["state"] target_sat_id = list(state.keys())[0] if orekit_utils.t1_lte_t2_string( shared_storage["swarm"][target_sat_id]["last_update_time"], state[target_sat_id]["last_update_time"]): shared_storage["swarm"][target_sat_id] = state[target_sat_id] @simulation.subscribe_nats_callback("state.attitude",
import numpy as np from gym import spaces from rl.agents.dqn import DQNAgent from rl.memory import SequentialMemory from tensorflow.keras.models import load_model from rl.policy import EpsGreedyQPolicy from tensorflow.keras.optimizers import Adam from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes from kubesat.validation import MessageSchemas, check_internal, SharedStorageSchemas import random simulation = BaseSimulation(ServiceTypes.RL, SharedStorageSchemas.RL_SERVICE_STORAGE) agents = [] @simulation.startup_callback async def initialize_rl(nats_handler, shared_storage, logger): """ Callback used to initialize the agent and model for the reinforcement learning and put it in the list. First checks shared storage to see if the satellite is in predict mode or training mode, if it is in predict mode it uses the phonebooks to create an input vector to the reinforcement learning model. This input vector consists of all possible nodes that the satellite could send or receive data from. The callbacks then loads the trained model and weights, and creates a new agent and appends it to the agent list so that other callbacks can access the agent. Args: nats_handler (NatsHandler): NatsHandler used to interact with NATS shared_storage (dict): Dictionary to persist memory across callbacks logger (JSONLogger): Logger that can be used to log info, error, etc,
from kubesat.base_simulation import BaseSimulation from kubesat.validation import MessageSchemas, SharedStorageSchemas, check_internal_data simulation = BaseSimulation("agriculture", SharedStorageSchemas.APPLICATION_SERVICE_STORAGE) @simulation.subscribe_data_callback("internal.data.in", MessageSchemas.IOT_DATA_MESSAGE, validator=check_internal_data) async def process_data(message, nats_handler, shared_storage, logger): """ Receives IOT data packets from the data service, processes them (currently not doing any processing), and then sends processed data back to the data service. Args: message (Message): incoming message with data to be forwarded nats_handler (NatsHandler): NatsHandler used to interact with NATS shared_storage (dict): Dictionary to persist memory across callbacks logger (JSONLogger): Logger that can be used to log info, error, etc, Returns: None """ await nats_handler.send_data("internal.data.out", message)
from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes from kubesat.validation import MessageSchemas, check_pointing_data, SharedStorageSchemas simulation = BaseSimulation( ServiceTypes.Groundstation, SharedStorageSchemas.GROUND_STATION_SERVICE_STORAGE) @simulation.subscribe_data_callback("data.out", MessageSchemas.IOT_DATA_MESSAGE, validator=check_pointing_data) async def receive_data(message, nats_handler, shared_storage, logger): """ Receives a data packet, updates the number of received packets, and requests more. Args: message (Message): incoming message with current pointing target of the sender nats_handler (NatsHandler): NatsHandler used to interact with NATS shared_storage (dict): Dictionary to persist memory across callbacks logger (JSONLogger): Logger that can be used to log info, error, etc, Returns: None """ shared_storage["packets_received"] += 1 if logger: await logger.info( f"Ground got {message.message_type} data {message.data} from {message.origin_id}" )
# # 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 csv from datetime import datetime from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes from kubesat.validation import MessageSchemas, SharedStorageSchemas simulation = BaseSimulation(ServiceTypes.Logging, SharedStorageSchemas.LOGGING_SERVICE_STORAGE) @simulation.startup_callback async def create_log_file(nats_handler, shared_storage, logger): """ Creates CSV for logger outputs Args: nats_handler (NatsHandler): NatsHandler used to interact with NATS shared_storage (dict): Dictionary to persist memory across callbacks logger (JSONLogger): Logger that can be used to log info, error, etc. """ if shared_storage["log_path"][-1] == "/": shared_storage["log_path"] = shared_storage[ "log_path"] + f"log-{datetime.utcnow().isoformat()}.csv"
# 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 math import asyncio from queue import Queue from datetime import datetime from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes from kubesat.validation import MessageSchemas, SharedStorageSchemas from kubesat.validation import check_pointing_and_mode, check_internal, check_internal_data, check_pointing simulation = BaseSimulation(ServiceTypes.Data, SharedStorageSchemas.DATA_SERVICE_STORAGE) buffer = Queue() @simulation.subscribe_data_callback("data.out", MessageSchemas.IOT_DATA_MESSAGE, validator=check_pointing_and_mode) async def receive_packet(message, nats_handler, shared_storage, logger): """ Receives a data packet and then forwards it to the internal satellite services (such as agriculture). Sends a logger message to signify it has received data. Args: message (Message): incoming message with the ID of the sending Satellite nats_handler (NatsHandler): NatsHandler used to interact with NATS shared_storage (dict): Dictionary to persist memory across callbacks logger (JSONLogger): Logger that can be used to log info, error, etc, Returns: None """
import json import asyncio from kubesat.message import Message import czml_utils as gutils import kubesat.orekit as orekit_utils from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes from kubesat.validation import MessageSchemas, SharedStorageSchemas simulation = BaseSimulation(ServiceTypes.Czml, SharedStorageSchemas.GRAPHICS_SERVICE_STORAGE) # These are hyperparameters, should be fine? # STEP_COUNT = 5 # STEP_SIZE = 300.0 PACKET_FREQUENCY = 5 # MESSAGE_SENT = False @simulation.subscribe_nats_callback("state", MessageSchemas.STATE_MESSAGE) async def cubesat_state(message, nats_handler, shared_storage, logger): """ Update the state of a cubesat in the shared dictionary Args: message (natsmessage): message message.data dictionary with structure as described in message_structure.json message.data["state"] is a dictionary containing telematry data of a satellite nats_handler (natsHandler): distributes callbacks according to the message subject shared_storage: dictionary containing information on on the entire swarm, the time, and the particular satellites phonebook """
import socket from kubesat.message import Message from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes from kubesat.validation import MessageSchemas, SharedStorageSchemas simulation = BaseSimulation("cluster", SharedStorageSchemas.CLUSTER_SERVICE_STORAGE) @simulation.subscribe_nats_callback("simulation.timestep", MessageSchemas.TIMESTEP_MESSAGE) async def send_ip_address(message, nats_handler, shared_storage, logger): """ Broadcasts the nats host on each time step which will be read by the ground station Args: message (Message): incoming message with the timestep nats_handler (NatsHandler): NatsHandler used to interact with NATS shared_storage (dict): Dictionary to persist memory across callbacks logger (JSONLogger): Logger that can be used to log info, error, etc, """ hostname = nats_handler.api_host ip_message = nats_handler.create_message(hostname, MessageSchemas.IP_ADDRESS_MESSAGE) await nats_handler.send_message("cluster.ip", ip_message) @simulation.subscribe_nats_callback("command.cluster", MessageSchemas.CLUSTER_MESSAGE) async def cluster(message, nats_handler, shared_storage, logger):
from datetime import datetime, timedelta from kubesat.message import Message from kubesat.services import ServiceTypes from kubesat.base_simulation import BaseSimulation from kubesat.validation import MessageSchemas, SharedStorageSchemas simulation = BaseSimulation(ServiceTypes.Clock, SharedStorageSchemas.CLOCK_SERVICE_STORAGE) @simulation.schedule_callback(0.4) async def send_timestep(nats, shared_storage, logger): """ Broadcast the current time of the simulation and updates it by the timestep interval defined in the config. Args: nats (NatsHandler): connection to nats used to send and receive messages shared_storage (dict): dictionary that stores local data for the service logger (NatsLogger): logger that can be used to communicate the state of the system """ time = shared_storage["start_time"] message = nats.create_message({"time": time}, MessageSchemas.TIMESTEP_MESSAGE) await nats.send_message("simulation.timestep", message) shared_storage["start_time"] = ( datetime.strptime(time, "%Y-%m-%dT%H:%M:%S.%f") + timedelta(seconds=shared_storage["time_step"]) ).strftime("%Y-%m-%dT%H:%M:%S.%f") print(f"Sent timestep {time}")
import asyncio from kubesat.validation import MessageSchemas, SharedStorageSchemas from kubesat.services import ServiceTypes from kubesat.base_simulation import BaseSimulation simulation = BaseSimulation(ServiceTypes.Template, SharedStorageSchemas.TEMPLATE_STORAGE, "./template_config.json") @simulation.startup_callback async def test_zero(natsHandler, shared_storage, logger): print("Hello, I am starting!!") @simulation.subscribe_nats_callback("publish-test", MessageSchemas.TEST_MESSAGE) async def test_one(msg, natsHandler, shared_storage, logger): print(msg.encode_json()) print(natsHandler._connection_string) print(shared_storage) await logger.error("This is template service") message = natsHandler.create_message({"testData": "Hello, it's me, 1!"}, MessageSchemas.TEST_MESSAGE) await natsHandler.send_data("data.test", message) print("Sent data 1 ") @simulation.subscribe_nats_callback("publish-test", MessageSchemas.TEST_MESSAGE)
import json from kubesat.validation import MessageSchemas, SharedStorageSchemas from kubesat.base_simulation import BaseSimulation from kubesat.services import ServiceTypes simulation = BaseSimulation(ServiceTypes.Config, SharedStorageSchemas.CONFIG_SERVICE_STORAGE, "./simulation_config/simulation/config.json") @simulation.request_nats_callback("initialize.service", MessageSchemas.SERVICE_TYPE_MESSAGE, append_sender_id=False) async def initialize_service(message, nats_handler, shared_storage, logger): """ Initalizes services based on given config files Args: message (Message): incoming message with the ID of the sending Satellite nats_handler (NatsHandler): NatsHandler used to interact with NATS shared_storage (dict): Dictionary to persist memory across callbacks logger (JSONLogger): Logger that can be used to log info, error, etc, """ service_type = message.data print( f"Initializing {service_type} while config storage is {shared_storage}" ) for service in shared_storage["simulation"]: if service == service_type and not shared_storage["simulation"][ service]: