New B&G Zeus™ 3S 9

This week I replaced my old Garmin GPSMAP® 740 with a brand new B&G Zeus™ 3S 9 chartplotter with C-MAP cartography. I’m excited about using this because I’ve used older B&G Zeus products on friends boats and this has everything I’m used to with more processor speed.

I had earlier upgraded to communication in my boat to connect the older Raymarine Seatalk instruments to the NMEA 2000 network using a Raymarine SeaTalk1 to SeaTalkng converter kit (Part Number E22158) with a blue DeviceNet adapter connecting to my NMEA 2000 backbone, and a white DeviceNet adapter connecting to my Garmin GPSMap 740. This allowed my garmin to show a few more details and my raspberry pi to capture and log the data from the depth and wind instruments.

I was hoping that beyond the physical changes to my instrument pod with the installation of the new B&G unit, the wiring changes would just require disconnecting the Garmin from the NMEA2000 connection and connecting the B&G to the same connection.

I did that. Then when I powered on the B&G, it asked for confirmation to discover all connected devices, which I had it do. It wasn’t seeing the results from the raymarine devices on the network, though it was getting AIS targets from the Garmin AIS 300 receiver and seeing my new fusion radio, both on the NMEA2000 bus. The communication path to either of those units was via the Seatalk converter, so I was confused as to if the B&G couldn’t see the old instruments, and spent a couple of days looking for possible solutions.

Most of the solutions I seemed to run across made me think that there may be too much power loss on the length of NMEA2000 backbone cable reaching from inside nav station to my outside pedestal. When I’d originally installed the converter kit, I spliced in power in the pedestal. Power was supplied directly to the converter, and it provided power to the NMEA2k backbone. During my installation of the B&G I attempted to do some wiring cleanup. I removed the power to the converter, and provided power to the NMEA2k bus in the nav station.

Here are several links to discussion that suggest power across the length of the backbone may be my problem:

I took video of the status led blinking on the converter, and it never was reporting low voltage. It was definitely reporting something with data, but I wasn’t sure if it was the first or second from the list.

I wasn’t excited about cutting and splicing my pedestal power connection again to provide power directly to the converter, and while playing around and power cycling everything, I realized that if I power cycled the converter/nmea2k bus, and brought up the B&G and just looked at the instruments, the converter was visible in the B&G!

If I selected it, I could see all the data it was publishing from the instruments on the NMEA2k bus.

That seemed like success! (The Sea Temperature reading has been whacky since I’ve bought the boat, and I can’t seem to figure out how to get it to read the correct temperature on the original ST60+ Tridata either.) So I told the B&G to auto select it’s data sources again.

After doing that, the Seatalk converter no longer was visible in the list of devices, or the data it was publishing. I also figured out that my Raspberry Pi stopped logging the data from the instruments when this happened. (I’m pretty sure my raspberry pi is the device at the top of the device list with — under both Model ID and Serial No. Fixing that is a low priority task for me. If you know how to properly configure the Pi please leave a comment pointing out what I should do. This is the platform I’m running.)

After several tests, I figured out that my Raymarine instruments continue working and putting data on the NMEA2k bus as long as I don’t have the B&G auto discover sources. I manually went through and configured the sources in the B&G settings, and was able to get things configured as I want.

I’m not 100% satisfied because I don’t think I should be able to take the converter offline with whatever commands the B&G is sending over the NMEA2k bus, but I’m happy that I didn’t have to splice more cables this week.

First Multi-Day Trip on Sola

My first multi day trip on Sola was over Memorial Day weekend 2021. I wasn’t good at planning, with every boater in the area also trying to take advantage of the perfect weather, but things worked out well and it was a good learning experience.

I loaded all of what I thought I’d need on my boat, returned my car to my apartment, and walked the two miles back to the boat. That meant that I didn’t pull away from my slip until close to noon on Friday. I then went to the fuel dock in Shilshole and added 14 gallons of diesel to my tank. I learned that the price of ice at the fuel dock is almost exactly the same as the nearest QFC. It was a little past 1:30 by the time I was away from the fuel dock.

After clearing the breakwater, I as able to engage the autopilot and stow all my fenders and docking lines. The wind was nice enough for sailing, so I raised the main sail and unfurled the head sail and sailed downwind towards Blake Island.

I passed the western shore of Blake Island about 4pm, and all of the mooring balls were already in use, with several additional boats anchored. Because I was moving nicely under sail power and the sunset is close to 9pm, I continued down Colvos Passage towards Gig Harbor.

I was able to sail all the way to the entrance of Gig Harbor, arriving about 7pm. After motoring into Gig Harbor and passing through a fleet of anchored boats I picked a spot and dropped my anchor with about 30 feet of water below me.

After my 80 foot chain, plus some of the rode, was off the boat, I was hailed by a large motor yacht to the south of me, with them saying that I was probably over their anchor, and that they had about 200 feet of chain out. I sat there for about 5 minutes, then pulled my anchor back up and moved north to another open area and dropped the anchor a second time. That location I stayed the night.

I’d previously taken the boat to Gig Harbor and anchored when I was racing the South Sound Series #4 on Mata Hari on March 20th. That trip I motored down Friday night, anchored, was picked up from my boat to race Saturday morning, returned to the boat Saturday night, and raised the anchor and motored home Sunday. I had the assistance returning to the dock in Shilshole, which was hugely beneficial. This trip I was planning to be alone the entire time.

I planned my departure from Gig Harbor to ride the tidal currents through the Tacoma Narrows south past Fox Island. I had the anchor up by 6:30am, but that wasn’t too much of an issue since the sun is now up before 5:30am.

South of Fox Island, I attempted to sail for a while, but after a couple of hours I wasn’t making much progress. I was slightly worried about finding a place to stay the night since I’d never been in the south sound to stay before. I powered up and passed Eagle Island between Anderson Island and McNeil Island and saw at least one mooring ball I could have used, and will probably revisit in the future.

I continued on, turning north and finally arrived at McMicken Island. There were two mooring balls on the south side of the island as I approached, one occupied. I was tired from not having slept well the previous night, and took possession of the empty mooring ball, and once the boat was secure took a nap.

I made hot coffee in the morning, but ran out of propane as I was preparing eggs in the afternoon. No more hot food for me. I had plenty of food that didn’t require cooking and it was hot during the day so I didn’t feel the need to heated food.

I spent two nights in the same place, on the same mooring ball. It was very relaxing, and mostly quiet. The south sound reminds me much more of a lake than the waters near Shilshole. I remembered that I had my drone on board, but hadn’t freshly charged the batteries, so each of my three batteries was only at 60%. I was still able to get some nice views of the area.

I was able to take time looking around and comparing what I could see to what the charts were showing.

The most important thing I figured out was that I wanted my dinghy so I could explore the park. I was reminded of the US Navy recruiting phrase: “Join the Navy, See the world.” and the army joke that went with it: “We own the part you can walk on.”

After two nights on the south side of McMicken Island, I motored to the south side to see what was available there. There were more mooring balls, and plenty of protected anchorage, but there was also a lot more boats in that area. My solitude on the south side had been nice while there was very little wind or weather.

I’d decided I wanted to explore Jerrell Cove State Park and then stay at Tolmie State Park on Monday. I had some nice south wind and was able to sail for a while going north in Case Inlet and around the northern point of Harstine Island, then dump the sail into the sailbag and motor into Jarrell Cove and back, then raise the sail and sail southwards again. I only sailed about 7 miles total, but it was certainly nice to not have the diesel running for a few hours.

I ran out of wind as I got a little farther south than I’d started the day. While it was now Monday of the long weekend, I wasn’t certain about where I was staying the night, and preferred to arrive and use a mooring ball instead of dropping anchor. I needn’t have worried, as there were three empty mooring balls when I arrived, and one boat anchored nearby. The location was exactly what I was hoping for. Quiet and flat, and an easy location to start back home from. There was 40 feet showing on my depth finder when I connected to the mooring ball. The views of Mt Rainier were incredible, and the water was glasslike in the morning.

While waiting for the currents to turn to the north, I flew my drone.

I timed the currents northwards and after leaving Tolmie State Park a bit past ten in the morning, I was able to be back in my slip in Shilshole just past four pm. I had about a knot of push during most of the trip, with as much as four knots at times.

Google Chrome Tab Search Button

Google Chrome recently added a tab search button to the title bar. When it was first enabled, it was possible to disable by going to chrome://flags and finding Enable Tab Search and changing it to Disabled.

A quick search of google will find multiple examples of how to disable it. Unfortunately in more recent versions of the browser, it no longer seems to be an available flag to disable.

I realized that my big issue with the drop down menu is it’s location, which Google has located on the left near the minimize button. Google has chosen to not have the traditional windows system menu on the left side of the title bar. The left side would be an ideal location for the tab management button.

SVG, CSS Style, dark-mode, and Apple

In my recent GoveeBTTempLogger Project I’ve been writing SVG files as temperature graphs. I realized I could organize the color combinations with CSS Style descriptions inside the SVG instead of fully describing each element of the graphic. I am using transparent backgrounds by default, and loading the SVG files in a simple index html file like any other image.

Playing with CSS in the HTML, I came across the ability to support dark-mode. I thought that this would be really nice for when I bring up the graphs on my phone late at night, not having everything being in a bright white background.

    @media screen and (prefers-color-scheme: dark) {
        body {
            background-color: black;
            color: grey;
        }
    }

I added the previous block to my style in the index.html file, which overrides the default body style of background-color: white and color: black. It works nicely at the top level, but now the black lines and text in my SVG became invisible, since now they match the background.

I tried something similar in the style for my SVG and it was working great in Chrome or Microsoft Edge. But then I realized that it doesn’t work on my phone. After realizing that it wasn’t working correctly on the phone, I decided to try switching the defaults so my default used grey, and if light mode was selected it would use black. It still didn’t work! It seems that apple is paying attention to my color-scheme selection, but doing something different from any other browser.

	<style>
		text { font-family: sans-serif; font-size: 12px; fill: grey; }
		line { stroke: grey; }
		polygon { fill-opacity: 0.5; }
	@media screen and (prefers-color-scheme: light) {
		text { fill: black; }
		line { stroke: black; }
	}
	</style>

I had a friend who works primarily on a Mac test to see if the problem was specific to the iPhone, or if it occurred in Safari on the desktop as well. Yes. Apple is handling my styles differently from the other browsers I tried.

Safari on Mac
Chrome on Mac
Firefox on Mac

You can see my choices displaying the way I want on Chrome and Firefox, with grey lines and text on a black background, while Safari isn’t showing the grey. Am I doing something explicitly wrong in my style that Chrome and Firefox are forgiving? Or is Apple not supporting the feature properly?

The frustrating thing is that all browsers on iPhones use the Apple rendering engine. That means there’s no way I know to get the functionality I want on my phone, where the phone uses dark mode overnight, but light mode during the day.

Govee H5177 Bluetooth Low Energy Smart Thermo-Hygrometer

After playing with Govee thermometers H5074 and H5075, I came across the H5177 model with similar specs but with a larger display including some buttons and backlight. I decided to give it a try, just to see if it used the same protocol as the previous units.

wim@WimPi4-dev:~ $ sudo ../visualstudio/projects/GoveeBTTempLogger/bin/ARM/Debug/GoveeBTTempLogger.out -v 2 | grep E3:5E:CC:21:5C:0F
 [2020-11-09T00:26:34] 44 E3:5E:CC:21:5C:0F 06 (UUID) 0A18F5FE88EC (Name) Govee_H5074_5C0F
 [2020-11-09T00:26:34] 26 E3:5E:CC:21:5C:0F 88EC000103DE106402 (Temp) 45.842°F (Humidity) 43.18% (Battery) 100%
 [2020-11-09T00:26:35] 44 E3:5E:CC:21:5C:0F 06 (UUID) 0A18F5FE88EC (Name) Govee_H5074_5C0F
 [2020-11-09T00:26:35] 42 E3:5E:CC:21:5C:0F 4C000215494E54454C4C495F524F434B535F485750740F5CC2 (Apple) (UUID) 494E54454C4C495F524F434B535F4857 (Major) 5074 (Minor) 0F5C (RSSI) C2
 ^C* SIGINT: Caught Ctrl-C, finishing loop and quitting. *
 GoveeBTTempLogger Version 1.20201016-1 Built on: Oct 16 2020 at 12:13:28 (exiting)
 wim@WimPi4-dev:~ $ sudo ../visualstudio/projects/GoveeBTTempLogger/bin/ARM/Debug/GoveeBTTempLogger.out -v 2 | grep A4:C1:38:13:AE:36
 [2020-11-09T00:27:05] 46 A4:C1:38:13:AE:36 GVH5075_AE36 (UUID) 88EC (Flags) 05 (Manu) 88EC0002859F4900 (Temp) 61.7502°F (Humidity) 27.9% (Battery) 73%
 [2020-11-09T00:27:05] 42 A4:C1:38:13:AE:36 4C000215494E54454C4C495F524F434B535F48575075F2FFC2 (Apple) (UUID) 494E54454C4C495F524F434B535F4857 (Major) 5075 (Minor) F2FF (RSSI) C2
 ^C* SIGINT: Caught Ctrl-C, finishing loop and quitting. *
 GoveeBTTempLogger Version 1.20201016-1 Built on: Oct 16 2020 at 12:13:28 (exiting)
 wim@WimPi4-dev:~ $ sudo ../visualstudio/projects/GoveeBTTempLogger/bin/ARM/Debug/GoveeBTTempLogger.out -v 2 | grep A4:C1:38:0D:3B:10
 [2020-11-09T00:27:35] 46 A4:C1:38:0D:3B:10 GVH5177_3B10 (UUID) 88EC (Flags) 05 (Manu) 01000101029D1A64
 [2020-11-09T00:27:35] 42 A4:C1:38:0D:3B:10 4C000215494E54454C4C495F524F434B535F48575177F2FFC2 (Apple) (UUID) 494E54454C4C495F524F434B535F4857 (Major) 5177 (Minor) F2FF (RSSI) C2
 ^C* SIGINT: Caught Ctrl-C, finishing loop and quitting. *
 GoveeBTTempLogger Version 1.20201016-1 Built on: Oct 16 2020 at 12:13:28 (exiting)

While I was able to see the device data in Bluetooth advertisements, it’s got some differences. The code snippets above are cherry picked from one device each that I know how to interpret and the new device last.

The Manufacturer data in the new H5177 device doesn’t start with the same 88EC signature, but at least appears to be the same length as H5075, and one byte shorter than the data packet from the H5074.

17.1C 28% matches with (Manu) 01000101029D1664. If anyone can point me to a quick decode algorithm, I’ll update my project to support this device very quickly.

iOS14 Date Time Picker Rant

I upgraded to iOS14 as soon as it was released just because I almost always keep my devices running the most up to date software I can. I don’t care about the widgets or interface customization options that were introduced with iOS14. I think much of that customization is actually what has kept me away from running Android.

The one thing that I really hate that was introduced was the date time picker in iOS14. I’ve included screenshots from my iPhone 11 Pro Max running the new version and my iPhone 7 running the old version.

The old version had the issue that it was not intuitive to be able to pick a minute that didn’t align to five minute increments, but was very easy to select the day, hour, or minute individually and scroll to a reasonable number for the start time, then switch the the end time and do the same. The keyboard was only shown when I was typing the name of the appointment or the location.

The new one uses half of the screen to pick just the day, as well as displaying the keyboard, which does not seem to affect the time. I touch the tiny display with the time, and if I can select the hour, I can scroll my finger up and down over the entire screen to scroll the number. If I miss the number slightly, the screen moves to show my another part of the entry field. Then I have to repeat the same solution with the minute. When I’m trying to hit the hour, I hit the minute, and vice versa.

Because of the size of the calendar entry, I have to scroll the entire screen to find where the end time might be.

This change just feels like change for change sake, and poorly implemented. I wonder if it’s even worse on a smaller screen.

Old Man Yells at Cloud

iOS14.1 was released today, and I’ve already upgraded to it, but don’t see anything I’d consider an improvement to this issue.

Access Windows Share from Raspberry Pi (revisited)

Last year I described a simple method of automounting a directory from my windows server to my Raspberry Pi. Since then I’ve gone down a couple of paths to simplify rebuilding my Raspberry Pi machines.

The method I used last year required modifying the /etc/hosts file, the /etc/fstab file, pre-creating the mount points, and creating a credentials file to store the windows login credentials.

My new method doesn’t require modification of the /etc/hosts or /etc/fstab files, or pre-creating the mount points. Instead I’m relying on two features, Multicast DNS and systemd.automount unit files.

In the old method, to find the windows server, I added it to the local hosts file on the raspberry pi.

192.168.0.12 Acid

Using Multicast DNS, if I simply recognize that I can reach the server with the name Acid.WimsWorld.local the raspberry pi will find the server on the local network. My first step was to modify my /etc/fstab enty to use the local address and clean up my hosts file.

//acid.wimsworld.local/web /media/acid/web/ cifs credentials=/etc/wimsworld.smb.credentials,noauto,x-systemd.automount,x-systemd.idle-timeout=2min,_netdev 0 0

I’d never been happy with modifying the /etc/fstab file as part of my system configuration because in newer installations it is unique to each machine, specifying the boot partitions by their formatted serial number:

proc            /proc           proc    defaults          0       0
PARTUUID=142ff4e3-01  /boot           vfat    defaults          0       2
PARTUUID=142ff4e3-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

In my recent programming projects I’ve been working with systemd unit files to control my service processes and have come to understand how they work for automounting directories as well. I like that each directory has its own unit files meaning that a modification is less likely to cause problems for the system as a whole.

The single line from the /etc/fstab file above is removed and replaced by two unit files, /etc/systemd/system/media-acid-web.mount and /etc/systemd/system/media-acid-web.automount.

[Unit]
Description=Acid Web

[Mount]
What=//acid.wimsworld.local/web
Where=/media/acid/web
Type=cifs
Options=credentials=/etc/wimsworld.smb.credentials,vers=2.1

[Install]
WantedBy=multi-user.target

and

[Unit]
Description=Automount Acid Web

[Automount]
Where=/media/acid/web
TimeoutIdleSec=120

[Install]
WantedBy=multi-user.target

I still had to create the credentials file for this to work, since I wanted the credentials file to be only root readable in a different location. /etc/wimsworld.smb.credentials

username=WindowsUsername
password=WindowsPassword
domain=OptionalDomainName

After the three files are created, systemd needs to reload its database with the systemctl daemon-reload command, the automount needs to be enabled with the systemctl enable media-acid-web.automount command, and then started with the systemctl start media-acid-web.automount command.

The naming of the mount files is important, and described explicitly in the man pages for each of mount and automount. In my case, /media/acid/web gets named media-acid-web.mount and media-acid-web.automount. I didn’t need to create mount points in the /media directory, as systemd automatically takes care of that.

I was able to create all of the above with a simple paste into my terminal with the following string:

sudo bash
cat > /etc/systemd/system/media-acid-web.mount <<EOF
[Unit]
Description=Acid Web

[Mount]
What=//acid.wimsworld.local/web
Where=/media/acid/web
Type=cifs
Options=credentials=/etc/wimsworld.smb.credentials,vers=2.1

[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/media-acid-web.automount <<EOF
[Unit]
Description=Automount Acid Web

[Automount]
Where=/media/acid/web
TimeoutIdleSec=120

[Install]
WantedBy=multi-user.target
EOF
cat > /etc/wimsworld.smb.credentials <<EOF
username=WindowsUsername
password=WindowsPassword
domain=OptionalDomainName
EOF
chmod 0600 /etc/wimsworld.smb.credentials
systemctl daemon-reload
systemctl enable media-acid-web.automount
systemctl start media-acid-web.automount
exit

With the standard Raspberry Pi setup, the cat command is not available as a sudo command while the bash shell is. I’m taking advantage of that by running the bash shell as root and then all of the other commands with root privileges.

tp-link Smart Plugs with Energy Monitoring

Several years ago I picked up a TP-Link HS110 switch so that I could turn lights on and off on a schedule. It had an interesting feature of being able to monitor energy usage as well.

The HS110 has an unfortunate design that covers the second socket in a wall outlet and makes it unusable. I purchased several HS105 units over time because two can be plugged into a standard outlet with the only drawback being the extra distance the normal plug extends from the wall. The HS105 was on sale as multipack on a somewhat regular basis. The drawback of the HS105 is that it doesn’t offer energy monitoring.

I came across the HS300 power strip that offers six switched outlets plus energy monitoring for each outlet. It has a flat angled plug, allowing two devices to fit in a standard wall outlet.

Each of these devices seems to be rated at 15A (1875W) total. That should be fine, since most of the standard wall plugs they would be plugged into aren’t rated for more than that, but it’s interesting that the current handling of the largest devices is the same as the smallest.

The energy monitoring was an interesting feature, and I was hoping to get around to doing more than glancing at it from my phone occasionally. Nearly three years after my first purchase I finally got around to writing a program to do what I wanted to log the energy usage.

I’d come across https://www.softscheck.com/en/reverse-engineering-tp-link-hs110/ when I first bought the HS110, and thought I would get around to doing what I wanted quickly, but as with so many projects, it was set aside as less important. With the transient nature of the web, I’m glad that this site is still visible, and the resulting github repository tools proved invaluable for me getting my project working. https://github.com/softScheck/tplink-smartplug

There are several python projects for communicating with these devices which I also found useful, but I was hoping to build a small program with very few dependencies. Part of what I wanted to know was the communication protocol over the ethernet, and that took the most time to decipher.

https://github.com/wcbonner/KasaEnergyLogger is my project, with all of the work done in a single threaded C++ file. I’ll hopefully describe what I know of the protocol in the future. As it is, I’m pulling data from multiple devices and logging it using MRTG. I know there are significantly better graphics dashboards available, but this requires very little infrastructure, and I’m logging the raw data in case I ever really want to revisit it.

MRTG graph of AC Power Usage

For most people these devices connect to Alexa or Google Home and the scheduling plus voice controls are all that they will ever use.

I was very happy with having lamps set to turn on at sunset and turn off at specific times. The fact that I live at a latitude where sunset changes from after 9pm in the peak of summer to before 5pm midwinter was plenty for me. I also use them for controlling fans to adjust the climate in my home when I’m not relying on air conditioning.

From a system monitoring perspective I’ve considered having two Raspberry Pi, each plugged into a HS105, monitoring each other and power cycling the other device if it can’t be reached for a designated period of time.

Here are some of the other sites I found useful in getting to my current state:

GoveeBTTempLogger as a Debian Package

After getting my program to listen and log Bluetooth Low Energy advertisements from Govee thermometers running reliably, I needed to figure out how to make the program automatically start when my Raspberry was rebooted. I was led down two paths to get things working, systemd unit files, and debian package files created with dpkg-deb.

The final file structure I came up with is visible in https://github.com/wcbonner/GoveeBTTempLogger but still can use some explanation as to what I did.

To create the debian package, I created a file structure under my source repository that mimicked what I wanted to put on the target system.

\GOVEEBTTEMPLOGGER\GOVEEBTTEMPLOGGER
├───DEBIAN
│       control
│       postinst
│       postrm
│       prerm
│
├───etc
│   └───systemd
│       └───system
│               goveebttemplogger.service
│
├───usr
│   └───local
│       └───bin
│               goveebttemplogger
│
└───var
    └───log
        └───goveebttemplogger
                gvh507x.txt

I had decided I wanted my executable to be located in /usr/local/bin. It’s the file named goveebttemplogger. I wanted it to write log files into /var/log/goveebttemplogger/ and the easiest way to make sure that directory was created was to put a zero length file in that directory, gvh507x.txt.

The files in the DEBIAN directory are used by the dpkg-deb program when building the distributable package. More on those later.

To get the program configured to automatically run when the machine boots, and properly stop when it shuts down, I settled on the systemd unit files as the both the easiest and most reliable method. I’ve been around linux long enough to first think of /etc/rc.local manipulation, then script files for various runlevels in the /etc/init.d/ directories, and was amazed at both the power and ease of setting up to use the systemd unit files. The hardest part was figuring out what other services my program must have already started. I knew it was dependent on Bluetooth, but the specific services was a bit of a guess.

# Contents of /etc/systemd/system/goveebttemplogger.service
[Unit]
Description=GoveeBTTempLogger service
After=bluetooth.target dbus-org.bluez.service network.target
Requires=bluetooth.target
KillSignal=SIGINT

[Service]
Type=simple
Restart=always
ExecStart=/usr/local/bin/goveebttemplogger -v 0 -l /var/log/goveebttemplogger/

[Install]
WantedBy=multi-user.target

After creating that file in the specified location, I was able to issue the following commands to make systemd start the program.

sudo systemctl daemon-reload
sudo systemctl enable goveebttemplogger.service
sudo systemctl start goveebttemplogger.service

The most unique bit of my unit file is that I specifically want my program to be sent the SIGINT signal to kill it, since I will recognize that and flush the log files before exiting. The ExecStart line is the command line to run my program, which I’m also specifying the log directory as one of the parameters.

I had the systemd unit file and the initial DEBIAN/control file figured out pretty easily. I’d come across this https://linuxconfig.org/easy-way-to-create-a-debian-package-and-local-package-repository article which helped understanding the control file.

Package: GoveeBTTempLogger
Version: 1.20200725-1
Section: custom
Priority: optional
Architecture: armhf
Essential: no
Installed-Size: 95
Maintainer: wcbonner@users.noreply.github.com
Description: Listen and log Govee Thermometer Bluetooth Low Energy Advertisments
Depends: libbluetooth3

What took me a while to figure out was how to get the systemctl commands to be run after the files were put in place by the package manager. There are four script commands, which I’m using three. preinst, postinst, prerm, and postrm. Each of them is a simple script and needs to be marked executable in the file system. They are each run at various stages by the package manager, Pre-Installation, Post-Installation, Pre-Removal, and Post-Removal.

#!/bin/sh
# POSTINST script for goveebttemplogger

echo "\033[36m HI I'M A POSTINST SCRIPT `date +"%s"` \033[39m"
systemctl daemon-reload
systemctl enable goveebttemplogger.service
systemctl start goveebttemplogger.service

exit 0

After installation of my program and the systemd unit file, I reload the systemd database, enable my service, and start my service.

#!/bin/sh
# PRERM script for goveebttemplogger

echo "\033[36m HI I'M A PRERM SCRIPT `date +"%s"` \033[39m"
systemctl stop goveebttemplogger.service
systemctl disable goveebttemplogger.service

exit 0

Before removal of my program, I stop the service and disable the service.

#!/bin/sh
# POSTRM script for goveebttemplogger

echo "\033[36m HI I'M A POSTRM SCRIPT `date +"%s"` \033[39m"
systemctl daemon-reload

exit 0

After removal of my program, I reload the systemd database, to make sure it’s not got my unit file in its database any longer.

When I retrieve a copy of my code with the command git clone https://github.com/wcbonner/GoveeBTTempLogger I then have a subdirectory below the GoveeBTTempLogger that is also named GoveeBTTempLogger. That deeper directory is the structure that will be created into the package.


GoveeBTTempLogger/usr/local/bin/goveebttemplogger: goveebttemplogger.cpp
        mkdir -p GoveeBTTempLogger/usr/local/bin
        g++ -lbluetooth goveebttemplogger.cpp -o GoveeBTTempLogger/usr/local/bin/goveebttemplogger

deb: GoveeBTTempLogger/usr/local/bin/goveebttemplogger GoveeBTTempLogger/DEBIAN/control GoveeBTTempLogger/etc/systemd/system/goveebttemplogger.service
        mkdir -p GoveeBTTempLogger/var/log/goveebttemplogger
        touch GoveeBTTempLogger/var/log/goveebttemplogger/gvh507x.txt
        chmod a+x GoveeBTTempLogger/DEBIAN/postinst GoveeBTTempLogger/DEBIAN/postrm GoveeBTTempLogger/DEBIAN/prerm
        dpkg-deb --build GoveeBTTempLogger

I made the very simple makefile above to both compile the code and build the debian package with the simple command of make deb. It produces the package ‘goveebttemplogger’ in ‘GoveeBTTempLogger.deb’.

I can then install the package and start it running with the command sudo apt-get install ./GoveeBTTempLogger.deb

I can stop and either remove it or purge it with the command sudo apt-get remove goveebttemplogger or sudo apt-get purge goveebttemplogger.

GoPro Flat Mount

I’ve had GoPro mounts fixed to either side of the boom of the sail boat I race on for several years. I primarily use the one on the starboard side, producing videos of races like the one below.

Last week the camera got caught in the reefing line as we raised the main sail, pulling the sticky mount completely off the boom. From past experience dropping the Gopro on the boat, I use a safety cord tied to the camera, so did not lose the camera.

This week I visited the boat the day before our race and installed a new mount on the boom. I also made sure that the reefing lines were resting on the port side of the boom so the camera wouldn’t be caught during the raise.

Soon after we had raised the main and taken a couple of tacks, the camera had shaken itself off the boom. The sticky pad didn’t stay stuck to the boom.

After I got home, I peeled the remainder of the sticky pad from the old mount with a lot of effort. I was able to peel the sticky pad from the new mount easily and in one piece.

The old mount is top right, the new mount is bottom left. An unused mount from my GoPro box is bottom right.

At one time I purchased a bunch of GoPro mounts in a kit from Amazon. The kit had a chest strap that was significantly cheaper than the original GoPro branded one. It was worth the price for me. I noticed that if I kept the new items in a Ziploc bag, the plastic had a distinct smell, while the original GoPro plastic did not. Knowing what I do about plastics, I didn’t want to trust my GoPro to the cheap plastic, unfortunately after having things sit around for a couple seasons I forgot that.

I believe the mount with the voids under the groove edges are from the inexpensive package. Along with questionable plastic, I believe it also used a less sticky adhesive pad.

I’ll try replacing the mount with the remaining original this coming week and hopefully be able to record another race