Hotkeys, buttons, lights
Global hotkeys, buttons on the phone remote and the Stream Deck, smart lights, Home Assistant and MIDI controllers.
Functions
hotkeys.on(keys, handler)
Run a function when a key is pressed anywhere, even while a game has the focus. Keys are written like "Ctrl+Shift+KeyB", "Alt+Digit1" or "F9": a letter, digit or anything you type needs Ctrl, Alt or Win with it. A key the app or another plugin uses is refused. At most 10. Needs "hotkeys".
keys:stringhandler:fun(e: { keys: string })
Returns integer id
hotkeys.on("Ctrl+Shift+KeyC", function() obs.save_replay() end)hotkeys.off(keys)
Let go of a hotkey.
keys:string
Returns boolean found
hotkeys.list()
The keys this plugin registered.
Returns string[]
remote.button(spec)
A button on the phone remote (Beta Lab). The same id again changes it. At most 24 buttons.
spec:PadButton
Returns string id
remote.remove(id)
Take a button off the phone remote.
id:string
deck.button(spec)
A button the Stream Deck can show, through ForgeCast's Stream Deck plugin: the streamer puts a "ForgeCast button" on a key and picks it. Call it again to change its label (a counter on a key).
spec:PadButton
Returns string id
local deaths = 0
local function show() deck.button{ id = "deaths", label = "Deaths: " .. deaths, on_press = add } end
function add() deaths = deaths + 1 show() end
show()deck.remove(id)
Take a button off the Stream Deck.
id:string
lights.list()
The lights the streamer added in Devices.
Returns LightInfo[]
lights.set(look, callback)
Change the lights: callback(how many changed) or callback(nil, why). Up to 10 changes a second.
look:LightLookcallback:fun(changed: integer?, error?: string), optional
Returns integer id
chats.on(Event.SuperChat, function() lights.set{ color = "#ffd700", brightness = 100 } end)lights.flash(color, opts, callback)
Flash a colour (2 times, 300 ms each by default), then put each light back as it was. Needs "lights".
Name
Type
Returns integer id
lights.off(light, callback)
Turn the lights (or one) off.
light:string|fun(changed: integer?, error?: string), optionalcallback:fun(changed: integer?, error?: string), optional
Returns integer id
homeassistant.call(service, data, callback)
Call a Home Assistant service ("light.turn_on", "switch.toggle", "scene.turn_on"…): callback(what changed). Locks, alarms, covers (garage doors), cameras and Home Assistant's own management are never allowed.
Name
Type
Returns integer id
homeassistant.call("light.turn_on", { entity_id = "light.desk", rgb_color = { 255, 0, 80 } })homeassistant.state(entity, callback)
One entity's state.
entity:string. "sensor.room_temperature"callback:fun(state: HaState?, error?: string)
Returns integer id
homeassistant.states(domain, callback)
Every entity (or one domain's, like "light").
domain:string|fun(states: HaState[]?, error?: string), optionalcallback:fun(states: HaState[]?, error?: string), optional
Returns integer id
midi.devices()
The MIDI controllers on this PC: { inputs = {…}, outputs = {…}, listening }.
Returns { inputs: string[], outputs: string[], listening: boolean }
midi.on(handler)
Hear every MIDI controller (Event.Midi): pads, keys, knobs and faders. New controllers are picked up within a few seconds.
handler:fun(m: MidiMessage)
Returns integer id
midi.on(function(m)
if m.type == "note_on" and m.note == 36 then sounds.play("airhorn") end
if m.type == "cc" and m.controller == 7 then obs.set_volume("Music", m.value / 127 * 60 - 60) end
end)midi.off(id)
Stop a handler made with midi.on.
id:integer
Returns boolean found
midi.send(device, message, callback)
Send to a controller (light a pad): { type = "note_on", note, velocity, channel }, { type = "cc", controller, value }, { type = "program", program } or raw bytes.
Name
Type
Returns integer id
Types
Open a type to see its fields; type names above link here.

