spliit-app / spliit

Free and Open Source Alternative to Splitwise. Share expenses with your friends and family.
https://spliit.app
MIT License
1.16k stars 184 forks source link

Home assistant add-on #56

Open ChristopherJohnston opened 10 months ago

ChristopherJohnston commented 10 months ago

[edited to better reflect the requirement]

When a branch is merged to main, could this be triggered a workflow to generate a versioned release archive? This will aid local (and potentially homeassistant) deployments.

Also, great that this has been moved into its own organisation - lends itself well to keeping related repositories together!

ChristopherJohnston commented 10 months ago

first stab at getting this running from homeassistant:

https://github.com/ChristopherJohnston/spliit-app-homeassistant-addons

Created a test release archive in my fork of spliit app and uses this in creating an add-on for home assistant which runs the app from within HA itself. Currently this connects to an external Postgres instance but could be configured to use the postgres add-on by default for a fully integrated experience.

image image

This is a bit messy when running from ingress, but I suspect that's related to permissions on the directory in the docker container.

image

but it runs nicely when exposed via port 3001:

image
scastiel commented 10 months ago

When a branch is merged to main, could this be triggered a workflow to generate a versioned release archive? This will aid local (and potentially homeassistant) deployments.

@ChristopherJohnston what do you need in the release? Does the app need to be built and exported as a tgz, and if so, with which environment variables?

ChristopherJohnston commented 10 months ago

The add on works by explicitly setting the release number in build.yaml, and upon merging into main the docker files for each supported architecture are built and published to the GitHub container registry, and then they are downloaded as part of the install procedure in home assistant.

With the implementation in my previous post I was taking the source code as a zip and running npm install/npm run build in order to build as part of the startup script (with the home assistant settings pulled in to set the postgres url Env variables).

The ideal option is a release build and publish a zip of the artifacts to be downloaded in the docker container but I hadn't thought that the environment variables are baked in at the point of building the app, so that might actually make things trickier.

ChristopherJohnston commented 10 months ago

In the docker file I think we want to be able to download and build the source:

RUN npm install --ignore-scripts
RUN npm install -g prisma
RUN prisma generate
RUN npm run build

and in the startup script set the Postgres urls and run the app:

#!/bin/bash
set -e

CONFIG_PATH=/data/options.json
export POSTGRES_PRISMA_URL=$(jq --raw-output '.postgres_url // empty' $CONFIG_PATH)
export POSTGRES_URL_NON_POOLING=$(jq --raw-output '.postgres_url_non_pooling // empty' $CONFIG_PATH)

prisma migrate deploy
npm run start

As it stands I think the app is expecting the urls at build time:

ollecting page data ...
d [ZodError]: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "POSTGRES_URL_NON_POOLING"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "POSTGRES_PRISMA_URL"
    ],
    "message": "Required"
  }
]
    at get error [as error] (/spliit2-2024.1.1/.next/server/chunks/776.js:12:8655)

Do you think it's possible for the app to take these environment variables at runtime? From what I can see it's only using them server side.

ChristopherJohnston commented 10 months ago

@scastiel any thoughts on the POSTGRES_URL env variables being set at runtime vs build time?

ChristopherJohnston commented 10 months ago

@scastiel any thoughts on the POSTGRES_URL env variables being set at runtime vs build time?

ah never mind I think I sorted it. need a .env file to build with defaults but any environment variables present at runtime will override this.

ChristopherJohnston commented 10 months ago

Some updates on this. I've managed to get it partially working (see https://github.com/ChristopherJohnston/spliit-app-homeassistant-addons)

The add-on now builds the app when the docker images are created, so this should speed up installation on home assistant.

I have had a few problems with getting the app to work from the "ingress" feature within homeassistant (which essentially puts the app in an iframe so it can be accessed from within home assistant itself). The first problem as above was due to the javascript files not being found (initial errors from chrome devtools was showing some cross-site scripting errors which led me down a bit of a rabbit hole on setting headers. Turned out that the files just weren't found - and I needed to set assetPrefix to "./" in order to get the assets from a path relative to where home assistant is "hosting" it. So now most of the assets load:

image

Note that the top image isn't found - I think this might be due to the src being set to an absolute path (ie /_next/image?url=%2Flogo-with-text.png&w=128&q=75)

The big problem I'm facing currently is that the router is linking things to an absolute path so, for example, when I click the "group" link, it's taking me to /groups and I'm getting a http404 error.

Home assistant appears to be loading the app from a path such as /api/hassio_ingress/FnkKuPNyqHbPSK8mv_F8FL3GF-aXNjXHcfFg8VYKzhQ/ - and it doesn't seem to be known at build time so I can't for example set "basePath" in next.config.js.

I think I need to find a way of having the app router link relative to the base path. The docs indicate that home assistant sets a request header X-Ingress-Path (see https://developers.home-assistant.io/docs/add-ons/presentation#ingress), which potentially could be used but this would be at runtime.

At present I'm a bit stuck so if anyone has home assistant add-on experience then I'd be grateful if you could take a look.

ChristopherJohnston commented 9 months ago

I made some progress on this last night to use an nginx reverse proxy. Still doesn't quite work but it's some way towards the end goal. Still having problems with the router linking to other pages in the app.

I will show my findings once I've committed

ChristopherJohnston commented 8 months ago

I think this add-on is at a point where it can be considered "stable". Main code base is currently at https://github.com/ChristopherJohnston/spliit-app-homeassistant-addons

This repository can be imported to home assistant as a repository and then split can be installed to home assistant as an add-on.

It still doesn't work with home assistant's "ingress" feature due to the fact that the nextjs router uses an absolute path when clicking links. This breaks the iframe in which the app is embedded, resulting in 404 errors. It does, however, work perfectly with an exposed port from homeassistant.

@scastiel let me know if you think this is something that can be brought into the split-app organisation. I'm happy to keep it in my own profile either way.

image image
ZenoBell commented 3 weeks ago

Would it be possible to create a Home Assistant integration using REST API or MQTT sensors? Also, for the add-on, it would be great if there were an option to link to a separate instance running on a different host.