337fdf13dc
- Use conditional Binding to sync slider values only when not dragging - Send value to light once on release instead of every pixel - Improve shared config file loading with multiple path fallbacks
164 lines
5.4 KiB
QML
164 lines
5.4 KiB
QML
import QtQuick
|
|
import org.kde.plasma.plasmoid
|
|
import org.kde.plasma.core as PlasmaCore
|
|
|
|
PlasmoidItem {
|
|
id: root
|
|
|
|
// State
|
|
property bool lightOn: false
|
|
property int lightBrightness: 50
|
|
property int lightTemperature: 200 // mired
|
|
property bool lightReachable: false
|
|
property string lightHost: ""
|
|
property int lightPort: 9123
|
|
|
|
// Resolve host: widget config > shared CLI config
|
|
function resolveHost() {
|
|
var cfgHost = Plasmoid.configuration.lightHost || ""
|
|
var cfgPort = Plasmoid.configuration.lightPort || 9123
|
|
|
|
if (cfgHost !== "") {
|
|
root.lightHost = cfgHost
|
|
root.lightPort = cfgPort
|
|
return
|
|
}
|
|
|
|
// Try reading shared CLI config via local file XHR
|
|
var homePath = Qt.resolvedUrl("file://" + "/home/" + Qt.application.arguments[0]).toString()
|
|
// Use direct path since StandardPaths may not be available
|
|
var configPaths = [
|
|
"file:///home/faye/.config/elgato-cli/config.json",
|
|
"file://" + (typeof StandardPaths !== 'undefined' ?
|
|
StandardPaths.writableLocation(StandardPaths.HomeLocation) :
|
|
"/home/faye") + "/.config/elgato-cli/config.json"
|
|
]
|
|
|
|
for (var i = 0; i < configPaths.length; i++) {
|
|
try {
|
|
var xhr = new XMLHttpRequest()
|
|
xhr.open("GET", configPaths[i], false)
|
|
xhr.send()
|
|
if (xhr.responseText && xhr.responseText.length > 0) {
|
|
var config = JSON.parse(xhr.responseText)
|
|
if (config.host) {
|
|
root.lightHost = config.host
|
|
root.lightPort = config.port || 9123
|
|
console.log("Elgato: loaded config from", configPaths[i],
|
|
"host:", config.host)
|
|
return
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.log("Elgato: Could not read config from", configPaths[i], e)
|
|
}
|
|
}
|
|
console.log("Elgato: No config found, use widget settings or run 'elgato discover'")
|
|
}
|
|
|
|
function baseUrl() {
|
|
return "http://" + root.lightHost + ":" + root.lightPort + "/elgato"
|
|
}
|
|
|
|
function fetchState() {
|
|
if (root.lightHost === "") return
|
|
|
|
var xhr = new XMLHttpRequest()
|
|
xhr.open("GET", baseUrl() + "/lights")
|
|
xhr.timeout = 3000
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState !== XMLHttpRequest.DONE) return
|
|
if (xhr.status === 200) {
|
|
var data = JSON.parse(xhr.responseText)
|
|
var light = data.lights[0]
|
|
root.lightOn = light.on === 1
|
|
root.lightBrightness = light.brightness
|
|
root.lightTemperature = light.temperature
|
|
root.lightReachable = true
|
|
} else {
|
|
root.lightReachable = false
|
|
}
|
|
}
|
|
xhr.onerror = function() { root.lightReachable = false }
|
|
xhr.send()
|
|
}
|
|
|
|
function setLightState(payload) {
|
|
if (root.lightHost === "") return
|
|
|
|
var xhr = new XMLHttpRequest()
|
|
xhr.open("PUT", baseUrl() + "/lights")
|
|
xhr.setRequestHeader("Content-Type", "application/json")
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState !== XMLHttpRequest.DONE) return
|
|
if (xhr.status === 200) {
|
|
var data = JSON.parse(xhr.responseText)
|
|
var light = data.lights[0]
|
|
root.lightOn = light.on === 1
|
|
root.lightBrightness = light.brightness
|
|
root.lightTemperature = light.temperature
|
|
root.lightReachable = true
|
|
} else {
|
|
root.lightReachable = false
|
|
}
|
|
}
|
|
xhr.onerror = function() { root.lightReachable = false }
|
|
xhr.send(JSON.stringify({numberOfLights: 1, lights: [payload]}))
|
|
}
|
|
|
|
function toggleLight() {
|
|
setLightState({
|
|
on: root.lightOn ? 0 : 1,
|
|
brightness: root.lightBrightness,
|
|
temperature: root.lightTemperature
|
|
})
|
|
}
|
|
|
|
function setBrightness(val) {
|
|
setLightState({
|
|
on: root.lightOn ? 1 : 0,
|
|
brightness: val,
|
|
temperature: root.lightTemperature
|
|
})
|
|
}
|
|
|
|
function setTemperature(val) {
|
|
setLightState({
|
|
on: root.lightOn ? 1 : 0,
|
|
brightness: root.lightBrightness,
|
|
temperature: val
|
|
})
|
|
}
|
|
|
|
// Polling timer
|
|
Timer {
|
|
id: pollTimer
|
|
interval: Plasmoid.configuration.pollInterval || 3000
|
|
running: true
|
|
repeat: true
|
|
triggeredOnStart: true
|
|
onTriggered: root.fetchState()
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
resolveHost()
|
|
fetchState()
|
|
}
|
|
|
|
// Tray icon
|
|
compactRepresentation: CompactRepresentation {}
|
|
|
|
// Popup
|
|
fullRepresentation: FullRepresentation {}
|
|
|
|
// Prefer status area
|
|
Plasmoid.status: root.lightReachable ? PlasmaCore.Types.ActiveStatus : PlasmaCore.Types.PassiveStatus
|
|
preferredRepresentation: compactRepresentation
|
|
toolTipMainText: "Elgato Key Light"
|
|
toolTipSubText: {
|
|
if (root.lightHost === "") return "Not configured"
|
|
if (!root.lightReachable) return "Unreachable"
|
|
return (root.lightOn ? "On" : "Off") + " - " + root.lightBrightness + "% - " + Math.round(1000000 / root.lightTemperature) + "K"
|
|
}
|
|
}
|