
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>A14M</title>
  <subtitle>Chartered Chemical Engineer, Process Control Engineer, Scout Leader</subtitle>
  <link href="https://www.a14m.uk/feed" rel="self"/>
  <link href="https://www.a14m.uk/"/>
  <updated>2026-02-17T11:46:00.000Z</updated>
  <id>https://www.a14m.uk/</id>
  <author>
    <name>Alistair Marshall</name>
  </author>
  <entry>
    <title>More Home Assistant Automations</title>
    <link href="https://www.a14m.uk/2026/02/more-home-assistant-automations/"/>
    <updated>2026-02-17T11:46:00.000Z</updated>
    <id>https://www.a14m.uk/2026/02/more-home-assistant-automations/</id>
    <content type="html"><![CDATA[
      <p>Following on from my <a href="/2025/07/pizza-oven-alarm/">pizza oven alarm post</a>, I thought it was worth writing up some of the other home automations I have been running. Some of these have been in place for years, others are more recent additions. A few rely on <a href="https://www.macrodroid.com/">MacroDroid</a> — an Android automation app — working in tandem with Home Assistant via webhooks.</p>
<h2>Arriving Home After Dark</h2>
<p>When I arrive home after dark, the front door lights turn on at full brightness for ten minutes, then automatically switch off again.</p>
<p>Home Assistant does have its own presence detection, but I found it was too slow — often I would already be in the house by the time it registered that I had arrived. Using MacroDroid on the phone gives a much faster response, because it can combine two triggers: entering a GPS geofence around the house, or connecting to the home Wi-Fi network. Either one will fire the macro. The combination means it typically triggers before I have even reached the driveway.</p>
<p>Before doing anything, the macro checks two conditions. First, it must be after sunset — no point turning on lights in daylight. Second, a stopwatch that resets each time the macro fires must have been running for at least eight minutes. That second check prevents repeated triggering if the phone briefly drops off the Wi-Fi and reconnects, or drifts in and out of the geofence boundary.</p>
<p>If both conditions are satisfied, the macro makes an HTTP PUT request to a Home Assistant webhook. On the HA side, this triggers an automation that turns on the front door lights at full brightness and starts a ten-minute timer. When the timer finishes, a second automation turns the lights back off.</p>
<p>There is also a “leaving home” automation that turns off the lights when both adults have left the home zone, so there is no risk of them being left on all day.</p>
<p>The MacroDroid-to-HA webhook pattern is something I use in a few places. It lets me use the phone’s location and connectivity awareness — things MacroDroid handles very well — whilst leaving the actual smart home control to Home Assistant.</p>
<p><strong>MacroDroid macro:</strong> The triggers are “Enter geofence: Home” and “Wi-Fi SSID in range: [your home SSIDs]”. The constraints are “After sunset” and “Stopwatch ‘Got home’ &gt; 8 minutes”. The actions reset the stopwatch then make an HTTP PUT to the HA webhook URL.</p>
<p><strong>Home Assistant automations:</strong></p>
<pre><code class="language-yaml"># Turn on front door lights when arriving home after dark
- alias: Arrived Home After Dark
  triggers:
    - trigger: webhook
      webhook_id: &quot;arrived-home-after-dark&quot;
      allowed_methods: [PUT]
  actions:
    - action: light.turn_on
      target:
        area_id: front_door
      data:
        brightness_pct: 100
    - action: timer.start
      target:
        entity_id: timer.arrived_home
      data:
        duration: &quot;00:10:00&quot;

# Turn lights off when the timer finishes
- alias: Arrived Home Complete
  triggers:
    - trigger: event
      event_type: timer.finished
      event_data:
        entity_id: timer.arrived_home
  actions:
    - action: light.turn_off
      target:
        area_id: front_door

# Turn off front door lights when everyone has left the house
- alias: Leaving Home
  triggers:
    - trigger: zone
      entity_id: person.adult_1
      zone: zone.home
      event: leave
    - trigger: zone
      entity_id: person.adult_2
      zone: zone.home
      event: leave
  conditions:
    - condition: not
      conditions:
        - condition: zone
          entity_id: person.adult_1
          zone: zone.home
    - condition: not
      conditions:
        - condition: zone
          entity_id: person.adult_2
          zone: zone.home
  actions:
    - action: light.turn_off
      target:
        area_id: front_door
</code></pre>
<h2>Children’s Bedroom Lights</h2>
<p>Both children have loft beds with bright LED strips underneath. The LEDs are wired via smart switches that Home Assistant can control, but the only physical remote in each room is for the main ceiling light.</p>
<p>Rather than fitting extra remotes or switches, I set up automations that follow the main light’s brightness. When the main light is turned up above a high brightness threshold, the under-bed LEDs switch on. When the main light drops below a lower threshold — or is turned off entirely — they switch off. The gap between the two thresholds acts as a deadband, preventing the LEDs from flickering while someone is slowly adjusting the brightness.</p>
<p>The end result is that one remote effectively controls both the overhead light and the under-bed task lighting, without the children needing to think about it at all.</p>
<pre><code class="language-yaml"># Example for one child's room — repeat with different entities for the other
- alias: Set Child Bedroom Under-Bed Light
  triggers:
    - trigger: state
      entity_id: light.bedroom_main_light
      attribute: brightness
    - trigger: state
      entity_id: light.bedroom_main_light
  actions:
    - choose:
        - conditions:
            - condition: numeric_state
              entity_id: light.bedroom_main_light
              attribute: brightness
              above: 190
          sequence:
            - action: light.turn_on
              target:
                entity_id: light.bedroom_under_bed
        - conditions:
            - condition: or
              conditions:
                - condition: numeric_state
                  entity_id: light.bedroom_main_light
                  attribute: brightness
                  below: 100
                - condition: state
                  entity_id: light.bedroom_main_light
                  state:
                    - &quot;off&quot;
                    - unavailable
                    - unknown
          sequence:
            - action: light.turn_off
              target:
                entity_id: light.bedroom_under_bed
</code></pre>
<p>Note that HA represents brightness on a scale of 0–255, so <code>above: 190</code> corresponds to roughly 75% brightness and <code>below: 100</code> to roughly 40%.</p>
<h2>The TV</h2>
<h3>Sharing Links from the Phone</h3>
<p>One of my favourite automations is being able to share a link from my phone directly to the living room TV.</p>
<p>Home Assistant’s companion app registers itself as a share target on Android. When you share a URL to it, HA fires a <code>mobile_app.share</code> event containing the URL. An automation picks this up and checks whether the URL is a YouTube link using a regular expression. If it is, it extracts the video ID and launches the YouTube app on the TV at that specific video, rather than opening a browser. If the URL is not a YouTube link, it opens the TV’s built-in browser at that address instead.</p>
<p>The TV has a kids lock enabled, which requires a PIN before content will play. A parallel sequence handles this automatically: two seconds after launching the app (to give it time to open and show the PIN prompt), it sends the PIN digits as individual button presses to the TV, followed by Enter.</p>
<p>The whole thing means I can be reading something on my phone, tap Share, select Home Assistant, and it is playing on the TV within a few seconds.</p>
<pre><code class="language-yaml">- alias: Share to TV
  triggers:
    - trigger: event
      event_type: mobile_app.share
  actions:
    - if:
        - condition: template
          value_template: &gt;
            {{ trigger.event.data.url | regex_match(
              '^(?:https?:\/\/)?(?:www\.|m\.)?(?:youtube\.com\/(?:watch\?v=|shorts\/)|youtu\.be\/)([0-9A-Za-z_-]{11}).*'
            ) }}
      then:
        - variables:
            vID: &gt;
              {{ trigger.event.data.url | regex_replace(
                '^(?:https?:\/\/)?(?:www\.|m\.)?(?:youtube\.com\/(?:watch\?v=|shorts\/)|youtu\.be\/)([0-9A-Za-z_-]{11}).*$',
                'v=\1'
              ) }}
        - parallel:
            - action: webostv.command
              data:
                entity_id: media_player.living_room_tv
                command: system.launcher/launch
                payload:
                  id: youtube.leanback.v4
                  contentId: &quot;{{ vID }}&quot;
            - sequence:
                - delay: &quot;00:00:02&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;1&quot;  # Replace these four digits with your PIN
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;2&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;3&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;4&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: ENTER
      else:
        - parallel:
            - action: webostv.command
              data:
                entity_id: media_player.living_room_tv
                command: system.launcher/open
                payload:
                  target: &quot;{{ trigger.event.data.url }}&quot;
            - sequence:
                - delay: &quot;00:00:02&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;1&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;2&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;3&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: &quot;4&quot;
                - action: webostv.button
                  data:
                    entity_id: media_player.living_room_tv
                    button: ENTER
</code></pre>
<h3>Notification When the TV Is Turned On</h3>
<p>This one started as a parenting tool. When the TV is turned on, Home Assistant sends a notification to any adult who is currently at home, telling them what time it came on and offering a “Turn Off” button. The check for whether each adult is home is there to avoid spamming someone who is out at work with notifications they cannot act on. Tapping the button fires a separate automation that turns the TV off via the media player integration.</p>
<p>The idea was to make it obvious to the children that we would always know if they had turned the TV on without permission. These days they are well aware the notification exists, which is arguably just as effective as it ever was.</p>
<pre><code class="language-yaml">- alias: TV Is On
  triggers:
    - trigger: device
      device_id: your_tv_device_id
      domain: media_player
      type: turned_on
  actions:
    - if:
        - condition: zone
          entity_id: person.adult_1
          zone: zone.home
      then:
        - action: notify.mobile_app_adult_1_phone
          data:
            title: TV is on
            message: &quot;Someone turned on the TV at {{ now().strftime('%H:%M') }}&quot;
            data:
              notification_icon: mdi:television
              actions:
                - action: TURN_OFF_TV
                  title: Turn Off
    - if:
        - condition: zone
          entity_id: person.adult_2
          zone: zone.home
      then:
        - action: notify.mobile_app_adult_2_phone
          data:
            title: TV is on
            message: &quot;Someone turned on the TV at {{ now().strftime('%H:%M') }}&quot;
            data:
              notification_icon: mdi:television
              actions:
                - action: TURN_OFF_TV
                  title: Turn Off

- alias: Turn Off TV via Notification
  triggers:
    - trigger: event
      event_type: mobile_app_notification_action
      event_data:
        action: TURN_OFF_TV
  actions:
    - action: media_player.turn_off
      target:
        entity_id: media_player.living_room_tv
</code></pre>
<h2>Bluetooth Headphone Battery in Home Assistant</h2>
<p>Home Assistant does a good job of tracking battery levels for devices — mobile phones, sensors, remote controls — but Bluetooth audio devices are a notable gap. There is no standard way for the Home Assistant mobile companion app to poll the battery level of a connected headset.</p>
<p>The solution uses MacroDroid on the phone. Android broadcasts a system intent (<code>android.bluetooth.device.action.BATTERY_LEVEL_CHANGED</code>) whenever a connected Bluetooth device reports a change in its battery level. MacroDroid can listen for system intents and extract values from the broadcast extras — in this case, the <code>BATTERY_LEVEL</code> extra is stored in a local variable.</p>
<p>The macro then POSTs that value as JSON to a Home Assistant webhook, but only when the value is not <code>-1</code>. Android uses <code>-1</code> to indicate that the battery level is unknown or unavailable, so that constraint prevents spurious updates reaching HA.</p>
<p>On the Home Assistant side, the webhook automation reads the <code>battery_level</code> field from the JSON payload and writes it into an <code>input_number</code> helper. From there it appears on the dashboard alongside every other battery sensor.</p>
<p><strong>MacroDroid macro:</strong> Trigger is “Intent received: <code>android.bluetooth.device.action.BATTERY_LEVEL_CHANGED</code>”, with the <code>android.bluetooth.device.extra.BATTERY_LEVEL</code> extra mapped to a local variable (e.g. <code>bt_batt</code>). The single action is an HTTP POST to the HA webhook with body <code>{&quot;battery_level&quot;: {lv=bt_batt}}</code>, with a constraint that <code>bt_batt != -1</code>.</p>
<p><strong>Home Assistant — helper and automation:</strong></p>
<p>First, create an <code>input_number</code> helper for the battery level (this can also be done via the UI under Settings → Helpers):</p>
<pre><code class="language-yaml">input_number:
  headphone_battery:
    name: Headphone Battery
    min: 0
    max: 100
    step: 1
    unit_of_measurement: &quot;%&quot;
    icon: mdi:headphones
</code></pre>
<p>Then the automation to receive updates from the webhook:</p>
<pre><code class="language-yaml">- alias: Update Headphone Battery
  triggers:
    - trigger: webhook
      webhook_id: &quot;headphone-battery-update&quot;
      allowed_methods: [POST]
  actions:
    - action: input_number.set_value
      target:
        entity_id: input_number.headphone_battery
      data:
        value: &quot;{{ trigger.json.battery_level }}&quot;
</code></pre>
<p>I have many other simple automations for example turning lights on and off at set times, but the ones listed here are the more interesting ones I thought it would be worth sharing. I hope this can be of help or inspiration to someone else.</p>

    ]]></content>
    <category term="Family"/>
    <category term="Personal"/>
    <category term="Home Automation"/>
  </entry>
  <entry>
    <title>Firetoys TechPro Cathedral Fire Poi</title>
    <link href="https://www.a14m.uk/2026/01/cathedral-poi-review/"/>
    <updated>2026-01-10T20:14:00.000Z</updated>
    <id>https://www.a14m.uk/2026/01/cathedral-poi-review/</id>
    <content type="html"><![CDATA[
      <h2>An amazing upgrade over the basic set</h2>
<p>I’ve been fire spinning for just under a year. After my first time spinning with fire, I immediately bought a set of <a href="https://cascadejuggling.com/products/cascade-50mm-fire-poi">basic fire poi</a> for under £20. These were nice enough as a starter set, allowing me to spin at occasions other than the fire clubs of nearby cities. But as my skills developed, their limitations became apparent.</p>
<h2>The problems with my starter set</h2>
<p>My first issue was that the heads were small and, when combined with the chains, meant that not much weight was at the end. This made spinning feel different from my homemade practice poi, adding an extra hazard to be aware of.</p>
<p>I also found that as my skills improved and I was able to perform a wider variety of tricks, the burn time became annoyingly short. I’d run out of fuel before I’d run out of performance.</p>
<h2>Enter the TechPro Cathedral</h2>
<p>The <a href="https://www.firetoys.co.uk/products/firetoys-techpro-cathedral-fire-poi">Firetoys TechPro Cathedral Fire Poi</a> are a significant improvement. At around £70 they’re a considerably higher investment than my starter set—probably too much if you’re not sure fire spinning is for you—but I’m delighted I made the upgrade.</p>
<p>The technora cords are lovely and, combined with the heavier heads, mean they behave much more like my practice poi. I’ve found performing tricks much smoother and easier than before. There’s a small section of chain between the head and the technora rope, which is great at letting the heads get dipped into the fuel whilst keeping the fuel off the rope. The chain is long enough to maintain this separation, but short enough not to interfere with the weight distribution or feel of the poi.</p>
<p>The heavier heads don’t feel burdensome—the lack of chains elsewhere actually helps—and I really like the extra weight at the business end.</p>
<p>It’s disappointing how few fire poi are sold with technora from UK suppliers. Even Firetoys seem to sell many more sets with chains rather than rope. I think rope should be the default, possibly with some “budget friendly” chain options for those who want them.</p>
<h2>Cathedral flames</h2>
<p>The wicks are much larger as well. I’m enjoying the bigger flames and louder roars, though I suspect these would have been quite intimidating for my first few spins. My wife commented on how much brighter the flames were and that they lit up my face better.</p>
<p>I didn’t test the maximum burn time because I ended the burn early using a fire blanket, but it was long enough for me to go through all the tricks I’m currently confident to perform—a marked improvement over my previous set.</p>
<h2>Nice touches</h2>
<p>The glow-in-the-dark handles are also a nice addition. I prefer holding them over the finger loops and, while I’m not yet ready to start tossing the poi, it’s nice to know that the equipment I have is capable when I am.</p>
<h2>One minor inconvenience</h2>
<p>My main issue with the new poi isn’t a fault of the poi themselves, but of my setup. I had a small paint tin and fuel container that worked nicely for the old small-headed poi, but the cathedral heads are much larger and don’t fit my existing setup. I need to source larger dipping and fuel storage containers.</p>
<h2>Verdict</h2>
<p>These are an excellent upgrade. The technora cords, heavier heads, and larger wicks have made spinning more enjoyable and my performances more confident. If you’re past the beginner stage and ready to invest in better equipment, I’d thoroughly recommend them.</p>

    ]]></content>
    <category term="Fire Poi"/>
    <category term="Review"/>
  </entry>
  <entry>
    <title>Farewell Grangemouth</title>
    <link href="https://www.a14m.uk/2025/12/farewell-grangemouth/"/>
    <updated>2025-12-19T16:12:00.000Z</updated>
    <id>https://www.a14m.uk/2025/12/farewell-grangemouth/</id>
    <content type="html"><![CDATA[
      <p>Today marks my final day working at Grangemouth refinery. Though I’m not entirely sure how true that statement is, considering we stopped refining oil earlier this year. I’ve been working on transitioning the site to an import oil terminal.</p>
<p>Lots of people have asked how I feel, and to be honest, there wasn’t much I was feeling at first.</p>
<p>There were occasions when it started to feel real. Emptying out the lockers and drawers. Bringing my books and course notes home. Saying goodbye to the various shifts, each time knowing it was the last time I would see them.</p>
<p>I think the sheer amount of work I was attempting to get done in the last few weeks kept me from truly thinking about it. Even within the last hour before leaving, I was still updating documentation and trying to complete one last job to make life easier for those staying behind a bit longer.</p>
<p>But that changed once I got home.</p>
<p>While I am sad, my overwhelming emotion is one of gratitude. I have been very lucky these last 14 years. Lucky that I have somewhere to go to immediately. I’ve definitely matured during my time at Grangemouth and learnt a lot along the way. Thanks to everyone who has helped me along the way.</p>
<p><img src="/images/2025/refinery.jpg" alt="Grangemouth Refinery"></p>

    ]]></content>
    <category term="Work"/>
  </entry>
  <entry>
    <title>Pizza Oven Alarm</title>
    <link href="https://www.a14m.uk/2025/07/pizza-oven-alarm/"/>
    <updated>2025-07-30T19:09:00.000Z</updated>
    <id>https://www.a14m.uk/2025/07/pizza-oven-alarm/</id>
    <content type="html"><![CDATA[
      <p>We’ve had our <a href="https://www.a14m.uk/2018/12/we-have-a-pizza-oven/">Ooni 3 pizza oven</a> since 2018 - back when the company was still called “uuni” and before they completed their rebranding. We use it almost every week, running it on gas rather than wood pellets, and it’s been brilliant. Well, mostly…</p>
<p>The problem is that strong winds we experiance have a tendency to blow out the gas flame. Not only can this be dangerous, but it’s also incredibly frustrating to discover that the stone has gone completely cold by the time I’ve noticed. This has been bothering me for quite some time, but I have finally got around to doing something about it.</p>
<h2>The Problem</h2>
<p>I wanted a reliable flame detection method to warn me before everything cooled down.</p>
<p>I have now wired up a thermocouple and connected this to my home-assistant to create an automated monitoring system.</p>
<h2>The Hardware</h2>
<p>I had an unused <a href="https://docs.m5stack.com/en/atom/atomecho">M5Stack Atom Echo</a> lying about, which I hoped would be suitable for the job. I paired it with a K-type thermocouple from Amazon - a temperature probe that can handle the high temperatures inside a pizza oven.</p>
<figure class="imgcontainer"><img src="/images/2025/temperature-probe.jpg" alt="A mess of wires at the back of a pizza oven" title="Messy Wires"><figcaption class="caption">Messy Wires</figcaption></figure>
<p>The wiring was mostly straightforward, though the Grove connector only has 4 pins and the MAX6675 requires 5. This meant I had to run an extra wire directly into the back of the Echo, which is a bit of a pain as it comes out at an odd angle compared to all the other wires. I connected the thermocouple to the MAX6675 amplifier board that came with the thermocouple I bought, then wired that to the Atom Echo.</p>
<p>I tucked the thermocouple probe into the back of the oven where it wouldn’t get in the way, and left the electronics safely outside. I am not measuring the stone temperature, or any other particular temperature, but close enough to the flame that I should see any changes quickly should the flame go out.</p>
<div style="clear:both;"></div>
<p>Here is the yaml configuration I added to the atom echo in the ESPHome Device Builder:</p>
<pre><code class="language-yaml"># SPI configuration for MAX6675 temperature sensor
spi:
  clk_pin: GPIO32  # Grove SCL pin
  miso_pin: GPIO26 # Grove SDA pin

# Temperature sensor
sensor:
  - platform: max6675
    name: &quot;Pizza Oven Temperature&quot;
    cs_pin: GPIO25   # Spare pin - needs wire access
    update_interval: 5s
    unit_of_measurement: &quot;°C&quot;
    accuracy_decimals: 1
    filters:
      - median:
          window_size: 5
          send_every: 5
</code></pre>
<h2>The Data</h2>
<p>Here’s what an evening of pizza-making looks like in numbers:</p>
<p><img src="/images/2025/pizza-oven-trend.jpg" alt="Pizza Oven Temperature Graph"></p>
<p>The graph shows the temperature throughout the evening. You can see the initial heating phase as the gas flame gets the oven up to temperature, reaching about 350°C. I suspect the brief gap in data when the oven was up to temperature was caused by my USB power bank going to sleep. There is some variation in temperature for most of the cooking period. Then there’s the dramatic drop when we finished cooking and turned the gas off.</p>
<p>With this data, I think I would struggle to work out where to place an ‘alarm’ for detecting that the fire has gone out. During the heating, it spent all of the time above 300°C, but there was one point when the temperature dropped close to that temperature (when the oven door was open and there was a short sudden downpour of rain). I suspect if I set my alarm at 300°C, It would be susceptible to spurious alarms, as well as taking some time before triggering during a genuine flame out.</p>
<p>Luckily home assistant makes it easy to track a derivative value, in this case rate of change of temperature:</p>
<p><img src="/images/2025/pizza-oven-trend-dt.jpg" alt="Pizza Oven Temperature Rate Graph"></p>
<p>In this case you can see four distinct dips where the door was opened to put pizzas in and take them out. The last dip is much more dramatic the final dip, much larger is the flame out. In this case, the drop is almost instant. If I set the alarm at -0.4°C/s, it should generate an alarm within a minute of the flame out, but hopefully not get triggered by normal fluctuations.</p>
<h2>The Fun Bit</h2>
<p>Once I had the temperature monitoring working, I couldn’t resist adding fun with the automation.</p>
<p>Now when I light the gas, my <a href="https://www.home-assistant.io/voice-pe/">Home Assistant voice</a> in the kitchen plays <a href="https://youtu.be/uZD8HKVKneI?t=202">“The Heat Is On” by Glenn Frey</a> from the Beverly Hills Cop soundtrack.</p>
<p>More importantly, when a flame-out occurs, it plays <a href="https://youtu.be/siQcRO8z7jY?t=61">“Fire’s Gone Out” by Chris Duarte Group</a>, in this case queued up to the words “I think this fire’s gone out” which seems perfect for the situation.</p>
<h2>Next Steps</h2>
<p>Now that I’ve got the basic monitoring working, there are a few practical improvements I need to make. I’ll need to monitor it a few more times and perhaps tweak the alarm limits or timing to avoid spurious alerts whilst also not missing any genuine flame-outs.</p>
<p>I also need to create a proper enclosure for the electronics to protect them from rain, ideally finding a way to mount it permanently - but it needs to be heat resistant since the oven surface gets really hot.</p>
<p>I may also need to find a better portable power supply or find a way to stop the USB power bank from going to sleep.</p>
<p>But for now, I’m quite pleased with my musical pizza oven alarm. It’s solved the original problem of not knowing when the gas had gone out, and it’s added a bit of theatre to our weekly pizza evenings.</p>

    ]]></content>
    <category term="Family"/>
    <category term="Personal"/>
    <category term="Cooking"/>
    <category term="Home Automation"/>
  </entry>
  <entry>
    <title>West Highland Way Challenge Race Report</title>
    <link href="https://www.a14m.uk/2025/06/whw-challenge-race-report/"/>
    <updated>2025-06-30T12:29:00.000Z</updated>
    <id>https://www.a14m.uk/2025/06/whw-challenge-race-report/</id>
    <content type="html"><![CDATA[
      <p>Running the West Highland Way has been on my bucket list for a while. I remember hearing about people running the route, 95 miles of tough terrain, and doing it continuously, in some cases in under 24 hours, and it blew my mind.</p>
<p>About 4 years ago I met a couple of people who had taken part. They were (relatively) normal runners, not the gods I imagined you would have to be, and for the first time, I thought maybe I could do it.</p>
<p>The West Highland Way is 155km with about 4000m climb and over rough trails, so a big step up from my previous ultras. My first ultra marathon was the Forth Ultra in April last year, a 79km loop from Falkirk mostly on roads. Then the Glasgow to Edinburgh, along the canal, 92km on tarmac and basically flat. This would be completely different.</p>
<h2>Pre-Race Nerves</h2>
<p>In the run-up to the race I was nervous. Really nervous.</p>
<p>On the Monday before the race I had a huge case of imposter syndrome. Why have I entered this? What gives me the right to even consider that I can do this?</p>
<p>On Friday I took the train to Fort William. After all the transfers and I knew I was on the right train, I had to accept that while the travel was making me nervous, most of the nerves were for the race itself.</p>
<p>Once I arrived in Fort William, I hid from a rain shower and had some lunch in a café. It was interesting to hear the war stories from a group of ladies about my age at the table next to me who had just finished. “The second day was the worst”. I am hoping that there won’t be a second day.</p>
<p>As I walked to my hotel, I heard an American walker cheer a group as they finished. The group thanked him and congratulated him as well. “How long did you take?” “5 days” “Oh that’s better than us, we took 6”, “hey 6 days is still great!”. And yet I want to do it in under 1?</p>
<h2>Race Morning</h2>
<p>I went down to breakfast slightly earlier than it was supposed to be open. A mountaineering tour group were staying in the hotel and had organised an early breakfast so they could get an early start climbing Ben Nevis. The hotel receptionist asked as I entered the lobby if I was part of the group and said we could go straight through for breakfast. I hung back to clarify if I was allowed. “I am not with a group, I am just a normal guest”. “Yes, no problem. There is no one normal here”. Thinking of the challenge ahead, I had to agree.</p>
<p>Overhearing the conversations at the other breakfast tables, I found out the mountaineering group were taking part in an organised 3 peaks challenge. One of the ladies said “I don’t want to do it, but I want to have done it”. What a beautiful quote that describes exactly how I was feeling.</p>
<h2>Race Run Through</h2>
<figure class="imgcontainer"><img src="/images/2025/whw/start.jpg" alt="Alistair standing beside the 'Original end of the West Highland Way'" title="Ready to go"><figcaption class="caption">Ready to go</figcaption></figure>
<div style="clear:both;"></div>
<h3>Fort William to Kinlochleven</h3>
<p>I set off and it feels like a normal Saturday morning run, perhaps somewhere I have never run before and with people I have never run with before, but still a normal run. The nerves had gone.</p>
<p>As we started to climb, I noticed my heart rate rise quickly, and I was one of the first in my group to slow to a walk. After my heart rate dropped back down, I started running again, but the heart rate shot up quickly. As a result of my focus on heart rate, I was a much slower ascender than the others around me and I started to drop places quickly. This didn’t bother me. I needed to protect myself. That was my main focus on this section, protecting my body to let me get to the end.</p>
<p>Once the climb levelled out, I was able to spend more time running than walking, and I started to catch up with folk again. On the downhill sections, I was much faster and descended quickly, letting my legs carry me, without adding much effort. I stubbed my foot a couple of times on rocks protruding from the path, tripping or losing balance. Each time I caught myself and kept going, but thought that was close. Too close. I needed to be more careful.</p>
<p>There was one section of the path which went straight through a ford. There was a detour path that went over a bridge, adding an extra 10m on each side of the small stream. I took the bridge. So far I had avoided the puddles and managed to keep my feet dry. Again, this was part of the protect myself strategy. Keep the feet dry, avoid blisters, get to the finish. At the same time, I could imagine my coach’s scorn at avoiding the water.</p>
<p>Once we crested the final hill and could see down into Kinlochleven, I really started to have fun and let my legs go. I picked up speed and rushed down the hill, much faster than the few folk I had been beside. There were a couple of close calls again where I nearly tripped, scaring myself a bit, but I still let my descending ability take me down the hill quickly and into the first checkpoint.</p>
<h3>Kinlochleven to Glencoe</h3>
<p>I was fairly quick in the checkpoint, refilling my water bottles, adding a sports drink sachet to one of them. Grabbing a banana and a couple of sandwiches before setting off again. I tried running while eating, but noticed that my heart rate shot up very quickly again. I decided to walk while finishing my sandwich, then forced myself to run again.</p>
<p>Once we got to the edge of the town, the climb began. Almost one continuous climb from sea level until the highest point in the course. At the start of the climb I resigned myself to being slow on the climbs again. Despite this, this was the point where I caught up with some of the walkers, people who were taking part and not intending to run at all but instead walk the whole distance in one go. They had set off two hours earlier than us.</p>
<p>About halfway through the first climb the rain started. I was actually rather hot and was worried I would overheat if I put my rain jacket on, however it looked like it was going to be heavy and persistent so I stopped early and got my jacket out of my bag and put it on over my race pack.</p>
<p>At the top of the Devil’s Staircase the wind from the south was very strong and combined with the rain made it a pretty miserable occasion. I certainly wasn’t enjoying any of the views but was focusing again on where I was putting my feet and attempting to avoid injury.</p>
<p>Descending the Devil’s Staircase I again let my legs go and pulled ahead of a couple of the other runners I had been with on the climb. My trail shoes were excellent at gripping the rocky surfaces and I made the most of it. Once I got to the bottom I realised I had possibly overdone it again and my heart rate was quite high.</p>
<p>After Kingshouse I made my way up towards checkpoint 2 at the Glencoe ski centre. By this point the rain was pretty heavy and the wind was strong and as it was an uphill section I was back to walking again. The walk was a long and slow drag and I was relieved when I reached the campervan that was acting as the checkpoint.</p>
<h3>Glencoe to Bridge of Orchy</h3>
<p>Once in the checkpoint I had to sign myself in and then refill my water bottles. By the time I’d finished that and grabbed a couple of bits of food I had started shivering. Ideally at this point I would have stopped and changed my socks for dry ones, but the wind and rain had me worried so I set off as quickly as I could.</p>
<p>After setting off I found it was a real struggle to run. The uphill sections where normally I was walking to keep my heart rate down were no longer spiking my heart rate like they were earlier. I suspect my problem at this point was I had gotten cold and was really struggling to get my body temperature back up again.</p>
<p>I knew that this section of the trail was very rough underfoot, but I still wasn’t properly prepared for it. There was no chance of me keeping my feet dry - they were soaked through by this point. This was a section where my footwear probably let me down. There was no cushioning in them and my feet got ripped to shreds.</p>
<p>At least the rain stopped for a bit. I eventually took my jacket off and strung it through the webbing on the back of my pack.</p>
<p>As I climbed the hill after Inveroran Hotel, I spotted a couple of groups of walkers setting their tents up for wild camping. It was a bit weird to see them finished for the day when I was aware we had such a long way to go.</p>
<p>As I was running down to Bridge of Orchy I noticed that, while I was still able to run downhill easily, my feet were hurting lots. It was a relief to reach the third checkpoint.</p>
<h3>Bridge of Orchy to Auchtertyre</h3>
<p>Checkpoint 3 was completely different from checkpoint 2. It was indoors for a start. Even though the rain had stopped, it was still a relief to be inside. When I got in a volunteer was very quick to bring me my first drop bag. I took the opportunity to change out of my damp t-shirt and put on a long sleeve top. Another volunteer offered a choice of meat or vegetarian chilli. I really enjoyed my vegetarian chilli as I fiddled transferring my race number from my old t-shirt to the new one.</p>
<p>By this point it was about 17:30, yet my body felt like it was lunchtime. As I left the building, I met one of the runners I had climbed out of Kinlochleven with. We ran together for a bit, but I was struggling to keep going, particularly on the uphill sections. I was happy to play leapfrog depending on the terrain for most of the next section.</p>
<p>As I passed through Tyndrum, one of the support crew for another runner told me that I was doing great and was in fourth place. My mind exploded. I would have guessed about 10th! By this point I was really feeling the fatigue. A part of me was really tempted to slow to a walk and give up on any decent times. But this news put a stop to that. If I was in 4th place, that was just one person ahead of me struggling or pulling out and I was in line for a trophy.</p>
<p>The section leaving Tyndrum was on paths through a wood and I loved it. I don’t know what it was about the terrain but the running felt smooth and easy for a bit. Once the path left the wood things became tough again but I continued to push on to the next checkpoint.</p>
<h3>Auchtertyre to Beinglas</h3>
<p>Auchtertyre was the first checkpoint where I was on my own. The field had spread out enough that the person ahead of me had (just) left as I arrived, and I was gone before the next person came in. The midges were also out in force here. They didn’t cause any issues while on the move, it was just when stationary that they got you. This was incentive to get going again.</p>
<p>I managed to make a couple of wrong turns on the next section. My watch was very good at telling me that I was off course after I had noticed myself and started to make my way back again.</p>
<p>The uphills were energy sapping and the downhills were painful on my feet. When passing the junction down to Crianlarich, the halfway point of the route, it really hit me how bad a state I was in. I was knackered, my feet were agony and I was only now at the halfway point. I didn’t let the thought stop me. I pushed on.</p>
<p>At one point, not far from the checkpoint, I had to stop to get something out of my bag. By the time I had finished I looked down to see my legs crawling. Literally. They were covered in midges, attracted by the smell of my sweat. It was a strong incentive to keep moving.</p>
<p>I was aware that after the next checkpoint, the course gets very tough and impossible to run. I was looking forward to that. At least everyone would have to walk that section and I would be able to rest, recover and get going fresh again.</p>
<h3>Beinglas to Rowardennan</h3>
<p>When I was in the Beinglas checkpoint, two other runners caught up with me. I changed my top for a second time and put my small running pack into my bigger one which also had my emergency bivvy bag and sleeping bag. I heated up a pouch of piri piri grains and set off first with my head torch on, ready for night to fall.</p>
<p>Sure enough it wasn’t long before the others caught up with me. I tried to push on with them but my feet ached a lot. Each step was painful and my energy levels were low.</p>
<p>Sure enough the path was difficult. I think I would have found it fun if I was running on fresh legs, lots of ups and downs, scrambling over rocks and tree roots. Yes there was no way to run the whole thing, but with fresh legs I could have run some bits and enjoyed some of the more technical descents. As it was, I just found it brutal.</p>
<p>I found myself walking even the runnable sections. My brain kept having a fight with itself. The problem was that every step hurt. The rational part of my brain knew that when I was running my stride length was bigger. Therefore if I were to run the whole way I would take less steps and find it less painful overall. Unfortunately the more primal part of my brain disagreed. When I was running I was taking steps at a much higher cadence therefore every minute I experienced much more pain than if I were walking. This battle would continue for the rest of the race, and more often than not the primal part of my brain would win.</p>
<p>The weirdest part of walking this section during the night was seeing lichen getting lit up by my head torch. It had an eerie glow to it and my brain would try and make sense of the weird shapes I could see. I often thought I’d seen a sign or a weird statue only for it to turn out to be lichen on a rock or a tree.</p>
<p>This was the section I realised that I wasn’t going to have the race I wanted. As time ticked by and I continued to walk rather than run I realised my chances of getting under 24 hours were slipping away.</p>
<p>I continued on, I had no other option. But Rowardennan couldn’t come soon enough.</p>
<h3>Rowardennan to Drymen</h3>
<p>Rowardennan was the checkpoint I helped at last year and as I remembered, the midges were there to encourage racers to move on quickly.</p>
<p>Despite how I felt, the option of giving up and retiring did not cross my mind. I swapped back to using only my small bag, refilled my water bottles, grabbed a sandwich and headed on. Still walking.</p>
<p>Not long after leaving the checkpoint, a runner I had last seen climbing out of Kinlochleven caught up with me. He was now running with his son as support. I was impressed. I could see that he was also struggling, but was still going. I decided to have a go at running with him.</p>
<p>Surprisingly I managed to maintain the run much longer than I had at any point in the previous few hours. It was still painful. I still wanted to stop, but having someone else, going at a similar pace and also struggling gave me extra willpower or stamina to keep going.</p>
<p>I found, once I was running, I was slightly faster than him. I adopted a leapfrog strategy. When I was walking, I would not let him get too far away from me, then would run to catch up. I was not allowed to stop, no matter how much it hurt, until I caught up with him again. The strategy kept me going at a much faster pace all the way to Balmaha and the foot of Conic Hill.</p>
<p>At the foot of the hill, the other runner stopped, I assume to get his jacket out. I continued up the hill, assuming he would catch me soon enough. As I climbed I saw many signs telling us to stay on the path. So I did. I followed the obvious stone pathway up the hill. And missed the turn off to stay on the West Highland Way, that was a more traditional dirt path. I was halfway up to the summit before I realised my mistake. I cursed myself a lot.</p>
<p>The walk back down was really painful. Climbing didn’t hurt my feet that much, but the descent was a different story. By the time I rejoined the proper path, the other runner had passed and was ahead of me again.</p>
<p>At this point we were starting to descend the hill, the kind of terrain that hurt the most. I did try to catch up with him, but he was running well down the hill and pulled away from me. I was back to walking on my own again. By this point my right knee was starting to hurt as well.</p>
<p>The route from Conic Hill to Drymen was deceptive. I didn’t think it was far, yet it seemed to keep going. I heard a ping from my phone in my bag. Despite a lot of messages in the family chat, the only one that I heard was my mum saying she had arrived at the finish and was waiting for me. I felt guilty that she was there so early and I had such a long way to go. I phoned her to let her know that I was struggling and she would have a long wait.</p>
<h3>Drymen to Milngavie</h3>
<p>When I made it to the Drymen checkpoint I felt pretty defeated. The volunteers said that I was doing great but I admitted that I was just walking at this point. “That doesn’t matter, walking is fine”.</p>
<p>After more water, crisps and a banana, I set off again. I was not giving in. I had not put myself through all that to give up. I wanted that goblet.</p>
<p>But then I thought of that phone call with my mum. I could phone her. She could probably pick me up in under half an hour and this would all be over…</p>
<p>Then I pushed that thought away. No, I can’t give in so close to the end. I would never forgive myself if I did.</p>
<p>But wow this section dragged on. The mile markers to Milngavie taunting me. I am not convinced how accurate they were, but with my slow walking pace they were amongst the longest miles I have experienced.</p>
<p>Eventually I left one path, walked along a short stretch of road and was about to follow the route down a new path when I heard lots of cheering from the woods. Then a man came out of the path and noticed me. “Are you in the Milngavie race?” I was confused but I was heading to Milngavie so maybe yes? He then started berating me about getting lost. My lack of sleep and general fatigue didn’t help, but he told me to get down that path.</p>
<p>Once I did get into the woods, I worked out what the confusion was. There was a local 8.4 mile trail race, and as I had a number on my front he thought that I must have been in that race and gotten lost.</p>
<p>I had merged with the other race just after the front runners had passed. I was running (ok, walking) down the same path, but all these fast and fresh runners were flying past me. Occasionally one would shout to check that I was ok, and I would reply that I was fine, just doing a different race.</p>
<p>Eventually the fast runners had passed and gave way to the slower pack. There were far more folk checking on my condition. Several suggested that they could get one of the race marshals to help. Again I would let them know that I was in a different race. I had set off at 10am the previous day from Fort William. That usually got a reaction.</p>
<p>It was about here that my watch eventually died. If I had managed my sub 24 hour target it would have been fine but with the delay, using navigation and needing the accurate GPS, it was too much. I got my phone out to record the remainder.</p>
<p>As I approached the outskirts of Milngavie the last of the trail runners passed me. I had a bit of a chat with the organiser who was acting as tail runner. She was intrigued by the idea of doing the race in the north to south direction, so she would be running home.</p>
<p>Again I was on my own, the path winding its way along beside the river. I kept moving, and eventually recognised a bridge. Not far now, but I didn’t have the energy to run for the finish. I heard a cheer, my mum and another couple clapping and shouting. It made me happy, but I still couldn’t run, just kept plodding. I made it to the obelisk and mum took a photo of me before I went to the race finish in the Fraser Centre across the square.</p>
<p>I was done. 27 hours after setting off I had finished.</p>
<figure class="imgcontainer"><img src="/images/2025/whw/finish.jpg" alt="Alistair standing beside the obelisk in Milngavie" title="Finished"><figcaption class="caption">Finished</figcaption></figure>
<figure class="imgcontainer"><img src="/images/2025/whw/goblet.jpg" alt="My finishers goblet filled with wine" title="My Goblet"><figcaption class="caption">My Goblet</figcaption></figure>
<div style="clear:both;"></div>
<p><a href="https://www.strava.com/activities/14663518875">Strava Activitiy</a></p>
<h2>Post-Race and Recovery</h2>
<p>I was presented with my goblet, and then made my way over to the other end of the room to sit down. Mum managed to find my drop bags and after a bit more hunting, my finish bag. I took my shoes off but as I started to peel the socks off decided against it.</p>
<p>We went to a McDonald’s drive-through and I got my usual post-ultra meal. I didn’t move from the car seat. At the time I was swearing that I had no interest in doing any part of the West Highland Way ever again.</p>
<p>For the next week, each day was a different kind of pain. The first day, it took a good 2 minutes each time I tried to stand up and put weight on my right leg. As a result I couldn’t drive as there was no way I could put my foot down on the brake hard if required.</p>
<p>The next day was still a struggle to walk, but the knee had recovered enough I was comfortable to drive. But it was the blisters that covered my feet that stopped me walking any distance.</p>
<p>As the week progressed, it was a different niggle that was bothering me most each day. Calves, hamstrings, Achilles. They all took their turn.</p>
<p>By the end of the week most of the blisters had subsided, but one went red and painful. I eventually went to the doctor’s and was seen by a nurse practitioner.</p>
<p>“I think I have an infected toe.”
“From an ingrowing toenail?”
“No, I had a bunch of blisters. I think this one got infected.”
She looked concerned, “How did you get the blisters?”
“I took part in an event last weekend and destroyed my feet”
“What was the event?”
Damn, I had hoped to avoid this.
“I attempted to run the West Highland Way”
She gave me a quick ‘well that was stupid’ look before moving on, checking the foot and issuing me a prescription for antibiotics.</p>
<h2>Reflection</h2>
<p>It is now a month since the race. I have managed a few runs. My right hamstring is still a bit tight and I have definitely lost a fair bit of fitness, but it is nice to be back running and training again.</p>
<p>It is amazing how fast the pain fades from memory. I remember the conversation with my mum about never wanting to have anything to do with The Way ever again, yet I am regularly thinking of things I could do differently. Different shoes could have protected my feet better. If I had had a support crew the whole way, I probably would have changed my socks at Glencoe. I could have done some practice runs in hillier terrain.</p>
<p>I need to be careful. All these optimisations and improvements could lull me into thinking it would be a good idea to try again for sub 24 hours.</p>

    ]]></content>
    <category term="Running"/>
    <category term="Personal"/>
    <category term="Ultra"/>
    <category term="Race Report"/>
  </entry>
</feed>
