Built-in Drivers
Muxit ships with five built-in drivers that are always available — no installation or DLL files needed. These cover testing, cameras, file storage, and IoT.
TestDevice
A simulated instrument for learning and testing. No hardware required — all values are stored in memory. Always available, doesn't count against your connector limit.
Properties
| Property | Type | Access | Unit | Description |
|---|---|---|---|---|
label | string | R/W | Device label (default: "Test Device") | |
count | int | R/W | Event counter (increments with each stream tick) | |
temperature | double | R/W | °C | Simulated temperature (default: 22.5) |
enabled | bool | R/W | Whether the device is active | |
streaming | bool | R/W | Enable/disable stream output | |
threshold | double | R/W | Alert threshold value (default: 50.0) | |
uptime | double | R | s | Seconds since initialization |
spectrum | double[] | R | Sample spectrum data (10 points, sine-wave based) | |
histogram | int[] | R | Sample histogram (8 random bins, 0–100) | |
logs | string[] | R | Recent log messages (last 20 entries) | |
status | object | R | Composite status: { label, enabled, temperature, count, uptime } |
Actions
| Action | Args | Description |
|---|---|---|
reset | — | Reset all values to defaults |
setThreshold | { value: double } | Set the alert threshold |
configure | { key: string, value: string } | Set a named config value (logged only) |
loadProfile | { values: double[] } | Load a numeric profile array |
calculate | { a: double, b: double } | Add two numbers and return the result |
Streams
| Stream | Description |
|---|---|
data | JSON objects every 500ms: { timestamp, temperature, count, enabled } |
Config Options
| Option | Type | Default | Description |
|---|---|---|---|
dashboardPort | int | 9999 | Port for the built-in HTTP test dashboard |
label | string | "Test Device" | Initial label value |
temperature | double | 22.5 | Initial temperature value |
Example Connector
// workspace/connectors/test-device.js
export default {
driver: "TestDevice",
config: {
label: "My Test",
temperature: 25.0,
},
poll: ["temperature", "count", "enabled", "threshold"],
};Example Script
const dev = connector("test-device");
await dev.temperature(50);
log.info(`Temperature: ${await dev.temperature()}°C`);
const result = await dev.calculate({ a: 3, b: 4 });
log.info(`3 + 4 = ${result}`);
await dev.reset();Webcam
USB webcam/video capture using OpenCV. Streams base64-encoded JPEG frames at a configurable framerate.
Properties
| Property | Type | Access | Unit | Description |
|---|---|---|---|---|
width | int | R/W | px | Frame width |
height | int | R/W | px | Frame height |
fps | int | R/W | Target framerate | |
quality | int | R/W | JPEG quality (1–100) | |
brightness | int | R/W | Brightness (0–100) | |
contrast | int | R/W | Contrast (0–100) | |
flipH | bool | R/W | Horizontal flip (mirror) | |
flipV | bool | R/W | Vertical flip | |
device | int | R | Camera device index | |
streaming | bool | R | Whether capture is active | |
resolution | string | R | Current resolution string (e.g., "640x480") |
Actions
| Action | Args | Description |
|---|---|---|
start | — | Start video capture and streaming |
stop | — | Stop video capture and streaming |
snapshot | — | Capture a single frame, return as base64 JPEG |
Streams
| Stream | Description |
|---|---|
video | Base64 JPEG frames at the configured FPS |
Config Options
| Option | Type | Default | Description |
|---|---|---|---|
device | int | 0 | Camera device index (0 = first camera) |
width | int | 640 | Capture width in pixels |
height | int | 480 | Capture height in pixels |
fps | int | 15 | Target framerate |
quality | int | 75 | JPEG quality (1–100) |
brightness | int | 50 | Brightness (0–100) |
contrast | int | 50 | Contrast (0–100) |
Example Connector
// workspace/connectors/webcam.js
export default {
driver: "Webcam",
config: {
device: 0,
width: 1280,
height: 720,
fps: 15,
quality: 80,
},
poll: ["streaming", "resolution"],
};Dashboard Integration
Display the webcam feed with a canvas widget:
{
"type": "canvas",
"config": {
"label": "Webcam",
"mode": "image",
"stream": "webcam:video"
}
}Take a snapshot from a script:
const cam = connector("webcam");
await cam.start();
const frame = await cam.snapshot(); // base64 JPEG string
log.info(`Captured frame: ${frame.length} chars`);Note: Requires OpenCV native libraries. Not available on Raspberry Pi (ARM64).
ONVIF (IP Camera)
ONVIF-compatible IP camera driver with live video streaming, snapshots, and PTZ (pan/tilt/zoom) control. Uses ONVIF SOAP for device control and OpenCV for RTSP stream capture.
Properties
| Property | Type | Access | Unit | Description |
|---|---|---|---|---|
ip | string | R | Camera IP address | |
port | int | R | ONVIF service port | |
fps | int | R/W | Target capture framerate | |
quality | int | R/W | JPEG encoding quality (1–100) | |
streaming | bool | R | Whether RTSP capture is active | |
connected | bool | R | Whether camera is reachable | |
resolution | string | R | Stream resolution (e.g., "1920x1080") | |
profiles | string[] | R | Available media profile names |
Actions
| Action | Args | Description |
|---|---|---|
start | — | Connect to RTSP stream and start video capture |
stop | — | Stop RTSP capture and streaming |
snapshot | — | Capture a single frame, return as base64 JPEG |
discover | — | Find ONVIF devices on the local network |
getProfiles | — | Fetch available media profiles from the camera |
ptzMove | { pan, tilt, zoom } | PTZ relative move (values -1.0 to 1.0) |
ptzStop | — | Stop PTZ movement |
gotoPreset | { preset: string } | Go to a PTZ preset position |
Streams
| Stream | Description |
|---|---|
video | Base64 JPEG frames from RTSP stream at configured FPS |
Config Options
| Option | Type | Default | Description |
|---|---|---|---|
ip | string | "" | Camera IP address (required) |
port | int | 80 | ONVIF service port |
username | string | "" | Authentication username |
password | string | "" | Authentication password |
profile | int | 0 | Media profile index (0 = main stream) |
fps | int | 10 | Target capture framerate (1–30) |
quality | int | 75 | JPEG encoding quality (1–100) |
Example Connector
// workspace/connectors/camera.js
export default {
driver: "Onvif",
config: {
ip: "192.168.1.100",
port: 80,
username: "admin",
password: "password",
profile: 0,
fps: 10,
},
poll: ["connected", "streaming", "resolution"],
methods: {
lookLeft: { fn: c => c.ptzMove({ pan: -0.5, tilt: 0, zoom: 0 }), description: "Pan left" },
lookRight: { fn: c => c.ptzMove({ pan: 0.5, tilt: 0, zoom: 0 }), description: "Pan right" },
zoomIn: { fn: c => c.ptzMove({ pan: 0, tilt: 0, zoom: 0.5 }), description: "Zoom in" },
zoomOut: { fn: c => c.ptzMove({ pan: 0, tilt: 0, zoom: -0.5 }), description: "Zoom out" },
stopMove: { fn: c => c.ptzStop(), description: "Stop PTZ movement" },
},
};Note: Requires OpenCV native libraries. Not available on Raspberry Pi (ARM64). If no IP is configured, use the
discoveraction to find cameras on your network.
FileAccess
Sandboxed file I/O restricted to a single directory (typically workspace/data/). Allows scripts and AI to read and write files without exposing the full filesystem.
Properties
| Property | Type | Access | Unit | Description |
|---|---|---|---|---|
basePath | string | R | Resolved absolute base path | |
fileCount | int | R | Total number of files (recursive) | |
totalSizeBytes | int | R | bytes | Total size of all files |
exists | bool | R | Whether the base directory exists |
Actions
| Action | Args | Description |
|---|---|---|
listFiles | { path? } | List files in a directory (default: root) |
listDirs | { path? } | List subdirectories |
readText | { path } | Read a text file |
writeText | { path, content } | Write text to a file (creates parent dirs) |
appendText | { path, content } | Append text to a file |
readBinary | { path } | Read a binary file as base64 |
writeBinary | { path, content } | Write base64-decoded bytes to a file |
deleteFile | { path } | Delete a file |
rename | { from, to } | Rename or move a file within the sandbox |
fileInfo | { path } | Get file metadata (name, size, created, modified, extension) |
mkdir | { path } | Create a directory (recursive) |
deleteDir | { path } | Delete an empty directory |
Config Options
| Option | Type | Default | Description |
|---|---|---|---|
basePath | string | — | Required. Root directory for all file operations |
maxFileSizeMB | int | 10 | Maximum file size in MB for read/write |
createIfMissing | bool | true | Create base directory if it doesn't exist |
Security
All file paths are validated to prevent directory traversal attacks. Operations are confined to the configured basePath — you cannot read or write files outside it.
Example Connector
// workspace/connectors/files.js
export default {
driver: "FileAccess",
config: {
basePath: "./data",
},
methods: {
saveReading: {
fn: async (c, args) => {
const line = `${new Date().toISOString()},${args.value}\n`;
return c.appendText({ path: "readings.csv", content: line });
},
description: "Append a timestamped reading to readings.csv",
},
},
};Example Script
const files = connector("files");
// Write a text file
await files.writeText({ path: "log.txt", content: "Experiment started\n" });
// Append data
await files.appendText({ path: "log.txt", content: "Reading: 42.5\n" });
// Read it back
const content = await files.readText({ path: "log.txt" });
log.info(content);
// List files
const fileList = await files.listFiles({});
log.info(`Files: ${JSON.stringify(fileList)}`);MqttBridge
MQTT broker bridge for IoT devices. Connects to any MQTT broker and bridges messages into Muxit as pollable properties and streams. Ideal for ESP32, Arduino, Home Assistant, Node-RED, and Tasmota devices.
For a complete setup guide, see MQTT & IoT Guide.
Properties
| Property | Type | Access | Description |
|---|---|---|---|
connected | bool | R | Whether connected to the broker |
host | string | R | Broker hostname |
port | int | R | Broker port |
clientId | string | R | MQTT client ID |
messageCount | int | R | Total messages received |
subscriptions | string[] | R | Active topic subscriptions |
topics | object | R | Map of topic → last received value |
lastTopic | string | R | Last topic that received a message |
lastPayload | string | R | Last payload received |
Actions
| Action | Args | Description |
|---|---|---|
connect | — | Connect to the MQTT broker |
disconnect | — | Disconnect from the broker |
subscribe | { topic, qos? } | Subscribe to a topic (supports wildcards: +, #) |
unsubscribe | { topic } | Unsubscribe from a topic |
publish | { topic, payload, qos?, retain? } | Publish a message to a topic |
get | { topic } | Get the last value received on a topic |
Streams
| Stream | Description |
|---|---|
message | Every received MQTT message: { topic, payload, qos, retain, timestamp } |
Config Options
| Option | Type | Default | Description |
|---|---|---|---|
host | string | "127.0.0.1" | Broker hostname or IP |
port | int | 1883 | Broker port |
username | string | — | Authentication username |
password | string | — | Authentication password |
clientId | string | "muxit-{guid}" | MQTT client ID |
topics | string[] | [] | Topics to auto-subscribe on connect |
qos | int | 0 | Default QoS level (0, 1, or 2) |
keepAlive | int | 60 | Keep-alive interval in seconds |
Example Connector
// workspace/connectors/mqtt.js
export default {
driver: "MqttBridge",
config: {
host: "192.168.1.50",
port: 1883,
topics: ["sensors/#", "home/#"],
qos: 0,
},
poll: ["connected", "messageCount", "lastTopic", "lastPayload"],
methods: {
connect: [c => c.connect(), "Connect to the MQTT broker"],
disconnect: [c => c.disconnect(), "Disconnect from the broker"],
publish: {
fn: (c, args) => c.publish({
topic: args.topic,
payload: typeof args.payload === "object"
? JSON.stringify(args.payload)
: String(args.payload ?? ""),
qos: args.qos ?? 0,
retain: args.retain ?? false,
}),
description: "Publish a message to a topic",
},
getValue: {
fn: (c, args) => c.get({ topic: typeof args === "string" ? args : args.topic }),
description: "Get the last received value from a topic",
},
},
properties: {
temperature: {
get: c => c.get({ topic: "sensors/temperature" }),
description: "Temperature from MQTT sensor",
poll: true,
},
},
};