Add power panel
This commit is contained in:
parent
48c276d22f
commit
cc59ec68d0
@ -2,6 +2,7 @@
|
||||
|
||||
#### 2020 11 28
|
||||
* Add option for enable in menu for configuration. This can hide certain options
|
||||
* Add Power panel to control power devices via moonraker
|
||||
|
||||
#### 2020 11 18
|
||||
* Changed configuration file format.
|
||||
|
@ -80,6 +80,12 @@ name: Temperature
|
||||
icon: heat-up
|
||||
panel: temperature
|
||||
|
||||
[menu __main actions power]
|
||||
name: Power
|
||||
icon: shutdown
|
||||
panel: power
|
||||
enable: {{ printer.power_devices.count > 0 }}
|
||||
|
||||
[menu __main actions disablemotors]
|
||||
name: Disable Motors
|
||||
icon: motor-off
|
||||
|
@ -202,6 +202,24 @@ class MoonrakerApi:
|
||||
updates
|
||||
)
|
||||
|
||||
def power_device_off(self, device, callback=None, *args):
|
||||
logger.debug("Sending machine.device_power.off: %s" % device)
|
||||
return self._ws.send_method(
|
||||
"machine.device_power.off",
|
||||
{device: False},
|
||||
callback,
|
||||
*args
|
||||
)
|
||||
|
||||
def power_device_on(self, device, callback=None, *args):
|
||||
logger.debug("Sending machine.device_power.on %s" % device)
|
||||
return self._ws.send_method(
|
||||
"machine.device_power.on",
|
||||
{device: False},
|
||||
callback,
|
||||
*args
|
||||
)
|
||||
|
||||
def print_cancel(self, callback=None, *args):
|
||||
logger.debug("Sending printer.print.cancel")
|
||||
return self._ws.send_method(
|
||||
|
@ -67,6 +67,9 @@ class KlipperScreenConfig:
|
||||
|
||||
return preheat_options
|
||||
|
||||
def get_printer_power_name(self):
|
||||
return self.config['settings'].get("printer_power_name", "printer")
|
||||
|
||||
|
||||
def log_config(self, config):
|
||||
lines = [
|
||||
@ -94,7 +97,8 @@ class KlipperScreenConfig:
|
||||
"icon": cfg.get("icon"),
|
||||
"panel": cfg.get("panel", False),
|
||||
"method": cfg.get("method", False),
|
||||
"confirm": cfg.get("confirm", False)
|
||||
"confirm": cfg.get("confirm", False),
|
||||
"enable": cfg.get("enable", True)
|
||||
}
|
||||
|
||||
try:
|
||||
|
@ -1,5 +1,7 @@
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("KlipperScreen.Printer")
|
||||
|
||||
class Printer:
|
||||
|
||||
def __init__(self, data):
|
||||
@ -12,6 +14,7 @@ class Printer:
|
||||
self.devices = {}
|
||||
self.state = data['print_stats']['state']
|
||||
self.data = data
|
||||
self.power_devices = {}
|
||||
|
||||
for x in self.config.keys():
|
||||
if x.startswith('extruder'):
|
||||
@ -36,6 +39,17 @@ class Printer:
|
||||
|
||||
logging.info("### Toolcount: " + str(self.toolcount) + " Heaters: " + str(self.extrudercount))
|
||||
|
||||
def configure_power_devices(self, data):
|
||||
self.power_devices = {}
|
||||
|
||||
logger.debug("Processing power devices: %s" % data)
|
||||
for x in data['devices']:
|
||||
logger.debug(x)
|
||||
self.power_devices[x['device']] = {
|
||||
"status": "on" if x['status'] == "on" else "off"
|
||||
}
|
||||
logger.debug("Power devices: %s" % self.power_devices)
|
||||
|
||||
def process_update(self, data):
|
||||
keys = ['virtual_sdcard','pause_resume','idle_timeout','print_stats']
|
||||
keys = ['fan','gcode_move','idle_timeout','pause_resume','print_stats','toolhead','virtual_sdcard']
|
||||
@ -61,6 +75,10 @@ class Printer:
|
||||
if "temperature" in d:
|
||||
self.set_dev_stat(x, "temperature", d["temperature"])
|
||||
|
||||
def process_power_update(self, data):
|
||||
if data['device'] in self.power_devices:
|
||||
self.power_devices[data['device']]['status'] = data['status']
|
||||
|
||||
def get_config_section_list(self):
|
||||
return list(self.config)
|
||||
|
||||
@ -72,6 +90,14 @@ class Printer:
|
||||
def get_data(self):
|
||||
return self.data
|
||||
|
||||
def get_power_devices(self):
|
||||
return list(self.power_devices)
|
||||
|
||||
def get_power_device_status(self, device):
|
||||
if device not in self.power_devices:
|
||||
return
|
||||
return self.power_devices[device]['status']
|
||||
|
||||
def get_stat(self, stat, substat = None):
|
||||
if substat != None:
|
||||
return self.data[stat][substat]
|
||||
|
122
panels/power.py
Normal file
122
panels/power.py
Normal file
@ -0,0 +1,122 @@
|
||||
import gi
|
||||
import logging
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib, Pango
|
||||
|
||||
from ks_includes.KlippyGtk import KlippyGtk
|
||||
from ks_includes.KlippyGcodes import KlippyGcodes
|
||||
from ks_includes.screen_panel import ScreenPanel
|
||||
|
||||
logger = logging.getLogger("KlipperScreen.PowerPanel")
|
||||
|
||||
def create_panel(*args):
|
||||
return PowerPanel(*args)
|
||||
|
||||
class PowerPanel(ScreenPanel):
|
||||
def initialize(self, panel_name):
|
||||
_ = self.lang.gettext
|
||||
self.devices = {}
|
||||
|
||||
# Create bottom bar
|
||||
bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
bar.set_hexpand(True)
|
||||
bar.set_vexpand(False)
|
||||
bar.set_halign(Gtk.Align.END)
|
||||
bar.set_margin_top(5)
|
||||
bar.set_margin_bottom(5)
|
||||
bar.set_margin_end(5)
|
||||
|
||||
# Add a back button to the bottom bar
|
||||
back = KlippyGtk.ButtonImage('back', None, None, 60, 60)
|
||||
back.connect("clicked", self._screen._menu_go_back)
|
||||
bar.add(back)
|
||||
|
||||
# Create a scroll window for the power devices
|
||||
scroll = Gtk.ScrolledWindow()
|
||||
scroll.set_property("overlay-scrolling", False)
|
||||
scroll.set_vexpand(True)
|
||||
|
||||
# Create a grid for all devices
|
||||
self.labels['devices'] = Gtk.Grid()
|
||||
scroll.add(self.labels['devices'])
|
||||
|
||||
# Create a box to contain all of the above
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
box.set_vexpand(True)
|
||||
box.pack_start(scroll, True, True, 0)
|
||||
box.pack_end(bar, False, False, 0)
|
||||
|
||||
self.load_power_devices()
|
||||
|
||||
self.panel = box
|
||||
self._screen.add_subscription(panel_name)
|
||||
|
||||
def add_device(self, device):
|
||||
|
||||
frame = Gtk.Frame()
|
||||
frame.set_property("shadow-type",Gtk.ShadowType.NONE)
|
||||
|
||||
name = Gtk.Label()
|
||||
name.set_markup("<big><b>%s</b></big>" % (device))
|
||||
name.set_hexpand(True)
|
||||
name.set_halign(Gtk.Align.START)
|
||||
name.set_line_wrap(True)
|
||||
name.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
|
||||
|
||||
switch = Gtk.Switch()
|
||||
switch.set_hexpand(False)
|
||||
switch.set_active(True if self._screen.printer.get_power_device_status(device) == "on" else False)
|
||||
switch.connect("notify::active", self.on_switch, device)
|
||||
switch.set_property("width-request", 150)
|
||||
switch.set_property("height-request", 80)
|
||||
|
||||
labels = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
labels.add(name)
|
||||
|
||||
dev = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
||||
dev.set_margin_top(10)
|
||||
dev.set_margin_end(15)
|
||||
dev.set_margin_start(15)
|
||||
dev.set_margin_bottom(10)
|
||||
dev.set_hexpand(True)
|
||||
dev.set_vexpand(False)
|
||||
|
||||
dev.add(labels)
|
||||
dev.add(switch)
|
||||
frame.add(dev)
|
||||
|
||||
self.devices[device] = {
|
||||
"row": frame,
|
||||
"switch": switch
|
||||
}
|
||||
|
||||
devices = sorted(self.devices)
|
||||
pos = devices.index(device)
|
||||
|
||||
self.labels['devices'].insert_row(pos)
|
||||
self.labels['devices'].attach(self.devices[device]['row'], 0, pos, 1, 1)
|
||||
self.labels['devices'].show_all()
|
||||
|
||||
def load_power_devices(self):
|
||||
devices = self._screen.printer.get_power_devices()
|
||||
for x in devices:
|
||||
self.add_device(x)
|
||||
|
||||
def on_switch(self, switch, gparam, device):
|
||||
logger.debug("Power toggled %s" % device)
|
||||
if switch.get_active():
|
||||
self._screen._ws.klippy.power_device_on(device)
|
||||
else:
|
||||
self._screen._ws.klippy.power_device_off(device)
|
||||
|
||||
def process_update(self, action, data):
|
||||
if action != "notify_power_changed":
|
||||
return
|
||||
|
||||
if data['device'] not in self.devices:
|
||||
return
|
||||
device = data['device']
|
||||
self.devices[device]['switch'].disconnect_by_func(self.on_switch)
|
||||
self.devices[device]['switch'].set_active(True if data['status'] == "on" else False)
|
||||
self.devices[device]['switch'].connect("notify::active", self.on_switch, device)
|
@ -3,7 +3,7 @@ import logging
|
||||
import os
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
from gi.repository import Gtk, Gdk, GLib, Pango
|
||||
|
||||
from ks_includes.KlippyGtk import KlippyGtk
|
||||
from ks_includes.screen_panel import ScreenPanel
|
||||
@ -25,6 +25,8 @@ class SplashScreenPanel(ScreenPanel):
|
||||
|
||||
self.labels['text'] = Gtk.Label(_("Initializing printer..."))
|
||||
self.labels['text'].get_style_context().add_class("text")
|
||||
self.labels['text'].set_line_wrap(True)
|
||||
self.labels['text'].set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
|
||||
|
||||
|
||||
self.labels['actions'] = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
@ -57,6 +59,7 @@ class SplashScreenPanel(ScreenPanel):
|
||||
_ = self.lang.gettext
|
||||
|
||||
if "firmware_restart" not in self.labels:
|
||||
self.labels['power'] = KlippyGtk.ButtonImage("reboot",_("Power On Printer"),"color3")
|
||||
self.labels['restart'] = KlippyGtk.ButtonImage("reboot",_("Restart"),"color1")
|
||||
self.labels['restart'].connect("clicked", self.restart)
|
||||
self.labels['firmware_restart'] = KlippyGtk.ButtonImage("restart",_("Firmware Restart"),"color2")
|
||||
@ -64,11 +67,22 @@ class SplashScreenPanel(ScreenPanel):
|
||||
|
||||
self.clear_action_bar()
|
||||
|
||||
devices = [i for i in self._screen.printer.get_power_devices() if i.lower().startswith('printer')]
|
||||
logger.debug("Power devices: %s" % devices)
|
||||
if len(devices) > 0:
|
||||
logger.debug("Adding power button")
|
||||
self.labels['power'].connect("clicked", self.power_on, devices[0])
|
||||
self.labels['actions'].add(self.labels['power'])
|
||||
|
||||
self.labels['actions'].add(self.labels['power'])
|
||||
self.labels['actions'].add(self.labels['restart'])
|
||||
self.labels['actions'].add(self.labels['firmware_restart'])
|
||||
|
||||
def firmware_restart(self, widget):
|
||||
self._screen._ws.klippy.restart_firmware()
|
||||
|
||||
def power_on(self, widget, device):
|
||||
self._screen._ws.klippy.power_device_on(device)
|
||||
|
||||
def restart(self, widget):
|
||||
self._screen._ws.klippy.restart()
|
||||
|
@ -320,6 +320,9 @@ class KlipperScreen(Gtk.Window):
|
||||
#self.files.add_file()
|
||||
elif action == "notify_metadata_update":
|
||||
self.files.update_metadata(data['filename'])
|
||||
elif action == "notify_power_changed":
|
||||
logger.debug("Power status changed: %s", data)
|
||||
self.printer.process_power_update(data)
|
||||
elif self.shutdown == False and action == "notify_gcode_response":
|
||||
if "Klipper state: Shutdown" in data:
|
||||
self.shutdown == True
|
||||
@ -384,6 +387,7 @@ class KlipperScreen(Gtk.Window):
|
||||
]
|
||||
info = self.apiclient.get_printer_info()
|
||||
data = self.apiclient.send_request("printer/objects/query?" + "&".join(status_objects))
|
||||
powerdevs = self.apiclient.send_request("machine/device_power/devices")
|
||||
if info == False or data == False:
|
||||
self.printer_initializing(_("Moonraker error"))
|
||||
return
|
||||
@ -392,6 +396,7 @@ class KlipperScreen(Gtk.Window):
|
||||
# Reinitialize printer, in case the printer was shut down and anything has changed.
|
||||
self.printer.__init__(data)
|
||||
self.ws_subscribe()
|
||||
self.printer.configure_power_devices(powerdevs['result'])
|
||||
|
||||
if self.files == None:
|
||||
self.files = KlippyFiles(self)
|
||||
|
Loading…
x
Reference in New Issue
Block a user