SDKs and languages

The repository has two optional helpers in sdk/, one file each with no dependencies. Copy the file next to your program.

Python

sdk/python/fenn.py works with Python 3.8 and later.

python
import fenn

app = fenn.Plugin()
tasks = app.load("tasks", [])              # JSON in FENN_DATA_DIR

def draw():
    app.tile(fenn.row([fenn.ring(0.3, label=str(len(tasks))), fenn.text("Tasks")], align="center"))
    app.page(fenn.column([
        fenn.text_input("new", hint="Add a task"),
        fenn.list_view([fenn.item(str(i), t) for i, t in enumerate(tasks)]),
    ], scroll=True))

@app.on("new")
def add(e):
    if e["kind"] == "submit":
        tasks.append(e["value"]); app.save("tasks", tasks); draw()

@app.every(60)
def tick(): draw()

draw()
app.run()

It has a builder for every component (column, row, text, ring, button, canvas, …), canvas shapes (rect, circle, arc, label, glyph), badge_ring, badge_glyph, badge_pulse, show, copy, open, load and save, plus poll_event() for poll mode.

Node.js

sdk/node/fenn.js works with Node 18 and later.

js
const fenn = require("./fenn");
const app = new fenn.Plugin();
let on = false;
const draw = () => app.setTile(fenn.row([
  fenn.icon("lightbulb", { fill: on, color: on ? "yellow" : "dim" }),
  fenn.spacer(),
  fenn.toggle("light", on),
], { align: "center" }));
app.on("light", (e) => { on = e.value; draw(); /* call your smart-home API here */ });
draw();

Any other language

There's nothing else to it. Read lines from stdin, write lines to stdout, and flush after each line.

  • Flush after every line. In C, Go, Rust or C#, flush stdout yourself.
  • Write UTF-8, one JSON object per line, with no newlines inside the object.
  • stderr goes to Fenn's log, and its last lines appear on the tile if your plugin stops. Use it for debug prints.
  • A compiled plugin can include its binary: run = ["bin/my-plugin.exe"].
go
out := bufio.NewWriter(os.Stdout)
send := func(v any) { b, _ := json.Marshal(v); out.Write(append(b, '\n')); out.Flush() }
send(map[string]any{"type": "tile", "view": map[string]any{"type": "text", "text": "Hi from Go"}})
sc := bufio.NewScanner(os.Stdin)
for sc.Scan() { /* json.Unmarshal(sc.Bytes(), &msg) … */ }

Report a bug

Sent with the page you’re on (/docs/sdk) and your browser’s name.