(To skip to the building instructions, scroll to the bolded steps text.)
IntroductionThe Covid-19 pandemic has brought a series of new challenges to the world, and one of those is the act of contact tracing. Contact tracing is a method of back-tracing a person's steps to see who they may have come into contact with, in the event that said person has contracted Covid-19. The most common method of doing so is by using mobile phones and recording phone to phone interactions when people pass each other by.
However, not everyone has a phone.
There are many scenarios in which people may be moving from place to place and not have phones. Remote locations where cellular data simply doesn't exist, buildings and towns where phone usage isn't permitted/is restricted (think: dropping phones in a basket before entering a complex), or even urban areas where phones with the proper wireless may not be affordable.
My system aims to fill this gap.
The Universal Low-Cost Contact Tracing Solution (hereafter ULCTS) is a highly-adaptable method of contact tracing in high-movement environments. Utilizing connectionless bluetooth central-peripheral links, the system is seamlessly able to notice and record when someone passes by one of its bluetooth server modules using an opt-in bluetooth peripheral "tag".
For a visual description of the network, see the attached diagrams for this project.
For an operational summary, see Step 8 of the below instructions.
The system works using two major components:
1. Bluetooth Tags
These tags, buildable using any microcontroller device capable of advertising a local name over bluetooth (nRF52840 and similar, either as a breakout board, standalone chip or dev kit; the now-retired Intel Curie module found on Arduino 101; the ESP-32, etc), are the heart of the system. By broadcasting anonymous IDs, they provide data for server modules to record where and when a tag is passing by, without having to actually make any bluetooth connections.
2. Bluetooth-WiFi (or Ethernet) server modules
These modules, which can be built using any device that has WiFi or Ethernet and is also capable of running a python script having access to internal bluetooth data (think: Raspberry Pi, BalenaFin, various Pi clones and derivatives), are responsible for recording data from tags. By combining tag IDs with timestamps and locations, the server is able to record the existence of a particular ID to give to a master device module, which processes the combined data of every module to determine a set of locations and times where and when each ID'd tag has existed. When someone (i.e. a healthcare official) diagnoses someone with Covid-19, they can then look up the tag's ID in the master device to determine locations they have passed, which can then be reported through the relevant public media channels so people have guidance on whether they may need to watch for symptoms or not.
Below are instructions and photos to set such a system up.
Step 1: Procure the tag modules.I developed my system using the nRF52840-DK, which has the area footprint of a phone, the height of a phone, low battery consumption but fairly high cost, retailing somewhat under $100. For a quick, high-output deployment, cheaper breakout boards can be used, though the universality of the system allows literally any board capable of bluetooth advertising to be used, which removes restrictions provided by product availability/shipment regions/etc. The following instructions are for the nRF52840-DK, with instructions for alternate boards given at the proper steps.
Note: the smaller the better. These devices are meant to be carried in your pockets, and while the nRF52840-DK actually is smaller than a mobile phone, it's still fairly large.
If you are not using an nRF52840-DK or similar nRF-based board, instructions here may not be applicable. See the endnote of this step.
Otherwise, you should first download nRF Connect for Desktop. This software is an all-in-one package that contains the tools necessary to program the development kit. Using the link in the things section of this project, scroll down on the page to "downloads" and select the correct version for your operating system. Upon downloading, follow all onscreen instructions to complete setup.
Once installed, open the app and install the toolchain manager. Open it once complete, then click the settings icon at the top of the window. Make sure (this is really important) that the installation directory path does not contain any spaces. If there are spaces, a step further down the line will crash. If there are spaces, use the select directory button to select a target folder with a path that doesn't have spaces in it.
After confirming this, go back to the SDK environments page and install one of the SDKs. I went with 1.2.0, though either should work. The files attached later were generated for 1.2.0 so if you're using those, use 1.2.0.
Once install is complete, hit "Open IDE". This will activate Segger Embedded Studio, which is used to program the board. On first boot, the application will ask you for a license. You should be able to hit a continue button for non-commercial evaluation; however, as Nordic Semiconductor customers (i.e. you, if you're using the nRF52840-DK or similar) are entitled to a free full license. This is explicitly mentioned on this same prompt, and you should be able to fill out the information on the provided form to receive a license key, which you can apply to the application.
Segger Embedded Studio may sometimes ask if you want to overwrite some files. You can either hit yes or no; these have no impact on the final program.
After this step you will be able to use the studio. First, download the following nRF52840-DK peripheral I have attached to this project: CMakeLists.txt, prj.conf and main.c. Save it in a folder named Peripheral (must be named Peripheral) where the directory path, once again, does not contain any spaces in it, then move main.c into a folder called src. In Windows, you would end up with something like this, with main.c inside src:
Open prj.conf in your favourite text editor. Inside there will be a line that says "CONFIG_BT_DEVICE_NAME". The name to the right of this is the name of the peripheral tag. To function properly, every tag must have a separate name, though they must all start with "detect". By default, I've set the name to detect0.
Then go File->open nRF Connect SDK Project.
There are four entry fields that appear. The first asks for the location of "CMakeLists.txt". This is a makefile used in project compilation, and is located back in the directory where you saved the downloaded project. Set the path in this field to lead to that file.
Note that this is the step that will crash if you have spaces in your directory filepaths. Again, make sure you don't.
The next asks for a board directory. This is where files for your board are stored. You will find this in the directory for the SDK install (which is specified back in toolchain manager under settings), by going v1.2.0->zephyr->boards->arm. Inside this folder are various directories for various boards are located. Choose the one that matches your board. If you are using an nRF52840-DK, it's nrf52840_pca10056. Other nRF boards have different product IDs and you can either find this on your board (mine was a sticker) or by looking up your product online. Paste the filepath to this directory into this second field.
Upon doing the above step, other fields should autofill. If they don't, see the screenshot below for the format they should be in. "C:/nrfprojects/" was my project directory; replace this with yours.
Check the Clean Build Directory box, which ensures the build directory is fresh for use. Then hit ok and wait for the project to load. You will then be presented with a large series of files. One of these says 'project app/libapp.a'. Hit the triangle beside it, the triangle by the folder inside that, and then double-click main.c.
You are then presented with the following code:
/*
* Code based on Zephyr libraries and an example
* that were Copyright (c) 2015-2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bluetooth/bluetooth.h> // bluetooth library
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR))
}; // bluetooth data struct containing default data about the board
void main(void)
{
// turn bluetooth on
bt_enable(NULL);
// advertise the local name and equip the above data struct
bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
// do nothing else forever, nothing else needs to be done
while (1);
}
This code simply activates bluetooth on the nRF module and turns advertising on, which automatically takes the name specified in prj.conf as the local name.
Before conducting the next step, take a Micro USB cable and plug one end into the USB port of the nRF52840-DK (the one nearest to the on-off switch, NOT the one labeled nRF-USB. Plug the other end into your computer and make sure the on-off switch on the nRF is on. (If you are using a different nRF board, follow the plug-in steps outlined for said board, which should be more or less equally straightforward.
If the board does not show up as a removable drive, there may be a small chance the following upload doesn't work. If this is the case, you may need to burn the bootloader to the board. If you have an nRF52840-DK, or a handful of other nRF processors you can try the build and run steps after this section without doing the burn, but if anything fails regarding board not found or something along those lines, try the following (note I did not test what would happen if you uploaded without burning the bootloader as I burned the bootloader before uploading):
- Download the Arduino IDE (the offline version) at https://www.arduino.cc/en/main/software
- Open the IDE and go to File->Preferences
- Click the window icon to the right of Additional Boards Manager URLs and paste this link inside the resulting popup: https://www.adafruit.com/package_adafruit_index.json
- Click ok, then ok again
- Go Tools->Board->Boards Manager
- Scroll down until you find the Adafruit nRF52 boards and install it
- Go Tools->Board and select Nordic nRF52840-DK (PCA10056) (if you are using a different device, you can check if it is supported here; if not, find the bootloader burn instructions for your board in the support documents for your board online)
- Tools->Programmer and select J-Link for Bluefruit nRF52
- With your nRF board plugged in, do Tools->Burn Bootloader and wait for burning to complete
- Close the IDE
Next, go to Build->Build and Run.
This compiles the code and uploads it to the nRF52840-DK using Segger's J-Link system. Note that I am not entirely sure whether this is a built-in component of the application or not, as I did a large amount of experimenting in order to achieve the straightfoward series of steps you see above. In the event that the application raises an error regarding J-link not existing, or the Build and Run link is greyed out, try downloading nRF Command Line tools at https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Command-Line-Tools/Download, which contains this program and will put it on your device. I did this before getting nRF Connect for Desktop, so I am unsure of the strict dependencies.
If everything worked, the nRF52840-DK or similar should now be successfully equipped with the Peripheral firmware. This completes Step 2.
To deploy the firmware to additional boards, do the following steps:
- Unplug the existing device
- Find the folder on your computer where you put the project directory
- Delete the existing build folder (it should have your board's name on it)
- Open prj.conf and change the name to a different one (again, still keeping the detect prefix)
- Go back to Segger Embedded Studio and repeat the original procedure from File->open nRF Connect SDK Project onwards, plugging in your new board instead of the old one.
FOOTNOTE: if you are not using an (nRF or not) board supported by the nRF SDK, you may be using one supported directly by the Arduino IDE. If this is the case, which you can check with a quick internet search of your board plus "Arduino IDE", do the following:
- Download the Arduino IDE from https://www.arduino.cc/en/main/software
- If necessary, go to File->Preferences and open the Additional Boards Manager URLs window, then add a boards manager URL in place of the previously mentioned Adafruit one (when you search the internet for confirmation, if a URL is necessary, it will be mentioned, otherwise it may already be in the boards manager)
- Go Tools->Board->Boards Manager and find the package for your board, then download it
- Go File->Examples and scroll down until you find examples for your board. If your board uses bluetooth, there should be bluetooth examples in there. If not, your particular board may need an extra library, which you can obtain by 1. figuring out which library you need with a quick internet search of the board plus "arduino bluetooth library", 2. Sketch->Include Library->Manage Libraries, 3. searching the name of the library you need, then downloading it, 4. File->Examples, then scrolling down until you see the name of your library
- In the examples folder for the relevant bluetooth library, look for an example that relates to peripherals, and find the simplest example possible (usually LED).
- Inside the example code will be a line that says "setLocalName" or something along those lines. Change the string to say "detect###" where ### is a unique name or number you haven't used yet for other boards.
- Go Tools->Board and select your board
- Go Tools->Port and select the COM port of your device, which should be plugged in
- Hit the upload button (top left corner) to upload
Now that the tags are programmed, they can be readied for deployment. If you are using an nRF52840-DK, there is a coin cell battery on the back side of the board. Remove the battery and the plastic tag underneath, then place the batter back inside. To power on the board, make sure the VDD switch is set to VDD, the nRF Only/Default switch is set to nRF Only, and the power switch is set to ON. None of the LEDs will power on, but the device itself will power on, using only the nRF chip to save battery power.
If you are using a different device, you may need to use a different method of battery power. Consult the operating instructions of your board to determine a suitable one. This could be either a coin cell battery for an nRF board, a Li-PO battery for ones that support one, or a simple pair of double-As. Make sure you follow specified instructions.
If you'd like, you can create a proper envelope case for your board, which would protect it while it is being carried around. This is much easier for smaller breakout boards.
This concludes all procedures for the peripheral modules.
Step 4: Procuring the WiFi-Bluetooth ServersFor this step, you will need a handful of Raspberry Pi-esque devices. For every spatial point in a building or mall or industrial complex you wish to allow the system to see, you will need one of these. Bluetooth has a specified range of a few hundreds of metres but a practical range of possibly ten (from personal previous testing), so place these accordingly. Server modules will be most effective when placed in high-traffic areas, such as right beside doorways.
I used a BalenaFin v1.0 to test the server setup, which provides the advantage of easy barrel jack wall power, as well as onboard bluetooth and WiFi for the integrated Pi Compute Module 3+Lite. For larger-scale deployments, two options. If you have a large amount of Pi or Pi compatible devices lying around, all of them can be pushed into service for this network. Otherwise, if you are starting from scratch, the $10 Raspberry Pi Zero W contains both network protocols, plus the necessary port peripherals for setup.
Note: I recommend doing this step in the location you will be deploying the board. You will need to obtain some information from the network router you will be plugging the board into, so this will largely simplify the setup process.
If using a Pi Compute Module based system, such as in the BalenaFin, that has no SD card but rather a Micro USB port: download the balenaEtcher program linked in the things section of this project. Once complete, download an image of Raspbian from this link: https://github.com/balena-os/pi-gen/releases (I used image_Raspbian-Fin-full.zip, but lite versions of the OS should work if you know how to use them. The only application necessary for the OS to have is Terminal). Extract this file and open balenaEtcher.
Plug a micro USB cable into the debugging port of the BalenaFin or similar breakout device. If using the v1.0 fin, plug the 12V wall power supply in afterward.
(Note the compute module gets very hot during runtime and lies on the bottom of the board; you may want to elevate it to prevent overheating your surface. I did this fairly crudely using a roll of tape and an LED friction-plugged into a plastic tube, but I recommend a more robust solution such as a plastic enclosure or at the very least screw-on raisers for the corner holes.)
Follow the instructions in balenaEtcher to flash the board. First, you'll need to select flash from file and locate the directory in which you extracted the Raspbian image.
Next, you will need to select target. If you are flashing a compute module for the first time, and are using a Windows device, balenaEtcher will prompt you to download USB drivers. Follow the prompt to find the drivers necessary for your system.
Otherwise, upon clicking Select target the compute module should automatically show up.
Finally, hit Flash, and wait for flashing and verifying to complete. Once finished, unplug the barrel power supply first (if using one), followed by the micro USB cable.
If you are using a Pi based system that uses not internal flash but rather an SD card, download the OS to the card from https://www.raspberrypi.org/downloads/raspberry-pi-os/
Find a keyboard and mouse, along with a suitable HDMI display, and plug them into the board. Alternatively, if you are capable of using SSH to access the board (which requires a configuration step during OS flashing which you can find at step 3 of https://www.raspberrypi.org/documentation/remote-access/ssh/), you can omit this step.
Power on the device. If you are booting into Raspbian for the first time, you will be prompted to set a password, locale, and internet. Make sure you do enable WiFi or Ethernet, as this will be necessary later.
Open Terminal if you are using a GUI OS version, otherwise you should already be in terminal. Run pip3 install bluepy
, followed by pip3 install flask
, which will download necessary Python libraries for the Python3 script that runs the server.
Two options now:
1. Download the attached file "central.py" to your Pi-based device and place it in the root directory, then open your favourite text editor (I use nano) as <name> central.py
(e.g. nano central.py
)
2. Open the text editor with a blank central.py file and directly copy the code in:
# libraries to access bluetooth
from bluepy.btle import Scanner, DefaultDelegate
# flask server
from flask import Flask, jsonify
# for defaultdict
from collections import defaultdict
# for timestamps
import time
# for command-line args
import sys
# create a dict where keys that don't exist are defined as empty lists
entrydict = defaultdict(list)
# set the name of this server to the given name from cmd line
servername = sys.argv[1]
# class for bluetooth scanner object
class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
def handleDiscovery(self, dev, isNewDev, isNewData):
global entrydict
for entry in entrydict:
for log in entrydict[entry].copy():
# if log is 14+ days old (time it takes for symptoms to arise), delete
if time.time() - log[0] > 1209600:
entrydict[entry].remove(log)
# 9 corresponds to the local name of the device
name = dev.getValueText(9)
# if the name is the type we need...
if name and name.startswith("detect"):
# log it with time, device ID and server ID
entrydict[name].append([time.time(), servername])
# create bt scanner
scanner = Scanner().withDelegate(ScanDelegate())
# create flask app with "main"
app = Flask(__name__)
# homepage
@app.route('/')
def main():
# scan for nearby devices
scanner.scan(1)
# send json data containing device logs
return jsonify(entrydict)
if __name__ == '__main__':
IP = "0.0.0.0" # change this to the LOCAL IP of your device (the one that starts with 192.168.1. when you call "ip address" in terminal)
PORT = 80 # change this to the port you forwarded on your router
#run the server on IP and PORT
app.run(host=IP, port=PORT)
Two things will need to be modified. First, you must change IP to the local IP of your device. You can find this by going to terminal and typing in ip address
, which returns IP information about your device. One number is of the form 192.168.1.<something>/<something>. The number before the slash (nothing after) is the IP address you need to type for IP instead of the given default string (make sure you enter it as a string with no ending slash)
Second, if you are not using one single internet network, you will need to provide a port-forwarded port. This step varies in execution depending on what kind of WiFi router you have, so the best solution here is to internet search "how to port forward a router" and click on one of the first options. When choosing the number port to forward, make sure your device is the only one using said port (i.e. if you have multiple devices on one network and are using port forwarding, give them different port IDs). Set PORT in the code to this port ID.
Close the terminal and run the program with sudo python3 central.py <name> &
, where you replace <name> (including brackets) with whatever you want to name your tower. I recommend names based on the location of the board, such as street intersections, store names, room numbers, etc. The sudo part ensures that the program can access bluetooth and the & part allows the program to run in the background, leaving the Pi itself open to whatever else you want to do.
To program more than one server device, repeat this step in its entirety for said device, setting IP and PORT to the corresponding device IP and additionally-forwarded port, respectively (unless you are using just one network, in which case PORT can be anything).
Note that once the program is running, if you have a monitor, mouse and keyboard connected, you can disconnect them. Note however if you are using a GUI-based OS, you will need to plug them in again to restart the program if the device ever shuts down. This can be avoided by using SSH instead of GUI.
This concludes Step 5.
Step 6: Provisioning the Master DeviceBy themselves, the (Ethernet or) WiFi-Bluetooth server modules are capable of sending JSON-based activity data to a particular global IP address on the internet (unless you are using a single internet network with local IPs). To determine this IP address, access https://whatismyipaddress.com/ from inside your server device in a browser, or do wget http://ifconfig.me/ip
followed by cat ip
. Take the IPv4 address and punch it into any web browser anywhere. If you successfully set up the server, and you port forwarded properly, a file of JSON data should appear. This file contains timestamped logs of any tag devices that came into range (which, if you don't have any on, will mean the webpage will just show {} or a blank screen).
(If you are using local IPs over a single network you can directly type in the local IP address you used inside the server, and the data should appear. You will only be able to see this data while inside the network.)
The above image is a simulation of one such site. Tag names are the uppermost level of the data, each of which contains a list of timestamped entries. Each entry is equipped with a Unix timestamp and the name of the location where the meet was recorded.
These pages by themselves, however, are hard to use. Thus, it is best to set up a master device that compiles all this data together for proper reading. Since other devices already have a server running on them, it is best to avoid overworking one of them by running this on a different device. This can be any old desktop or laptop you have, it just needs to be able to access the internet.
This can be accomplished using a basic Python script to avoid having to manage yet another server device. There are two options here: a simple script that anyone can download to their computer and run, or a more complex one that servers another server so that everyone can access the same point.
To build this program, you will need to collect the global IPs of every device in your system. Note that there is a very very small chance that if one of these devices shuts down for whatever reason, it will start back up with a different IP. If you want to avoid this problem, you can either avoid shutting down said device, or attach the global IP to a DNS service such as https://www.duckdns.org/ or anything similar. Only do this if your device is guaranteed to shut down at some point, or if it does not have a Static IP (a quick internet search for "raspberry pi set static ip" will help).
Once you've collected all the IP addresses (or DNS URLs), paste them into one of the following two scripts. Command-Line version (feel free to modify for whatever output format you'd like) (make sure to change utcsub to the correct UTC offset):
import requests # for looking up websites
import time # for timestamps
# replace all entries here with URLs or IPs of all your servers (no limit to how many)
urls = ["192.168.1.00", "192.168.1.01", "192.168.1.02", "192.168.1.03"]
utcsub = -7 # your local UTC offset assuming your servers use UTC
while True:
res = input("Enter a name to lookup\n")
primedict = {}
for url in urls: # get all urls and merge content
content = requests.get(url)
toappend = content.json()
primedict.update(toappend)
primelist = []
for entry in primedict:
if entry == res: # filter list by ID to search
primelist += primedict[entry]
primelist.sort(key = lambda x: x[0]) # sort by time
outstring = ""
for entry in primelist: # format
outstring+=f"{time.ctime(entry[0]+3600*utcsub)}: {entry[1]}\n"
print(outstring)
Flask Server version (you can either access the site through your local network, or run the port-forwarding process again to get a global IP which you can distribute to the public):
from flask import Flask, request # for the server
import requests # for urls
import time # for timestamps
# replace all entries here with URLs or IPs of all your servers (no limit to how many)
urls = ["192.168.1.00", "192.168.1.01", "192.168.1.02", "192.168.1.03"]
utcsub = -7 # your local UTC offset assuming your servers use UTC
app = Flask(__name__)
@app.route('/')
def main():
res = request.args.get('tag') # look for the tag querystring
if not res:
return "Please use the format your_url/?tag=tag_name"
primedict = {}
for url in urls: # get all urls and merge content
content = requests.get(url)
toappend = content.json()
primedict.update(toappend)
primelist = []
for entry in primedict:
if entry == res: # filter list by ID to search
primelist += primedict[entry]
primelist.sort(key = lambda x: x[0]) # sort by time
outstring = ""
for entry in primelist: # format
outstring+=f"{time.ctime(entry[0]+3600*utcsub)}: {entry[1]}<br>"
return outstring
if __name__ == '__main__':
IP = "0.0.0.0" # change this to the LOCAL IP of your device (call "ip address" or check your router homepage)
PORT = 80 # change this to the port you forwarded if you did so
app.run(host=IP, port=PORT)
I have attached both of these to the project attachments below. Pick one and save it to your computer to run. If your master device does not already have Python3, download it at https://www.python.org/downloads/
For convenience, make sure you add Python to PATH if prompted, as this allows Python to be accessed from Terminal (at least in Windows).
Open said terminal and cd (change directory) to the directory where you saved the master device program. Run python3 prime.py
and that's it.
To use the command line version, just enter the ID of the tag you want to look up when prompted.
To use the Flask version, visit your URL with the following format: your_url/?tag=tag_name
where your_url is the URL or IP of your Flask server and tag_name is the name of the tag you want to search up.
This concludes Step 6.
Step 7: Progressing Project DeploymentAfter completing all the above steps, the ULCTS is ready for deployment. This can be done in the following stages:
- Give the tag devices to people who use the area in which you want to deploy the ULCTS. This can be done through entrances, giveaway stations, mail shipments, etc.
- Figure out where you will be deploying the servers. Each location must have WiFi (or Ethernet) and mains power to supply your board. Boards should be relatively off to the side, but still within range (10 m) of your target zone (e.g. a doorway).
- Deploy the servers. If a board is not already plugged in and ready to go, plug it in and set it up (through GUI if you have a monitor, otherwise through SSH). Avoid redundancy; don't put more than one server in one general location.
- Deploy the master device somehow. If using a simple command line Python script, share it with the people involved. If using the more public-intuitive Flask server, share the URL to the server with the people involved (i.e. the people with the tags)
- Everyone who uses a particular area/building complex/office, or most of everyone, gets one of the tag devices (plus the ID belonging to the device).
- The tag devices are opt-in: nothing is recorded if the device is off, and the device must explicitly be on to do anything (power switches, battery, etc).
- When someone walks into a room or zone with a server device, if the tag is on, the server will record the time and tag ID. This ID is anonymous; the only person capable of knowing who an ID belongs to is the person who programmed it in the first place, or anyone they tell (without isolation it is impossible to trace one ID over bluetooth back to a particular device, plus devices are usually hidden from view).
- Enough of these records creates a movement profile, or a "trace". Using the master device, one can then look up their trace using their tag ID. If they are then diagnosed with Covid-19, a healthcare official can read the ID of the tag (which was provided by the tag distributor), conduct this lookup on the master device, and then report dates, times and locations where the person has been to to the public. People can then use the same master device themselves to look up their own traces to determine whether they were in one of those places at the same time, and whether they may need to watch for symptoms. The locations where the diagnosed person went to can then perform necessary cleaning procedures. Thus, we have contact tracing. This is all opt-in systems: a person who happened to be in the same place as someone diagnosed would need to explicitly state they were in the same place to proceed the contact tracing chain, as the IDs are anonymous. Nobody can be forced to do so under this anonymous system.
- Servers automatically wipe old location data after 14 days, the amount of time it usually takes for Covid-19 symptoms to arise. This prevents data build-up and removes unnecessary data from being saved.
This step is to be conducted only after contact tracing is no longer necessary.
The tag devices can either be kept with their owners (recommended if they are not to be wiped), or returned. If returned, they can be repurposed for a variety of things, including usage as item tags/trackers in short-range environments, or as bluetooth-based keycards for accessing secure rooms (think: the local name of the device is a password, and the password changes every so often for security). Assuming the tags have USB ports, they can be reprogrammed by users with different names or even entirely different application code. Throwing the devices away is entirely unnecessary, and thus e-waste is avoided.
The server devices, being based off Raspberry Pi units, are fully functional computers. As such, they could be donated to schools that need computers to help enhance learning experiences. If a particular server did not have a private keyboard/mouse/monitor set, it can still be SSH'd into and used for teaching Unix systems. Plus, the boards usually come with a plethora of GPIO pins, which can be used to teach some programmable circuit concepts. Once again, e-waste is avoided.
Recommendations- To minimize cost given you have no existing devices, use Pi Zero W modules for the servers and nRF52840-DONGLE (PCA10059) devices equipped with coin cell batteries for the tags. While I have not tested this myself, it should be possible to solder a 3V coin cell battery to whatever power pin it uses. According to https://devzone.nordicsemi.com/f/nordic-q-a/58030/looking-for-ideas-to-mount-coin-battery-holder-to-nrf52840-dongle (which I am not affiliated with, I merely found it through an internet search) this is possible through VDD OUT and by cutting SB2 and soldering SB1 on the board. See the post for info, I have not tested this myself, though I would think this should be done only after programming.
- If you want to bring costs down to absolute zero, use devices you already have.
Servers: these can be any kinds of Pi modules (2 with WiFi/Bluetooth dongle, 3A, 3B(+), 4, Zero W, Zero with WiFi/Bluetooth dongle, Compute Module with WiFi/Bluetooth carrier, BalenaFin v1.0 or 1.1, countless Pi derivatives, etc), and if you try really, really hard, you can actually use any device capable of a. running Python, b. having bluepy access your device's bluetooth hardware, and c. accessing the internet (thus you could possibly use laptops, desktops, etc). If you tried even harder it may be possible to replicate the server code on an ESP-32, which is equipped with both WiFi and Bluetooth. However, as this is usually programmed in not-Python, I am unable to confirm whether this can actually work.
Tags: Anything that is a bluetooth device capable of advertising a name. Literally anything. nRF, Arduino 101, ESP-32, regular bluetooth dongles, anything. The only thing the device needs to be able to do is broadcast a user-set local name.
- Do not deploy the system if an alternate contact tracing system is already in place. This would only create unnecessary redundancy, and result in procurement of materials where they could be better used to manage a contact tracing system where one does not already exist.
- Be wary of privacy. When publicizing location info for Covid-19 diagnosed users, do not attach names OR IDs to the locations. Just state approximate time ranges (experimentation shows boards tend to make more than one log in the system when passing) and locations.
The Universal Low-Cost Contact Tracing Solution is a highly-adaptable way of managing contact tracing in phoneless environments. Compatible with countless low-cost devices, it provides a simple solution for contact tracing deployment from the ground up. Anonymous and non-complex, it permits informing the public about exposure while also preserving privacy. It's also contactless, which means less chances for surface exposure to Covid-19. And as a bonus, the system can be saved from becoming e-waste after it is no longer necessary, being easily repurposed for many alternative uses.
Hopefully this system will be of use to someone, either in its original form or as inspiration for something better.
Comments