Skip to content
This repository has been archived by the owner on Sep 29, 2021. It is now read-only.

Commit

Permalink
Merge pull request #9 from VIP-LES/develop
Browse files Browse the repository at this point in the history
Final changes before launch, added some bash scripts to make things e…
  • Loading branch information
Skyman authored Apr 6, 2017
2 parents a5b2274 + bb7ee39 commit 99672db
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 48 deletions.
53 changes: 48 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,73 @@ These instructions will get you a copy of the project up and running on your loc

The software is designed to be run on a Docker container where a number of software libraries will be installed. As a result, the docker-ce package is required. Run the following command to install Docker:

`curl -sSL https://get.docker.com | sh`
```bash
curl -sSL https://get.docker.com | sh
```

### Building the Image

The Docker image is not available at the moment on the Docker hub, as a result, you need to compile it using the following command:

`docker build -t gtviples/verne .`
```bash
docker build -t gtviples/verne .
```

### Installing and Running

To run the project, a container must be created with this image and the correct parameters, including the unless-stopped restart policy and the correct volume links to any devices. For example:
To run the project, a container must be created with this image and the correct parameters. For example:

```
```bash
docker create \
--name=verne
--device /dev/ttyAMA0 \
--device /dev/i2c-1 \
-v /home/pi/vernedata:/data \
--restart=on-failure \
gtviples/verne
```

Then, the container can be started and stopped using the `docker start verne` and `docker stop verne` commands.

Note that we are not running this container with a restart policy because of the fact that we want the code to run just once.
As a result, we need another way of making sure that the container is started on startup.

We start by making sure that the responsibility of starting docker is on systemd and not on upstart:

```bash
echo manual | sudo tee /etc/init/docker.override
sudo systemctl enable docker
```

We will use a systemd service setup to ensure that our container is run on boot. Create a file `/etc/systemd/system/verne.service` with the following contents:
```
[Unit]
Description=Verne
Requires=docker.service
After=docker.service
[Service]
Restart=no
ExecStart=/usr/bin/docker start -a verne
ExecStop=/usr/bin/docker stop -t 5 verne
[Install]
WantedBy=default.target
```
For convenience, this file is provided in the repository so that you can just copy and paste it.

To run the service, do the following:
```
systemctl daemon-reload
systemctl start verne.service
```

And to set it to start on startup, do the following:
```bash
systemctl enable verne.service
```

The script can be built using `sudo ./scripts/build-image.sh`, the container can be created using `sudo ./scripts/create-container.sh` and the startup settings can be configured using `sudo ./scripts/startup-config.sh`

## Built With

* [Docker](https://www.docker.com/) - The container-based deployment system
Expand Down
68 changes: 25 additions & 43 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,6 @@
fileDir = os.path.dirname(os.path.realpath(__file__))
CONFIG_PATH = "/data/config.yml"

class GracefulKiller:
kill_now = False

def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)

def exit_gracefully(self, signum, frame):
self.kill_now = True

def getSmallestCSVFileNumberGreaterThan(currentFile, modules):
# If files exist, we want to find an int at which file-i does not exist, and increment it
# once more to make it clear that this is from a new recording.
Expand All @@ -41,7 +31,7 @@ def getCSVFilesFromModules(modules, missionTime, i):
csvs = {}
for m in modules.keys():
f = open('/data/%s-%d.csv' % (m, i), 'wb')
writer = csv.writer(f, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
writer = csv.writer(f, delimiter=', ', quotechar='|', quoting=csv.QUOTE_MINIMAL)

printableMissionTime = missionTime - datetime.fromtimestamp(0)
writer.writerow([int(printableMissionTime.total_seconds() * 1000)])
Expand All @@ -55,8 +45,6 @@ def closeCSVFiles(csvs):
c[0].close()

if __name__ == '__main__':
killer = GracefulKiller()

# Initialize the logger
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("verne")
Expand Down Expand Up @@ -131,46 +119,40 @@ def death(error):
timeToRenewFile = missionTime + timedelta(hours=cutFileAfterHours)

currentFile = getSmallestCSVFileNumberGreaterThan(0, modules)
currentFile += 1 # So that we get a gap from the last time this script was run

logger.info("Creating initial CSV files. File number: %d" % currentFile)
csvs = getCSVFilesFromModules(modules, missionTime, currentFile)

logger.info("Liftoff: starting recording.")

forcedStop = False
while True:
currentTime = datetime.now()
missionElapsedTime = int((currentTime - missionTime).total_seconds() * 1000)

if currentTime > timeToKill:
# It's time to end the recording! Goodbye!
forcedStop = False
break
try:
while True:
currentTime = datetime.now()
missionElapsedTime = int((currentTime - missionTime).total_seconds() * 1000)

if currentTime > timeToRenewFile:
closeCSVFiles(csvs)
if currentTime > timeToKill:
# It's time to end the recording! Goodbye!
break

currentFile = getSmallestCSVFileNumberGreaterThan(currentFile, modules)
csvs = getCSVFilesFromModules(modules, missionTime, currentFile)
if currentTime > timeToRenewFile:
closeCSVFiles(csvs)

timeToRenewFile = currentTime + timedelta(hours=cutFileAfterHours)
logger.info("File cutoff time reached. New file number: %d" % currentFile)
currentFile = getSmallestCSVFileNumberGreaterThan(currentFile, modules)
csvs = getCSVFilesFromModules(modules, missionTime, currentFile)

for m in modules.keys():
data = modules[m].poll(missionElapsedTime)
timeToRenewFile = currentTime + timedelta(hours=cutFileAfterHours)
logger.info("File cutoff time reached. New file number: %d" % currentFile)

if data is not None and len(data) > 0:
writer = csvs[m][1]
for m in modules.keys():
data = modules[m].poll(missionElapsedTime)

for datum in data:
writer.writerow([missionElapsedTime] + list(datum))

if killer.kill_now:
forcedStop = True
break
if data is not None and len(data) > 0:
writer = csvs[m][1]

closeCSVFiles(csvs)
if forcedStop:
logger.info("The script has been force-stopped. Maybe restart it?")
sys.exit(1)
else:
for datum in data:
writer.writerow([missionElapsedTime] + list(datum))
finally:
closeCSVFiles(csvs)
logger.info("The eagle has landed: stopping recording. Goodbye!")
sys.exit(0)
4 changes: 4 additions & 0 deletions scripts/build-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
set -ex #Fail if any line fails, print everything

docker build -t gtviples/verne .
4 changes: 4 additions & 0 deletions scripts/create-container.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
set -ex #Fail if any line fails, print everything

docker create --name=verne --device /dev/ttyAMA0 --device /dev/i2c-1 -v /home/pi/vernedata:/data gtviples/verne
13 changes: 13 additions & 0 deletions scripts/startup-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh
set -ex #Fail if any line fails, print everything

SCRIPTDIR="$(dirname "$0")"

# Copy the service
\cp -rf "$SCRIPTDIR/../verne.service" /etc/systemd/system/

# Reload systemd
systemctl daemon-reload

# Add it to startup
systemctl enable verne.service
12 changes: 12 additions & 0 deletions verne.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Verne
Requires=docker.service
After=docker.service

[Service]
Restart=no
ExecStart=/usr/bin/docker start -a verne
ExecStop=/usr/bin/docker stop -t 5 verne

[Install]
WantedBy=default.target

0 comments on commit 99672db

Please sign in to comment.