Manifest and Settings
manifest.json tells Kamoji what a Kamoji Mini App is, what it uses, which
settings it has and where its data comes from. It is the only required file.
{
"id": "mqtt-value",
"name": "MQTT Value",
"version": "1.0.0",
"author": "Your Name",
"api_version": 1,
"min_firmware": "0.1.80",
"permissions": ["net.mqtt", "touch"],
"params": [
{ "key": "broker", "type": "string", "label": "Broker",
"default": "mqtt://broker.hivemq.com:1883" },
{ "key": "topic", "type": "string", "label": "Topic", "default": "kamoji/demo/value" }
],
"sources": [
{ "id": "v", "type": "mqtt", "broker": "{{param.broker}}", "topic": "{{param.topic}}" }
]
}
Fields
| Field | Required | Meaning |
|---|---|---|
id | Yes | The mini app's id: lowercase letters, digits and -, starting with a letter or digit, 2 to 40 characters. It must equal the folder name, and is unique on a Kamoji. Mini apps appear in alphabetical order of their ids |
api_version | Yes | Must be 1. A mini app with another value is not run |
name | No | Shown in the Kamoji app and on the error card. Defaults to the id |
version | No | Your version, e.g. 1.0.0 (use semver). Reported by APPS_LIST and after an install |
author | No | Your name |
min_firmware | No | The oldest firmware the mini app needs, e.g. "0.1.80". Kamoji does not check it yet |
permissions | No | What the app uses (below) |
params | No | The app's settings (below) |
sources | No | Data sources: MQTT topics. See MQTT and Data |
side_taps | No | "app" to use single left/right taps in the mini app instead of switching modes. See Side taps |
platforms | No | Phones the mini app works with: ["android"], ["ios"] or both (the default). The Kamoji app only lists it, and only installs it from a file, on those phones. Navigation is ["android"] (it reads Android notifications) |
If manifest.json is missing, over 16 KB, not valid JSON, has an id that is
not the folder name, or an api_version other than 1, the mini app is listed
as unavailable and does not appear as a mode.
Side taps
Normally a single tap on Kamoji's left or right side switches to the previous or next mode, and a mini app never sees it. A game or anything else that needs two buttons can take these taps over:
"side_taps": "app"
While such a mini app is on screen:
- a single left / right tap calls
on_left_tap()/on_right_tap()in your Lua (needs thetouchpermission); - tapping and holding left or right (about 0.6 s) switches to the previous / next mode instead;
- when the mini app opens, Kamoji shows "Hold left / right to switch" for 3 seconds, so users know how to leave.
Settings, sleep and the left + right squeeze work as usual. The Snake example uses this.
Permissions
List everything your mini app uses. The Kamoji app shows the permissions in plain words before an install.
| Permission | Allows |
|---|---|
sensors.imu | The motion sensor: the imu and drive groups |
sensors.light | The light sensor: the light group |
sensors.mic | The microphone (coming later) |
sensors.env | The temperature: the env group |
sensors.obd | OBD-II car data: the obd group (firmware 0.2.2+). Kamoji also keeps the paired adapter polled while the mini app is on screen |
events.drive | Driving events: bump, hard_brake, hard_accel, lean |
events.device | Device events (coming later) |
touch | Top tap, top hold and pinch |
net.mqtt | MQTT sources and the mqtt.* Lua functions |
net.http | HTTP sources (coming later) |
net.phone | Data from the phone (coming later) |
phone.navigation | Turn-by-turn navigation from the phone: the nav group and builtin:nav_icon / builtin:nav_icon_large. On Android the Kamoji app forwards Google Maps; it asks the user for notification access only once a mini app with this permission is installed |
Today Kamoji enforces net.mqtt (without it, MQTT sources are skipped
and mqtt.publish / mqtt.subscribe raise an error), phone.navigation
(without it, the nav group stays empty) and sensors.obd (without it, the
obd group stays empty). The other permissions
will be enforced later, so declare them now; a mini app that relies on a
missing one will stop working.
Settings (params)
params lists the mini app's settings. The Kamoji app draws a Settings
form for every installed mini app from this list, so users can change them without
touching any file. On Kamoji, the current values live in the app's
config.json, and your expressions and Lua read them as param.<key>.
The clock's time zone (utc_offset), the Excite-O-Meter's sounds switch
and the MQTT mini app's broker and topic in the
examples are settings users change this way.
"params": [
{ "key": "utc_offset", "type": "number", "label": "UTC offset (hours)",
"help": "8 for Singapore, -5 for New York", "default": 8, "min": -12, "max": 14, "step": 0.25 },
{ "key": "show_seconds", "type": "bool", "label": "Show seconds", "default": true },
{ "key": "label", "type": "string", "label": "City", "default": "Singapore" },
{ "key": "units", "type": "enum", "label": "Units", "options": ["kmh", "mph"], "default": "kmh" },
{ "key": "accent", "type": "color", "label": "Accent colour", "default": "#64D2FF" },
{ "key": "token", "type": "secret", "label": "API token", "optional": true }
]
| Field | Meaning |
|---|---|
key | Required. The name in param.<key> and in config.json. Use letters, digits and _ so it works as a Lua name |
type | Required. One of the types below |
label | The name shown in the form. Defaults to the key |
help | A hint line shown under the field |
default | The value until the user changes it |
min, max, step | number only: the allowed range and step of the stepper or slider |
options | enum only: the allowed values, as strings |
optional | true when the setting may be left empty (cleared back to its default) |
| Type | Form field | Value in Lua | Accepted values |
|---|---|---|---|
number | Stepper or slider | number | Within min / max |
bool | Switch | true / false | true, false |
string | Text field | string | Any text |
enum | Picker | string | One of options |
color | Swatches and hex | string, e.g. "#64D2FF" | #RGB or #RRGGBB |
secret | Password field | string | Any text; can be cleared |
Hiding the Wi-Fi icon (hide_wifi)
A bool setting with the key hide_wifi is reserved: when it is true,
Kamoji hides its Wi-Fi icon and network name at the top of the screen while
your mini app is showing, and brings them back when it leaves. Add it to
params so users can choose (every Originally US mini app has it):
{ "key": "hide_wifi", "type": "bool", "label": "Hide Wi-Fi icon", "default": false,
"help": "Hide the Wi-Fi icon and network name at the top of the screen while this app is showing" }
Set "default": true if your layout needs the top of the screen to itself.
Kamoji's own WiFi Display setting still applies: if it is set to None, the icon is hidden anyway.
How values reach your app:
- When the mini app comes on screen, Kamoji fills the
paramtable: the value fromconfig.jsonif there is one, elsedefault. A setting with neither isnil, so writeparam.token or ""for optional ones. colorvalues work directly in colour properties:"color": "{{ param.accent }}".- When the user changes a setting, Kamoji validates it against the
setting's type (
min/max,options, a#RGBor#RRGGBBcolour), saves it toconfig.jsonin one step and, if the mini app is on screen, restarts it so the change shows at once. Settings never change under a running mini app. Clearing asecretor anoptionalsetting removes it fromconfig.json, so the default applies again. - An update of the mini app keeps the user's
config.json(and itsdata/folder), unless the new bundle ships its own. - A
secretis stored on Kamoji and never sent back out: the Kamoji app only learns whether it is set. Your mini app reads it as a normal string, for example as an MQTT password. - Settings are also usable in manifest strings, such as a source's
broker,topic,usernameandpassword:"{{param.broker}}".
config.json is a flat JSON object of key to value:
{ "utc_offset": 1, "label": "London", "accent": "#FF9F0A" }
Kamoji writes it; you normally do not ship one. Put your starting values in
default instead: a config.json in your bundle replaces the user's
settings on every update. Tool builders can read and change settings over Bluetooth
with APP_PARAMS and APP_SET.