188 lines
7.6 KiB
JavaScript
188 lines
7.6 KiB
JavaScript
const Desklet = imports.ui.desklet;
|
|
const St = imports.gi.St;
|
|
const GLib = imports.gi.GLib;
|
|
const Mainloop = imports.mainloop;
|
|
const Settings = imports.ui.settings;
|
|
const Gio = imports.gi.Gio;
|
|
|
|
function MyDesklet(metadata, desklet_id) {
|
|
this._init(metadata, desklet_id);
|
|
}
|
|
|
|
MyDesklet.prototype = {
|
|
__proto__: Desklet.Desklet.prototype,
|
|
|
|
_init: function(metadata, desklet_id) {
|
|
try {
|
|
Desklet.Desklet.prototype._init.call(this, metadata, desklet_id);
|
|
|
|
this.settings = new Settings.DeskletSettings(this, this.metadata.uuid, desklet_id);
|
|
this.settings.bindProperty(Settings.BindingDirection.IN, "font-size", "fontSize", this._onSettingsChanged, null);
|
|
this.settings.bindProperty(Settings.BindingDirection.IN, "custom-color", "customColor", this._onSettingsChanged, null);
|
|
this.settings.bindProperty(Settings.BindingDirection.IN, "use-custom-color", "useCustomColor", this._onSettingsChanged, null);
|
|
|
|
// Главный контейнер
|
|
this.container = new St.BoxLayout({
|
|
style_class: "desklet-with-borders",
|
|
vertical: true,
|
|
style: "padding: 20px; border-radius: 15px; text-align: center; min-width: 250px;"
|
|
});
|
|
|
|
// Горизонтальный контейнер для двух колонок
|
|
this.contentBox = new St.BoxLayout({ vertical: false });
|
|
|
|
// Колонка Температуры
|
|
this.tempBox = new St.BoxLayout({ vertical: true, style: "margin: 0 15px;" });
|
|
this.labelT = new St.Label({ text: "Температура, °C" });
|
|
this.emojiT = new St.Label({ text: "⏳" });
|
|
this.valT = new St.Label({ text: "00.0" });
|
|
this.tempBox.add_actor(this.labelT);
|
|
this.tempBox.add_actor(this.emojiT);
|
|
this.tempBox.add_actor(this.valT);
|
|
|
|
// Колонка Влажности
|
|
this.humBox = new St.BoxLayout({ vertical: true, style: "margin: 0 15px;" });
|
|
this.labelH = new St.Label({ text: "Влажность, %" });
|
|
this.emojiH = new St.Label({ text: "⏳" });
|
|
this.valH = new St.Label({ text: "00.0" });
|
|
this.humBox.add_actor(this.labelH);
|
|
this.humBox.add_actor(this.emojiH);
|
|
this.humBox.add_actor(this.valH);
|
|
|
|
this.contentBox.add_actor(this.tempBox);
|
|
this.contentBox.add_actor(this.humBox);
|
|
|
|
// Статус внизу
|
|
this.updateLabel = new St.Label({
|
|
text: "Запуск системы...",
|
|
style: "margin-top: 15px; font-size: 0.8em; opacity: 0.6;"
|
|
});
|
|
|
|
this.container.add_actor(this.contentBox);
|
|
this.container.add_actor(this.updateLabel);
|
|
this.setContent(this.container);
|
|
|
|
this._onSettingsChanged();
|
|
|
|
// Запуск чтения через 2 секунды
|
|
Mainloop.timeout_add_seconds(2, () => {
|
|
this._initArduinoRead();
|
|
return false;
|
|
});
|
|
|
|
} catch (e) {
|
|
global.logError(e);
|
|
}
|
|
},
|
|
|
|
_onSettingsChanged: function() {
|
|
let fs = this.fontSize || 12;
|
|
let color = this.useCustomColor ? this.customColor : "#ffffff";
|
|
|
|
let headerStyle = "color: " + color + "; font-size: " + (fs * 0.9) + "pt; opacity: 0.8;";
|
|
let emojiStyle = "font-size: " + (fs * 2.1) + "pt; margin: 0 0;";
|
|
let valueStyle = "color: " + color + "; font-weight: bold; font-size: " + (fs * 1.4) + "pt;";
|
|
|
|
this.labelT.set_style(headerStyle);
|
|
this.labelH.set_style(headerStyle);
|
|
this.emojiT.set_style(emojiStyle);
|
|
this.emojiH.set_style(emojiStyle);
|
|
this.valT.set_style(valueStyle);
|
|
this.valH.set_style(valueStyle);
|
|
this.updateLabel.set_style("color: " + color + "; font-size: " + (fs * 0.7) + "pt;");
|
|
},
|
|
|
|
_initArduinoRead: function() {
|
|
this.arduinoPath = "/dev/arduino";
|
|
|
|
if (this.dataStream) {
|
|
try { this.dataStream.close(null); } catch (e) {}
|
|
this.dataStream = null;
|
|
}
|
|
|
|
if (!GLib.file_test(this.arduinoPath, GLib.FileTest.EXISTS)) {
|
|
this.updateLabel.set_text("Порт /dev/arduino не найден");
|
|
Mainloop.timeout_add_seconds(5, () => this._initArduinoRead());
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Настройка порта
|
|
GLib.spawn_command_line_sync("stty -F " + this.arduinoPath + " 9600 raw -echo -icanon hupcl");
|
|
|
|
let file = Gio.File.new_for_path(this.arduinoPath);
|
|
file.read_async(GLib.PRIORITY_LOW, null, (source, res) => {
|
|
try {
|
|
let inputStream = source.read_finish(res);
|
|
this.dataStream = new Gio.DataInputStream({ base_stream: inputStream });
|
|
this.updateLabel.set_text("Подключено. Ожидание данных...");
|
|
this._readNext();
|
|
} catch (e) {
|
|
this.updateLabel.set_text("Ошибка открытия потока");
|
|
Mainloop.timeout_add_seconds(5, () => this._initArduinoRead());
|
|
}
|
|
});
|
|
} catch (e) {
|
|
this.updateLabel.set_text("Ошибка stty");
|
|
Mainloop.timeout_add_seconds(5, () => this._initArduinoRead());
|
|
}
|
|
},
|
|
|
|
_readNext: function() {
|
|
if (!this.dataStream) return;
|
|
this.dataStream.read_line_async(GLib.PRIORITY_LOW, null, (source, res) => {
|
|
try {
|
|
let [line, length] = source.read_line_finish(res);
|
|
if (line !== null) {
|
|
let text = line.toString().trim();
|
|
let matches = text.match(/[-+]?[0-9]*\.?[0-9]+/g);
|
|
|
|
if (matches && matches.length >= 2) {
|
|
let t = parseFloat(matches[0]);
|
|
let h = parseFloat(matches[1]);
|
|
let now = GLib.DateTime.new_now_local();
|
|
|
|
this.valT.set_text(t.toFixed(1));
|
|
this.valH.set_text(h.toFixed(1));
|
|
|
|
// Логика для Температуры
|
|
if (t > 27) {
|
|
this.emojiT.set_text("🥵");
|
|
} else if (t < 22) {
|
|
this.emojiT.set_text("🥶");
|
|
} else {
|
|
this.emojiT.set_text("😊");
|
|
}
|
|
|
|
// Логика для Влажности
|
|
if (h < 40) {
|
|
this.emojiH.set_text("😮💨");
|
|
} else if (h > 60) {
|
|
this.emojiH.set_text("😶🌫️");
|
|
} else {
|
|
this.emojiH.set_text("😊");
|
|
}
|
|
|
|
this.updateLabel.set_text("Обновлено: " + now.format("%H:%M:%S"));
|
|
}
|
|
}
|
|
this._readNext();
|
|
} catch (e) {
|
|
this.updateLabel.set_text("Переподключение...");
|
|
Mainloop.timeout_add_seconds(2, () => this._initArduinoRead());
|
|
}
|
|
});
|
|
},
|
|
|
|
on_desklet_removed: function() {
|
|
if (this.dataStream) {
|
|
try { this.dataStream.close(null); } catch (e) {}
|
|
}
|
|
this.settings.finalize();
|
|
}
|
|
}
|
|
|
|
function main(metadata, desklet_id) {
|
|
return new MyDesklet(metadata, desklet_id);
|
|
}
|