211 lines
7.4 KiB
QML
211 lines
7.4 KiB
QML
import QtQuick
|
||
import QtQuick.Layouts
|
||
import org.kde.plasma.plasmoid
|
||
import org.kde.plasma.components as PlasmaComponents
|
||
import org.kde.plasma.plasma5support as Plasma5Support
|
||
import org.kde.plasma.core as PlasmaCore
|
||
|
||
PlasmoidItem {
|
||
id: root
|
||
|
||
readonly property int fontSize: (Plasmoid.configuration.fontSize
|
||
> 0) ? Plasmoid.configuration.fontSize : 16
|
||
readonly property color textColor: Plasmoid.configuration.useCustomColor ? Plasmoid.configuration.customColor : PlasmaComponents.Label.color
|
||
|
||
// Настройка заголовка и иконки через присоединенное свойство
|
||
Plasmoid.title: i18n("Home Meteo")
|
||
Plasmoid.icon: "applications-system"
|
||
|
||
property string tempValue: "--.-"
|
||
property string humValue: "--.-"
|
||
property string tempEmoji: "⏳"
|
||
property string humEmoji: "⏳"
|
||
property string lastUpdate: "..."
|
||
|
||
width: 320
|
||
height: 180
|
||
Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground
|
||
| PlasmaCore.Types.ConfigurableBackground
|
||
|
||
fullRepresentation: Rectangle {
|
||
id: mainCanvas
|
||
implicitWidth: 320
|
||
implicitHeight: 180
|
||
color: Qt.rgba(root.textColor.r, root.textColor.g,
|
||
root.textColor.b, 0.2)
|
||
radius: 15
|
||
border.color: root.textColor
|
||
border.width: 1
|
||
|
||
clip: true
|
||
|
||
GridLayout {
|
||
// Привязываемся к краям родителя с внутренним отступом
|
||
anchors.fill: parent
|
||
anchors.margins: 10
|
||
columns: 2
|
||
rowSpacing: 0 // Убираем лишние промежутки между строками
|
||
columnSpacing: 10
|
||
|
||
// Заголовки
|
||
PlasmaComponents.Label {
|
||
Layout.fillWidth: true
|
||
horizontalAlignment: Text.AlignHCenter
|
||
text: "Температура, °C"
|
||
font.pointSize: root.fontSize * 0.8
|
||
color: root.textColor
|
||
opacity: 0.7
|
||
}
|
||
PlasmaComponents.Label {
|
||
Layout.fillWidth: true
|
||
horizontalAlignment: Text.AlignHCenter
|
||
text: "Влажность, %"
|
||
font.pointSize: root.fontSize * 0.8
|
||
color: root.textColor
|
||
opacity: 0.7
|
||
}
|
||
|
||
// Эмодзи
|
||
Text {
|
||
Layout.topMargin: 5
|
||
Layout.fillWidth: true
|
||
horizontalAlignment: Text.AlignHCenter
|
||
text: root.tempEmoji
|
||
font.pointSize: root.fontSize * 2.6
|
||
}
|
||
Text {
|
||
Layout.topMargin: 5
|
||
Layout.fillWidth: true
|
||
horizontalAlignment: Text.AlignHCenter
|
||
text: root.humEmoji
|
||
font.pointSize: root.fontSize * 2.6
|
||
}
|
||
|
||
// Значения
|
||
PlasmaComponents.Label {
|
||
Layout.fillWidth: true
|
||
horizontalAlignment: Text.AlignHCenter
|
||
text: root.tempValue
|
||
font.pointSize: root.fontSize * 1.6
|
||
font.bold: true
|
||
color: root.textColor
|
||
}
|
||
PlasmaComponents.Label {
|
||
Layout.fillWidth: true
|
||
horizontalAlignment: Text.AlignHCenter
|
||
text: root.humValue
|
||
font.pointSize: root.fontSize * 1.6
|
||
font.bold: true
|
||
color: root.textColor
|
||
}
|
||
|
||
|
||
PlasmaComponents.Label {
|
||
Layout.columnSpan: 2
|
||
Layout.fillWidth: true
|
||
Layout.topMargin: 5 // Небольшой отступ от цифр
|
||
horizontalAlignment: Text.AlignHCenter
|
||
text: "Обновлено: " + root.lastUpdate
|
||
font.pointSize: root.fontSize * 0.6
|
||
opacity: 0.7
|
||
color: root.textColor
|
||
}
|
||
}
|
||
|
||
gradient: Gradient {
|
||
GradientStop {
|
||
position: 0.0
|
||
color: "azure"
|
||
}
|
||
GradientStop {
|
||
position: 0.7
|
||
color: "honeydew"
|
||
}
|
||
GradientStop {
|
||
position: 2.0
|
||
color: "lightgoldenrodyellow"
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// Источник данных для чтения файла
|
||
Plasma5Support.DataSource {
|
||
id: fileProcessor
|
||
engine: "executable"
|
||
connectedSources: []
|
||
onNewData: (source, data) => {
|
||
let stdout = data.stdout ? data.stdout.trim() : "";
|
||
|
||
// ШАГ 1: Проверка размера
|
||
if (source.includes("stat -c%s")) {
|
||
let size = parseInt(stdout) || 0;
|
||
if (size > 1024) {
|
||
fileProcessor.connectSource("> /tmp/arduino_last_run");
|
||
console.log("Критический размер файла! Очистка.");
|
||
} else {
|
||
// Переход к шагу 2
|
||
fileProcessor.connectSource("stat -c%y /tmp/arduino_last_run | awk '{print $2}' | cut -d. -f1");
|
||
}
|
||
}
|
||
// ШАГ 2: Получение времени (ищем формат 00:00:00)
|
||
else if (stdout.match(/^\d{2}:\d{2}:\d{2}$/)) {
|
||
root.lastUpdate = stdout;
|
||
// Переход к шагу 3
|
||
fileProcessor.connectSource("cat /tmp/arduino_last_run");
|
||
}
|
||
// ШАГ 3: Чтение самих данных
|
||
else if (source.includes("cat ")) {
|
||
parseData(stdout);
|
||
}
|
||
|
||
disconnectSource(source);
|
||
}
|
||
}
|
||
|
||
Timer {
|
||
id: refreshTimer
|
||
interval: 5000
|
||
running: true
|
||
repeat: true
|
||
triggeredOnStart: true
|
||
onTriggered: {
|
||
// Запуск цепочки: проверяем размер.
|
||
// Если файла нет, echo 0 предотвратит ошибку DataSource.
|
||
fileProcessor.connectSource("stat -c%s /tmp/arduino_last_run 2>/dev/null || echo 0");
|
||
}
|
||
}
|
||
|
||
function parseData(out) {
|
||
|
||
if (!out) return;
|
||
let m = out.match(/[-+]?[0-9]*\.?[0-9]+/g)
|
||
if (m && m.length >= 2) {
|
||
let t = parseFloat(m[0])
|
||
let h = parseFloat(m[1])
|
||
root.tempValue = t.toFixed(1)
|
||
root.humValue = h.toFixed(1)
|
||
root.tempEmoji = t > 27 ? "🥵" : (t < 22 ? "🥶" : "😊")
|
||
root.humEmoji = h < 40 ? "😮💨" : (h > 60 ? "😶🌫️" : "😊")
|
||
}
|
||
}
|
||
|
||
Plasma5Support.DataSource {
|
||
id: scriptLauncher
|
||
engine: "executable"
|
||
connectedSources: []
|
||
|
||
Component.onCompleted: {
|
||
// В Plasma 6 используем Qt.resolvedUrl для получения пути к текущей папке
|
||
// .replace("file://", "") нужно, так как DataSource ожидает путь к системе, а не URL
|
||
let currentDir = Qt.resolvedUrl(".").toString().replace("file://",
|
||
"")
|
||
let scriptPath = currentDir + "arduino_bridge.sh"
|
||
|
||
if (scriptPath) {
|
||
scriptLauncher.connectSource(`chmod +x ${scriptPath} && ${scriptPath}`)
|
||
}
|
||
}
|
||
}
|
||
}
|