Strategies for Self-Hosted Apps?

A little update: my old bash script to push updates was extremely simple and unaware of any changes it was pushing, plus I believe it was causing me some timeout issues with the API.

I’ve written a new node script that will re-render your pixlet .star file, grab the image as a base64-encoded string, and then issue a push to the API to update your device. I’m also comparing each new render with the previous one, and if nothing has changed, it won’t bother making a new push to the API. Feel free to borrow this if you’re hosting your own app! (Note you’ll need to run this with a modern version of node, and the pixlet binary needs to exist in the same directory you run this script from.)

Important note: I have this running every 2 seconds because the endpoint my pixlet script uses to grab new data is also self-hosted and implements some rate-limiting so as not to overload any services I’m calling. If your pixlet script is calling a third-party API, make sure to adjust the interval so that you don’t get yourself rate-limited with any external services.

/*
* App to render pixlet, grab base64 encoded string of .webp, and push to Tidbyt API
*/

import axios from 'axios'
import fs from 'fs'
import * as child from 'child_process'

const apiToken = 'your-api-token-here'
const deviceId = 'your-device-id-here'
const installationID = 'your-installation-id-here'

const axiosConfig = {
	headers: { Authorization: `Bearer ${apiToken}` }
}

let previousHash = '';

const pushInterval = setInterval(() => {
	let renderPixlet = child.spawn('./pixlet', ['render', 'your-app.star'])
	let base64webp = fs.readFileSync('./your-app.webp', 'base64')

	if (base64webp !== previousHash) {
		previousHash = base64webp
		
		axios
			.post(
				'https://api.tidbyt.com/v0/devices/'+deviceId+'/push',
				{
					"image": base64webp,
					"installationID": installationID,
					"background": true
				},
				axiosConfig
			)
			.then((response) => {
				/* No need to do anything */
			})
			.catch((error) => {
				console.log(error)
			})
	} else {
		/*console.log('nochange')*/
	}
}, 2000)
1 Like