Here’s everything you’ll need for this tutorial.
Note, that this setup has all available channels enabled including these EMWIN updates. It also includes enhancements from usradioguy.com for Custom Colors and Fire Data.
Hardkernel store
- odroid n2+ itself
- 32gb emmc card for OS
- emmc reader
- odroid n2+ case
- wifi module if needed (wired is always best)
- power supply
Amazon canada
- EMMC Adapter
- nooelec goes receiver kit
- weatherproof box
- 50+ feet of sma cable
- sma connector grab box
- 256gb Micro SD card for storing images (this will die eventually!)
- powered usb hub
Here’s how to make it all work.
get odroid n2+ unpacked
download latest ubuntu image from here as of Jan 26, 2023 you want this one
install balenca etcher
put your emmc on the usb reader card and insert to pc
open balenca and burn the image you downloaded to the emmc card
attach emmc card to your n2+ and insert the 256gb micro-sd card to the slot, and replace case.
attach keyboard + hdmi to your n2+ and power on the system (ensure set to boot from emmc)
do one of the following to find out the ip address of the odroid
a) either go to your router, and view the dhcp lease for
odroid
b) on the odroid itself if connected to a monitor and keyboard, type
ifconfig -a
to find your local ip (usually on eth0)from your main box, ssh to the odroid
$ ssh -l root ip.address.goes.here
the default login is
user: root
,password: odroid
update ubuntu and remove anything and set timezone
# apt-get update # apt-get upgrade && apt-get autoremove # timedatectl set-timezone America/Toronto
reboot the system
# reboot
this step is optional, setup wifi if applicable.
a. type in this to view the wlan card info
typically wlan0
$ ls /sys/class/net eth0 lo wlan0
b. view your available SSID’s if you don’t know them
# nmcli dev wifi list
c. now you want to run the console gui to connect to wifi
# nmtui
d. now you want to click
edit a connection
and scroll down to your wifi network then hit entere. hit tab to get to the password field and enter your password
f. tab down to
OK
and hit enterg. now hit esc to exit to main screen, then scroll down to
quit
and hit enter.h. now type
ifconfig -a
to see if you have an ip address on wlan0 or whatever your interface is.i. reboot to make sure everything sticks
# reboot
j. run ifconfig to ensure you have wifi or wired or both ip’s set properly.
now you want place the system where you need it, plug in your usb hub, and, your RTLSDR devices to the system and power it on.
now you want to ssh to your system again
$ ssh -l root ip.address.of.system
now we want to install some basic stuff
$ apt-get install aptitude git cmake build-essential libusb-1.0 libopencv-dev libproj-dev screen apache2 libapache2-mod-php8.1 zip php8.1-gd gdal-bin
now run lsusb to make sure your hub, and, sdr device is found.
$ lsusb
it should look like
Bus 002 Device 002: ID 05e3:0620 Genesys Logic, Inc. USB3.1 Hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 005: ID 051d:0002 American Power Conversion Uninterruptible Power Supply Bus 001 Device 007: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T Bus 001 Device 006: ID 05e3:0608 Genesys Logic, Inc. Hub Bus 001 Device 004: ID 05e3:0608 Genesys Logic, Inc. Hub Bus 001 Device 003: ID 0bda:a811 Realtek Semiconductor Corp. RTL8811AU 802.11a/b/g/n/ac WLAN Adapter Bus 001 Device 002: ID 05e3:0610 Genesys Logic, Inc. Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
now is probably a good time to put together the receiver dish, and, run your cable. Here are those instructions
now we want to run some stuff on our radio server (the odroid). first being creating a new user.
# useradd -m radio # passwd radio <set a password> # su radio # chsh <enter password> input /bin/bash <hit enter> $ cd ~
Now we want to get the rtl-sdr sources
$ git clone https://github.com/steve-m/librtlsdr.git $ cd librtlsdr $ mkdir build $ cd build $ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DINSTALL_UDEV_RULES=ON .. $ exit # cd /home/radio/librtlsdr/build # make -j2 install # cp ../rtl-sdr.rules /etc/udev/rules.d/ # mv /etc/udev/rules.d/rtl-sdr.rules /etc/udev/rules.d/10-rtl-sdr.rules # ldconfig # echo 'blacklist dvb_usb_rtl28xxu' | sudo tee --append /etc/modprobe.d/blacklist-dvb_usb_rtl28xxu.conf
now we want to add the
radio
user to thesudo
andplugdev
groups and then reboot# usermod -aG sudo radio # usermod -aG plugdev radio # reboot
now let’s see if it all works
$ ssh -l radio ip.address.of.server $ rtl_test
you should see output like this
Found 1 device(s): 0: Realtek, RTL2838UHIDIR, SN: TEST Using device 0: Generic RTL2832U OEM Detached kernel driver Found Elonics E4000 tuner Supported gain values (14): -1.0 1.5 4.0 6.5 9.0 11.5 14.0 16.5 19.0 21.5 24.0 29.0 34.0 42.0 Sampling at 2048000 S/s. Info: This tool will continuously read from the device, and report if samples get lost. If you observe no further output, everything is fine. Reading samples in async mode... Allocating 15 zero-copy buffers Failed to allocate zero-copy buffer for transfer 14 Falling back to buffers in userspace lost at least 80 bytes
now we want to start the GOES setup
$ sudo apt-get dist-upgrade $ sudo reboot
then ssh again
$ ssh -l radio ip.address.of.radiobox
then issue this to install goestools
$ mkdir source && cd source $ git clone https://github.com/pietern/goestools.git $ git clone https://github.com/jim-minter/goestools.git goestools_jim_minter $ git clone https://github.com/tmbates12/goestools.git goestools_tmbates12 $ cd goestools_jim_minter $ git checkout -b update_proj $ git format-patch -1 3a15b3a091ba38569c6fe76eb85d93d2403e11eb $ cp 0001-update-proj.patch ../goestools $ cd ../goestools_tmbates12 $ git format-patch -1 2f54169cabfe05c6bfdc4f68dca0307fe7117df1 $ cp 0001-Added-config-option-for-EMWIN-handler-to-disable-out.patch ../goestools $ cd ../goestools $ git am < 0001-Added-config-option-for-EMWIN-handler-to-disable-out.patch $ git am < 0001-update-proj.patch $ git submodule init $ git submodule update --recursive $ git config --global user.email "you@example.com" $ git config --global user.name "Your Name" $ mkdir build $ cd build $ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr .. $ make $ sudo make install $ cd $ mkdir goes_stuff $ cd goes_stuff $ wget https://usradioguy.com/wp-content/uploads/2020/07/usradioguycustomlut.png $ wget https://usradioguy.com/wp-content/uploads/2022/06/usradioguy_goes16_ch02_curve.png $ sudo cp /usr/share/goestools/goesproc-goesr.conf /usr/share/goestools/goesproc-goesr.original.conf
Now we want to configure goesrecv by creating the configuration file
$ nano goesrecv.conf
paste this in then exit and save the file
[demodulator] mode = "hrit" source = "rtlsdr" [rtlsdr] frequency = 1694100000 sample_rate = 2000000 gain = 5 bias_tee = false [costas] max_deviation = 200e3 [decoder.packet_publisher] bind = "tcp://0.0.0.0:5004" send_buffer = 1048576 [monitor] statsd_address = "udp4://localhost:8125" [clock_recovery.sample_publisher] bind = "tcp://0.0.0.0:5002" send_buffer = 2097152 [demodulator.stats_publisher] bind = "tcp://0.0.0.0:6001" [decoder.stats_publisher] bind = "tcp://0.0.0.0:6002" # Change rtlsdr to airspy if you're using an AirSpy, etc. # Publishes IQ samples coming straight from the SDR over # nanomsg [rtlsdr.sample_publisher] bind = "tcp://0.0.0.0:5000" send_buffer = 2097152
now let’s create a small script for testing our dish orientation. You may want two people for this, one person to move the dish around until the signal is correct, and one to watch the screen. Or, bring your laptop with you to watch the output. I use
termux
from my android phone and ssh to the radio server and run the script for testing.$ nano goes_receive.sh
paste these contents in, close and save the file, then make it executable.
$ chmod +x goes_receive.sh
now run your script
$ goes_receive.sh 2023-01-26T22:17:55Z [monitor] gain: 12.05, freq: 3.9, omega: 2.157, vit(avg): 2081, rs(sum): 0, packets: 0, drops: 32 2023-01-26T22:17:56Z [monitor] gain: 27.27, freq: 105.2, omega: 2.157, vit(avg): 2129, rs(sum): 0, packets: 0, drops: 35 2023-01-26T22:17:57Z [monitor] gain: 36.82, freq: -197.6, omega: 2.156, vit(avg): 2155, rs(sum): 0, packets: 0, drops: 34 2023-01-26T22:17:58Z [monitor] gain: 42.88, freq: -51.4, omega: 2.155, vit(avg): 2182, rs(sum): 0, packets: 0, drops: 32 2023-01-26T22:17:59Z [monitor] gain: 46.80, freq: -954.5, omega: 2.157, vit(avg): 2214, rs(sum): 0, packets: 0, drops: 33 2023-01-26T22:18:00Z [monitor] gain: 49.30, freq: -280.0, omega: 2.160, vit(avg): 2253, rs(sum): 0, packets: 0, drops: 34
take note of the
vit(avg)
how it is over 2000, you want this number as low as possible. go adjust your dish until this number comes down to hopefully less than 400, or around there. You also want as littledrops
as possible too. Fine tune your dish until these are the best you can get them.now you want to setup processing.
$ nano goes_process.sh
paste this in
goesproc -c /usr/share/goestools/goesproc-goesr.conf -m packet --subscribe tcp://127.0.0.1:5004
exit and save your file, then make it executable.
$ chmod +x goes_process.sh
edit the goesprocessor file (you’ve already made a backup of this above, so it’s fine to save your changes here)
$ sudo nano /usr/share/goestools/goesproc-goesr.conf
and paste the folllowing in
# Store all original GOES-16 products. [[handler]] type = "image" origin = "goes16" directory = "./goes16/{region:short|lower}/{channel:short|lower}/{time:%Y-%m-%d}" filename = "GOES16_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # Store all original GOES-17 products. [[handler]] type = "image" origin = "goes17" directory = "./goes17/{region:short|lower}/{channel:short|lower}/{time:%Y-%m-%d}" filename = "GOES17_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # GOES-16 ABI false color CUSTOMLUT VERSION 2.8 and jpg. [[handler]] type = "image" origin = "goes16" regions = [ "fd" ] channels = [ "ch02", "ch13" ] directory = "./goes16/{region:short|lower}/CUSTOMLUT/{time:%Y-%m-%d}" filename = "GOES16_{region:short}_FC_CUSTOMLUT_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false [handler.remap.ch02] path = "/usr/share/goestools/wxstar/wxstar_goes16_ch02_curve.png" [handler.lut] path = "/home/radio/goes_stuff/usradioguycustomlut.png" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # GOES-16 ABI false color. [[handler]] type = "image" origin = "goes16" regions = [ "fd", "m1", "m2" ] channels = [ "ch02", "ch13" ] directory = "./goes16/{region:short|lower}/fc/{time:%Y-%m-%d}" filename = "GOES16_{region:short}_FC_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false [handler.remap.ch02] path = "/usr/share/goestools/wxstar/wxstar_goes16_ch02_curve.png" [handler.lut] path = "/usr/share/goestools/wxstar/wxstar_goes16_lut.png" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # GOES-16 ABI RGB-enhanced [[handler]] type = "image" origin = "goes16" regions = [ "fd", "m1", "m2" ] channels = [ "ch07", "ch08", "ch09", "ch13", "ch14", "ch15" ] directory = "./goes16/{region:short|lower}/{channel:short|lower}_enhanced/{time:%Y-%m-%d}" filename = "GOES16_{region:short}_{channel:short}_enhanced_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false ## The following gradients are rough approximations of the ## McIDAS RGB enhancements used by NOAA/NESDIS/STAR on their site.. ## ## For more info: ## ## https://www.star.nesdis.noaa.gov/GOES/GOES16_FullDisk.php ## http://cimss.ssec.wisc.edu/goes/visit/water_vapor_enhancement.html ## http://cimss.ssec.wisc.edu/goes/visit/enhanced_v_enhancements.html ## Shortwave IR (Channel 7) [handler.gradient.ch07] points = [ { units = 400, color = "#000000" }, { units = 250, color = "#b9b9b9" }, { units = 249.999, color = "#00ffff" }, { units = 240, color = "#000080" }, { units = 230, color = "#00ff00" }, { units = 220, color = "#ffff00" }, { units = 210, color = "#ff0000" }, { units = 200, color = "#000000" }, { units = 190, color = "#ffffff" } ] ## Water Vapor (Channels 8 and 9) [handler.gradient.ch08] points = [ { units = 276, color = "#000000" }, { units = 275.9, color = "#ff0000" }, { units = 258, color = "#ffff00" }, { units = 250, color = "#000070" }, { units = 233, color = "#ffffff" }, { units = 195, color = "#408020" }, { units = 178, color = "#00ffff" } ] [handler.gradient.ch09] points = [ { units = 276, color = "#000000" }, { units = 275.9, color = "#ff0000" }, { units = 258, color = "#ffff00" }, { units = 250, color = "#000070" }, { units = 233, color = "#ffffff" }, { units = 195, color = "#408020" }, { units = 178, color = "#00ffff" } ] ## Longwave IR (Channels 13, 14, and 15) # [handler.gradient.ch13] # points = [ # { units = 333, color = "#000000" }, # { units = 238, color = "#b9b9b9" }, # { units = 237.999, color = "#00ffff" }, # { units = 228, color = "#000080" }, # { units = 218, color = "#00ff00" }, # { units = 208, color = "#ffff00" }, # { units = 198, color = "#ff0000" }, # { units = 188, color = "#000000" }, # { units = 178, color = "#ffffff" } # ] ## usradioguy edits ## Longwave IR (Channels 13, 14, and 15 SSEC/CIRA) [handler.gradient.ch13] points = [ { units = 333, color = "#000000" }, { units = 273, color = "#b9b9b9" }, { units = 263, color = "#EAEAEA" }, { units = 253, color = "#00ffff" }, { units = 238, color = "#0000FF" }, { units = 237.999, color = "#000080" }, { units = 235, color = "#003300" }, { units = 230, color = "#008000" }, { units = 222, color = "#ffff00" }, { units = 208, color = "#FF0000" }, { units = 198, color = "#FF7F7F" }, { units = 193.15, color = "#800080" }, { units = 188, color = "#000000" }, { units = 178, color = "#ffffff" } ] [handler.gradient.ch14] points = [ { units = 333, color = "#000000" }, { units = 238, color = "#b9b9b9" }, { units = 237.999, color = "#00ffff" }, { units = 228, color = "#000080" }, { units = 218, color = "#00ff00" }, { units = 208, color = "#ffff00" }, { units = 198, color = "#ff0000" }, { units = 188, color = "#000000" }, { units = 178, color = "#ffffff" } ] # original # [handler.gradient.ch15] # points = [ # { units = 333, color = "#000000" }, # { units = 238, color = "#b9b9b9" }, # { units = 237.999, color = "#00ffff" }, # { units = 228, color = "#000080" }, # { units = 218, color = "#00ff00" }, # { units = 208, color = "#ffff00" }, # { units = 198, color = "#ff0000" }, # { units = 188, color = "#000000" }, # { units = 178, color = "#ffffff" } # ] ## usradioguy edits [handler.gradient.ch15] points = [ { units = 333, color = "#000000" }, { units = 273, color = "#b9b9b9" }, { units = 263, color = "#EAEAEA" }, { units = 253, color = "#00ffff" }, { units = 238, color = "#0000FF" }, { units = 237.999, color = "#000080" }, { units = 235, color = "#003300" }, { units = 230, color = "#008000" }, { units = 222, color = "#ffff00" }, { units = 208, color = "#FF0000" }, { units = 198, color = "#FF7F7F" }, { units = 193.15, color = "#800080" }, { units = 188, color = "#000000" }, { units = 178, color = "#ffffff" } ] #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # GOES-16 ABI FIRE HOTSPOT LAYERING [[handler]] type = "image" origin = "goes16" regions = [ "fd", "m1", "m2" ] channels = [ "ch02", "ch13" ] directory = "./goes16/{region:short|lower}/fire/{time:%Y-%m-%d}" filename = "GOES16_{region:short}_FCFIREMAP_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false [handler.remap.ch02] path = "/usr/share/goestools/wxstar/wxstar_goes16_ch02_curve.png" [handler.lut] path = "/home/radio/goes_stuff/usradioguycustomlut.png" [[handler.map]] path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" [[handler.map]] path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" [[handler.map]] path = "/home/radio/goes_stuff/fire.json" color = "#FF6700" #GOES 16 DCS Data Stream [[handler]] type = "dcs" directory = "./dcs/{time:%Y-%m-%d}" ## GOES-16 LEVEL 02 & Level 03 ABI Imagery- should generate: #Rainfall rate/QPE RRQPE #Sea surface temperature (skin) SST #Land surface temperature (skin) LST #Total precipitable water TPW #Derived stability indices DSI #Cloud top height ACTH # NOT ALL IMAGERY IS AVAILABLE AT ALL TIMES. NOAA SCHEDULES VARY # GOES-16 ABI Non-CMIP RGB-enhanced (Black Borders) [[handler]] type = "image" origin = "goes16" products = [ "sst", "lst", "dsi", "tpw" ] directory = "./goes16/non-cmip/{region:short|lower}/{product:short|lower}/{time:%Y-%m-%d}" filename = "GOES16_{region:short}_{product:short}_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #color = "#000000" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" #color = "#000000" ## The following gradients are rough approximations of the ## McIDAS RGB enhancements used by NOAA/NESDIS/STAR on their site.. ## ## For more info: ## ## https://www.ospo.noaa.gov/data/sst/contour/global.cf.gif (SST) ## https://www.goes-r.gov/products/baseline-LST.html (LST) ## http://cimss.ssec.wisc.edu/goes/OCLOFactSheetPDFs/ABIQuickGuide_BaselineDerivedStabilityIndices.pdf (DSI) ## https://www.goes-r.gov/products/baseline-total-precipitable-water.html (TPW) # Skin Sea Surface Temperature (Degrees K) [handler.gradient.SST] points = [ { units = 180, color = "#ffffff" }, { units = 270.65, color = "#ffffff" }, { units = 273.25, color = "#b005c6" }, { units = 275.5, color = "#8f06e4" }, { units = 277.75, color = "#6c1ff7" }, { units = 280, color = "#486afa" }, { units = 282.25, color = "#24b4fc" }, { units = 284.5, color = "#00ffff" }, { units = 287.25, color = "#00e696" }, { units = 289, color = "#00d54b" }, { units = 291.3, color = "#0cc600" }, { units = 293.6, color = "#59d800" }, { units = 295.85, color = "#a5ea00" }, { units = 298.1, color = "#f2fc00" }, { units = 300.35, color = "#ffc900" }, { units = 302.6, color = "#ff9400" }, { units = 304.85, color = "#ff5500" }, { units = 307.1, color = "#ff1500" }, { units = 340, color = "#ffffff" } ] # Skin Land Surface Temperature (Degrees K) [handler.gradient.LST] points = [ { units = 215, color = "#102469" }, { units = 220, color = "#0002b5" }, { units = 240, color = "#0359fa" }, { units = 260, color = "#03eee9" }, { units = 280, color = "#87f36c" }, { units = 300, color = "#fee502" }, { units = 320, color = "#f34900" }, { units = 342, color = "#7f1100" }, { units = 353, color = "#ffffff" } ] # CAPE Derived Stability Index (Joules/kg) [handler.gradient.DSI] points = [ { units = 0, color = "#543e20" }, { units = 500, color = "#a58154" }, { units = 750, color = "#cfa370" }, { units = 1000, color = "#c3afc2" }, { units = 1500, color = "#8181c5" }, { units = 1750, color = "#6363a3" }, { units = 2000, color = "#969656" }, { units = 2500, color = "#fffc02" }, { units = 2750, color = "#ffd327" }, { units = 3000, color = "#ff9063" }, { units = 3500, color = "#ff231e" }, { units = 4000, color = "#b10032" }, { units = 4250, color = "#680063" }, { units = 4500, color = "#8d0090" }, { units = 4961.3914, color = "#ea00ef" }, { units = 4980.9245, color = "#000000" } ] # Total Precipitable Water (mm) [handler.gradient.TPW] points = [ { units = 0, color = "#3a290b" }, { units = 11, color = "#d1a777" }, { units = 12, color = "#8999ee" }, { units = 22, color = "#584c96" }, { units = 23, color = "#9a6a5c" }, { units = 32, color = "#72a429" }, { units = 33, color = "#97c03c" }, { units = 43, color = "#f4fe00" }, { units = 44, color = "#fd775e" }, { units = 53, color = "#982a19" }, { units = 54, color = "#6f0069" }, { units = 65, color = "#fb00ee" }, { units = 66, color = "#ffc8ff" }, { units = 69, color = "#f0bbef" }, { units = 99, color = "#f069ef" }, { units = 99.6187, color = "#ffffff" }, ] # GOES-16 ABI Non-CMIP RGB-enhanced (White Borders) [[handler]] type = "image" origin = "goes16" products = [ "rrqpe", "acht", "acha" ] directory = "./goes16/non-cmip/{region:short|lower}/{product:short|lower}/{time:%Y-%m-%d}" filename = "GOES16_{region:short}_{product:short}_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false # [[handler.map]] # path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" # [[handler.map]] # path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" ## The following gradients are rough approximations of the ## McIDAS RGB enhancements used by NOAA/NESDIS/STAR on their site.. ## ## For more info: ## ## https://www.goes-r.gov/products/baseline-rainfall-rate-qpe.html (RRQPE) ## https://cimss.ssec.wisc.edu/goes/blog/archives/32657 (ACHT) ## https://catalog.data.gov/dataset/noaa-goes-r-series-advanced-baseline-imager-abi-level-2-cloud-top-height-acha # Rainfall Rate (mm/hr) [handler.gradient.RRQPE] points = [ { units = 0, color = "#000000" }, { units = 6.35, color = "#303030" }, { units = 12.6, color = "#303030" }, { units = 12.7, color = "#009cff" }, { units = 25.3, color = "#050dc8" }, { units = 25.4, color = "#36ef31" }, { units = 38.1, color = "#1e8f01" }, { units = 40.64, color = "#fff92e" }, { units = 50.8, color = "#f23027" }, { units = 53.34, color = "#ff00f8" }, { units = 63.5, color = "#c168c6" }, { units = 66.04, color = "#fcfcfc" }, { units = 100, color = "#ffffff" } ] # Cloud top Height (Degrees K) [handler.gradient.ACHT] points = [ { units = 180, color = "#000000" }, { units = 193, color = "#ffe300" }, { units = 213, color = "#81ff00" }, { units = 233, color = "#00ff23" }, { units = 253, color = "#00ffbb" }, { units = 273, color = "#00abff" }, { units = 293, color = "#0011ff" }, { units = 313, color = "#7500eb" }, { units = 321, color = "#000000" }, ] # Cloud Top Height Algorithm (Meters) [handler.gradient.ACHA] points = [ { units = 0, color = "#000000" }, { units = 1500, color = "#5e10b1" }, { units = 3000, color = "#360ae5" }, { units = 6050, color = "#0d85e4" }, { units = 9100, color = "#16f2b4" }, { units = 12200, color = "#19f108" }, { units = 15250, color = "#e4ff2b" }, { units = 19845, color = "#ef630e" }, { units = 19923, color = "#000000" }, ] # GOES-17 ABI false color CUSTOMLUT VERSION 2.8 and jpg. [[handler]] type = "image" origin = "goes17" regions = [ "fd", "m1", "m2" ] channels = [ "ch02", "ch13" ] directory = "./goes17/{region:short|lower}/CUSTOMLUT/{time:%Y-%m-%d}" filename = "GOES17_{region:short}_FC_CUSTOMLUT_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false # This reuses the GOES-16 contrast curve assuming it is identical [handler.remap.ch02] path = "/usr/share/goestools/wxstar/wxstar_goes16_ch02_curve.png" # This reuses the GOES-16 LUT assuming it is identical [handler.lut] path = "/home/radio/goes_stuff/usradioguycustomlut.png" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # GOES-17 ABI false color. [[handler]] type = "image" origin = "goes17" regions = [ "fd", "m1", "m2" ] channels = [ "ch02", "ch13" ] directory = "./goes17/{region:short|lower}/fc/{time:%Y-%m-%d}" filename = "GOES17_{region:short}_FC_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false # This reuses the GOES-16 contrast curve assuming it is identical [handler.remap.ch02] path = "/usr/share/goestools/wxstar/wxstar_goes16_ch02_curve.png" # This reuses the GOES-16 LUT assuming it is identical [handler.lut] path = "/usr/share/goestools/wxstar/wxstar_goes16_lut.png" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # GOES-17 ABI RGB-enhanced [[handler]] type = "image" origin = "goes17" regions = [ "fd", "m1", "m2" ] channels = [ "ch07", "ch08", "ch09", "ch13", "ch14", "ch15" ] directory = "./goes17/{region:short|lower}/{channel:short|lower}_enhanced/{time:%Y-%m-%d}" filename = "GOES17_{region:short}_{channel:short}_enhanced_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false ## The following gradients are rough approximations of the ## McIDAS RGB enhancements used by NOAA/NESDIS/STAR on their site.. ## ## For more info: ## ## https://www.star.nesdis.noaa.gov/GOES/GOES16_FullDisk.php ## http://cimss.ssec.wisc.edu/goes/visit/water_vapor_enhancement.html ## http://cimss.ssec.wisc.edu/goes/visit/enhanced_v_enhancements.html ## Shortwave IR (Channel 7) [handler.gradient.ch07] points = [ { units = 400, color = "#000000" }, { units = 250, color = "#b9b9b9" }, { units = 249.999, color = "#00ffff" }, { units = 240, color = "#000080" }, { units = 230, color = "#00ff00" }, { units = 220, color = "#ffff00" }, { units = 210, color = "#ff0000" }, { units = 200, color = "#000000" }, { units = 190, color = "#ffffff" } ] ## Water Vapor (Channels 8 and 9) [handler.gradient.ch08] points = [ { units = 276, color = "#000000" }, { units = 275.9, color = "#ff0000" }, { units = 258, color = "#ffff00" }, { units = 250, color = "#000070" }, { units = 233, color = "#ffffff" }, { units = 195, color = "#408020" }, { units = 178, color = "#00ffff" } ] [handler.gradient.ch09] points = [ { units = 276, color = "#000000" }, { units = 275.9, color = "#ff0000" }, { units = 258, color = "#ffff00" }, { units = 250, color = "#000070" }, { units = 233, color = "#ffffff" }, { units = 195, color = "#408020" }, { units = 178, color = "#00ffff" } ] ## Longwave IR (Channels 13, 14, and 15) [handler.gradient.ch13] points = [ { units = 333, color = "#000000" }, { units = 238, color = "#b9b9b9" }, { units = 237.999, color = "#00ffff" }, { units = 228, color = "#000080" }, { units = 218, color = "#00ff00" }, { units = 208, color = "#ffff00" }, { units = 198, color = "#ff0000" }, { units = 188, color = "#000000" }, { units = 178, color = "#ffffff" } ] [handler.gradient.ch14] points = [ { units = 333, color = "#000000" }, { units = 238, color = "#b9b9b9" }, { units = 237.999, color = "#00ffff" }, { units = 228, color = "#000080" }, { units = 218, color = "#00ff00" }, { units = 208, color = "#ffff00" }, { units = 198, color = "#ff0000" }, { units = 188, color = "#000000" }, { units = 178, color = "#ffffff" } ] #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" ####ADMINISTRATIVE#### [[handler]] type = "text" product = "other" dir = "./goes16/ADMIN/text/{time:%Y-%m-%d}" filename = "{time:%Y%m%dT%H%M%SZ}_{filename}" # Emergency Mangers Weather Information Network # The HRIT stream on the GOES-R series includes EMWIN data. This handler writes EMWIN files and decompresses them if applicable (a subset of EMWIN files is compressed as ZIP file). [[handler]] type = "emwin" directory = "./emwin/{time:%Y-%m-%d}" exclude_txt = true # Images relayed from Himawari-8. [[handler]] type = "image" origin = "himawari8" directory = "./himawari8/{region:short|lower}/{time:%Y-%m-%d}" filename = "Himawari8_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # NWS text (weather reports). [[handler]] type = "text" origin = "nws" directory = "./nws/{time:%Y-%m-%d}" filename = "{time:%Y%m%dT%H%M%SZ}_{awips:nnn}{awips:xxx}" json = false # NWS images. [[handler]] type = "image" origin = "nws" directory = "./nws/{time:%Y-%m-%d}" filename = "{time:%Y%m%dT%H%M%SZ}_{filename}" format = "png" json = false # Miscellaneous text. [[handler]] type = "text" origin = "other" directory = "./text/{time:%Y-%m-%d}" filename = "{time:%Y%m%dT%H%M%SZ}_{filename}" json = false # Store relayed GOES-15 full disks [[handler]] type = "image" origin = "goes15" regions = [ "fd" ] directory = "./goes15/{region:short|lower}/{time:%Y-%m-%d}" filename = "GOES15_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" crop = [ -2374, 2371, -1357, 1347 ] format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # Store relayed GOES-15 northern hemisphere region [[handler]] type = "image" origin = "goes15" regions = [ "nh" ] directory = "./goes15/{region:short|lower}/{time:%Y-%m-%d}" filename = "GOES15_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" crop = [ -1864, 1447, -1357, -3 ] format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # Store relayed GOES-15 southern hemisphere region [[handler]] type = "image" origin = "goes15" regions = [ "sh" ] directory = "./goes15/{region:short|lower}/{time:%Y-%m-%d}" filename = "GOES15_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" crop = [ -1864, 896, -19, 1043 ] format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # Store relayed GOES-15 US region [[handler]] type = "image" origin = "goes15" regions = [ "us" ] directory = "./goes15/{region:short|lower}/{time:%Y-%m-%d}" filename = "GOES15_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" crop = [ -1312, 1542, -1327, -345 ] format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # Store relayed GOES-15 special regions # No crop specified because it is expected to move around [[handler]] type = "image" origin = "goes15" regions = [ "si00", "si01", "si02", "si03", "si04" ] directory = "./goes15/{region:short|lower}/{time:%Y-%m-%d}" filename = "GOES15_{region:short}_{channel:short}_{time:%Y%m%dT%H%M%SZ}" format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # The following handler takes the same crop from the FD, NH, and US # products to get more frequent imagery of a smaller area on the # northern hemisphere. The crop region is a combination of the NH and # US crop regions. [[handler]] type = "image" origin = "goes15" regions = [ "fd", "nh", "us" ] crop = [ -1312, 1447, -1327, -345 ] directory = "./goes15/combine-north/{time:%Y-%m-%d}" filename = "GOES15_{channel:short}_{time:%Y%m%dT%H%M%SZ}_{region:short}" format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json" # The following handler takes the same crop from the FD and SH # products to get more frequent imagery of a smaller area on the # southern hemisphere. [[handler]] type = "image" origin = "goes15" regions = [ "fd", "sh" ] crop = [ -1864, 896, -19, 1043 ] directory = "./goes15/combine-south/{time:%Y-%m-%d}" filename = "GOES15_{channel:short}_{time:%Y%m%dT%H%M%SZ}_{region:short}" format = "jpg" json = false #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json"
this isn’t secure, but meh, let’s make the html directory world writeable
$ sudo chmod -R 777 /var/www
now we want to setup pretty directory listings for apache
$ cd $ wget https://release.larsjung.de/h5ai/h5ai-0.30.0.zip $ unzip h5ai-0.30.0.zip $ mv _h5ai /var/www/html $ chmod 777 /var/www/html/_h5ai/public/cache $ cd /var/www/html
now you want to edit the default apache site config
$ sudo nano /etc/apache2/sites-enabled/000-default.conf
look for the
DocumentRoot /var/www/html
and paste this below it;<Directory "/var/www/html"> Options +Indexes AllowOverride all Order allow,deny Allow from all Require all granted </Directory> DirectoryIndex index.html index.php /_h5ai/public/index.php
now restart apache
$ sudo systemctl restart apache2
visit your site in a web browser (http://ip.address.of.radio.server) and you should see a pretty directory listing
now we set this up to automate on reboot.
$ nano ~/goes_start.sh
paste this in
#!/bin/sh /usr/bin/sudo -u radio /usr/bin/screen -dmS goesrecv /usr/bin/goesrecv -v -i 1 -c /home/radio/goesrecv.conf /usr/bin/sudo -u radio /usr/bin/screen -dmS goesproc /usr/bin/goesproc -c /usr/share/goestools/goesproc-goesr.conf -m packet --subscribe tcp://127.0.0.1:5004 --out /var/www/html/goes
exit and save your file, and make it executable
$ chmod +x goes_start.sh
now we need to setup the fire data
$ nano ~/goes_fire.sh
paste this into the file, exit and save
# automate fire data receiving export DIR="/home/radio/goes_stuff" if [ ! -f '$DIR/fire.json' ] then echo "no previous fire data to delete" else echo "deleting fire.json" rm '$DIR/fire.json' fi if [ ! -d $DIR ] then echo "no directory available, can't continue" exit 0 else echo "entering directory" cd $DIR fi echo -n "downloading fire data: " wget -q https://firms2.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/shapes/zips/MODIS_C6_1_Global_24h.zip echo "done" echo -n "extracting fire data: " unzip -qq MODIS_C6_1_Global_24h.zip -d fire_data echo "done" echo -n "extracting data to create fire.json: " ogr2ogr -f "GeoJSON" -dialect SQLite -sql "select ST_Buffer(geometry,0.01) from MODIS_C6_1_Global_24h" fire.json ./fire_data/MODIS_C6_1_Global_24h.shp echo "done" echo -n "removing old data: " rm -rf fire_data rm -f MODIS_C6_1_Global_24h.zip echo "done"
make it executable then run it for the first time
$ chmod +x /home/radio/goes_fire.sh $ ./goes_fire.sh
then edit your crontab
$ crontab -e
paste this in after all the comments
@reboot sleep 15 && /usr/bin/sudo -u radio /usr/bin/screen -dmS goesrecv /usr/bin/goesrecv -v -i 1 -c /home/radio/goesrecv.conf @reboot sleep 15 && /usr/bin/sudo -u radio /usr/bin/screen -dmS goesproc /usr/bin/goesproc -c /usr/share/goestools/goesproc-goesr.conf -m packet --subscribe tcp://127.0.0.1:5004 --out /var/www/html/goes # run the fire collection script every 10 minutes */10 * * * * /home/radio/goes_fire.sh
exit and save the file
now, we have to add our microsdcard as a directory / mountable drive. first you want to run fdisk to view your current drives. you’ll see a few, but we’re looking for
/dev/mmc*
in this use-case. Mine look like this.$ sudo fdisk -l Disk /dev/mmcblk1: 119.08 GiB, 127865454592 bytes, 249737216 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x00000000 Device Boot Start End Sectors Size Id Type /dev/mmcblk1p1 32768 249737215 249704448 119.1G 7 HPFS/NTFS/exFAT Disk /dev/mmcblk0: 29.12 GiB, 31268536320 bytes, 61071360 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x03823826 Device Boot Start End Sectors Size Id Type /dev/mmcblk0p1 2048 264191 262144 128M c W95 FAT32 (LBA) /dev/mmcblk0p2 264192 61069312 60805121 29G 83 Linux
in our case, the 128gb disk is
/dev/mmcblk1p1
so we want to delete any partitions that exist, in our case,1
through4
then write the changes$ sudo fdisk /dev/mmcblk1p1 d 1 d 2 d 3 d 4 w
now we want to re-setup the new partition by creating a new partition under position 1 and writing the changes
$ sudo fdisk /dev/mmcblk1p1 n p 1 <enter> <enter> w
now we want to reboot
$ sudo reboot
now we want to format the new drive as ext4
$ sudo mkfs.ext4 /dev/mmcblk1p1
now we want to copy out any files from the current web directory to
/tmp
$ mkdir /tmp/www $ sudo cp -R /var/www/html /tmp/www
now we need to find the
blkid
of our drive to add it to fstab$ sudo blkid
The above command outputs something like
/dev/mmcblk0p2: LABEL="rootfs" UUID="e139ce78-9841-40fe-8823-96a304a09859" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="03823826-02" /dev/mmcblk1p1: UUID="e8d29822-6bdf-4bf8-817c-915e0db7572d" BLOCK_SIZE="4096" TYPE="ext4" /dev/mmcblk0p1: SEC_TYPE="msdos" LABEL_FATBOOT="BOOT" LABEL="BOOT" UUID="F702-39CB" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="03823826-01"
so in our case, our drive is
/dev/mmcblk1p1
so we want to copy theUUID
of this drivee8d29822-6bdf-4bf8-817c-915e0db7572d
now we want to edit fstab and make this drive auto mount on boot
$ sudo mv /var/www/html /var/www/html.old $ sudo nano /etc/fstab
then we want to add our drive using the
UUID
you got aboveUUID=e8d29822-6bdf-4bf8-817c-915e0db7572d /var/www/html ext4 defaults 0 0
exit and save your file, then try mounting it.
$ sudo mkdir /var/www/html $ sudo chmod 777 /var/www/html $ sudo mount /var/www/html $ cd /var/www/html $ ls lost+found
if you see the lost and found directory, you’re setup properly. so lets copy over our existing files and directory lister now.
$ cd /var/www/html $ sudo mv /var/www/html.old/* .
at this point your
/var/www/html
mounted drive should look like this$ ls -l total 24 drwxrwxr-x 4 radio radio 4096 Jan 24 2021 _h5ai drwxrwxrwx 6 root root 4096 Jan 29 00:00 goes drwx------ 2 root root 16384 Jan 29 01:38 lost+found
now we want to reboot to ensure it’s loaded properly on reboot and files still get written
$ sudo reboot
now ssh back to your server and issue the following commands to ensure everything is working;
$ ssh -l radio ip.address.of.radio $ screen -r There are several suitable screens on: 3199.goesrecv (01/29/23 01:58:59) (Detached) 3197.goesproc (01/29/23 01:58:59) (Detached)
this means your screen sessions are running (you can join either of them with
screen -r sessionname
)now you want to check if your new mountpoint is working
$ mount | grep html /dev/mmcblk1p1 on /var/www/html type ext4 (rw,relatime,data=ordered)
if you see the mountpoint you should be all good, if you don’t, time to troubleshoot bro.
now you can delete your old backup directories
$ sudo rm -rf /var/www/html.old $ sudo rm -rf /tmp/www
reboot to make sure it all works
$ sudo reboot
once logged in again, verify your receiving, and processing the data
$ screen -r goesrecv <ctrl-a-d to leave> $ screen -r goesproc <ctrl-a-d to leave>
congrats! everything is setup, now you just got to wait for some images to be generated, where you can visit your web server to check them out.
NOTE YOU MIGHT WANT TO ENABLE THE COUNTRY/PROVINCE/STATE OUTLINES - THIS IS TOTALLY UP TO YOU. MY EXAMPLE ABOVE HAS THEM DISABLED. IF YOU WANT TO DO THIS, FOLLOW THESE STEPS;
edit the goes processing file
$ sudo nano /usr/share/goestools/goesproc-goesr.conf
for all the lines that look like this;
#[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" #[[handler.map]] #path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json"
UNcomment them out so they look like this
[[handler.map]] path = "/usr/share/goestools/ne/ne_50m_admin_0_countries_lakes.json" [[handler.map]] path = "/usr/share/goestools/ne/ne_50m_admin_1_states_provinces_lakes.json"
exit and save the file
reboot for changes to take effect (or, stop and start your screen sessions).
$ sudo reboot