ArgonOne NVMe Expansion

  • Post category:Photos

This weekend I upgraded the Raspberry Pi that hosts my Mastodon instance and Home Assistant (among other services) with an NVMe drive.  Previously it was using an old mechanical USB hard drive, so the performance increase with the NVMe is huge!  

It runs a bit hotter than with the microSD card + external HDD, but it’s nice to have everything in one case without worrying about SD card wear anymore.

I also finally got around to upgrading from Ubuntu 20.04 to Ubuntu 22.04, just in time for the next LTS release later this year.

Home Assistant OS on KVM

  • Post category:Photos

Migrated my #HomeAssistant server to the new Home Assistant OS ARM64 image running in #Linux KVM on my #RaspberryPi 4.

I was previously using a docker installation on #Ubuntu that is no longer officially supported, and various things stopped working properly recently.

Haven’t noticed any performance difference between docker and the virtual machine, and now it’s officially supported and much easier to maintain!

Input/Output Error

  • Post category:Photos

The SD card I use in my Raspberry Pi finally wore out this week after running non-stop for almost 2.5 years. Managed to move everything safely to a new “endurance” card, hopefully it will last longer!

Argon ONE V2

  • Post category:Photos

My Raspberry Pi has been in the same dusty old case for a few years now, and the fan recently stopped working. Time for an upgrade!

Recently migrated my smart home automations from SmartThings to Home Assistant and Node-RED

  • Post category:Photos

Quite happy with this flow I wrote that automatically adds a task in Todoist to replace a sensor’s battery when it’s low.

[
{
"id": "57cd083.640ddf8",
"type": "group",
"z": "9c2fe368.3156b",
"style": {
"stroke": "#2e333a",
"stroke-opacity": "1",
"fill": "#2e333a",
"fill-opacity": "0.75",
"label": true,
"label-position": "nw",
"color": "#a4a4a4"
},
"nodes": [
"e30ec927.c9cf98",
"7f684585.8f9bcc",
"df0a0486.fa8208",
"a1d34834.2a3008",
"eb03bc70.17297",
"673dcdaf.9cee44",
"b6d33022.6ade6",
"d8c95920.05e568",
"fd170b20.6bfb58",
"c862faec.6cfee8",
"a1a1818f.84d5",
"9afe842a.46e888",
"f8f7e5de.4c4f68",
"1582535e.7b192d",
"bde473a.2a0c99",
"56638388.98f5fc",
"4c487b02.0aa994",
"5bf167a2.0ce568",
"4238a7f7.639a78"
],
"x": 34,
"y": 159,
"w": 872,
"h": 322
},
{
"id": "2ebb81e.39d4b7e",
"type": "subflow",
"name": "Todoist Token",
"info": "",
"category": "",
"in": [
{
"x": 40,
"y": 80,
"wires": [
{
"id": "a7be04bc.9983b8"
}
]
}
],
"out": [
{
"x": 460,
"y": 80,
"wires": [
{
"id": "6b560c2f.af0674",
"port": 0
}
]
}
],
"env": [],
"color": "#DDAA99"
},
{
"id": "6b560c2f.af0674",
"type": "credentials",
"z": "2ebb81e.39d4b7e",
"name": "",
"props": [
{
"value": "headers['Authorization']",
"type": "msg"
}
],
"x": 330,
"y": 80,
"wires": [
[]
]
},
{
"id": "a7be04bc.9983b8",
"type": "function",
"z": "2ebb81e.39d4b7e",
"name": "reset headers",
"func": "msg.headers = {}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 160,
"y": 80,
"wires": [
[
"6b560c2f.af0674"
]
]
},
{
"id": "201f0843.1ef468",
"type": "comment",
"z": "2ebb81e.39d4b7e",
"name": "Enter Todoist API key into the Credentials node in the format \"Bearer 69420xxxxxx…\"",
"info": "",
"x": 370,
"y": 40,
"wires": []
},
{
"id": "ce62daf1.32ac38",
"type": "subflow",
"name": "Get Or Create Todoist Label",
"info": "",
"category": "",
"in": [
{
"x": 40,
"y": 80,
"wires": [
{
"id": "b05ef05d.e89d7"
}
]
}
],
"out": [
{
"x": 900,
"y": 120,
"wires": [
{
"id": "45ae6120.eb748",
"port": 0
},
{
"id": "4f06bd54.657744",
"port": 0
}
]
}
],
"env": [],
"color": "#DDAA99"
},
{
"id": "4f06bd54.657744",
"type": "http request",
"z": "ce62daf1.32ac38",
"name": "Create Label",
"method": "POST",
"ret": "obj",
"paytoqs": "query",
"url": "https://api.todoist.com/rest/v1/labels",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 730,
"y": 160,
"wires": [
[]
]
},
{
"id": "53123516.0368dc",
"type": "function",
"z": "ce62daf1.32ac38",
"name": "POST body",
"func": "msg.payload = {\n \"name\": msg.label_name\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 570,
"y": 160,
"wires": [
[
"4f06bd54.657744"
]
]
},
{
"id": "d889905d.5939",
"type": "http request",
"z": "ce62daf1.32ac38",
"name": "Get Todoist Labels",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.todoist.com/rest/v1/labels",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 370,
"y": 80,
"wires": [
[
"d3f0ad2.1b49c5"
]
]
},
{
"id": "d3f0ad2.1b49c5",
"type": "function",
"z": "ce62daf1.32ac38",
"name": "Find label for label_name",
"func": "msg.label_id = -1;\nmsg.payload.forEach((label) => {\n if(label.name == msg.label_name) {\n msg.payload = label\n }\n});\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 590,
"y": 80,
"wires": [
[
"45ae6120.eb748"
]
]
},
{
"id": "45ae6120.eb748",
"type": "switch",
"z": "ce62daf1.32ac38",
"name": "Does label exist?",
"property": "label_id",
"propertyType": "msg",
"rules": [
{
"t": "neq",
"v": "-1",
"vt": "num"
},
{
"t": "eq",
"v": "-1",
"vt": "num"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 190,
"y": 140,
"wires": [
[],
[
"3d5b82ab.8e1fde"
]
]
},
{
"id": "7eb15e65.37c24",
"type": "comment",
"z": "ce62daf1.32ac38",
"name": "Get or create Todoist label named label_name",
"info": "",
"x": 190,
"y": 40,
"wires": []
},
{
"id": "b05ef05d.e89d7",
"type": "subflow:2ebb81e.39d4b7e",
"z": "ce62daf1.32ac38",
"name": "",
"env": [],
"x": 180,
"y": 80,
"wires": [
[
"d889905d.5939"
]
]
},
{
"id": "3d5b82ab.8e1fde",
"type": "subflow:2ebb81e.39d4b7e",
"z": "ce62daf1.32ac38",
"name": "",
"env": [],
"x": 400,
"y": 160,
"wires": [
[
"53123516.0368dc"
]
]
},
{
"id": "e30ec927.c9cf98",
"type": "comment",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Create Todoist task if sensor battery is low",
"info": "",
"x": 220,
"y": 200,
"wires": []
},
{
"id": "7f684585.8f9bcc",
"type": "server-state-changed",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Sensor Battery Levels",
"server": "c822cecb.8a7ba",
"version": 1,
"exposeToHomeAssistant": false,
"haConfig": [
{
"property": "name",
"value": ""
},
{
"property": "icon",
"value": ""
}
],
"entityidfilter": "sensor.bedroom_motion_sensor_battery,sensor.bedroom_window_1_power,sensor.bedroom_window_2_power,sensor.front_door_power,sensor.goodnight_button_battery,sensor.kitchen_motion_sensor_power,sensor.kitchen_window_power,sensor.living_room_motion_sensor_battery,sensor.patio_door_power,sensor.storage_room_battery,sensor.third_reality_inc_3rss008z_power",
"entityidfiltertype": "substring",
"outputinitially": true,
"state_type": "num",
"haltifstate": "",
"halt_if_type": "str",
"halt_if_compare": "is",
"outputs": 1,
"output_only_on_state_change": true,
"for": 0,
"forType": "num",
"forUnits": "minutes",
"ignorePrevStateNull": false,
"ignorePrevStateUnknown": false,
"ignorePrevStateUnavailable": false,
"ignoreCurrentStateUnknown": false,
"ignoreCurrentStateUnavailable": false,
"x": 180,
"y": 240,
"wires": [
[
"df0a0486.fa8208"
]
]
},
{
"id": "df0a0486.fa8208",
"type": "switch",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "state < 25",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "lt",
"v": "25",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 360,
"y": 240,
"wires": [
[
"a1a1818f.84d5"
]
]
},
{
"id": "a1d34834.2a3008",
"type": "http request",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Active Todoist Tasks",
"method": "GET",
"ret": "obj",
"paytoqs": "query",
"url": "https://api.todoist.com/rest/v1/tasks",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 620,
"y": 400,
"wires": [
[
"673dcdaf.9cee44"
]
]
},
{
"id": "eb03bc70.17297",
"type": "function",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Filter Query",
"func": "msg.payload = {\"filter\":\"@HomeAssistant & @battery & @\" + msg.topic}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 430,
"y": 400,
"wires": [
[
"a1d34834.2a3008"
]
]
},
{
"id": "673dcdaf.9cee44",
"type": "switch",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Empty List",
"property": "payload.length",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "0",
"vt": "num"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 810,
"y": 400,
"wires": [
[
"4238a7f7.639a78"
]
]
},
{
"id": "b6d33022.6ade6",
"type": "http request",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Create Task",
"method": "POST",
"ret": "obj",
"paytoqs": "query",
"url": "https://api.todoist.com/rest/v1/tasks",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 590,
"y": 440,
"wires": [
[]
]
},
{
"id": "d8c95920.05e568",
"type": "function",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Build Task",
"func": "var friendly_name = msg.data.new_state.attributes.friendly_name.toLowerCase();\nfriendly_name = friendly_name.replace(\" power\", \"\");\nfriendly_name = friendly_name.replace(\" battery\", \"\");\nfriendly_name += \" sensor\";\nmsg.payload = {\n \"content\": \"Replace battery in \" + friendly_name,\n \"label_ids\": [msg.ha_label_id, msg.batt_label_id, msg.label_id]\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 430,
"y": 440,
"wires": [
[
"b6d33022.6ade6"
]
]
},
{
"id": "fd170b20.6bfb58",
"type": "change",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "Set label_id",
"rules": [
{
"t": "set",
"p": "label_id",
"pt": "msg",
"to": "payload.id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 690,
"y": 360,
"wires": [
[
"5bf167a2.0ce568"
]
]
},
{
"id": "c862faec.6cfee8",
"type": "subflow:ce62daf1.32ac38",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "",
"env": [],
"x": 480,
"y": 280,
"wires": [
[
"bde473a.2a0c99"
]
]
},
{
"id": "a1a1818f.84d5",
"type": "change",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "HomeAssistant label",
"rules": [
{
"t": "set",
"p": "label_name",
"pt": "msg",
"to": "HomeAssistant",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 240,
"y": 280,
"wires": [
[
"c862faec.6cfee8"
]
]
},
{
"id": "9afe842a.46e888",
"type": "subflow:ce62daf1.32ac38",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "",
"x": 480,
"y": 320,
"wires": [
[
"56638388.98f5fc"
]
]
},
{
"id": "f8f7e5de.4c4f68",
"type": "change",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "battery label",
"rules": [
{
"t": "set",
"p": "label_name",
"pt": "msg",
"to": "battery",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 270,
"y": 320,
"wires": [
[
"9afe842a.46e888"
]
]
},
{
"id": "1582535e.7b192d",
"type": "change",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "device label",
"rules": [
{
"t": "set",
"p": "label_name",
"pt": "msg",
"to": "topic",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 270,
"y": 360,
"wires": [
[
"4c487b02.0aa994"
]
]
},
{
"id": "bde473a.2a0c99",
"type": "change",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "set ha_label_id",
"rules": [
{
"t": "set",
"p": "ha_label_id",
"pt": "msg",
"to": "payload.id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 700,
"y": 280,
"wires": [
[
"f8f7e5de.4c4f68"
]
]
},
{
"id": "56638388.98f5fc",
"type": "change",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "set batt_label_id",
"rules": [
{
"t": "set",
"p": "batt_label_id",
"pt": "msg",
"to": "payload.id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 700,
"y": 320,
"wires": [
[
"1582535e.7b192d"
]
]
},
{
"id": "4c487b02.0aa994",
"type": "subflow:ce62daf1.32ac38",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "",
"x": 480,
"y": 360,
"wires": [
[
"fd170b20.6bfb58"
]
]
},
{
"id": "5bf167a2.0ce568",
"type": "subflow:2ebb81e.39d4b7e",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "",
"env": [],
"x": 260,
"y": 400,
"wires": [
[
"eb03bc70.17297"
]
]
},
{
"id": "4238a7f7.639a78",
"type": "subflow:2ebb81e.39d4b7e",
"z": "9c2fe368.3156b",
"g": "57cd083.640ddf8",
"name": "",
"env": [],
"x": 260,
"y": 440,
"wires": [
[
"d8c95920.05e568"
]
]
},
{
"id": "c822cecb.8a7ba",
"type": "server",
"name": "Home Assistant",
"addon": true
}
]