So I put a command in the rc.local to run on boot on an Ubuntu server. Didn’t start. What the hell. perms OK. script runs OK. Frickin’ Systemd Dammit. I think I am done with systemd now. Just too intrusive. First – monolithic and HUGE. Second I want text log files. And I don’t want to have to google how to make rc.local run with a damn config file. WTF?
/etc/systemd/system/rc-local.service
[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99
[Install]
WantedBy=multi-user.target
sudo systemctl enable rc-local
I saw a presentation on PWAs a few weeks ago and wanted to try making one because for a developer this is something of a Holy Grail. It offers the opportunity to develop an App once, in the Web Browser, and run it ‘everywhere’. Clearly there are potential performance issues etc. but in general, it is a great opportunity. There are a few gotchas:
- YOU MUST SERVE THE PWA OVER HTTPS (NOTE THE S in HTTPS). Yes you need to have a secure web connection and therefore you need to acquire a certificate for your site.
- Your manifest file MUST contain the correct properties. There is documentation on the web for this.
- Different browsers handle this process differently. I strongly suggest using Google Chrome for now. When the app is loaded, on the desktop you can choose “Install QR Code PWA”, which will install it as a Chrome App.
And in Chrome for Android you should be prompted to install it if you wish.
This will add the app to the Home Screen and also to the Apps Menu. The app is now available fully offline. FireFox does not quite behave the same way and only adds the app to the home screen and the icon also has a little FireFox icon over it.
If you notice that your manifest file is not being loaded, even though it is referenced in your html <HEAD> section, then you should check that you are using HTTPS for your connection.
There are several places where you MUST use an absolute path for the files you need. Please check the demo and look at the loaded files.
Now when you open the PWA it will look like a native Android app. There will be no URL etc.
The 3B+ behaves a little differently. The LEDs are, by default, controlled by the kernel. There are device drivers for them. This is a new script to enable an added momentary action button to control the LEDs and shutdown the Pi 3B+
#!/usr/bin/env python3
from gpiozero import Button
from signal import pause
import warnings, os, sys
# Script to process a button press on the GPIO of a Raspberry Pi 3B+
# and alter the LEDs of the device according to:
#
# Press and release, toggle the LEDs off, or default, depending.
# Press and hold, for 6 seconds, shutdown the Pi.
# Note the Pi 3B+ is controlled from kernel devices, not direct from the GPIO
# unless you wish to.
#
# Add to /etc/rc.local
# For example
#
# ~pi/shutdown_pi.py 21 6 1
offGPIO = int(sys.argv[1]) if len(sys.argv) >= 2 else 21
offtime = int(sys.argv[2]) if len(sys.argv) >= 3 else 6
defaultOff = True if len(sys.argv) >= 4 else False
mintime=1
powerLedDev = "/sys/class/leds/led1/"
activityLedDev = "/sys/class/leds/led0/"
powerLedDefAction = "default-on"
activityLedDefAction = "mmc0"
powerLedNewAction = powerLedDefAction
activityLedNewAction = activityLedDefAction
def ledSet(led, item, value):
f = open(led + item, "w+")
f.write(value)
f.close()
def LEDsOff():
ledSet(powerLedDev, "trigger", "none")
ledSet(activityLedDev, "trigger", "none")
def when_held(b):
p = b.pressed_time
#timer_val = "{0:.0f}".format(500/p)
timer_val = int(500/p)
os.system("echo timer > " + powerLedDev + "trigger")
ledSet(powerLedDev, "delay_on", str(timer_val))
ledSet(powerLedDev, "delay_off", str(timer_val))
if p > offtime:
ledSet(powerLedDev, "trigger", "none")
ledSet(activityLedDev, "trigger", activityLedDefAction)
os.system("/sbin/shutdown -h now")
def when_pressed():
global powerLedNewAction
global activityLedNewAction
if powerLedNewAction == powerLedDefAction:
powerLedNewAction = "none"
activityLedNewAction = "none"
else:
powerLedNewAction = powerLedDefAction
activityLedNewAction = activityLedDefAction
LEDsOff()
def when_released():
ledSet(powerLedDev, "trigger", powerLedNewAction)
ledSet(activityLedDev, "trigger", activityLedNewAction)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if defaultOff:
LEDsOff()
btn = Button(offGPIO, hold_time=mintime, hold_repeat=True)
btn.when_held = when_held
btn.when_pressed = when_pressed
btn.when_released = when_released
pause()
Background
It has been my experience, working in the software field for many years that the understanding of Requirements Analysis leaves a lot to be desired even by those who profess to understand them. The concept, it seems, is too simple, making it tough for many to grasp the actual finer nuances.
Introduction
The process of solving any problem involves identifying the problem and what goal this problem is preventing you from reaching. Putting this concept straight into the world of software engineering is too much of a leap. Most software developers (engineers, coders, hackers etc. depending on capability and training) will automatically begin to bring to bear their existing processes and really miss the whole thing. So let’s begin with something else:-
The Issue of the Dripping Gutter.
The Snow Blower.
Follow Up.
There are stories on the web about this issue and I have experienced it myself now. Twice.
The issue seems to occur when the device is powered off when accessing the SD Card. Exactly what the damage is is not clear though. The Pi boots and displays many file system errors. The first time this occurred, after the usual fsck attempts, I decided to build the machine again on another SD Card. The second time it occurred I tried something new. I used my Linux machine to dd the SD Card content to another identical SD Card. There were no read errors and no write errors on the first SDCard which was from the first build.
My assumption is that at some point on the file system a low voltage event has occurred that has set a low value in one of the flash nodes. Research required on my part to understand the flash storage and access circuitry but it seems to work fine when read and written to from my laptop and via a USB flash adapter.
So the flash just needed to be completely read and rewritten.
So I have now added a shutdown button. This will shutdown the Pi when the button is depressed for six seconds. There are many examples of how this is done on the web but none apply to the Pi 3B+.
Using a switch over pins 39 and 40 of the GPIO is called GPIO 21.
LEDS to indicate activity such as flashing can be controlled via system commands to echo values to /sys/class/leds/led1/trigger and delay_on and delay_off when trigger is set to timer.
Add this code to your theme’s functions.php file.
add_filter('wp_nav_menu_items', 'add_login_logout_link', 10, 2);
function add_login_logout_link($items, $args) {
ob_start();
wp_loginout('index.php');
$loginoutlink = ob_get_contents();
ob_end_clean();
if ($args->theme_location == 'top')
$items .= '<li>'. $loginoutlink . '</li>';
return $items;
}
Adding the headings of direct children of the page to the page automatically. Just add the code below to the end of the content-page.php file in your theme directory.
<?php
$mypages = get_pages( array( 'parent' => $post->ID,
'sort_column' => 'post_date',
'sort_order' => 'desc' ) );
foreach( $mypages as $page ) {
$content = $page->post_content;
if ( ! $content ) // Check for empty page
continue;
$content = apply_filters( 'the_content', $content );
?>
<h2><a href="<?php echo get_page_link( $page->ID );?>"> <?php echo $page->post_title; ?></a></h2>
<div class="entry">
<?php// echo $content; ?>
</div>
<?php
}
?>
After creating the desired router and configuration, it was time to move on to the Web Server. In the past Drupal was the Web Server of choice but it was time to look at other options and compare. WordPress came out on top. This became a lesson in installing and configuring WordPress
Last week there was a need for a new feature on the main office router. This feature was not available. It seemed time to explore new options. The end result was an journey through the maze of the Open Source WiFi firmware world. The center of the maze turned out to be OpenWRT or LEDE.
Installation of OpenWRT went surprising well and configuration fairly easy. Options used included USB storage, sftp server and sqm (QoS). There will be a project page on this.