Skip to content

Instantly share code, notes, and snippets.

@klinquist
klinquist / update_qbt_port.sh
Created December 10, 2025 14:59
ProtonVPN+Synology+qBittorrent. Run natpmpc every minute, update qbittorrent config if port changes.
#!/bin/sh
# Keep qBittorrent's incoming port in sync with ProtonVPN NAT-PMP.
# Runs natpmpc to fetch the current mapped port, updates qBittorrent.conf
# if it changed, and restarts the container so the new port is applied.
set -eu
# ---- configurable bits ------------------------------------------------------
# NAT-PMP gateway (ProtonVPN typically uses 10.2.0.1)
GATEWAY="${GATEWAY:-10.2.0.1}"
@klinquist
klinquist / safeway.js
Created November 22, 2023 16:19
Safeway Just4u clipper
function loadUntilDone() {
let buttons = document.getElementsByClassName('load-more')
if (buttons.length > 0) {
// Still a load more button. Click until it goes away
console.log("Loading more coupons...")
try {
buttons[0].click()
@klinquist
klinquist / streamWaterHeaterData.js
Last active March 25, 2023 01:21
Stream Rheem water heater data
// Stream data from Rheem hybrid water heaters.
// Run "npm install async-mqtt axios" to install dependencies
// Then execute via "node streamWaterHeaterData.js"
// Written by Kris Linquist
const axios = require('axios')
const MQTT = require("async-mqtt");
const rheem_username = '';
const rheem_password = '';
# Invoked via Crontab:
# 59 18 * * THU /home/pi/recordPodcast.sh PollockPines 22
TODAY=`date +'%Y-%m-%d'`
HOMEPATH=/home/pi
REGION=$1
MEMORY=$2
SECONDS=90.0
@klinquist
klinquist / aprscounter.js
Created September 7, 2021 13:50
Count APRS radios in use by region
const aprs = require('aprs-parser');
const stream = new aprs.APRSISConnector;
stream.connect('W1ADV');
const geolib = require('geolib');
const stats = {
us: {},
eu: {},
jp: {}
};
definition(
name: "Turn Lights On When I'm Home",
namespace: "",
author: "[email protected]",
description: "Turns light(s) on when I arrive",
category: "Convenience",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png",
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png")
const getEntryEveryMinutes = 5;
const randomNumber = (min, max) => {
return Math.floor(Math.random() * (max - min) + min);
};
const myArray = [];
setInterval(() => {
myArray.push(randomNumber(1,100));
if (myArray.length == 13) myArray.shift();
let total = 0;
for (let i = 0; i < myArray.length; i++){
for f in *.mp4
do
echo "file $f">>concatlist.txt
done
ffmpeg -f concat -i concatlist.txt -c copy output.mp4
rm concatlist.txt
@klinquist
klinquist / nginx.conf
Created May 31, 2018 05:02
NGINX reverse proxy config for Proscan
# IP address of the computer running Proscan. Assuming it's running on port 80
upstream scanner {
server 192.168.0.99;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
module.exports = {
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"globals":{