Skip to content

Commit

Permalink
Latest changes
Browse files Browse the repository at this point in the history
  • Loading branch information
cmsj committed Oct 3, 2023
1 parent 2cc1c3d commit 4074331
Show file tree
Hide file tree
Showing 4 changed files with 317 additions and 50 deletions.
38 changes: 35 additions & 3 deletions Spoons/ElgatoKeyLight.spoon/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ obj.serviceDomain = "local."
obj.matchNames = {}
obj.foundLights = {}

obj.logger = hs.logger.new("ElgatoKeyLight", "info")

--- ElgatoKeyLight.infoPollingInterval
--- Variable
--- A number, in seconds, for how often to poll discovered lights for their current state. Defaults to `5`
Expand All @@ -47,9 +49,6 @@ function obj:init(matchNames, serviceName, serviceDomain)
self.matchNames = matchNames
if serviceName then self.serviceName = serviceName end
if serviceDomain then self.serviceDomain = serviceDomain end

self.logger = hs.logger.new("ElgatoKeyLight", "debug")
self.bj = hs.bonjour.new()
end

--- ElgatoKeyLight:start([keepSearching])
Expand All @@ -66,6 +65,8 @@ end
--- * If `keepSearching` is `true` then the `ElgatoKeyLight:stop()` method can be used to stop the search process
--- * It is recommended to only use `keepSearching` if you are expecting to add new KeyLight devices to the network, you change network frequently, or some other reason why you expect the set of KeyLight devices to change
function obj:start(keepSearching)
self.bj = hs.bonjour.new()

if (type(keepSearching) == "boolean") then
self.keepSearching = keepSearching
end
Expand Down Expand Up @@ -175,6 +176,37 @@ function obj:turnOff(name)
end)
end

--- ElgatoKeyLight:isOn(name)
--- Method
--- Check if a KeyLight device is on
---
--- Parameters:
--- * name - The name of the device to check
---
--- Returns:
--- * A boolean, `true` if the device is on, otherwise `false`
function obj:isOn(name)
if (self.foundLights[name] == nil) then return false end
return self.foundLights[name]["on"] == 1
end

--- ElgatoKeyLight:toggle(name)
--- Method
--- Toggle the power state of a KeyLight device
---
--- Parameters:
--- * name - The name of the device to toggle
---
--- Returns:
--- * None
function obj:toggle(name)
if (self:isOn(name)) then
self:turnOff(name)
else
self:turnOn(name)
end
end

--- ElgatoKeyLight:setBrightness(name, brightness)
--- Method
--- Set the brightness of a KeyLight device
Expand Down
133 changes: 133 additions & 0 deletions Spoons/StreamDeck.spoon/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
--- === Stream Deck ===
---
--- Control your Elgato Stream Deck
---
--- Note: This Spoon assumes it has complete control of all connected Decks - if you have other software that is also controlling them, you may see unexpected behaviour.
---
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/StreamDeck.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/StreamDeck.spoon.zip)

local obj = {}
obj.__index = obj

-- Metadata
obj.name = "StreamDeck"
obj.version = "1.0"
obj.author = "Chris Jones <[email protected]>"
obj.homepage = "https://github.com/Hammerspoon/Spoons"
obj.license = "MIT - https://opensource.org/licenses/MIT"

obj.logger = hs.logger.new("StreamDeck.spoon", "debug")
obj.decks = {}

--- StreamDeck:init(config)
--- Method
--- Initialise a StreamDeck Spoon
---
--- Parameters:
--- * config - A table containing the configuration for one or more Stream Deck devices. Table keys should be the serial numbers of the devices, and the values should be tables containing information for each button of that device.
---
--- Returns:
--- * None
---
--- Notes:
--- * Each configured deck's table should have button numbers as the keys, with the value being a table containing the following keys:
--- * image - An hs.image object to display on the button
--- * callback - A function to call when the button is pressed. The function should accept three arguments:
--- * deck - The hs.streamdeck object that was pressed
--- * button - The button number that was pressed
--- * isDown - A boolean indicating whether the button was pressed or released
---
--- Example:
--- ```
--- {
--- ["12345678"] = {
--- [1] = {
--- image = hs.image.imageFromPath("/path/to/image.png"),
--- callback = function(deck, button, isDown)
--- print("Button "..button.." was pressed: "..tostring(isDown))
--- end
--- },
--- [2] = {
--- image = hs.image.imageFromPath("/path/to/another/image.png"),
--- callback = function(deck, button, isDown)
--- print("Button "..button.." was pressed: "..tostring(isDown))
--- end
--- }
--- }
--- }
--- ```
function obj:init(config)
self.deckConfig = config
end

function obj:start()
hs.streamdeck.init(function(isConnect, deck)
self:deckConnectCallback(isConnect, deck)
end)
end

function obj:stop()
for _, deck in ipairs(self.decks) do
self.logger.df("Stopping deck: "..deck:serialNumber())
deck:buttonCallback(nil)
end
self.logger.df("Stopping discovery")
hs.streamdeck.discoveryCallback(nil)
end

function obj:deckConnectCallback(isConnect, deck)
if isConnect then
local serialNumber = deck:serialNumber()
self.logger.f("Stream Deck connected: "..serialNumber)
deck:reset()
deck:buttonCallback(function(deckObj, button, isDown)
self.logger.f("(outer) Button "..button.." on deck "..deckObj:serialNumber().." was pressed: "..tostring(isDown))
self:deckButtonCallback(deckObj, button, isDown)
end)
self.decks[serialNumber] = deck

if self.deckConfig[serialNumber] then
self.logger.f("Setting up deck: "..serialNumber)
self:setupDeck(serialNumber)
end
else
self.logger.f("Stream Deck disconnected: "..deck:serialNumber())
self.decks[deck:serialNumber()] = nil
end
end

function obj:deckButtonCallback(deck, button, isDown)
self.logger.f("(inner) Button "..button.." on deck "..deck:serialNumber().." was pressed: "..tostring(isDown))
local deckConfig = self.deckConfig[deck:serialNumber()]
if deckConfig == nil then
self.logger.f("No configuration for deck: "..deck:serialNumber())
return
end

local buttonConfig = deckConfig[button]
if buttonConfig == nil then
self.logger.f("No configuration for button: "..button.." on deck: "..deck:serialNumber())
return
end

if buttonConfig.callback == nil or type(buttonConfig.callback) ~= "function" then
self.logger.f("No callback (or value is not a function) for button: "..button.." on deck: "..deck:serialNumber())
return
end

buttonConfig.callback(deck, button, isDown)
end

function obj:getDeck(serialNumber)
return self.decks[serialNumber]
end

function obj:setupDeck(serialNumber)
local deck = self:getDeck(serialNumber)
local deckConfig = self.deckConfig[serialNumber]
for button, buttonConfig in pairs(deckConfig) do
deck:setButtonImage(button, buttonConfig.image)
end
end

return obj
File renamed without changes.
Loading

0 comments on commit 4074331

Please sign in to comment.