xblax / flashforge_ad5m_klipper_mod

Unoffical mod for Flashforge Adventurer 5M (Pro) 3D printers to run Moonraker, custom Klipper, Mainsail & Fluidd
GNU General Public License v3.0
83 stars 4 forks source link

Shutdown printer #56

Open Tiwatz opened 2 months ago

Tiwatz commented 2 months ago

The power button on the 5M Pro does nothing. When I select "Shutdown" in Mainsail something shuts down but not the entire printer. The printer becomes unresponsive and the LED light, fans etc stays on.

In the original firmware there is an option to enable auto shutdown when printer has been idle for some time (30 min?). Is there a way to implement this?

KaruroChori commented 2 months ago

Most of us initially involved only had the 5m available. It is likely the software power button was never implemented properly.

@consp , @xblax Should it be used just to turn off lights, screen fans, and keep wifi and lan enabled so that it can be resumed remotely? Or should it be used to simply turn it off the screen, since the printer is already silent in idle? A panic button? Or should it pause/resume the current job?

I would be a bit against a full shutdown. If the printer is turned off right after a print is completed, without cooling the nozzle down first, there is a real risk of clogging while using materials like PLA because of the heat creep.

xblax commented 2 months ago

Shutdown in Mainsail just does the same as poweroff on the command line would to.

Pretty sure it can be implemented but someone with the 5M Pro has to reverse engineer how that function works with the stock firmware. There are some hidden pins in the printer config, that I assume are used for this in the stock firmware.

# unclear what the "power" pins do at the moment
# disable them in the UI for now
[gcode_button btn_power]
pin: !PC15
press_gcode:
    M105

[output_pin _power_off]
pin: PC14
value: 1
shutdown_value: 1

[output_pin _clear_power_off]
pin: PG1
value: 0
shutdown_value: 0 

@KaruroChori Afaik Afaik that physical power button on the Pro actually cuts the power (including the PSU). But somebody has to confirm that. Would also be good to know how the power button is wired to the Mainboard.

Could be an interesting upgrade for 5M non pro as well.

KaruroChori commented 2 months ago

Afaik that physical power button on the Pro actually cuts the power (including the PSU).

I have read multiple reports of people complaining about the psu fan noise while putting the printer in stand-by with that button, which is where my assumptions came from.

I have to check the schematics in the research repo of @g992

consp commented 2 months ago

Looking at the PCBs the Pro has a different power connector with a mosfet next to it.

KaruroChori commented 2 months ago

https://github.com/g992/flashforge-ad5m-5mpro-research/blob/main/photo/_5m_full_view_marked.png

On the base model the area marked as 6 is just not populated.

consp commented 2 months ago

On the base model the area marked as 6 is just not populated.

If that's for the power switch, i would really like to know what they switch with it 🤣 it's a lot of stuff for a simple momentary button and software shutdown.

Btw, I ordered a pro. My custom old enclosures hinges broke yesterday and figured might as well replace it with a pro since I do not want to glue everything together again, so I'll be able to test that as well.

g992 commented 2 months ago

On the base model the area marked as 6 is just not populated.

If that's for the power switch, i would really like to know what they switch with it 🤣 it's a lot of stuff for a simple momentary button and software shutdown.

Btw, I ordered a pro. My custom old enclosures hinges broke yesterday and figured might as well replace it with a pro since I do not want to glue everything together again, so I'll be able to test that as well.

This button (like the power button) does not simply turn off the host, but turns off or turns on power to the entire board. she controls this mosfet transistor image

consp commented 2 months ago

This button (like the power button) does not simply turn off the host, but turns off or turns on power to the entire board. she controls this mosfet transistor

Would have been my guess anyway (sarcasm doesn't show well in text), but does it do it via the NC32 chip (and thus klipper), the sunxi chip or is it wired straight through?

g992 commented 2 months ago

This button (like the power button) does not simply turn off the host, but turns off or turns on power to the entire board. she controls this mosfet transistor

Would have been my guess anyway (sarcasm doesn't show well in text), but does it do it via the NC32 chip (and thus klipper), the sunxi chip or is it wired straight through? N32 chip + button. N32 can power off printer in moment, button require long press From 5M PRO config:

[output_pin power_off]
pin: PC14
value: 1
shutdown_value: 1
consp commented 2 months ago

From 5M PRO config:

[output_pin power_off]
pin: PC14
value: 1
shutdown_value: 1

Should be doable to do a partial shutdown (sync, umount usb, shutdown everything which might write except for klipper) and then kill the power if it's controllable from the linux part. Complete proper shutdown would be more difficult if it needs uart to klipper but not impossible. Wonder if it's a latch with multiple inputs or something else entirely, maybe I'm overthinking it.

consp commented 2 months ago

Sending 0 to power_off does a hard shutdown (kills power and psu goes into "low" mode) clear_power_pin doesn't do anything noticable but who knows what it does. Propbably resets something.

I see no real point in exposing the power pins directly though, maybe something like this for start?

[gcode_macro POWER_OFF]
gcode:
    SET_PIN PIN=_power_off VALUE=0

Can be triggered by the power button in that case. Could also make a shutdown script to complete first (sync, umount usb, shutdown all except klipper, kill power)

xblax commented 2 months ago

@consp I would recommend to look in to the stock software with Ghidra to see how they handle the power pins. Or maybe they are only used to read out the physical power button? The physical button might trigger the GCode Button and then the clear pin resets it (but that is just my assumption).

Power pins should not be exposed directly. Via Macro it's also easier to have it only for the 5M Pro. Maybe the macro should not be allowed while printing (look at REBOOT_STOCK_SYSTEM for example).

Sync before shutdown should be enough. I always shutdown the printer by just killing the power. Had no problem with this so far.

consp commented 2 months ago

The doPowerOff function calls SET_PIN PIN=power_off VALUE=0 after some QT magic, probably the "do you want to shutdown yes/no" message.

I would not be surprised if the other pin is just set during boot (at default value) and not used otherwise like the PE1 pin for the runout sensor. Can find no reference to it at least.

There is also a "powerSavingMode" but I cannot make heads or tails of it what it does, doesn't call any macro's at least.

consp commented 2 months ago

So this is the idea:

Add _POWER_OFF gcode, not to be triggered by the user:

[gcode_macro _POWER_OFF]
gcode:
    SET_PIN PIN=_power_off VALUE=0

Add script to stop everything (so it should be graceful, log wise etc) /usr/libexec/shutdown.sh:

#!/bin/sh

# simple shutdown script, kills everything except klipper and then sync, and then shutdown should be send via GCODE pin set

# kill klipperscreen and affliliates
/etc/init.d/S80klipperscreen stop
/etc/init.d/S40xorg stop
/etc/init.d/S35tslib stop
# kill peripherals
/etc/init.d/S75camera stop
/etc/init.d/S45ntpd stop
# kill frontends
/etc/init.d/S65mainsail stop
/etc/init.d/S65fluidd stop
/etc/init.d/S60moonraker stop

sync
for mnt in `cat /proc/mounts | awk '{ print $2 }' | grep '/media'`;
do
    umount $mnt
done
# now we wait ...

And the main course gcode (synchonous is by design):

[gcode_shell_command _STOP_AND_SYNC]
command: /usr/libexec/shutdown.sh
timeout: 60
verbose: False

[gcode_macro SHUTDOWN]
gcode:
    _STOP_AND_SYNC
    SET_PIN PIN=_power_off VALUE=0

And code to trigger via button press, it triggers M105 (report temps):

[gcode_macro M105]
rename_existing: M105.1
gcode:
    SHUTDOWN

Triggering SHUTDOWN should be a "graceful" end of operation.

Todo is a nice fat warning in klipperscreen before commencing but that's for another day as it requires communication.

Let me know if this is desireable. Another question I have if someone knowns if klipper has shutdown guards, e.g. a variable which says "of this is not [something] you cannot shutdown", if it does it should be checked before triggering.

xblax commented 1 month ago

@consp I think the shutdown script can be further improved by iterating over the init scripts, like on normal shutdown: https://github.com/xblax/flashforge_adm5_klipper_mod/blob/master/build_overlay/common/etc/init.d/rcK (just skip the klipper script). Then it's more universal, if more or other scripts are added in the future.

We can also make the Macro compatible with the regular 5M, by issuing poweroff after setting the pin.

I think the warning can be done similar to the exiting Reboot macros. Or does that not work with klipperscreen?

consp commented 1 month ago

Then it's more universal, if more or other scripts are added in the future.

Probably better yes, was my initial thought as well but I had some issues with it ignoring the ignoring of the klipper shutdown. So this was a first attempt.

We can also make the Macro compatible with the regular 5M, by issuing poweroff after setting the pin.

Good point, that should work universally since the power is off anyway for the pro. User must still disable it then for the non-pro. Can also send an image to the FB, should be on display until power off, like the infamous windows 95 "it's safe to turn off your computer now".

I think the warning can be done similar to the exiting Reboot macros. Or does that not work with klipperscreen?

I must confess I have not looked into it yet. You mean the (firmware) restart macros? I know notifications show up but not interactive messages.

xblax commented 1 month ago

I must confess I have not looked into it yet. You mean the (firmware) restart macros? I know notifications show up but not interactive messages.

Should be interactive confirm, but have not tried it in Klipperscreen. Can do it tonight.

We can also make the Macro compatible with the regular 5M, by issuing poweroff after setting the pin.

Good point, that should work universally since the power is off anyway for the pro. User must still disable it then for the non-pro. Can also send an image to the FB, should be on display until power off, like the infamous windows 95 "it's safe to turn off your computer now".

On second though, regular 5M already has safe shutdown via the default Shutdown menu in Mainsail/Fluidd. That triggers "systemctl poweroff" command via Moonraker (afaik not a Klipper Macro).

We can just add the "safe to turn off" now as S00shutdown_screen script init init.d

consp commented 1 month ago

No message is displayed in klipperscreen (bit as expected). It's an internal mainsail/fluidd thing.

xblax commented 1 month ago

No message is displayed in klipperscreen (bit as expected). It's an internal mainsail/fluidd thing.

But KlipperScreen Docs say it supports Macro Prompts: https://github.com/xblax/flashforge_adm5_klipper_mod/issues/56#issuecomment-2013165735 Maybe used something incompatible.

consp commented 1 month ago

No message is displayed in klipperscreen (bit as expected). It's an internal mainsail/fluidd thing.

But KlipperScreen Docs say it supports Macro Prompts: #56 (comment) Maybe used something incompatible.

Yes, figured that out while you posted:

[gcode_macro SHUTDOWN]
gcode:
    RESPOND TYPE=command MSG="action:prompt_begin Question"
    RESPOND TYPE=command MSG="action:prompt_text Klipper Mod will shutdown. This will end any active prints. Are you sure?"
    RESPOND TYPE=command MSG="action:prompt_footer_button Abort|RESPOND TYPE=command MSG=action:prompt_end"
    RESPOND TYPE=command MSG="action:prompt_footer_button Shutdown|_SHUTDOWN_STAGE|error"
    RESPOND TYPE=command MSG="action:prompt_show"

Shows the prompt.

consp commented 1 month ago

Version now ask the question, shuts down all except klipper, sync and umounts and then either does "systemctl poweroff" or kills the power. Last thing to do is the shutdown message.

Also responds to button with the same question and effect.

Tweaking it a little bit and then I'll push a feature branch.

consp commented 1 month ago

Pushed to https://github.com/xblax/flashforge_adm5_klipper_mod/tree/feature/shutdown

The shutdown in mainsail/fluidd does not trigger it (for now), only the macro.

consp commented 1 month ago

After a klipper reset it triggers the shutdown (just the warning message), I wonder if the default state of the button is messing about.

fixed in e7e3287dd8c2368b0de977db85e07d1efe2f0930

The button must be reset (which was kind of obvious by the name of the second button pin) after pressing. It might also trigger 0-2 times during reset which is avoided by delaying the availability of the command by one second.

xblax commented 1 month ago

Ah, I also run in that issue when testing it yesterday. Thought it was caused by by the M105 being called from Moonraker/Mainsail on start but didn't have time to test that assumption.

I think it's not the best idea to repurpose the M105. Is there any reason why it can't be a Macro like _SHUTDOWN_BUTTON_TRIGGER ?

consp commented 1 month ago

I think it's not the best idea to repurpose the M105. Is there any reason why it can't be a Macro like

No reason, just sticked to the original firmware. Since we modify the printer.cfg anyway there is no reason not to change it.

Changed it in the feature branch. Also fixed the prompt staying up in fluidd.

xblax commented 1 month ago

Pushed this to master now.

Noticed the shutdown image is missing, but can add this when I also improve the wording of the installation screen, unless you have already prepared one.

consp commented 1 month ago

Pushed this to master now.

Noticed the shutdown image is missing, but can add this when I also improve the wording of the installation screen, unless you have already prepared one.

Made one, it's in the images dir (mod_shutdown.png), thought they were autogenerated, apperantly not :)

b81705a

xblax commented 1 month ago

Added it to master. The shutdown screen is working semi-well because it's only displayed briefly. Reason for that is that the screen is turned off on shutdown.

Tried to manually unbind the driver, but has the same effect: echo "5000000.disp" > /sys/class/graphics/fb0/device/driver/unbind

But it's not critical, unless someone has an idea how to avoid it.

consp commented 1 month ago

I guess it's hardcoded in the display driver module. Since it's baked into the kernel I don't really see a way of working around it.

Tiwatz commented 1 month ago

There probably is a better way to do a auto shutdown feature but I found this https://github.com/tinntbg/auto-power-off-klipper and then made some small changes to work with this version.

Would be nice to have something like a toggle button in KlipperScreen to enable/disable auto shutdown.

Add to Machine end g-code: AUTO_SHUTDOWN

Add to macros.cfg:

[gcode_macro AUTO_SHUTDOWN]
gcode:
  UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=30

[delayed_gcode AUTO_SHUTDOWN_CHECK]
gcode:
  {% if printer.idle_timeout.state == "Idle" or printer.idle_timeout.state == "Ready" %}
    {% if printer.extruder.temperature < 50.0 and printer.heater_bed.temperature < 50.0 %}
        {% if printer.extruder.target == 0.0 and printer.heater_bed.target == 0.0 %}
            UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=0
            _SHUTDOWN_STAGE
        {% else %}
            UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=2
        {% endif %}
    {% else %}
        {% if printer.idle_timeout.state == "Printing" %}
            UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=0
        {% else %}
            {% if printer.extruder.target == 0.0 and printer.heater_bed.target == 0.0 %}
                UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=2
            {% else %}
                UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=0
            {% endif %}
        {% endif %}
    {% endif %}
  {% endif %}
consp commented 1 month ago

Would be nice to have something like a toggle button in KlipperScreen to enable/disable auto shutdown.

That would be custom code, if you have any good suggestions how to do this they are welcome. Maybe it can be done by firing a macro which sets a variable/flag (see the delayed "enabling" of the shutdown gcode). Adding the configuration variable is quite easy fortunately.

consp commented 1 month ago

Add to macros.cfg:

This is only needed for a "wait for print, cooldown and then shutdown" if I understand it correctly?

Tiwatz commented 1 month ago

This is only needed for a "wait for print, cooldown and then shutdown" if I understand it correctly?

That is how I understand it also :)

consp commented 1 month ago

Would be nice to have something like a toggle button in KlipperScreen to enable/disable auto shutdown.

I've been looking at it and I think it's better to add it to your slicer config. I do not think it is cancelable and that would give the wrong impression with a toggle switch. Unless it is but I do not know how at the moment.

Macro has been added at least.

Tiwatz commented 1 month ago

Is it possible to do a "wake on lan" feature?

consp commented 1 month ago

Is it possible to do a "wake on lan" feature?

get_wol and set_wol are not implemented in the "SUNXI Gbgit driver" (spelling mistake not mine) so my guess is no or there must be a low level workaround somewhere. I'd say get a home-automation relay to turn it on/off si the easiest way (which is what I use).

consp commented 1 month ago

The following features are either included, are on the master branch or are on the feature branch of the specific variant:

Am I missing something? Is there something else still needed?

For the auto shutdown switch: If someone can guide me to how to cancel a macro it's probably doable to add a switch somewhere in the gui(s) but I'm hesitant to include it if it's not possible.

Tiwatz commented 1 month ago

For the auto shutdown switch: If someone can guide me to how to cancel a macro it's probably doable to add a switch somewhere in the gui(s) but I'm hesitant to include it if it's not possible.

I've updated the macros so I can cancel the auto shutdown but I'm not really pleased of how everything works. For example if some other macro is executed after the ACTIVATE_AUTO_SHUTDOWN the macro is canceled but there is no info to the user that it has been canceled.

[delayed_gcode AUTO_SHUTDOWN_CHECK]
gcode:
  {% if printer.idle_timeout.state == "Idle" or printer.idle_timeout.state == "Ready" %}
    {% if printer.extruder.temperature < 50.0 and printer.heater_bed.temperature < 50.0 %}
        {% if printer.extruder.target == 0.0 and printer.heater_bed.target == 0.0 %}
            UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=0
            _SHUTDOWN_STAGE
        {% else %}
            UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=2
        {% endif %}
    {% else %}
        {% if printer.idle_timeout.state == "Printing" %}
            UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=0
        {% else %}
            {% if printer.extruder.target == 0.0 and printer.heater_bed.target == 0.0 %}
                UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=2
            {% else %}
                UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=0
            {% endif %}
        {% endif %}
    {% endif %}
  {% endif %}

[gcode_macro ACTIVATE_AUTO_SHUTDOWN]
gcode:
    UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=60
    RESPOND TYPE=echo MSG="Auto Shutdown Activated"

[gcode_macro DEACTIVATE_AUTO_SHUTDOWN]
gcode:
    UPDATE_DELAYED_GCODE ID=AUTO_SHUTDOWN_CHECK DURATION=0
    RESPOND TYPE=echo MSG="Auto Shutdown Deactivated"
consp commented 1 month ago

I'm not that well versed into klipper macro's, someone else will definetly have to look into this 😅 looks like a possible race condition