-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from tetrabiodistributed/move-display-code-to-p…
…roject-tetra-display-repo move display code to project-tetra-display repo
- Loading branch information
Showing
48 changed files
with
3,862 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
FROM golang:latest | ||
EXPOSE 8000 | ||
RUN apt update \ | ||
&& apt install -y libzmq5-dev \ | ||
python3-zmq \ | ||
supervisor \ | ||
python3-pip | ||
RUN go get github.com/pebbe/zmq4 && go get github.com/gorilla/websocket | ||
|
||
RUN mkdir -p /var/log/supervisor | ||
RUN mkdir -p /src/zmq_proxy/static | ||
RUN mkdir -p /src/zmq_proxy/TestData | ||
WORKDIR /src/zmq_proxy | ||
COPY main.go /src/zmq_proxy | ||
COPY static /src/zmq_proxy/static | ||
RUN go build | ||
|
||
COPY requirements.txt /src/zmq_proxy | ||
RUN pip3 install -r /src/zmq_proxy/requirements.txt | ||
COPY *.py /src/zmq_proxy/ | ||
COPY TestData/20200609T2358Z_patrickData.txt /src/zmq_proxy/TestData | ||
COPY services.conf /etc/supervisor/conf.d/services.conf | ||
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
How to Run an Application at Launch on a Raspberry Pi | ||
===================================================== | ||
|
||
Running an application at launch is fairly simple. You simply use the `autostart` system to add to the boot procedure (there are other ways, but `autostart` guarantees that the X windowing system is loaded). To do this, you need to create a file `/home/pi/.config/autostart/TetraVentilatorSplitter.desktop` (or whatever name `*.desktop`), and add this bit of code to it: | ||
|
||
``` | ||
[Desktop Entry] | ||
Name=TetraVentilatorSplitter | ||
Exec=# Whatever you run to execute the application | ||
``` | ||
|
||
Then you can save that file and `sudo reboot` and the Pi will launch into the application specified. | ||
|
||
This is based on the tutorial [here](https://learn.sparkfun.com/tutorials/how-to-run-a-raspberry-pi-program-on-startup/all). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
How to Run a Docker Container from a Python Script | ||
================================================== | ||
|
||
Docker is a very useful tool for when you want to run an application from a known environment. If you're developing a Docker container and testing the components within it outside the container, you may want to write a test program to validate your container. The obvious way to do this in Python is by calling shell commands with `os.system()`. But you can, in fact, use the Docker SDK to do this! | ||
|
||
This snippet here | ||
```python | ||
import docker | ||
|
||
client = docker.from_env() | ||
image = client.images.build( | ||
path=".", tag="example:latest") | ||
container_name = "example_container" | ||
client.containers.run("example:latest", | ||
name=container_name, | ||
detach=True, | ||
auto_remove=True, | ||
ports={"8000/tcp": 8000}) | ||
|
||
# Test that it's working | ||
|
||
client.containers.get(container_name).kill() | ||
``` | ||
is equivalent to this shell script. | ||
```bash | ||
docker build -t example:latest . | ||
docker run --rm -dp 8000:8000 --name example_container example:latest | ||
# Test that it's working | ||
docker kill example_container | ||
``` | ||
You can learn more about the Docker SDK at https://docker-py.readthedocs.io/en/stable/. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
How to set up a Raspberry Pi for headless developement | ||
====================================================== | ||
|
||
Writing software for a Raspberry Pi is an interesting challenge because the outcome of the software often depends on the particular hardware configuration of the Pi, especially if you're writing software that uses sensors and other auxilliarly hardware. The easiest way to write software then is to connect a monitor and keyboard to the Pi and do development directly on the hardware. However, this is suboptimal because you can't necessarily use your favorite text editor, and Pis up through the 3B+ can only connect to one monitor. A better solution is to do headless development where you send files from your big computer to the Pi over a network communication protocol. | ||
|
||
To make this happen, you're going to need to set up SSH on the Pi and SFTP communication on you big computer. | ||
|
||
SSH | ||
--- | ||
|
||
There are many online tutorials to set up SSH on the Pi. I think [this one]() is good. Also as a quality-of-life thing, you can add your Pi's IP address to `/etc/hosts` so you don't have to type out the whole IP every time. | ||
|
||
After you've done all that, you'll need to get onto your Pi with a monitor and keyboard and enter `ssh [username]@[hostname]` into the the terminal. Then you can remove your monitor and keyboard from the Pi for good. Enter `ssh [username]@[hostname]` into your big computer's terminal and you'll be set. | ||
|
||
SFTP | ||
---- | ||
|
||
The details of how to set up SFTP will depend on your text editor. I'll show how to do this for Sublime Text. | ||
|
||
1. First, make sure the package manager is set up. Open the command palette with Ctrl+Shift+P (Linux/Windows) or Cmd+Shift+P (Mac) and type `Install Package Control` and hit Enter | ||
2. Again open the command palette and type `Package Control: Install Package` and hit Enter | ||
3. In the text box that pops up after you hit Enter, type `SFTP` and select the first option that comes up (the description should say something like "Commercial SFTP/FTP plugin - upload, sync, browse, remote edit, diff and vcs integration") | ||
4. Open the root directory for your project with Sublime such that you see the side bar with all the files in it. Right click on the root folder and from the Tooltip menu select `SFTP>Map to Remote...` | ||
5. This will create a file `sftp-config.json` in your project's root directory that defines how the SFTP plugin will connect to your Pi. Make sure to add this file to your `.gitignore` because it'll contain sensitive information like a password. | ||
6. Enter your Pi's IP address for the `"host"` field, your username on the Pi (by default `pi`) for the `"username"` field, and your password for the Pi for the `"password"` field (make sure you have a password on your Pi if you don't already). | ||
7. By default, you need to manually tell the SFTP program which file to upload to the Pi when. But if you set `"upload_on_save"` to `true`, then it'll upload every time you save. | ||
|
||
Once you've got SSH and SFTP set up, you can just write code, it'll update on the Pi automatically, and the you can test you code in the Pi's terminal on your big computer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
How to turn on the Tetra Ventilator Splitter | ||
============================================ | ||
|
||
1. Ensure that the splitter is connected to a power supply | ||
|
||
2. Ensure that the airlines connecting the splitter and ventilator are attached (detailed in a serperate document) | ||
|
||
3. Flip the on-off switch to on | ||
|
||
4. After a short boot-up sequence, a screen showing data for each of the patient airlines should appear, which looks like this | ||
|
||
![Tubing data information screen](https://cdn.discordapp.com/attachments/718703783730741290/720436682851352697/VentilatorDisplay_1.jpeg) | ||
|
||
- If this screen doesn't appear, ensure that the Tetra Ventilator Splitter software is installed | ||
|
||
5. Verify that all the tubing connections are good | ||
|
||
1. Plug in a patient tubing to port 1 | ||
|
||
2. Connect the patient tubing to a lung model or a balloon | ||
|
||
3. Turn on the ventilator | ||
|
||
4. The numbers on column 1 of the Tubing Data Information Screen should be changing | ||
|
||
- If the numbers are not changing, make sure the stop valve for that port is open | ||
|
||
5. Turn the knobs on the control valves for that port. The PIP and PEEP values should change with them | ||
|
||
- If they aren't changing, ensure all the pneumatic connections are made and tight | ||
|
||
6. Repeat substeps 1.-5. for ports 2, 3, and 4 | ||
|
||
6. Sterilize the patient tubing used for testing and begin treating patients | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
How to Use the SPL06-007 Pressure Sensor | ||
======================================== | ||
|
||
The SPL06-007 is a calibrated pressure sensor often used for drone applications. This describes how to use the sensor via it's I2C interface, though it'd only really be a change in the first step to use a 3- or 4-wire SPI interface (and in hardware of course). Note that I connected the sensor to a Raspberry Pi via an I2C multiplexor (mux), so the second step isn't necessary if you don't have that. | ||
|
||
- To initialize I2C, I use Adafruit's busio.I2C(board.SCL, board.SDA) | ||
- For the mux select, I write a [0-4] integer to 0x70 (there's also a mux on 0x74, but I don't have anything connected to it right now, so it doesn't do anything. | ||
- I then reset the sensor to clear any previous state by writing 0b1001 to 0x0C | ||
- After that, I set the sensor into standby mode by writing 0 to 0x08 | ||
- Then in the case of the tests I'm having issues with, I set the sensor to measure pressure at 1Hz with 16 measurements per sample by writing 0 | 0b0100 to 0x06. Because there are more than 8 measurements per sample, I also set the sensor to bit shift the pressure by writing 0b0100 to 0x09. | ||
- I do the same to get the temperature, but now it's 1Hz 1 sample, so 0 | 0 gets written to 0x07. | ||
- Then I set the op mode to "command-pressure" by writing 0b0001 to 0x08 so I can read out what the current pressure is. | ||
- After waiting a few milliseconds for the measurement to be ready, I read addresses 0x00, 0x01, and 0x02 to get the pressure measurement. | ||
- Then the op mode is changed to "command-temperature" by writing 0b0010 to 0x08. | ||
- Finally, I read the temperature measurement from 0x03, 0x04, and 0x05 | ||
|
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
Ventilator Splitter Display | ||
=========================== | ||
|
||
A system to take pressure and flow data from sensors on a ventilator splitter, calculate descriptive parameters based on these data like PEEP or Tidal Volume, and display them for medical professionals to monitor. This is for use against COVID-19. | ||
|
||
To set it up for tests, run `./setup.sh` to build the virtual environment and then `source ./venv/bin/activate` to activate it. To do the tests, run `./runtests.sh`. This will first show the results of unit tests and then behaviour tests. | ||
|
||
To run the display, first make sure Docker is installed, then run these commands. | ||
|
||
```bash | ||
docker build -t zmq_proxy:latest . | ||
docker run --rm -p 8000:8000 zmq_proxy:latest | ||
``` | ||
|
||
Then open http://localhost:8000 in a browser. With this, you'll see a webpage which every second writes some JSON in a bullet list, where each bullet ought to looks something like this (though it won't be printed as nicely). | ||
|
||
```json | ||
{ "0": { "Flow Rate": -0.12102553332090354, | ||
"Inspiratory Pressure": 25.185687032203397, | ||
"PEEP": 7.600443036648329, | ||
"Peak Pressure": 29.143715376593427, | ||
"Tidal Volume": 2982.643040302767}, | ||
"1": { "Flow Rate": -0.1853025137003232, | ||
"Inspiratory Pressure": 27.589362195098154, | ||
"PEEP": 9.0296093948397, | ||
"Peak Pressure": 32.05751894822633, | ||
"Tidal Volume": 123.60199756683565}, | ||
"2": { "Flow Rate": -0.23654912423232322, | ||
"Inspiratory Pressure": 26.474812956451874, | ||
"PEEP": 7.607352013212795, | ||
"Peak Pressure": 27.6944434648811, | ||
"Tidal Volume": 3712.3769706397325}, | ||
"3": { "Flow Rate": 0.13331473843016745, | ||
"Inspiratory Pressure": 10.52283673388029, | ||
"PEEP": 7.33283292927223, | ||
"Peak Pressure": 23.519565988527702, | ||
"Tidal Volume": 359.06476658825846}} | ||
``` |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import tkinter as tk | ||
|
||
# A cheezy thing to make a green screen to superimpose images onto | ||
|
||
root = None | ||
|
||
def destroy(event=None): | ||
global root | ||
root.destroy() | ||
|
||
if "__main__" == __name__: | ||
root = tk.Tk() | ||
root.title("Green") | ||
frame = tk.Frame(root, cursor="none", bg="green") | ||
frame.pack(fill=tk.BOTH, expand=1) | ||
root.bind("<Escape>", destroy) | ||
root.attributes("-fullscreen", True) | ||
root.mainloop() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import constants | ||
from tca9548a import I2CMux | ||
import sys | ||
from pathlib import Path | ||
sys.path.append(str(Path(".").absolute().parent)) | ||
|
||
|
||
pressure_sensor_mux = I2CMux(constants.PRESSURE_SENSOR_MUX_ADDRESS) | ||
|
||
print(f"Initial scan:\t\t{pressure_sensor_mux.scan()}") | ||
|
||
for i in range(8): | ||
pressure_sensor_mux.select_channel(i) | ||
print(f"{constants.PRESSURE_SENSOR_MUX_ADDRESS:#x} Mux Port {i}:" | ||
f"\t{pressure_sensor_mux.scan()}") | ||
pressure_sensor_mux.close() | ||
|
||
flow_sensor_mux = I2CMux(constants.FLOW_SENSOR_MUX_ADDRESS) | ||
|
||
for i in range(8): | ||
flow_sensor_mux.select_channel(i) | ||
print(f"{constants.FLOW_SENSOR_MUX_ADDRESS:#x} Mux Port {i}:" | ||
f"\t{flow_sensor_mux.scan()}") | ||
flow_sensor_mux.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import time | ||
|
||
from spl06_007 import PressureSensor, Calibrator, Communicator | ||
|
||
|
||
if "__main__" == __name__: | ||
print("--Initialization") | ||
comms = Communicator(dump_communication=True) | ||
print("--Set Op Mode") | ||
comms.set_op_mode(PressureSensor.OpMode.command) | ||
print("--Set Pressure Sampling") | ||
comms.set_pressure_sampling() | ||
print("--Set Temperature Sampling") | ||
comms.set_temperature_sampling() | ||
|
||
calibrator = Calibrator(comms.calibration_coefficients, | ||
comms.pressure_scale_factor, | ||
comms.temperature_scale_factor) | ||
running = True | ||
with comms: | ||
while running: | ||
try: | ||
print("--Get Pressure") | ||
raw_pressure = comms.raw_pressure() | ||
print("--Get Temperature") | ||
raw_temperature = comms.raw_temperature() | ||
pressure = calibrator.pressure(raw_pressure, raw_temperature) | ||
temperature = calibrator.temperature(raw_temperature) | ||
time.sleep(1.0) | ||
except Exception as exception: | ||
print(exception) # TODO: change this to logging | ||
running = False |
Oops, something went wrong.