Tutorial 1: Scepter setup and configuration

This is the first tutorial in a five-part series. By the end of the fifth and final tutorial, our aim is to have set up both Scepter and Javelin to work on our machines. Then, by configuring the two to communicate, we can create a full engineering workbench which allows the user to send a ping to a ‘satellite’ and receive a message back via the workbench.
During this tutorial, we will introduce you to Scepter, the OSSO Command and Control API. This tutorial will take you through how we were able to set up Scepter to work both locally on our machine and remotely on a local network, and how to send some basic commands.

Workbench overview

To begin, install the Scepter package from GitLab using any installation method (this tutorial was written using a simple ZIP file download on a Linux Ubuntu OS, however any standard installation of the repository will be sufficient.)
You will also need to download and install PostgreSQL 11+, the database software for this API. It is assumed that you have installed and configured PostgreSQL to your system prior to continuing on to the next step of the tutorial. For those who haven't, some helpful links are provided below.

Environment setup

To run the code, it is recommended that a virtual environment is used. This will prevent any conflicts between Scepter's configuration and the pre-existing dependencies on your computer. To create the virtual environment and install the required packages, use the following commands in the scepter-master directory.
1
python3 -m venv venv
2
source venv/bin/activate
3
pip install --upgrade pip
4
pip install -r requirements-dev.txt
Along with this, the database environment file, example.env will need to be copied from the scepter-master directory to the scepter directory and be renamed .env. You will eventually need to update this file to match your own Postgres database, however, it acts as a good example and starting point.
Once this is complete, you will need to run an update to your database. To do this, use the following terminal commands from the scepter-main directory. Before running these commands, ensure that the configuration file in the Scepter directory is updated to match your Postgres setup (i.e. your username and password, etc.)
1
cd scepter
2
python -m migrator.main
Alternatively, you may wish to speed up the above process by simply running the following shell script file from the scepter-master directory.
1
#!/bin/sh
2
# This is a shell script file that will set up Javelin ready for use as per
3
# OSSO Tutorial 1: Scepter Setup and Configuration. It does not include updating
4
# the exampl.env to User's local installation of PostgreSQL.
5
6
# From the Scepter Master Directory
7
# Step 1: Create and configure Virtual Environment
8
python3 -m venv venv
9
source venv/bin/activate
10
pip install --upgrade pip
11
pip install -r requirements-dev.txt
12
13
# Step 2: Copy example.env file to the scepter directory
14
cp ~/Documents/scepter-master/example.env ~/Documents/scepter-master/scepter/.env
15
16
# Step 3: Migrate Database
17
cd ~/Documents/scepter-master/scepter
18
python3 -m migrator.main
19
20
# Step 4: Run pytest to check the setup and code
21
cd ~/Documents/scepter-master
22
pytest scepter
The last step in this process runs a test on the Scepter installation to check for any errors or missing components in the installation. It is recommended that users do this for every new installation of Scepter.

Running Scepter

Once the setup is complete, Scepter can be activated by running the following command from the scepter directory.
1
python -m gunicorn api:app -c api/gunicorn.conf.py
The terminal should then print out the following (or similar) messages.
1
[2022-06-21 15:04:20 +1000] [2570] [INFO] Starting gunicorn 20.1.0
2
[2022-06-21 15:04:20 +1000] [2570] [INFO] Listening at: http://0.0.0.0:5000 (2570)
3
[2022-06-21 15:04:20 +1000] [2570] [INFO] Using worker: sync
4
[2022-06-21 15:04:20 +1000] [2571] [INFO] Booting worker with pid: 2571
5
[2022-06-21 15:04:20 +1000] [2572] [INFO] Booting worker with pid: 2572

Talking to Scepter (local)

Scepter is designed to take requests and respond in the HTTP format. With each request, Scepter requires a series of headers to ensure that the correct information is given to right people. There are three headers, the content type, user number, and user access token. Since Scepter is being run locally in this tutorial, you can simply use the series of headers below with their requests.
1
headers = {
2
"Content-Type": “application/json”,
3
"x-osso-user":00000000-0000-0000-0000-000000000000,
4
"x-osso-token": “dev”
5
}
To make life easier, it is recommended that you make requests to Scepter via a Python script. To do this, install the Requests and PPrint libraries as they will be used in the remainder of the tutorial.
To install the packages on Linux Ubuntu OS, use the following commands in the terminal.
1
pip install requests
2
pip install pprint
The first command we will go through gets a list of satellites in your database. We get to this by accessing the satellite endpoint of Scepter by running the following lines in Python.
1
import requests
2
import pprint
3
4
url = ‘http://localhost:5000/satellite’
5
response = requests.get(url=url, headers=headers)
6
pprint.pprint(response.json())
User's should then receive the following message (or similar) in the terminal.
1
{‘pages’: 1, ‘sat_results’: [], ‘total_pages’: 1}

Talking to Scepter (remote)

As previously mentioned, this tutorial was written using a Linux OS. All the methods, commands and coding has been designed around this. It is not supported for other operating systems.
To talk to Scepter remotely, a similar process will be followed. Since Scepter runs on the ‘0.0.0.0’ host, it is able to communicate wih other devices on the same network. To send a command via another device, first check that your firewall isn't blocking the connection port (by default, this is port 5000). If this is clear, you should be able to update the URL in the above script to be able to access Scepter on another computer.
The same command as above becomes:
1
import requests
2
import pprint
3
4
headers = {
5
‘Content-Type’: “application/json”,
6
‘x-osso-user’:00000000-0000-0000-0000-000000000000,
7
‘x-osso-token’: “dev”
8
}
9
10
url = ‘http://[IPv4 Address]:5000/satellite’
11
12
response = requests.get(url=url, headers=headers)
13
pprint.pprint(response.json())
The response should be the same as the local response. Some important tips to note when doing this for the first time:
  • Ensure the correct IP address is being used (this could change if your internet connection changes).
  • Ensure the correct port is being used (will be port 5000 by default).
  • Check the computer's firewall settings in case there is a blockage in one of the ports (inbound or outbound)

Basic Scepter examples

The following section will show users how to reach and communicate with some other Scepter endpoints. These will be done using a local host server under a similar setup to the scripts seen above. For a full extensive outline, see the Introduction.

Get a single satellite

You will notice when using the above command, when there is more than one or two satellites in the database, the terminal response can get large. Scepter does have the ability to return the information for a particular satellite via the use of the satellite's ID. This can be done for the following script.
1
import requests
2
import pprint
3
4
headers = {
5
'Content-Type': 'application/json',
6
'x-osso-user': '00000000-0000-0000-0000-000000000000',
7
'x-osso-token': 'dev'
8
}
9
10
sat_id = input('Enter the satellite\'s ID: ')
11
url = 'http://localhost:5000/satellite/' + sat_id
12
13
response = requests.get(url=url, headers=headers)
14
pprint.pprint(response.json())

Create a new satellite

1
import requests
2
import pprint
3
4
headers = {
5
'Content-Type': 'application/json',
6
'x-osso-user': '00000000-0000-0000-0000-000000000000',
7
'x-osso-token': 'dev'
8
}
9
10
url = 'http://localhost:5000/satellite/'
11
12
tle_query = {
13
'norad_cat_id': '0001',
14
'tle_line_0': 'ISS(ZARYA)',
15
'tle_line_1': '1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927',
16
'tle_line_2': '2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537',
17
'last_updated': '22-06-21T17:52:30',
18
'object_type': 'Station'}
19
20
querystring = {'commission_date': '2022-06-21T00:00:01',
21
'config': 'None',
22
'decoder': 'None',
23
'description': 'this is a new sat from querystring builder',
24
'encoder': 'None',
25
'launch_date': '2022-06-20T00:00:01',
26
'norad_id': '0001',
27
'nssdc_id': '0002',
28
'publicly_visible': False,
29
'sat_name': 'test for querybuild',
30
'tle': tle_query
31
}
32
33
response = requests.post(url=url, headers=headers, json=querystring)
34
pprint.pprint(response.json())
If the satellite is successfully added, a message should appear in the terminal with the following format:
1
{"msg": "<Scepter Message>", "sat_id": "<sat_id>"}

Update a satellite

To update a satellite's information, a similar process can be used. However, Scepter doesn't require you to rewrite all the fields seen above. To update a satellite, the only mandatory fields to be updated are the NORAD and NSSDC ID's. Along with this, the input requires the satellite name and description fields along with the fields to be updated. An example of this can be seen in the script below.
1
import requests
2
import pprint
3
4
headers = {
5
'Content-Type': 'application/json',
6
'x-osso-user': '00000000-0000-0000-0000-000000000000',
7
'x-osso-token': 'dev'
8
}
9
10
url = 'http://localhost:5000/satellite/<sat_id>'
11
12
querystring = {'description': 'this is a new sat from querystring builder',
13
'norad_id': '0002',
14
'nssdc_id': '0003',
15
'sat_name': 'test for querybuild',
16
'<field to be updated>': '<update>'
17
}
18
19
response = requests.put(url=url, headers=headers, json=querystring)
20
pprint.pprint(response.json())
Again, following this, you should receive a message in the terminal with the format.
1
{"msg": "<Scepter Message>", "sat_id": "<sat_id>"}
Along with this, there is a subsection below provided to help you with the formatting of the querystring input.

Conclusion

This concludes the tutorial. For more information, see the source code or documentation on Scepter. The next tutorial will take you through setting up Javelin.

Additional resources

To help you get familiar with the inputs and the formats required in the requests above, some helpful scripts have been provided. All code from this tutorial is also summarized and compiled within the Tutorial 1 package in the OSSO Tutorials folder.

New satellite input format

The code below was made to help you out with creating a new satellite. For more information on the inputs, you should see the Scepter documentation.
1
# Outline the inputs
2
commission_date = 'YY-MM-DD' + 'T' + 'HH:MM:SS'
3
launch_date = 'YY-MM-DD' + 'T' + 'HH:MM:SS'
4
decoder = 'None'
5
encoder = 'None'
6
description = 'Satellite Description'
7
norad_id = '1234'
8
nssdc_id = '4321'
9
publicly_visible = 'True' # or False
10
sat_name = 'example sat'
11
tle_query = {} # See example
12
13
# Build the input file
14
output = {
15
'commission_date': commission_date,
16
'decoder': decoder,
17
'description': description,
18
'encoder': encoder,
19
'launch_date': launch_date,
20
'norad_id': norad_id,
21
'nssdc_id': nssdc_id,
22
'publicly_visible': publicly_visible,
23
'sat_name': sat_name,
24
'tle': tle_query
25
}

TLE input format

The code below was made to help with the Two Line Element (TLE) input for the Satellite endpoint. It should be used in conjunction with the above and/or below scripts.
1
# Example format for ISS
2
norad_cat_id = "0001"
3
tle_line_0 = "ISS(ZARYA)"
4
tle_line_1 = "1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927"
5
tle_line_2 = "2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537"
6
update_time = "22-06-21T17:52:30"
7
object_type = "Station"
8
# # Build the input file
9
tle_query = {
10
"norad_cat_id": norad_cat_id,
11
"tle_line_0": tle_line_0,
12
"tle_line_1": tle_line_1,
13
"tle_line_2": tle_line_2,
14
"last_updated": update_time,
15
"object_type": object_type
16
}

Update satellite input format

The code below was made to help you with the update. It is written in a similar style as above and includes the necessary fields plus a single updated field to the input. Note, you are allowed to update multiple fields in one request.
1
# Examples of possible inputs
2
sat_name = "example sat"
3
description = "Satellite Description"
4
norad_id = "1234"
5
nssdc_id = "4321"
6
field_to_update = "launch_date"
7
update_to_field = 'YY-MM-DD' + 'T' + 'HH:MM:SS'
8
9
# Build the input file
10
output_put = {
11
"sat_name": sat_name,
12
"description": description,
13
"norad_id": norad_id,
14
"nssdc_id": nssdc_id,
15
field_to_update: update_to_field
16
}
Table of contents