Hello everyone! I’m the developer/maintainer of a project that utilizes Balena’s incredibly awesome OpenFleets concept: Ribbit Network.
We have a raspberry pi balena device that has several sensors connected to it and uses a wifi Radio to connect to the internet. Given that this is an Open Fleet, it’s sometimes not obvious what issues are for someone building their own sensor given that they don’t have access to the Balena UI. So I would like to build a local UI that gives as much status about the sensor as possible.
Is there a good starting place for a local User Interface / Web Page like this which I could fork and modifying for my Balena project?
I’m thinking this should be a local web server that displays some basic information to help diagnose the following issues:
Sensor Connection Issues - Is there a good connection to the CO2 Sensor, Barometer, and GPS?
GPS Location Fix - Does that GPS have enough satellites for a good location fix?
Additionally, it would probably be useful to display some other information like:
I’m not so sure what it is you’re looking for. The fact that it is sensors you want to aggregate status of rather than Balena device indicators means it is probably going to be very bespoke. Something that sprung to mind maybe for inspiration is the open balena dashboard project, maybe just something to spur some ideas. Its online though but may be useful to adapt for aggregating device status. https://forums.balena.io/t/open-balena-dashboard-project/2219
And for the UI design itself im having a love affair with Quasar. Reading about your project of stats it sprung to mind. Here is someone else’s example project showing off components: https://quasar-admin-demo.netlify.app/. Check out the charts tab in the menu and others.
@mpous@jmakivic@cywang117 is there a dummy Supervisor you have laying around somewhere for development? I may try and throw together a quick example, but rather than develop on a device it would be helpful to have a dummy supervisor to send requests to for development. I figured this may be something you guys have already developed?
@maggie0002 The “bespoke” aspect of the LocalUI indeed poses an interesting dilemma. We’ve discussed this previously and it may be possible to have the local-ui balenaBlock pull from a user-defined services section of the balena.yml contract. There, the user may specify what info they may provide. Of course the implementation may be complex, but this sounds like an ideal solution if we can manage it. Feel free to follow/contribute to this repo it’s still under development!
As for the dummy Supervisor, I am not personally aware of any such item, but I have had luck provisioning an amd64 balenaOS in a VM as an Intel NUC, which I can then livepush on with even more speed than with a Raspberry Pi 4. I can provide the scripts I use if you’d like?
Alternatively, there is the balenaOS-in-container workflow described in the Supervisor’s README.
I had a look this morning and managed to push to the device for testing. Hopefully I will not be so far into the UI to make it worth going through the VM process, but thanks for the offer.
Here are my two-cents:
NGINX branch:
It always seemed a little cumbersome to have to build another backend for a frontend to communicate with just to then be passed to a second backend (the supervisor). So here I used an NGINX reverse proxy to bring the Supervisor on to an open port, then used the same NGINX instance to host a UI which communicated with the supervisor on the reverse proxy port. Pros: great image size, around 15mb, Cons: security having opened the supervisor on a port, and not much room to grow. If the goal was to pursue other features like CPU usage that isn’t on the Supervisor API it would be problematic. Moreover, no means of adding a useful authentication at a later date.
Main branch:
This is probably a little more logical. It has an ExpressJS backend but a super simple one. The idea is it acts as a proxy for Axios to the main UI and then all the work is done on the UI itself. It means less code base to maintain and problems to debug (hopefully). Downside is the container with Node in it is 100+mb, but because the express js backend is so simple it should be relatively easy for someone to create the same link in Flask (Python) or other languages, then reuse the same interface out of the box. Would mean more contributes to the frontend. And then by having different languages, image size isn’t so much of a problem as people can align it with whatever image they already have on the device and benefit from Docker/balena-engine image sharing. It also has the potential to add in future features like authentication, and reading local CPU stats etc (while at its core is still very portable to other languages and the UI interchangeable).
I put all the Supervisor paths in one file for easier maintenance. Then built the UI example in Quasar because it has a whole bunch of easy to drop in components for the UI development. If hoping to get more open source contributions then thinking the code really needs to be as easy to access and manipulate as possible (take wifi-connect for example that is in Rust, is popular but has had no contribution as it’s a rarer language). Quasar setup allows for some other drop-in features, so added i18n for future proofing, I’m sure there are lots of language speakers in the community.
Not sure how I landed in the UI thing, but was a bit of fun tinkering for a while. Also not sure if drifting off of @keenanjohnson question. Is any of this helpful? If you are putting something together could it be towards a generic base for the community?
It’s only the logic and a few buttons, but yes of course by all means use it as you wish. If you do have time it would be appreciated if you could put it into some commits moving it forward as something everyone can use, and then at the last stage fork it to do any of your custom components.
The most obvious next step is adding the routes from the balena supervisor docs to the supervisorRoutes in the app.
Then perhaps the tricker part. How should the UI be laid out? There are a lot of components to fit in and some menu items to name and consider what will go where. I wonder if using vuedraggable so that users can drag the components around to where they want them to be may be better than trying to work out an answer for everyone? And then in the settings panel add a bunch of toggles for each component with a description of it to enable or disable it. It will reduce clutter but also reduce every route being hit with a request each time the page loads (for things like stats that you would want to show immediately without a button click).
Ui wise though the Quasar docs are the place to start. They are extensive and detailed, there are a whole bunch of components ready to go: https://quasar.dev/. I would probably want to try one without draggable and see how clutter it is, because draggable would require storing the state of the layout for the users next visit and while very possible maybe best to get something working done rather than aim high and not finish it. Keep throwing some ideas around, best to think out loud.
Hmm, the juices are flowing now. I will put a GitHub workflow in to build it as a multi arch docker image from the main branch. It will mean someone can ssh into a device and run a balena run command rather than have to push it through the balena cli or cloud or local. Then remove it when done. Useful for debugging or getting some control immediately on site without tampering with running services.
Would need to know from the Balena people how to make the supervisor accessible in that instance though. My understanding is the supervisor does the assigning of the api keys and url based on the label? If working outside of the supervisor how best to get the api key and url vars into the container and permission to interact? Would it need to attach to a certain network?
That’s about as far as I go for now. There are lots of things that could be done in terms of code, adding Supervisor endpoints, cleaning up the example components and adding others. Will see how it goes and if anyone finds it useful.
Following up on this thread, I have created some starter routes/ui using the balena SDK to provide information from the source of truth (in the cloud) for device information and env var configuration as a PR. This should enable a huge/wide variety of functionality to be added going forward: https://github.com/maggie0002/balena-device-ui/pull/1
I want to keep the conversation open to what could be useful, but there is a lot of work (offline/online state as an example) to get this project to a point where it’s easy to add a custom page for a specific application. Buttttttt the future is looking bright here!