Skip to content
/ pything Public

trwy7/pything

Repository files navigation

PYThing

PYThing is a python version of DeskThing, designed to be easy to write apps for, and to be light on the client.

Features

  • Automatic carthing connection
  • Many different clients can be used, as long as they provide chromium
  • Easy setup
  • Light on the client
  • No internet is required, unless an app needs it.
  • Very modular, all features that are not important to the core are within apps that can be removed/replaced easily

Optimization

  • The client facing html/css/js is written with as little dependencies as possible to save space and load time.
  • With as modular as this app is, any unneeded features can be taken away by removing the app responsible for it.
  • Apps have access to an app.should_poll() function, which returns true if any client has the app open. This allows apps to not poll a service when no clients have the app open.
    • This helps performance and helps prevent rate limits from being hit.
  • All built in apps use a cache when, like the lyrics app, which stores in memory and wipes after a song change, and spotify, that stores until an app restart, or until manually cleared in development.
    • This saves a lot of data from being re-downloaded constantly, at the cost of extra storage writes.
  • The server only sends data to clients that need the data, by having the server keep track of what app is open, so when an app sends data, it only goes to clients that have the app open.
    • This saves a lot of bandwidth

🎥 Demo

It's a little blurry, sorry.

pythingdemo.mp4

🏃 Running

Prebuilt

Go to releases, and download the release for your device, and run it. On linux, you may need to run chmod +x pything-linux before running. If you are using an ARM device or a mac, you will need to run from source.

From source

You must know the basics of python development, and how to make a virtual environment.

Clone this repo

Create a virtual environment named .venv, and activate it

Run src/init.py using python3

Usage

If you have a Car Thing, it should be detected automatically. If you do not, you may visit the web UI from http://127.0.0.1:5192.

All app settings can be configured from http://127.0.0.1:5192/settings. Some apps require this to work.

❓ Troubleshooting

My Car Thing won't connect

Make sure you are running the custom Thing Labs firmware, if the device is not detected by the script, make sure the device shows up in ADB. You may need udev rules on linux. If it is not detected when your computer turns on, it may need to be manually unplugged and replugged.

▶️ Apps

All apps can store data in the form of settings, you can access any visible settings from /settings

  • Clock
    • A basic clock app
  • System
    • Shows information about your computer
      • RAM
      • CPU
      • Disk
      • Network
  • Music
    • App that can take input from other apps.
    • Basically, takes input from a 'provider' app, and passes that data to everything else.
    • Injects code into the client to display a playbar
  • Spotify
    • A music provider app, takes data from spotify. Requires spotify premium.
    • Does not have a UI
    • Because it relies on the Spotify API, song changes will take ~2-4 seconds to show up, sometimes longer.
  • Lyrics
    • An app that takes the data from the music provider, and gets the lyrics for the current song.
    • Uses LRCLIB and only requests lyrics when the app is open on at least one device
  • Customizer
    • An app that provides custom colors to the UI
    • Takes broadcasts from other apps so any app can set the accent color
  • device-carthing
    • Sets up any connected Car Things
    • Prompts to download ADB if it is not already installed.

🛠️ Making an app

To create a custom app, you must be using the source build. Apps have a defined structure, but not all files are needed. Apps can either be in /src/apps or /src/customapps. /src/customapps are excluded from git, but /src/apps is not., they are both loaded the same way, but a custom app cannot take the same id as a built in app. All apps are loaded as a python module, so your init script should be in /src/apps//__init__.pyt__.py. The app needs to expose an app variable, of the App class. This is a basic example of an app that has a few settings.

from flask import render_template, redirect

from init import App, StringSetting, FloatSetting, IntegerSetting, BooleanSetting


app = App("Test App", [
     StringSetting("string-test", "Test string", "Test one\nType whatever you want", "Hello!"),
     StringSetting("hidden-string-test", "", "", "default", True),
     FloatSetting("float-test", "Test float", "Test two\nType a float", 3.14),
     IntegerSetting("integer-test", "Test integer", "Test three\nType an integer", 42),
     BooleanSetting("boolean-test", "Test boolean", "Test four\nToggle this", False)
])



@app.blueprint.route("/settings")  # Results in /apps//settings, which becomes /apps/demoapp/settings for this appis app

def test_settings():
     return render_template(f"{app.dirname}/pages/settings.html")


@app.blueprint.route("/launch")

def launch(): # Removing or commenting this route results in the app not showing on the dashboard
     return redirect(f"/apps/{app.dirname}/settings")
/settings, which becomes /apps/demoapp/settings for this app def test_settings(): return render_template(f"{app.dirname}/pages/settings.html") @app.blueprint.route("/launch") def launch(): # Removing or commenting this route results in the app not showing on the dashboard return redirect(f"/apps/{app.dirname}/settings")ings.html") @app.blueprint.route("/launch") def launch(): # Removing or commenting this route results in the app not showing on the dashboard return redirect(f"/apps/{app.dirname}/settings")}/settings")" tabindex="0" role="button">

If you use this code, you should have a /apps//pages/settings.htmls.html with some basic content, following this loose structure:

{% extends "templates/app.html" %}
{% block head %}

 here -->

style>gt;
     html, body {
         overflow: hidden;
    }

style>gt;
{% endblock %}
{% block content %}
}
-->

h1 id="auto-time">gt;h1>gt; -->

span id="appid">gt;This is the {{app.id}} app!span>gt;
{% endblock %}
{% block script %}
}
-->

script>gt;
     alert("hi!")

script>gt;
{% endblock %}}
should go here --> {% endblock %} {% block content %}

This is the {{app.id}} app! {% endblock %} {% block script %} {% endblock %}quot;hi!") {% endblock %}pt> {% endblock %}" tabindex="0" role="button">

To make more complex apps, look around at the built in apps to see what you can do! While there are no docs yet, PYThing is made to be easy to extend, and part of the experience is making your own app!

🏗️ Building

Building pything with your modifications can be done by either running build.sh (linux, from within your virtual environment) or build.bat (windows). The result should be in dist. Keep in mind that apps must be in /src/apps to be included in the build.

🚧 Making a client

If you want to make hardware to be used with PYThing, there are some basic rules to follow. The hardware buttons of the Car Thing are shown below, apps may rely on these for functionality.

  • Menu button (Key M)
    • Required
  • Scroll wheel (Horizontal scroll, scroll right on clockwise)
  • Select (Key Enter)
    • On the Car Thing, it is placed on the scroll wheel
  • Back key (Key Backspace)
  • Button row (Numbers 1-4) The device should boot to a chromium webview (Should be v70 or higher if possible), and when ready, load the page http://localhost:5192/client?device=id>, feel free to make the ID whatever you want. You may check if the server is ready by pinging http://localhost:5192/isready, and loading when it is.