Categories
Uncategorized

Getting a Tuya ZY-N1 Sound Detector Working in Zigbee2MQTT (and Using It as a Smoke Alarm Listener)

IMPORTANT NOTE:  If you wait a few weeks this should be supported by Z2M by default, so you might want to just wait.

The Tuya ZY-N1 sound detector works in Zigbee2MQTT today with a community external converter, and it makes a handy smoke alarm listener for Home Assistant. Getting there took one non-obvious setting change, so here is the whole route.

The ZY-N1 is a small USB-powered Zigbee sound sensor that reports how loud a room is. It shows up as TS0601 with manufacturer _TZE204_r6kfl9ta. At the time of writing there is no built-in support in Zigbee2MQTT: the device request is still an open issue, Koenkk/zigbee2mqtt #33195, and that issue is where the working converter comes from.

My setup: Home Assistant with the Zigbee2MQTT add-on (version 2.x). The converter was tested by its author on Zigbee2MQTT 2.14.1, and automatic loading of external converters needs 2.x.

Step 1: Pair it and check the fingerprint

Pair the sensor first, before adding any converter. Turn on Permit Join in Zigbee2MQTT and plug the sensor in. It joins as a router, because it is mains powered, and appears as unsupported with an “Automatically generated definition”.

Open the device’s About tab and check two values. The Zigbee model must be TS0601 and the manufacturer must be exactly _TZE204_r6kfl9ta. The converter only matches that exact pair, so a unit with a different manufacturer string needs a different converter.

Step 2: Add the external converter

The converter is a single JavaScript file that tells Zigbee2MQTT how to read the sensor. Its author posted it in the “External definition” section of issue #33195, along with detailed notes on what each datapoint does.

  1. Using the File Editor or Studio Code Server add-on, find the folder that holds Zigbee2MQTT’s own configuration.yaml and database.db. On a standard add-on install that is /homeassistant/zigbee2mqtt/.
  2. Inside it, create a folder called exactly external_converters.
  3. In that folder, create a file called zy-n1.mjs. The .mjs extension matters, because the file uses import statements.
  4. Paste in the whole code block from the issue, from the first import line to the final ];. Leave out the triple backticks GitHub shows around it.

The two import lines at the top need no setup. They borrow code from zigbee-herdsman-converters, the device library that ships inside Zigbee2MQTT.

What the converter gives you:

Entity What it does Updates
sound_class Loudness class: 0 quiet, 1 medium, 2 loud Live, pushed by the device
noise_detected Noise detected, yes or no Live, pushed by the device
sound_level Sound level in dB Only when asked for (see Step 3)
dpNN_raw Unmapped settings, read-only When asked for

The sensitivity and timing settings from the printed manual are not mapped yet. That is why the converter exposes them only as raw, read-only values.

The gotcha: external JavaScript was switched off

My converter was correct and in the right place, but Zigbee2MQTT ignored it because the enable_external_js setting was off. The symptoms were confusing:

  • The device kept showing “Automatically generated definition”, even after deleting and re-pairing it.
  • Clicking Reconfigure gave the error Device "..." cannot be configured. That message means the device’s definition has no configure step, which is true of the generic fallback but not of the converter.
  • The startup log said nothing at all about external converters.

The setting is documented in the Zigbee2MQTT settings reference. It allows external extensions and converters to run, which is why it can be switched off. You can turn it on in the Zigbee2MQTT web UI under Settings, Advanced, or add it to Zigbee2MQTT’s configuration.yaml:

advanced:
  enable_external_js: true

If an advanced: section already exists, add the line under it rather than creating a second one. The change needs a restart of the Zigbee2MQTT add-on. After that, the device page showed Tuya ZY-N1 instead of the generated definition.

Step 3: Reconfigure and poll for the dB reading

With the converter loaded, click Reconfigure on the device page. This runs the converter’s setup, which also asks the sensor for all its values, including the dB level.

The sensor never sends the dB level on its own; it only answers when asked. The converter’s author works around this by re-running the configure step once a minute from Home Assistant, and I did the same. Replace SoundDetector with your device’s friendly name:

alias: Poll ZY-N1 sound level
triggers:
  - trigger: time_pattern
    minutes: "/1"
actions:
  - action: mqtt.publish
    data:
      topic: zigbee2mqtt/bridge/request/device/configure
      payload: '{"id": "SoundDetector"}'
mode: single

This step is optional. The smoke alarm alert below uses sound_class, which updates live without any polling.

Step 4: Listen for the smoke alarm

The alert fires when the sensor hears loud noise for 10 seconds in a row, allowing for the gaps between beeps. A smoke alarm beeps in bursts, so reacting to a single loud reading would be triggered by a door slam, while requiring perfectly continuous noise would miss the alarm.

First, a template binary sensor in Home Assistant’s main configuration.yaml (not the Zigbee2MQTT one). The delay_off keeps it on through short pauses:

template:
  - binary_sensor:
      - name: "Loud noise sustained"
        unique_id: loud_noise_sustained
        state: "{{ is_state('sensor.sounddetector_sound_class', '2') }}"
        delay_off: "00:00:05"

Reload it from Developer Tools, YAML, Template entities. Then the automation. I send alerts through a WhatsApp gateway and ntfy; swap in your own notify actions:

alias: Smoke alarm heard
triggers:
  - trigger: state
    entity_id: binary_sensor.loud_noise_sustained
    to: "on"
    for: "00:00:10"
actions:
  - action: rest_command.whatsapp_send
    continue_on_error: true
    data:
      chatid: "YOUR_CHAT_ID"
      message: "Smoke alarm sounding at home ({{ now().strftime('%H:%M') }})"
  - action: shell_command.notify
    continue_on_error: true
    data:
      device: "Smoke alarm"
      state: "sounding"
  - delay: "00:05:00"
mode: single

Two details matter here. continue_on_error: true means a failed WhatsApp call does not stop the second alert. The 5-minute delay with mode: single stops a continuous alarm from sending a message every few seconds.

Testing, and the 5-minute trap

My first real test failed, and the cause was the automation’s own cooldown. I had used “Run actions” to check the notifications a few minutes earlier. That run was still sitting in its 5-minute delay, so mode: single quietly ignored the new trigger. The second test worked, and both the WhatsApp message and the ntfy alert arrived.

For testing, I used a siren near the sensor. In quiet conditions sound_class read 0; with the siren going it jumped to 2. If a test does not trigger, check these in History:

  • sound_class never reaches 2: the sound is not loud enough at the sensor. Move it closer.
  • sound_class reaches 2 but the helper flickers: raise delay_off to about 8 seconds.
  • The helper stays on for over 10 seconds: open the automation’s Traces to see whether a previous run was still in its delay. Restart the automation from its menu to clear it.

Finally, test with the real smoke alarm’s test button, held for 15 to 20 seconds, from where the sensor actually sits.

Wrap-up

The ZY-N1 now alerts me within about 10 seconds of a sustained alarm, for the price of one converter file and one setting. A few limitations are worth knowing:

  • Any loud, sustained sound can trigger it, including loud music, a TV or another siren. Mine also fires when my SOS siren sounds, which I am happy with.
  • The sensitivity and timing settings cannot be changed from Home Assistant until someone maps them.
  • It is an extra alert for when you are away, not a replacement for proper smoke alarms. Zigbee or interconnected smoke detectors are the more dependable route to fire alerts.

When official support lands in a Zigbee2MQTT release, delete the external converter file so it does not override the built-in definition.

Credit to GitHub user HACucoo, who wrote the converter and documented the device’s datapoints in the issue.

Sources

Categories
Uncategorized

Solution for Cryptogram Letters and Numbers game 17th October 2025 17/10/2025

What a nightmare having a non-english puzzle. Here’s the solution!

en una
vasta
extension
de lava
al sur de
la ciudad
de mexico
me
propuse
arrobado
por la
belleza
de ese
antiguo
paisaje
volcanico
realizar
algunos
jardines
que
humanizaran
sin
destruir
tan
maravilloso
espectaculo

Categories
Uncategorized

Proxmox Helper Scripts OpenProject behind nginx reverse proxy

To get this to work:

  1. Point your nginx server config for your domain to your OpenProject LXC http://ipaddress:80
  2. This throws the error “Invalid host_name configuration” when visiting your hostname for it.
  3. On the OpenProject LXC edit /etc/openproject/server and /etc/openproject/other (I also edited /etc/openproject/installer.dat) and change the hostname to your hostname.
  4. Run the command
    openproject config:set SERVER_PROTOCOL_FORCE_HTTPS="true"
    and then
    openproject configure

Further thoughts… I bet you can do step 3 with the config:set command!

Categories
Uncategorized

How to update firmware on Android Auto Wireless Adapter

After a few attempts at this I have finally worked out how to do this.

1) Plug the wireless adapter into a charger
Do no use your car data USB connection.
Either use a car cigarette lighter charger, or a wall charger in your house.

2) Once it is powered up, connect to the Wifi. Mine looks like “smartBox-A12B”

3) If asked, choose always connect.

4) Navigate on Chrome to http://192.168.1.101/ (or whatever your manual says)

5) At the bottom of the page, it will show “Online Update – Checking for updates”, and “Switch P2P”.
Given that we’re now connected to this device, there’s no internet access, so “Checking for updates” never works.
If you disconnect the Wifi it will detect new firmware (if there is any), but then if you click update it will fail because you are no longer connected to the device.
The way around this is to…

6) Click “Switch P2P”.

7) In your Android phone settings go to Connections -> Wi-Fi -> 3 dots in the top right -> Wi-fi Direct and it should find something like “smartBox-A12B”
You will also need to be connected to the internet some other way, like mobile internet or your home wi-fi.

8) Go back to Chrome and you should be able to refresh the http://192.168.1.101/ page and perform an update as you would expect.

9) The first time I did the update it zoomed up to 70%, but then slowly went up from there.

10) After you have updated, you might find that there are more updates. You will probably need to power off the device and power it back on again to get it to stop thinking that there
are updates. You will need to re-do the above process to get it back into Wi-fi direct mode if you need to update again.

11) You should now go into your Wi-fi settings and find the smartbox network, press and hold it and choose “Forget Network” as it is only needed for updating the firmware.

Categories
Uncategorized

Hiaku R1/Beta5 mirror

Here is a London, UK mirror of the files

https://zebadger.com/haiku-r1beta5-x86_64-anyboot.iso (64 bit)

https://zebadger.com/haiku-r1beta5-x86_gcc2h-anyboot.iso (32 bit)

$ sha256sum haiku-r1beta5-x86_*
22ae312a38e98083718b6984186e753d15806bd6ea44542144fdcef42c4dcb69 haiku-r1beta5-x86_64-anyboot.iso
bd6d5015ce1d94ab2c3fa2f4f685491249938bde9acc55345f76098eb2ea424f haiku-r1beta5-x86_gcc2h-anyboot.iso

Categories
Uncategorized

Virgin Media Hub 5 Modem Only Not Working

I have just renewed my Virgin Media contract and they sent me a new Hub 5 as part of the deal.

My old hub was in modem only mode, so I thought it would be easy to swap them out.

However, my router was failing to connect to it, saying “Not connected”. I tried many times but I could just not get it working. I could connect to the internet directly from the hub, but not via the router. I found a note about the 5x hub (which mine isn’t) that suggested taking the hub out of modem only mode and in the settings disabling UPNP, DMZ and DHCP, before switching back to modem mode.

I followed these instructions and sure enough, when I switched back to modem only mode my router connected immediately.

Sigh.

Categories
Uncategorized

Blood Pressure 7 Day Record Form

I’ve written a 7 day blood pressure record form for my father. The one that was provided by the doctor wasn’t very intuitive.

You can access it on Google Docs here : https://docs.google.com/spreadsheets/d/1pUDhr3YuVaerV4CJGScBGCSyO4KwNSNFO8rITQTj0rM/edit?usp=sharing

Categories
Uncategorized

Freetrade Dividend Overview Spreadsheet

If you have a Freetrade account and want to keep track of your dividends in a simple table / graph, then I have written a Google Spreadsheet to help.

Step Instruction
1 Got to the Activity Tab on the Freetrade app
2 Click the Share icon in the top right corner
3 Select all activity
4 Select Gmail, or similar, to email it to yourself
5 Clear everything in the Full Export tab
6 Open your export in Google Sheets, copy all data
7 Paste the data from the export at the first cell the Full Export tab
8 View your dividend overview on the Dividends tab

https://docs.google.com/spreadsheets/d/1kGhEDiDVKsY2kS_G10e3fthJacIkR77tGcMHmm5TQFo/

Automated overview of dividend payments
Automated overview of dividend payments

Graph of dividends per month, per year
Graph of dividends per month, per year

Categories
Uncategorized

Frigate

I had a camera “front”.
I renamed it in the config to “front1” and added another camera called “front2”.
Once I was happy with my new higher resolution camera, I removed the old one and went back to just one camera in the config called “front”. I think that this caused all my recordings to disappear from disk.

However, the Frigate database seemed to think that they were still there. Deleting them all manually is somewhat tedious (especially because I had 29k of them!). So, I decided to delete them from the sqlite database with a command.

First I installed a sqlite client:

sudo apt install sqlite3

Then I worked out the date timestamp value that I needed by visiting Epoch Converter and picking the date time that I know I made a mess.

Yr Mon Day Hr Min Sec
2023- 6- 29 21 : 0 : 0 GMT
Human date to Timestamp
Epoch timestamp: 1688072400
Timestamp in milliseconds: 1688072400000
Date and time (GMT): Thursday, 29 June 2023 21:00:00
Date and time (your time zone): Thursday, 29 June 2023 22:00:00 GMT+01:00

I then copied the Timestamp in milliseconds into my delete command

$ sudo sqlite3 frigate.db
SQLite version 3.34.1 2021-01-20 14:10:07
Enter “.help” for usage hints.
sqlite> delete from event where start_time <= 1688072400; sqlite> .q

It took a few seconds, but dropped my events from 29k to 71.

Categories
Uncategorized

nginx case insensitive URL

There was a requirement for a website on the server to have a case-insensitive.

There is no simple option in nginx to make it case-insensitive, there are also no nested if statements available.

This isn’t easy to achieve, but the below seems to have done it me (for only 1 URI!)

location ~* ^/TNG/$ {
return 301 https://www.theirdomain.co.uk/TNG/index.php;
}

location ~* ^/TNG$ {
return 301 https://www.theirdomain.co.uk/TNG/index.php;
}

set $BOTH "";

# Does the case-insensitive pattern match?
if ( $request_uri ~* ^/TNG/index.php$ )
{
set $BOTH "${BOTH}1";
}

# Is it not an exact match to the correct case?
if ( $request_uri != /TNG/index.php )
{
set $BOTH "${BOTH}2";
}

# If both true, then redirect to the correct case
if ( $BOTH = 12 )
{
return 301 https://www.theirdomain.co.uk/TNG/index.php;
}