** About
This document was created by Steven Baltakatei Sandoval on
~2020-10-24T23:37Z~ under a [[https://creativecommons.org/licenses/by-sa/4.0/][Creative Commons BY-SA 4.0 license]]. It was
-updated by Steven Baltakatei Sandoval on ~2020-10-24T23:59Z~
+updated by Steven Baltakatei Sandoval on ~2020-10-27T18:50Z~
** Narrative
The ~ninfacyzga-01~ device may log temperature readings from
- The Raspberry Pi Zero W's internal temperature CPU sensors
Whatever the source, an associated ~python~ script should report the
-temperature in the form of JSON data sent to the script's standard
-output ("stdout") stream.
+temperature and associated metadata within a JSON value outputted to
+the script's "stdout" stream and formatted using the following
+standards:
+
+- [[https://www.json.org/json-en.html][JSON]] (JavaScript Object Notation): A data-interchange format.
+
+- [[https://jsonlines.org/][JSON Lines]] : A method of formatting JSON values so they may be
+ streamed using newline characters as separators.
+
+- [[https://www.w3.org/TR/json-ld/][JSON-LD]] (JSON Linked Data): A messaging format capable of encoding
+ RDF data (ex: RDF triples) in a JSON value.
+
+- [[https://www.w3.org/TR/vocab-ssn/][SSN]] (Semantic Sensor Network Ontology): A namespace for building RDF
+ graphs describing relationships between various characteristics of a
+ sensing system (ex: Which sensor made the observation? What kind of
+ observation was made? Which station was the sensor a part of? Where
+ was the station? When was an observation made?). An example
+ application of SSN ontology to NOAA weather data can be found [[https://github.com/anhlt18vn/Semantic2019][here]].
In turn, this "stdout" is then piped into the ~bklog~ which takes care
-of packaging, encrypting, and appending the JSON data to a timestamped
-~tar~ file.
+of packaging, encrypting, and appending the stream of JSON lines to a
+timestamped ~tar~ file.
~cron~ is used to call a single script which performs all of the above
actions at regular time intervals.
*** Software
- [[https://www.raspberrypi.org/downloads/raspberry-pi-os/][Raspberry Pi OS]] : A GNU/Linux operating system derived from
Debian 10. This procedure was developed with version ~August 2020~.
+*** Output
+**** Simple
+Temperature readings may be recorded into a comma-delimited format:
+
+#+BEGIN_EXAMPLE
+20201027T182039+0000,1603822839,18.37500
+20201027T182041+0000,1603822841,18.43700
+20201027T182043+0000,1603822843,18.43700
+20201027T182045+0000,1603822845,18.43700
+#+END_EXAMPLE
+
+**** JSON-LD log
+A typical temperature reading will be formatted thus:
+
+(TODO: Insert example output following JSON-LD, SSN standards)
+
+#+BEGIN_EXAMPLE
+{
+ "@context": {
+ "sosa": "http://www.w3.org/ns/sosa/",
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+ "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
+ "xsd": "http://www.w3.org/2001/XMLSchema#"
+ "ssn": "http://www.w3.org/ns/ssn/"
+ }
+ "temperature"
+}
+#+END_EXAMPLE
+
+
** Operating Procedures
*** Initial Startup
**** Perform initial setup.
See [[file:../setup/README.org][Main Setup]] procedure.
**** Install Hardware for temperature logging
+***** DS18B20 1-Wire wiring
+The DS18B20 temperature sensor must be connected to the Raspberry Pi's
+GPIO pins through a circuit assembly that contains a "pull-up" 4.7KΩ
+resistor. A circuit diagram may be found [[https://electrosome.com/ds18b20-sensor-raspberry-pi-python/][here]]. The data lead should be
+connected to GPIO pin 4 (physical pin number 7; see [[https://pinout.xyz/][ref]]). Using a
+different GPIO pin will require a slightly different 1-Wire
+configuration.
+
+**** Install Software for temperature logging
+***** DS18B20 1-Wire programming
+The DS18B20 temperature sensor output may be polled by a Python script
+via the Raspberry Pi's "1-Wire" communications protocol.
+
+****** Enabling 1-Wire support
+1-Wire support at GPIO pin 4 is enabled by adding the following lines
+to ~/boot/config.txt~:
+
+: # Enable 1-Wire at GPIO 4 (DS18B20 temperature probe)
+: dtoverlay=w1-gpio,gpiopin=4
+
+****** Testing DS18B20 1-Wire availability
+
+The temperature sensor output may be manually polled by running the
+following commands:
+
+: sudo modprobe w1-gpio
+: sudo modprobe w1-therm
+: cd /sys/bus/w1/devices/
+
+There should be a directory with a name resembling
+~28-3c01b556f672~. Enter it and read the ~w1_slave~ file.
+
+: cd 28-3c01b556f672
+: cat w1_slave
+
+An example of such output will resemble:
+
+#+BEGIN_EXAMPLE
+2a 01 55 05 7f a5 a5 66 76 : crc=76 YES
+2a 01 55 05 7f a5 a5 66 76 t=18625
+#+END_EXAMPLE
+
+The ~YES~ in the first line indicates the 1-Wire protocol is
+functioning. The ~t=18625~ indicates that the DS18B20 sensor is
+detecting the temperature to be ~18.625°C~.
+
+****** Sample script to automatically poll DS18B20 sensor
+
+A sample python script for automatically outputting a stream of
+temperature readings via stdout is explained [[https://pimylifeup.com/raspberry-pi-temperature-sensor/][here]] (along with wiring
+instructions) and found [[https://github.com/pimylifeup/temperature_sensor][here]].
+
+***** Install temperature logging scripts
+Several scripts in this repository should be installed to the local
+user's executable directory at ~$HOME/.local/bin~.
+
+Cron jobs should be configured (via ~$ crontab -e~) to call these
+scripts automatically.
-**** Install Software for temperature loggin
+: [TODO fill me]
***** Install packages via ~apt~
Run the following command to install the required packages.
-: $ sudo apt install [fill me]
+: $ sudo apt install [TODO: fill me]
*** Normal Startup
*** Normal Operation
--- /dev/null
+#!/usr/bin/env python3
+
+import os
+import glob
+import time
+from time import strftime
+
+os.system('modprobe w1-gpio')
+os.system('modprobe w1-therm')
+
+base_dir = '/sys/bus/w1/devices/'
+device_folder = glob.glob(base_dir + '28*')[0]
+device_file = device_folder + '/w1_slave'
+
+def read_temp_raw():
+ f = open(device_file, 'r')
+ lines = f.readlines()
+ f.close()
+ return lines
+
+def read_temp():
+ lines = read_temp_raw()
+ while lines[0].strip()[-3:] != 'YES':
+ time.sleep(0.2)
+ lines = read_temp_raw()
+ equals_pos = lines[1].find('t=')
+ if equals_pos != -1:
+ temp_string = lines[1][equals_pos+2:]
+ temp_c = float(temp_string) / 1000.0
+ temp_f = temp_c * 9.0 / 5.0 + 32.0
+ temp_c_2dec = f"{temp_c:.5f}" # https://stackoverflow.com/a/15263885/10850071
+ #return temp_c, temp_f
+ return temp_c_2dec
+
+while True:
+ nowTimeIso8601 = strftime("%Y%m%dT%H%M%S%z")
+ nowTimeUE = strftime("%s")
+ nowTemp = read_temp()
+ print(str(nowTimeIso8601) + ',' + str(nowTimeUE) + ',' + str(nowTemp))
+ time.sleep(1)