Sunday, July 14, 2019

Using the Pimoroni Fan Shim with LibreElec


Trying out the latest LibreElec alpha on a Raspberry Pi 4 on the hottest day of the year so far I found the CPU temperature reaching 70ºC. A bit too warm for my liking, so I've added a Pimoroni Fan Shim.

There's no way you can install the Pimoroni python library on LibreElec, but there is an alternative.

I found a script on https://forum-raspberrypi.de/forum/thread/43568-fan-shim-steuern/, and edited it slightly. Change the min and max temperatures to suit yourself:

    
#!/usr/bin/env python
# https://forum-raspberrypi.de/forum/thread/43568-fan-shim-steuern/
# place command below in /storage/.config/autostart.sh
#   nohup /storage/fanshim.py &
import os
import time
import signal
import sys
sys.path.append('/storage/.kodi/addons/virtual.rpi-tools/lib')
import RPi.GPIO as GPIO
import subprocess
Pause = 30
CoreTempMax = 57
CoreTempMin = 46
GPIO_Pin = 18
Run_Fan_function = False
def init():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(GPIO_Pin, GPIO.OUT)
    return()
def Set_Fan_ON():
    GPIO.output(GPIO_Pin, True)
    return()
    
def Set_Fan_OFF():
    GPIO.output(GPIO_Pin, False)
    return()
def get_CPU_Temp():
    temp = subprocess.check_output(['vcgencmd', 'measure_temp'])[5:-3]
    return temp
    
def Watch_Temp():
    global Run_Fan_function
    CPU_Temp = float(get_CPU_Temp())
    if Run_Fan_function==False and CPU_Temp>=CoreTempMax:
        Run_Fan_function = True
        Set_Fan_ON()
    if Run_Fan_function==True and CPU_Temp<=CoreTempMin:
        Run_Fan_function = False
        Set_Fan_OFF()
    return();
try:
    init() 
    while True:
        Watch_Temp()
        time.sleep(Pause)
except KeyboardInterrupt:
    GPIO.cleanup()

I've saved it as /storage/fanshim.py, and

chmod +x /storage/fanshim.py

Then edit /storage/.config/autostart.sh so it contains the line:

nohup /storage/fanshim.py &

Reboot your Pi 4 for it to take effect.

If you're using a TV Hat, you'll need an extra tall stacking header to give a good gap between the fan and the TV Hat.

Enjoy.


Posted by Phil at 10:06 PM
Edited on: Sunday, July 14, 2019 10:30 PM
Categories: IT, Raspberry Pi

Saturday, April 27, 2019

A Raspberry Pi Stratum 1 NTP Server


Overview

The following instructions are how to make a cheap Pulse Per Second (PPS) disciplined Stratum 1 NTP Time server using one of the Raspberry Pi U-blox M8Q based GPS boards sold by Uputronics.

Our basic requirement is for an NTP server which will work standalone without connectivity to other NTP servers, so if a datacentre loses connectivity its servers will still have a stable time source.

As we’re only interested in time and not height, motion, or location, all we’re interested in is the NMEA xxZDA and xxRMC sentences and the highly accurate PPS signal from the GPS module, both of which we feed straight into the ntp daemon. The xxZDA sentences (which give us full 4-digit years) are not output by default by the M8Q so we have to enable them at boot time.

Many guides on the net use gpsd to feed ntp via shared memory. That’s an additional overhead and complexity, especially if we want to enable Galileo reception (gpsd initialises the U-blox the way it sees fit). I prefer to let the NTP daemon read the NMEA stream from the GPS receiver itself, avoiding the middle man.

In this guide we’ve chosen to use NMEA output from the GPS module via the ntp Generic GPS Receiver driver 20 ( https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver20.html ) and the PPS signal via driver 22 ( https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver22.html ).

You will need a Raspberry 3 B+, the Uputronics Raspberry Pi+ GPS Expansion Board and a suitable GPS antenna.

This guide assumes that you’re using Raspbian Stretch Lite November 2018 released 2018-11-13 image, or later. Download and write this to an SD card.

See https://www.raspberrypi.org/documentation/installation/installing-images/windows.md

Create a file named ssh in the boot folder after burning the MicroSD card.

Attach the Uputronics Raspberry Pi+ GPS Expansion Board to the Pi, insert the SD card, connect the antenna and network cable and boot the Pi up. Either connect locally or via SSH to the Pi. If you can’t SSH in and don’t have a monitor see this

https://www.raspberrypi.org/documentation/configuration/wireless/headless.md

Follow the instructions carefully if you miss steps things won’t work.

The Uputronics board has u-blox firmware 3.01 on it, dated 2016.

The week number rollover is set to 1867 (October 2015). All transmitted week numbers are mapped to the ~19.5 year period between week 1867 and week 2990 (April 2035).

A Note About Accuracy

In theory, GPS-based time receivers can give a very high accuracy, with the PPS (Pulse per Second) signal being accurate to within 10ns.

However, fix data from gpsctl shows:


    
pi@ntp2:~ $ /usr/local/bin/gpsctl -Q fix
Time (UTC): 2019-04-18 15:31:27 (yyyy-mm-dd hh:mm:ss)
Latitude: 52.05994980 N
Longitude: 2.72698960 W
Altitude: 198.789 feet
Motion: 0.338 mph at 53.114 degrees heading
Satellites: 5 used for computing this fix
Accuracy: time (39 ns), height (+/-18.199 feet), position (+/-103.911 feet), heading(+/-8.230 degrees), speed(+/-0.132 mph)

Note the 39ns time accuracy from that fix. The more satellites, the better.

Errors are also caused by signal delay (4ns per foot) in the cable from the aerial to the GPS receiver, etc.

So we’d be lucky to get 100ns accuracy from the PPS pulse.

Add to that the processing overheads of the PPS interrupt, and processor clock jitter in the Raspberry Pi, and overheads transferring and decoding the NMEA sentences. The jitter on the PPS signal is less than 5 microseconds.

The output from the ntp NMEA driver without PPS correction can have a jitter of a few milliseconds, and an offset from real time which has to be tweaked manually to get within 5ms of the correct time.

NTP sources on the internet can show offsets / jitter of over 5ms, local LAN 50us or more.

On the Pi 3B+ we can expect an average jitter of less than 1 microsecond.

Required Components

I sourced my components from ModMyPi (now taken over by the Pi Hut) unless noted elsewhere:

1 Raspberry Pi Model 3B+

1 8GB or larger micro SD card

(a Transcend High Endurance 32GB micro SD card would be better choice than a generic one for longevity)

1 Uputronics GPS Hat

1 ModMyPi Pi GPS case

1 Raspberry Pi 3 power supply

1 GPS SMA Antenna

(optional) 1 SMA-male to TNC-female (or BNC, as needed) adaptor to connect to existing GPS aerial (from Amazon or eBay)

Prerequisite Settings

Login as pi / raspberry, and immediately change the password from the default

passwd

sudo raspi-config

7 Advanced Options

A1 Expand filesystem

5 Interfacing Options

P2 SSH -> Would you like the SSH server to be enabled – YES (Recommended)

P6 Serial -> Login Shell (no) Hardware (yes) (Optional)

Quit but no need to reboot at this point.

sudo systemctl disable hciuart

sudo systemctl disable serial-getty@ttyAMA0.service

sudo systemctl mask serial-getty@ttyAMA0.service

sudo apt install pps-tools ntp setserial wiringpi

sudo apt purge bluez bluez-firmware wpasupplicant (assuming no wifi required)

sudo apt update

sudo apt full-upgrade

sudo nano /boot/config.txt and add at the bottom :

dtoverlay=pi3-disable-bt
dtoverlay=pi3-disable-wifi
dtoverlay=pps-gpio,gpiopin=18

Make sure that enable_uart=1 is set in /boot/config.txt

sudo nano /etc/modules and add at the bottom :

pps-gpio
  

Save and Quit Nano.

sudo nano /etc/udev/rules.d/80-gps-to-ntp.rules (needed for refclock 20 in ntp)

# Change MODE of ttyAMA0 so it is readable by NTP and provide

# a symlink to /dev/gps0 
KERNEL=="ttyAMA0", SUBSYSTEM=="tty", DRIVER=="", SYMLINK+="gps0", MODE="0666" 
# Symlink /dev/pps0 to /dev/gpspps0 

KERNEL=="pps0", SUBSYSTEM=="pps", DRIVER=="", SYMLINK+="gpspps0", MODE="0666"

and then sudo reboot


Enabling Galileo Satellites and Setting Stationary Mode

Stationary mode gives a faster GPS fix.

See Tom Dilatush’s gpsctl:

http://www.jamulblog.com/2017/11/paradise-ponders-gpsctl-functionally.html

I’ve customised it further to enable the use of a config file and put it in my GitHub repo:

https://github.com/philrandal/gpsctl

Download and build gpsctl.

cd ~
wget https://github.com/philrandal/gpsctl/archive/master.zip
unzip gpsctl-master.zip
mv gpsctl-master gpsctl
cd gpsctl
./build.sh
sudo cp /home/pi/gpsctl/gpsctl /usr/local/bin
sudo cp /home/pi/gpsctl/etc/gpsctl.conf /etc/gpsctl.conf

Individual settings can be tweaked in /etc/gpsctl.conf.

To set port speed to 115200 baud, enable Galileo satellites, set stationary mode, tweak antenna delays, PPS timing, etc:

/usr/local/bin/gpsctl -a -B 115200 --configure_for_timing -vv

To reset the device to its defaults

/usr/local/bin/gpsctl -a --reset -vv

To view info:

/usr/local/bin/gpsctl –a –Q satellites

/usr/local/bin/gpsctl –a –Q config

/usr/local/bin/gpsctl –a –Q fix

Note that these commands can only be run when gpsd / ntp are not using /dev/ttyAMA0

Example /etc/gpsctl.conf which configures the U-blox M8Q for this environment:

    
# # example gpsctl.conf which enables Galileo as in --galileo parameter
#
[gpsctl]
port = /dev/serial0
# sync method: ASCII = 1, NMEA = 2, UBX = 3
sync method = 3
verbosity = 0
[NMEA]
enabled = true
version = 41
GGA = off
GLL = off
GSA = off
GSV = off
RMC = on
VTG = off
GRS = off
GST = off
ZDA = on
[GPS]
enabled = yes
minimum channels=8
maximum channels=16
[SBAS]
enabled = no
minimum channels=1
maximum channels=3
[Galileo]
enabled = yes
minimum channels=4
maximum channels=8
[Beidou]enabled = no
minimum channels=8
maximum channels=16
[IMES]
enabled = no
minimum channels=0
maximum channels=8
[QZSS]
enabled = no
minimum channels=0
maximum channels=3
[GLONASS]
enabled = yes
minimum channels=8
maximum channels=14
[Navigation Engine]
# Dynamic model: Portable = 0, Stationary = 2, Pedestrian = 3, Automotive = 4,
# Sea = 5, Air1G = 6, Air2G = 7, Air4G = 8, Watch = 9
Dynamic model = 2
# Fix mode: 2D only = 1, 3D only = 2, auto 2D/3D = 3
Fix mode = 3
Fixed altitude (2D) = 0.00 meters
Fixed altitude variance (2D) = 1.0000 meters^2
Minimum elevation = 5 degrees
Position DoP mask = 10.0
Time DoP mask = 10.0
Position accuracy mask = 100 meters
Time accuracy mask = 300 meters
Static hold threshold = 0 cm/s
Dynamic GNSS timeout = 60 seconds
Threshold above C/No = 0 satellites
C/No threshold = 0 dBHz
Static hold max distance = 0 meters
# UTC Standard: AutoUTC = 0, USNO_UTC = 3, GLONASS_UTC = 6, BeiDou_UTC = 7
UTC standard = 3
[Time Pulse]
# the nanoseconds / microseconds after the numbers are just reminders,
# they don't mean anything to the config parser
Antenna cable delay = 56 nanoseconds
RF group delay = 20 ns
Unlocked pulse period = 1000000 microseconds
Unlocked pulse length = 0
Locked pulse period = 1000000 microseconds
Locked pulse length = 500000 microseconds
User configurable delay = 0

    

To run gpsctl at system startup,

sudo cp /home/pi/gpsctl/systemd/ublox-init.service /etc/systemd/system/ublox-init.service

or

nano /etc/systemd/system/ublox-init.service

and add the following contents

[Unit]
Description=u-blox initialisation
Before=gpsd.service
Before=ntp.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/gpsctl -q -a -B 115200 --configure_for_timing
[Install]
WantedBy=multi-user.target

    

This will enable Galileo satellites, set stationary mode, configure comms at 115200 baud, and restrict NMEA output to RMC and ZDA records.

Then

sudo systemctl enable ublox-init.service

sudo systemctl daemon-reload

For maximum stability and ntp performance, add these lines to the end of /etc/rc.local, before the exit 0 line

echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

    

Verifying that PPS Is Working

Ensure the GPS has a lock and the Green PPS LED on the Uputronics Pi+ GPS Expansion Board is blinking once a second.

lsmod | grep pps

Output should be similar to :

pps_gpio                3089  1pps_
core                8606  4 pps_gpio

dmesg | grep pps

Output should be similar to :

[    2.735586] pps_core: LinuxPPS API ver. 1 registered
[ 2.738121] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 2.763842] pps pps0: new PPS source pps@12.-1
[ 2.766361] pps pps0: Registered IRQ 169 as PPS source

    

This indicates that the PPS Module is loaded.

sudo ppstest /dev/pps0

Output should be similar to:

trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1418933982.998042450, sequence: 970 - clear  0.000000000, sequence: 0
source 0 - assert 1418933983.998045441, sequence: 971 - clear  0.000000000, sequence: 0

    

(Press CTRL+C to quit). This indicates that the PPS Module is working.

Enabling PPS/ATOM Support in NTPD

The supplied version of NTPD on the Raspberry Pi in Raspbian Stretch 2018-11-13 and later supports PPS so there is no need to roll your own NTP.

You need to pick a few local NTP servers to use. The easiest way to do this is pick your region:

https://support.ntp.org/bin/view/Servers/NTPPoolServers

Select your region then you get a list of the country servers. E.g for the UK its uk.pool.ntp.org.

Type:

dig uk.pool.ntp.org

You will get four IP’s back:

;; &lt;&lt;&gt;&gt; DiG 9.10.3-P4-Raspbian &lt;&lt;&gt;&gt; +answer uk.pool.ntp.org
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 51647
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;uk.pool.ntp.org. IN A
;; ANSWER SECTION:
uk.pool.ntp.org. 24 IN A 193.150.34.2
uk.pool.ntp.org. 24 IN A 176.58.109.199
uk.pool.ntp.org. 24 IN A 195.195.221.100
uk.pool.ntp.org. 24 IN A 185.53.93.157


sudo nano /etc/ntp.conf

Add

# PPS Driver
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 time1 +0.000000 flag3 0 refid PPS
#flag3 Controls the kernel PPS discipline: 0 for disable (default), 1 for enable.
#time1 PPS time offset
tos mindist 0.002
# NMEA driver (/dev/gps0 and /dev/gpspps0)
server 127.127.20.0 mode 89 minpoll 4 maxpoll 4 iburst prefer
fudge 127.127.20.0 flag1 0 flag2 0 flag3 0 time2 0.043 refid GPS stratum 2
#flag1 Disable PPS signal processing if 0 (default); enable PPS signal processing if 1.
#flag2 If PPS signal processing is enabled, capture the pulse on the rising edge if 0 (default); capture on the falling edge if 1.
#flag3 If PPS signal processing is enabled, use the ntpd clock discipline if 0 (default); use the kernel discipline if 1.
#time1 PPS time offset
#time2 NMEA time offset
#mode bit 0 - process $GPMRC (value = 1)
# bit 1 - process $GPGGA (value = 2)
# bit 2 - process $GPGLL (value = 4)
# bit 4 - process $GPZDA or $GPZDG (value = 8)
# bits 4/5/6 - select serial bitrate (0 for 4800 - the default, 16 for 9600, 32 for 19200, 48 for 38400, 64 for 57600, 80 for 115200)
# mode 89 = process only xxRMC and xxZDA NMEA records at 115200 baud

    
  

(Note that I used “fudge 127.127.20.0 time2 0.043 …” to adjust the GPS time according to the other NTP servers. You can try some higher/lower values to have the offset of your NMEA driver compared to the offsets of those other NTP servers very small. We’ll cover that later.)

We want to make sure that the second reported by the NMEA driver is the second that the last PPS pulse referred to, so it needs to be within a few hundred milliseconds of the correct time so that NTP does the right thing. This is why it’s desirable to mark another NTP server as “prefer” to help the NTP daemon get it right.

Note that we use NTP PPS discipline, not kernel PPS (which in my testing results in warnings from ntp that kernel PPS discipline isn’t supported).

Comment out all the pool lines.

Add the servers from the dig command, or use servers of your choice) with the top one saying prefer on it (example only, don't all use these IP addresses):

server 176.58.109.199 iburst prefer
server 195.195.221.100 iburst
server 185.53.193.157 iburst
# By default, exchange time with everybody, but don't allow configuration.
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict -6 ::1
restrict 10.0.0.0 mask 255.0.0.0
restrict 172.16.0.0 mask 255.240.0.0
restrict 192.168.0.0 mask 255.255.0.0
# Drift file etc.
driftfile /var/lib/ntp/ntp.drift

    

Note You MUST add a preferred server or PPS doesn’t work.

Save and close nano.

sudo systemctl restart ntp.service

After a few minutes run

ntpq –p

If you get oPPS(0) this indicates source selected, Pulse Per Second (PPS) used and everything is working.

pi@ntp2:~ $ ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
o127.127.22.0 .PPS. 0 l 6 16 377 0.000 -0.002 0.001
*127.127.20.0 .GPS. 1 l 5 16 377 0.000 -0.323 1.052
+195.195.221.100 .GPS. 1 u 49 64 377 18.307 0.190 0.127
+193.150.34.2 85.199.214.101 2 u 56 64 377 7.953 0.067 0.114
  

And then

pi@ntp2:~ $ ntpq -csysinfo
associd=0 status=0115 leap_none, sync_pps, 1 event, clock_sync,
system peer: PPS(0)
system peer mode: client
leap indicator: 00
stratum: 1
log2 precision: -21
root delay: 0.000
root dispersion: 2.015
reference ID: PPS
reference time: e0601d81.248b4b37 Tue, Apr 16 2019 10:23:13.142
system jitter: 0.000477
clock jitter: 0.003
clock wander: 0.001
broadcast delay: -50.000
symm. auth. delay: 0.000

    

If you aren’t seeing the settings its possible the NTP server is picking up the NTP information via DHCP which is overriding your settings above. Do this :

rm /etc/dhcp/dhclient-exit-hooks.d/ntp

rm /var/lib/ntp/ntp.conf.dhcp

At this point you have a NTP server which will use an external time source and use your local PPS to discipline it.

GPS Offset Tuning

Your PPS time is going to be more accurate than NTP pool servers. Unless you have specialised equipment and local LAN GPS / DCF77 / MSF PPS sources to calibrate against, it’s not really possible to determine the appropriate PPS offset. It’s likely to be in the order of a few microseconds at most ( http://lists.ntp.org/pipermail/questions/2011-September/030338.html ).

The PPS is a precise signal with around 10 ns of jitter. On the other hand, the offset of the GPS serial data output (GPSD) generally will have much more variation than the PPS because of the variables involved in sending data over an asynchronous serial port. However, the GPSD offset can be reduced somewhat by adjusting the GPSD reference clock fudge parameter time2 in the ntp.conf file.

The initial value used in our ntp.conf file is 43ms (0.043s). This means that the GPS ZDA packet arrives in the NTP daemon approximately 43ms after the PPS pulse corresponding to it. On our test device, we see a jitter of under 3ms on the GPS_NMEA clock.

We might need to adjust the GPS ntp.conf time2 (offset) value to get the NMEA time offset low enough that the offset isn’t great enough to confuse NTP as to which second the PPS pulse referred to.

This option can be used to compensate for a constant error. The specified offset (in seconds) is applied to all samples produced by the reference clock. The default is 0.000s.

Start with these ntp.conf settings, they should get you close enough to get everything working properly:

sudo nano /etc/ntp.conf

#kernel-mode PPS
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 time1 +0.000 flag3 0 refid PPS
tos mindist 0.002

    
#GPS (NMEA)
server 127.127.20.0 mode 89 minpoll 4 maxpoll 4 iburst prefer
fudge 127.127.20.0 flag1 0 flag3 0 time2 0.043 refid GPS stratum 2

    

Add these lines at the top of ntp.conf:

statsdir /var/log/ntpstats/
statistics peerstats
filegen peerstats file peerstats type day enable

    

This enables logging of the peer server statistics.

To calculate the GPS offset we must disable GPS by placing a noselect in the ntp.conf GPS line. We'll run the time server for a few hours and then compare the ntpq -p GPS offset to the average public time server offset. For accurate tuning use a bunch of known-good Stratum 1 servers in ntp.conf.

sudo nano /etc/ntp.conf

#PPS
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 time1 +0.000 flag3 0 refid PPS
tos mindist 0.002
#GPS (NMEA)
server 127.127.20.0 mode 89 minpoll 4 maxpoll 4 iburst prefer noselect
fudge 127.127.20.0 flag1 0 flag3 0 time2 0.043 refid GPS stratum 2

    

sudo systemctl stop ntp.service

sudo rm –f /var/log/ntpstats/*

sudo systemctl start ntp.service

Start ntpd and let it run for at least four hours. Periodically check progress with "ntpq -p" and wait until change has settled out.

Look for the row with GPS_NMEA(0) and refid GPSD. The offset values probably will be different for each

query. Note that the ntpq offsets are in milliseconds, but the peerstats file offsets and NTP’s time2 parameter are in seconds.

Calculate the average GPS offset (in seconds) using this script:

sudo nano ~/nmeaoffset

#!/bin/sh
#
# Generate an estimate of your GPS's offset from a peerstats file
#
awk '
/127\.127\.20\.0/ { sum -= $5 ; cnt++; }
END { printf("%.6f\n", sum / cnt); }
' </var/log/ntpstats/peerstats

    

Then sudo chmod +x ./nmeaoffset

Run by typing

pi@ntp2:~ $ ./nmeaoffset

-0.001212
  

That’s within a few milliseconds, close enough for anyone as PPS is going to do its magic to give us accuracy within a few microseconds.

Adjust the "time2" value for the GPS source of your ntp.conf by adding the average offset from above.

sudo systemctl stop ntp.service

sudo rm –f /var/log/ntpstats/*

sudo systemctl start ntp.service

Repeat the procedure above until -5ms < offset < +5ms (or under 10ms, if that’s OK with you). When you’re done, remove the noselect from the server 127.127.20.0 line in ntp.conf.

If you decide to recalculate the average offset using the above procedures, wait at least another day or two.

Avoid unnecessarily changing the time2 value. A typical value for the Adafruit GPSD driver is +0.534 s when using its default 4800 baud interface and in the HAB Supplies/Uputronics GPSD it’s +0.043 s when using 115200 baud and the gpsctl --config_for_timing tweaks.

To save wear and tear on the SD card, comment out the statistics line in /etc/ntp.conf when done.

Automatically updating GPS leap seconds

These semi-annual changes will be made no later than 1 June and 1 December of each year to indicate what action (if any) is to be taken on 30th June and 31st December, respectively

Make a cron script for auto-downloading leap seconds file (based on https://developers.redhat.com/blog/2017/02/22/how-to-build-a-stratum-1-ntp-server-using-a-raspberry-pi/ )

nano /usr/local/bin/leap-seconds.sh

#!/bin/sh
/usr/bin/wget –q –N https://www.ietf.org/timezones/data/leap-seconds.list -O /var/lib/ntp/leap-seconds.list
/usr/sbin/service ntp restart &> /dev/null
  

Once this is done, make sure it is executable:

sudo chmod a+x /usr/local/bin/leap-seconds.sh

Now, create an entry in root’s crontab to check on the 7th June and the 7th December:

sudo crontab -e

0 0 07 6,12 * /usr/local/bin/leap-seconds.sh
  

Lastly, modify the “/etc/ntp.conf” configuration file once again, and add this near the top of the file:

# leap seconds file
leapfile /var/lib/ntp/leap-seconds.list
  

Static IP and Hostname

If you want to fix your LAN IP you do it by amending /etc/dhcpcd.conf adding the following lines (adjust to suit your environment):

# It is possible to fall back to a static IP if DHCP fails:
# define static profile
profile static eth0
static ip_address=192.168.1.7/24
static routers=192.168.1.254
static domain_name_servers=8.8.8.8 8.8.4.4
# fallback to static profile on eth0
interface eth0
fallback static_eth0

    

This way DHCP will work if plugged into a client switch port, but static IP will default when no DHCP is available.

Great for testing the box on one’s desktop before going live.

Amend your hostname by editing /etc/hostname and then adding the below to /etc/hosts.

i.e if you call your machine ‘ntp’ fix the /etc/hosts 127.0.1.1 line:

127.0.1.1 ntp
  

Further Reading

The original text this document was based on can be found at https://ava.upuaut.net/?p=951

Updated to include information from comments at https://blog.webernetz.net/ntp-server-via-gps-on-a-raspberry-pi/

David Taylor’s website https://satsignal.eu/ntp/Raspberry-Pi-NTP.html goes into much further detail about the process above and covers graphing, remote access monitoring.

Rob Robinette has a good write up on Pi-based NTP servers

https://robrobinette.com/pi_GPS_PPS_Time_Server.htm

Whitham D. Reeve’s GpsNtp-Pi Installation and Operation Guide

http://www.reeve.com/RadioScience/Raspberry%20Pi/GpsNtp-Pi.htm

Rich Laager’s Raspberry Pi 3 Stratum 1 NTP Server has the best stuff on offsets

https://coderich.net/2016/11/21/raspberry-pi-3-stratum-1-ntp-server/

Tech Solvency’s similar setup

https://www.techsolvency.com/ntp/systems/tackleberry-uputronics/

Gary Miller’s GPSD Time Service HOWTO

http://www.catb.org/gpsd/gpsd-time-service-howto.html

Jack Zimmerman’s Raspberry PI NTP Server LCD Display

https://github.com/jacken/Raspberry-Pi-ntp-server-LCD-display

Jack Zimmerman’s Pi U-Blox Stationary Mode

https://github.com/jacken/Raspberry-Pi-U-Blox-Stationary-Mode

Tom Dilatush’s gpsctl

http://www.jamulblog.com/2017/11/paradise-ponders-gpsctl-functionally.html

My improved gpsctl with added .conf file support GitHub repo

https://github.com/philrandal/gpsctl

u-blox M8 Receiver Description (the bible)

https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_%28UBX-13003221%29_Public.pdf

GNSS Firmware 3.01 for u-blox M8

https://www.u-blox.com/sites/default/files/GNSS-FW3.01_ReleaseNotes_%28UBX-16000319%29_Public.pdf

Postscript, June 27th, 2019

On Raspbian Buster, the /etc/udev/rules.d/80-gps-to-ntp.rules file needs changing to

# Change MODE of ttyAMA0 so it is readable by NTP and provide

# a symlink to /dev/gps0

KERNEL=="ttyAMA0", SYMLINK+="gps0", MODE="0666"

# Symlink /dev/pps0 to /dev/gpspps0

KERNEL=="pps0", SYMLINK+="gpspps0", MODE="0666"

Postscript, July 15th, 2019

You can enable either BeiDou satellites, or Glonass, but not both with gpsctl. You'll get an error if you try. Section 4.2 of the u-blox m8 receiver description manual has a hint as to why.

From version 1.5 of gpsctl, enabling either BeiDou or Galileo automatically enables NMEA 4.1.


Posted by Phil at 10:26 AM
Edited on: Saturday, July 20, 2019 7:47 PM
Categories: IT, Raspberry Pi, Software

Friday, January 29, 2016

In the MoOde for streaming internet radio on the Raspberry Pi Zero (updated)


When I saw the announcement of the Raspberry Pi Zero my first thought was that it would be a good basis for a headless Internet Radio Streamer for my hifi system.

So when I got my Pi Zero, I looked around for a cost-effective Digital to Audio Converter and found Pimoroni's pHAT DAC for the Pi Zero.

After a bit of web searching and reading, I settled on Tim Curtis' MoOde as my Media Player.

I've updated the instructions which follow for Moode 2.6 TR1 and later.

So, I downloaded MoOde 2.6 TR1 and flashed it to a MicroSD card.

I had a spare TP-Link wifi USB stick which worked with the Pi, so to make that work I booted up MoOde with the TV and USB keyboard plugged in, and edited /etc/network/interfaces so it looked something like this:

auto lo
iface lo inet loopback
#allow-hotplug eth0
#iface eth0 inet dhcp lan0 inet dhcp
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid your-ssid
wpa-psk your-pre-shared-key

Change the ssid and PSK to suit your environment.

After a reboot, I could SSH into moode.local and had a web interface to play with.

For the pHAT DAC, I selected the hifiberry DAC as it uses the same chipset, and lo, I soon had internet radio streaming into my hifi.

But gosh, the low quality BBC radio streams sounded just awful.

A bit more web searching revealed the solution.

And so I installed minimserver and minimstreamer and access the Beeb's HLS streams via minimstreamer.

The process is:

1: install JDK 8.

    sudo apt-get install oracle-java8-jdk

2: download MinimServer-0.8.4-linux-armhf.tar.gz and MinimWatch-0.8.4-linux-armhf.tar.gz from the minimserver download page.

3: extract as follows:

    sudo tar zxvf MinimServer-0.8.4-linux-armhf.tar.gz -C /opt
sudo tar zxvf MinimWatch-0.8.4-linux-armhf.tar.gz -C /opt

4: configure minimserver and minimwatch

    sudo /opt/minimserver/bin/setup

change the settings to not run at startup, and do the same for minimwatch

5: configure minimserver's media directory and enable the minimstreamer module in minimserver:

    sudo /opt/minimserver/bin/startc
packages
install minimstreamer-0.5.24
exit

6: create a new file minimserver.service in /etc/systemd/system

    sudo nano /etc/systemd/system/minimserver.service
with the following contents

[Unit]
Description=MinimServer

[Service]
RemainAfterExit=true
ExecStart=/opt/minimserver/bin/startd
ExecStop=/opt/minimserver/bin/stopall

[Install]
WantedBy=network.target

7: Enable the newly created minimserver service

    sudo systemctl enable minimserver.service

8: Create a BBCRadio.m3u file in minimplayer's media directory with contents as per here

9: Reboot your Raspberry Pi

10: Add individual stations via Moode's interface using urls like http://127.0.0.1:9790/minimstreamer/*/R1/

And then enjoy the BBC's 320kbps HLS streams via your Pi Zero and pHAT DAC.

MoOde has excellent support over on the DIYAudio forum


Posted by Phil at 3:39 PM
Edited on: Monday, May 02, 2016 12:01 PM
Categories: Raspberry Pi

Sunday, January 18, 2015

H G Wells on Technological Unemployment


The concept of "Technological Unemployment" seems to be in fashion once again.

The sanest words I've read on the subject come from H. G. Wells in his 1914 work "The World Set Free":

He asked a passing stroller, and was told that the men had struck that day against the use of an atomic riveter that would have doubled the individual efficiency and halved the number of steel workers.
'Shouldn't wonder if they didn't get chucking bombs,' said Barnet's informant, hovered for a moment, and then went on his way to the Alhambra music hall.
Barnet became aware of an excitement in the newspaper kiosks at the corners of the square. Something very sensational had been flashed upon the transparencies. Forgetting for a moment his penniless condition, he made his way over a bridge to buy a paper, for in those days the papers, which were printed upon thin sheets of metallic foil, were sold at determinate points by specially licensed purveyors. Half over, he stopped short at a change in the traffic below; and was astonished to see that the police signals were restricting vehicles to the half roadway. When presently he got within sight of the transparencies that had replaced the placards of Victorian times, he read of the Great March of the Unemployed that was already in progress through the West End, and so without expenditure he was able to understand what was coming.
He watched, and his book describes this procession which the police had considered it unwise to prevent and which had been spontaneously organised in imitation of the Unemployed Processions of earlier times. He had expected a mob but there was a kind of sullen discipline about the procession when at last it arrived. What seemed for a time an unending column of men marched wearily, marched with a kind of implacable futility, along the roadway underneath him. He was, he says, moved to join them, but instead he remained watching. They were a dingy, shabby, ineffective-looking multitude, for the most part incapable of any but obsolete and superseded types of labour. They bore a few banners with the time-honoured inscription: 'Work, not Charity,' but otherwise their ranks were unadorned.
They were not singing, they were not even talking, there was nothing truculent nor aggressive in their bearing, they had no definite objective they were just marching and showing themselves in the more prosperous parts of London. They were a sample of that great mass of unskilled cheap labour which the now still cheaper mechanical powers had superseded for evermore. They were being 'scrapped'—as horses had been 'scrapped.'
Barnet leant over the parapet watching them, his mind quickened by his own precarious condition. For a time, he says, he felt nothing but despair at the sight; what should be done, what could be done for this gathering surplus of humanity? They were so manifestly useless—and incapable—and pitiful.
What were they asking for?
They had been overtaken by unexpected things. Nobody had foreseen——
It flashed suddenly into his mind just what the multitudinous shambling enigma below meant. It was an appeal against the unexpected, an appeal to those others who, more fortunate, seemed wiser and more powerful, for something—for INTELLIGENCE. This mute mass, weary footed, rank following rank, protested its persuasion that some of these others must have foreseen these dislocations—that anyhow they ought to have foreseen—and arranged.
That was what this crowd of wreckage was feeling and seeking so dumbly to assert.
'Things came to me like the turning on of a light in a darkened room,' he says. 'These men were praying to their fellow creatures as once they prayed to God! The last thing that men will realise about anything is that it is inanimate. They had transferred their animation to mankind. They still believed there was intelligence somewhere, even if it was careless or malignant.... It had only to be aroused to be conscience-stricken, to be moved to exertion.... And I saw, too, that as yet THERE WAS NO SUCH INTELLIGENCE. The world waits for intelligence. That intelligence has still to be made, that will for good and order has still to be gathered together, out of scraps of impulse and wandering seeds of benevolence and whatever is fine and creative in our souls, into a common purpose. It's something still to come....'

Posted by Phil at 7:28 PM
Edited on: Sunday, January 18, 2015 7:41 PM
Categories: Comment

Wednesday, June 04, 2014

Deja Vu, Again


The Beeb's been at it again. Their finest journos have rehashed a press release from Premier Oil into yet another gushing news item about fossil fuels.

Just as in my "Here We Go Again" blog post from last June, there's no mention of climate change, not one word, apart from the "Climate" in the Department for Energy and (for) Climate Change's title.

Read it and weep.

Again.


Posted by Phil at 8:44 PM
Edited on: Wednesday, April 01, 2015 9:53 PM
Categories: Environment

Sunday, October 13, 2013

Domestic LED lighting is Cost-effective Right Now


Of late I've been looking in the lighting sections of supermarkets in search of usable LED replacements for compact fluorescent and incandescent lamps for normal room lighting, but to no avail.

Until yesterday, that is, when I stumbled across this little beauty in my local Aldi store.

This is a Medion MD14536 11W LED lamp (equivalent to 75W incandescent, 18W compact fluorescent), 1055 lumens, 2700K colour temperature, rated lifetime of 35000 hours. Their light output is around 100 lumens per watt. And all for a princely £9.99. The only drawback is that they are not dimmable.

An equivalent Philips 18W compact fluorescent with a 6000 hour lifetime sells for a fiver on Amazon and gives around 60 lumens per watt.

10W (60W incandescent, 810 lumens) and 5.5W (40W incandescent, 470 lumens) are also available.

My experience of modern CFLs is that they rarely last their rated lifetime. I'm lucky if they get to half of it in my residence. CFLs I purchased over a decade ago were much more reliable.

LED lighting at this price is cost-effective right now. A real bargain!

Postscript, October 14th

My local Asda now has 12W (60W incandescent, 810 lumens, 25000 hour rated lifetime) LED lamps for £16. Not such a bargain.


Posted by Phil at 8:45 PM
Edited on: Wednesday, April 01, 2015 9:20 PM
Categories: Comment, Environment

Friday, September 06, 2013

Scientific Illiteracy, Propaganda, or Both?


The Beeb are are being sloppy, ignorant, incompetent, or just plain malicious propaganda-spreaders once again.

A tweet by Greenpeace Nuclear @nukereaction alerted me this morning

Here it is:

 

Back in November, I commented on this nonsense:

 

The irony is that nuclear energy is the ultimate non-renewable, actually destroying matter.


Posted by Phil at 11:53 AM
Edited on: Wednesday, April 01, 2015 9:53 PM
Categories: Comment, Environment

Monday, June 03, 2013

Here we go Again


BBC Radio 4's just run a pro shale gas propaganda piece on behalf of UK firm IGas which says "there may be up to 170 trillion cubic feet of gas in the areas it is licensed to explore in northern England".

Up to.

And guess what, no mention of climate change, not one word, though it does appear twice in their web version of the article. In the title of the Dept for Energy and [for] Climate Change.

As I've mentioned several times before, the BBC seems to have a blind spot on the issue of fossil fuels and climate change.

Sigh.


Posted by Phil at 7:47 AM
Edited on: Wednesday, April 01, 2015 9:52 PM
Categories: Environment

Thursday, May 02, 2013

That Which Must Not be Mentioned, Episode 5,100,000


The Beeb reports that Royal Dutch Shell's profits are up.

As usual, no mention of the impacts of the consumption of fossil fuels on the climate.

Worse than that, BBC Radio 4's Today programme's coverage sounded like a worshipful paean to the company, praising the company's performance without any mention of the impacts of burning the stuff.


Posted by Phil at 8:02 AM
Edited on: Wednesday, April 01, 2015 9:54 PM
Categories: Comment, Environment

Monday, April 29, 2013

Migrating Nagios Configuration from Nagmin to Check_MK's WATO


When I first set up a Nagios server, many years ago, in the days of Nagios 1.x, the best configuration tool I could find was Fred Reimers' Nagmin. That has since turned into abandonware, but there is a fork, NagminV, under development.

I'd patched Nagmin to support Nagios 2.x and 3.x, and added a few fields to its database, but it was still buggy and quirky.

So, after I'd installed Mathias Kettner's Check_MK for its livestatus broker module for use with PNP4Nagios, I started investigating Check_MK's broader features.

What soon caught my eye was Check_MK's use of rulesets based on host tags. The temptation of editing text files (python scripts in disguise) was too great for me, so I started converting my Nagios service checks into Check_MK format.

These are very rough notes, proceed with caution. Back up everything first!!!

First thing to do was get Check_MK's agent on all our hosts.

Then, to list all of them in /etc/check_mk/main.mk:

# don't generate host config yet
# comment this out when Nagmin is decommissioned
generate_hostconf = False
all_hosts = [
host1,
host2,
]

Then I added the obvious tags, win, linux, etc, and created config files for legacy checks in /etc/check_mk/conf.d, until eventually all service checks were defined in Check_MK and not in Nagmin.

After each check was migrated to Check_MK, I'd run

check_mk -U
nagios -v /etc/nagios/nagios.cfg

The first command generates a new Nagios config in /etc/nagios/check_mk.d/check_mk_objects.cfg

The second validates the resulting config. Here I'd find duplicate definitions, reminding me to delete them from Nagmin.

So, after a while plodding away at this - in my case this meant over a year of coexistence - all that was left in Nagmin was hosts, host groups, contacts, contact groups, and timeperiods.

Time to abandon Nagmin and get serious.

Do not, under any circumstances, try to generate a Nagios config using Nagmin again. It will always fail!

Comment out the Command.cfg include in nagios.cfg

#cfg_file=/etc/nagios/Command.cfg

Try validating the nagios config again, with nagios -v. If it fails, you've forgotten to define some commands as legacy checks

Rinse, repeat until you've got it right.

Check the contents of /etc/nagios/Services.cfg - if it contains any service definitions, you've forgotten something.

Do the same with all the service-related .cfg files; if things fail, change your config to use Check_MK's default service templates.

Get your custom Time Periods into WATO - check_mk has a default, hidden timeperiod 24X7 (Nagmin's is 24x7, case matters), and comment out TimePeriods.cfg in nagios.cfg. Revalidate.

And so on till you're left only with hosts, host groups, contacts, and contact groups from the original Nagmin.

So now was the time to take the leap and use Check_MK's WATO to configure nagios.

I created contacts and contact groups manually in WATO. There's no conflict with your existing Nagios config until you associate a contact group with hosts and/or services in WATO. That was the last thing I did.

Now comes the fun bit.

We need to import our hosts into WATO.

Run the attached hosts.py which will generate a list of hosts in the format hostname;alias;parents;ipaddress

python hosts.py >wato.csv

Our import script requires a file containing

wato folder;hostname;alias;parents;ipaddress;tags

where tags is a list of check_mk tags separated by |

So, we'll have to manually edit it. I didn't use WATO folders so just preceded each line with a ;

Tags are the fun bits. By now you may have been using them in your check_mk config. WATO comes with some predefined ones, which we need to list in our import file (wato.csv).

You'll need one each of the 'agent', 'criticality', and 'networking' tags. As well as your custom tags, which should also be entered into WATO.

Download and edit my_wato_import.py adding your tag definitions into tagz, run:

python my_wato_import.py wato.csv

and watch the output scroll by. If there are any errors reported, then you've forgotten to add a tag definition to tagz, or misspelt a tag in wato.csv. Rinse and repeat until all's well.

Set testing = False near the top of the script, and run again.

Comment out generate_hostconf = False in your main.mk, and check_mk -U

Comment out Host.cfg in /etc/nagios/nagios.cfg

Validate your nagios configuration. It should be OK.

A look in WATO will show all your hosts, with appropriate tags.

Hidden away in /usr/share/doc/check_mk/treasures is a script wato_host_svc_groups.py

I ran this against my original Nagmin Hosts.cfg file, which produced output which was easily massaged into the form needed for WATO. I could have amended the script to produce output of the following form, but a few regular-expression search and replaces got me there quickly enough.

host_groups = [
( 'group1', []. ['server1', 'server2']),
( 'group2', []. ['server3', 'server3']),
]

Place that code into /etc/check_mk/conf.d/wato/rules.mk and create the host groups (with descriptions) in WATO. Before applying changes in WATO, run check_mk -U

Comment out the Hostgroup.cfg include in nagios.cfg, and validate config once more.

#cfg_file=/etc/nagios/HostGroup.cfg

Now, if you've done everything properly, the Nagios config validation will succeed, and on a restart of Nagios your host groups will be there as before.

That just leaves Contacts, Contact Groups and notifications.

I'll leave that as an exercise for the reader. Hint: don't try any of the above until you've figured out how to apply contact groups to hosts and services.

And you'll also need to adjust host and service check intervals and retries in WATO too, otherwise everything gets polled every minute, which probably isn't what you want.


Posted by Phil at 9:59 PM
Edited on: Wednesday, April 01, 2015 9:24 PM
Categories: IT, Software

July 2019
Mon Tue Wed Thu Fri Sat Sun
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Syndicate this site
Archives
July 2019
April 2019
January 2016
January 2015
June 2014
October 2013
September 2013
June 2013
May 2013
April 2013
March 2013
February 2013
December 2012
November 2012
June 2012
May 2012
March 2012
January 2012
December 2011
November 2011
September 2011
May 2011
April 2011
March 2011
January 2011
December 2010
October 2010
September 2010
August 2010
May 2010
April 2010
December 2009
October 2009
September 2009
June 2009
May 2009
April 2009
February 2009
January 2009
December 2008
November 2008
October 2008
July 2008
June 2008
May 2008
April 2008
March 2008
January 2008
December 2007
November 2007
July 2007
June 2007
May 2007
February 2007
January 2007
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
April 2006
February 2006
January 2006
December 2005
November 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
January 2005
December 2004
November 2004
September 2004
August 2004
July 2004
May 2004
April 2004
February 2004
August 2003
January 2003
December 2002

Archive Index
Categories
Comment
Computer Security
Doctor Who
Environment
IT
Music
Photos
Poetry
Raspberry Pi
Software
Tsunami
Waffle
Weird
Credits
Design by Movablestyle
Twitter Updates
Tweets by @philrandal
Powered by
Thingamablog 1.5.1