Add power panel

This commit is contained in:
Jordan Ruthe 2020-11-28 14:00:26 -05:00
parent 48c276d22f
commit cc59ec68d0
8 changed files with 198 additions and 2 deletions

View File

@ -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.

View File

@ -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

View File

@ -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(

View File

@ -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:

View File

@ -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
View 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)

View File

@ -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()

View File

@ -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)