Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
c32de8e
Resolve Pause Loop
Jul 2, 2018
a4ed2e7
update and version renaming
Floyz Jul 2, 2018
99c2f5c
Updating plugin URL
Floyz Jul 2, 2018
76495cb
testing better logs
Floyz Jul 2, 2018
372de77
correcting global variable
Floyz Jul 2, 2018
64dafec
Correcting a noob fail
Jul 3, 2018
868d6c9
correcting some indentation errors
Floyz Jul 3, 2018
43ed950
adding debug logs
Floyz Jul 3, 2018
0a8a3b0
versionning change
Floyz Jul 3, 2018
36c675c
more debug logs
Floyz Jul 4, 2018
8b49ecf
some more logs
Floyz Jul 4, 2018
6b7d413
Init navbar elements
Floyz Jul 7, 2018
2f18800
-
Floyz Jul 7, 2018
d89f00f
Start of navbar implementation
Floyz Jul 8, 2018
20699e6
Test Navbar Icon
Floyz Jul 8, 2018
49030d3
tests without gpio
Floyz Jul 9, 2018
597864b
-
Floyz Jul 9, 2018
0ebd2d1
-
Floyz Jul 9, 2018
c2532e7
-
Floyz Jul 9, 2018
4fa3454
-
Floyz Jul 9, 2018
821e92c
better js/css/html integration.
Jul 9, 2018
fdc207b
Merge pull request #1 from Floyz/Dev-Web
Floyz Jul 9, 2018
51c3cfa
reactivate gpio
Floyz Jul 10, 2018
54f6b52
- first message implementation
Floyz Jul 10, 2018
f069882
first message implementation
Floyz Jul 10, 2018
187537a
adding web icon to show cable status
Floyz Jul 11, 2018
42adf86
corecting js bug
Floyz Jul 11, 2018
5453af9
-
Floyz Jul 11, 2018
8a1f875
-
Floyz Jul 11, 2018
56d4811
-
Floyz Jul 11, 2018
816f44b
-
Floyz Jul 11, 2018
b1e24a7
better monitoring of filament status change
Floyz Jul 12, 2018
1da9b68
adding navbar checkrate in the settings
Floyz Jul 12, 2018
9342c6a
-
Floyz Jul 12, 2018
f21eb09
-
Floyz Jul 12, 2018
4afe54b
save bug
Floyz Jul 12, 2018
f49fddc
-
Floyz Jul 12, 2018
4407085
testing thread changes
Floyz Jul 12, 2018
52258a1
-
Floyz Jul 12, 2018
a5c35f1
-
Floyz Jul 12, 2018
4765c64
-
Floyz Jul 12, 2018
7fafeab
Bug Fix - Adding filament after resuming print works
draagc May 20, 2019
a50bc35
Added option to prevent printing if no filament detected
draagc May 20, 2019
97d36f6
Removed unnecessary logging
draagc May 21, 2019
05a96ac
Update __init__.py
simon-adriaanse Aug 28, 2019
185419d
Update __init__.py
simon-adriaanse Aug 28, 2019
ae2edf8
added pullup resistor setting
simon-adriaanse Aug 28, 2019
a010b97
Adding test to prevent SegFault errors
ShadowNinja May 12, 2020
a562195
naming bug
ShadowNinja May 12, 2020
ca5f199
typos
ShadowNinja May 12, 2020
95bc597
more indent issues...
ShadowNinja May 12, 2020
9023789
Workable version
ShadowNinja May 12, 2020
8973f68
Update README.md
mrseeker Jul 24, 2020
6b6bace
Update README.md
mrseeker Jul 24, 2020
a52cc8e
Revert "Update README.md"
ssorgatem Sep 23, 2020
9a7c065
Revert "Update README.md"
ssorgatem Sep 23, 2020
a3b3773
Revert "typos"
ssorgatem Sep 23, 2020
49a5637
Revert "naming bug"
ssorgatem Sep 23, 2020
cd7ecba
undo renaming
ssorgatem Sep 23, 2020
3ec916b
Merge branch 'master' of github.com:draagc/Octoprint-Filament-Reloade…
ssorgatem Sep 23, 2020
ca2adfa
code reformatting
ssorgatem Sep 23, 2020
2f4c3c2
make Python3-compatible
ssorgatem Sep 23, 2020
84135b9
renamed repo
ssorgatem Sep 23, 2020
e9f8148
fixed url
ssorgatem Sep 23, 2020
f07b2ae
fixed url in readme
ssorgatem Sep 23, 2020
621e8aa
hopefully finally undo the renaming
ssorgatem Sep 23, 2020
94327f6
fix formatting
ssorgatem Sep 23, 2020
f169150
fix formatting mess
ssorgatem Sep 23, 2020
89a9e86
Revert "fix formatting"
ssorgatem Sep 23, 2020
eb93777
Revert "fix formatting mess"
ssorgatem Sep 23, 2020
952558a
Revert "hopefully finally undo the renaming"
ssorgatem Sep 23, 2020
e3410ca
Revert "code reformatting"
ssorgatem Sep 23, 2020
ed43bfd
Revert "Merge branch 'master' of github.com:draagc/Octoprint-Filament…
ssorgatem Sep 23, 2020
31c7ebd
hopefully finally undo the renaming
ssorgatem Sep 23, 2020
9fd120a
update repo info
ssorgatem Sep 23, 2020
1cbe62c
fix missing parenthesis
ssorgatem Sep 23, 2020
198d851
Bug Fix - Adding filament after resuming print works
draagc May 20, 2019
29d064e
Removed unnecessary logging
draagc May 21, 2019
4c9879c
Added option to prevent printing if no filament detected
draagc May 20, 2019
4769edf
Merge branch 'master' of https://github.com/simon-adriaanse/Octoprint…
ssorgatem Sep 24, 2020
681bc9a
Merge branch 'simon-adriaanse-master' into master
ssorgatem Sep 24, 2020
52fb53e
Merge branch 'master' of https://github.com/Floyz/Octoprint-Filament-…
ssorgatem Sep 24, 2020
783ab32
Revert "adding debug logs"
ssorgatem Sep 24, 2020
a7970dd
remove redundant check
ssorgatem Sep 26, 2020
e79cf29
fixed reamde
ssorgatem Sep 26, 2020
3f3bc22
fix tab formatting
ssorgatem Sep 26, 2020
5c226e9
revert change to setup.py
ssorgatem Sep 26, 2020
967ce13
why disable it when paused?
ssorgatem Sep 26, 2020
f43fb9f
removing commented code
ssorgatem Sep 26, 2020
49ab454
change parent class order
ssorgatem Sep 26, 2020
2773849
last_state not needed
ssorgatem Sep 26, 2020
b799862
remove unnecessary state variable
ssorgatem Sep 26, 2020
dda76e4
remove unused variable
ssorgatem Sep 26, 2020
e69cacc
Revert "Merge branch 'simon-adriaanse-master' into master"
ssorgatem Sep 26, 2020
71bb3bb
Revert "Merge branch 'simon-adriaanse-master' into master"
ssorgatem Sep 26, 2020
c8681e3
fix silly typo
ssorgatem Sep 26, 2020
c1c6b3a
Merge branch 'floyz-master'
ssorgatem Sep 26, 2020
3d0b5a1
bump version
ssorgatem Sep 26, 2020
17229be
Incorporate simon-adriaanse's
ssorgatem Sep 26, 2020
5e02fef
fix for when the value of pullup is None, reverting to the default
ssorgatem Sep 26, 2020
ffab292
trying to debug some pesky bug
ssorgatem Sep 26, 2020
aa13461
Revert "trying to debug some pesky bug"
ssorgatem Sep 26, 2020
1170a98
version bump
ssorgatem Sep 26, 2020
855bce9
sillyfunnypedro's fix
ssorgatem Sep 27, 2020
2ed4e40
Merge branch 'master' into sillyfunnypedro
ssorgatem Sep 27, 2020
c5c618d
version bump
ssorgatem Sep 28, 2020
a724cc5
removed duplicated line before if
ssorgatem Sep 30, 2020
2eace7c
version bump
ssorgatem Oct 1, 2020
027f0e6
hopefully fix prints not pausing
ssorgatem Oct 6, 2020
5997fdb
version bump
ssorgatem Oct 6, 2020
c1793aa
Add default value for FilamentReloadedPlugin.active
ssorgatem Nov 2, 2020
ff536d4
Merge pull request #9 from ssorgatem/master
ssorgatem Nov 10, 2020
e43351a
Version bump
ssorgatem Nov 18, 2020
bd0f4a5
Version bump
ssorgatem Nov 18, 2020
9f8b185
Merge pull request #10 from ssorgatem/bugfix
ssorgatem Nov 18, 2020
0957dbb
TOUCHUI Work - Created Less Template
nickmitchko Feb 28, 2022
6185b52
Version Bump
nickmitchko Feb 28, 2022
566b491
Update README.md
nickmitchko Feb 28, 2022
64a8370
Update __init__.py
nickmitchko Feb 28, 2022
ecb20b4
Update __init__.py
grk3010 Jun 13, 2022
af0d804
Update __init__.py
grk3010 Jun 13, 2022
6bb86c1
Revert "Update __init__.py"
grk3010 Jun 14, 2022
9ec4020
Merge pull request #14 from grk3010/grk3010
nickmitchko Jan 30, 2023
0371f2c
Update __init__.py
robbrad Jan 30, 2023
3f1ed06
Update __init__.py
robbrad Jan 30, 2023
798cd5b
Update pullup default
nickmitchko Jan 30, 2023
4464a48
Update __init__.py
robbrad Jan 30, 2023
adae980
Fix #3 pullup
nickmitchko Jan 30, 2023
359124a
Merge branch 'master' into bugfix/15_default_pullup_setting
robbrad Jan 30, 2023
a351985
Based on latest changes, bumped version
nickmitchko Jan 30, 2023
553e5a1
Merge branch 'nickmitchko:master' into bugfix/15_default_pullup_setting
robbrad Jan 31, 2023
4f832e0
Merge pull request #16 from robbrad/bugfix/15_default_pullup_setting
nickmitchko Jan 31, 2023
0433b0c
Update setup.py
nickmitchko Jan 31, 2023
5300d0c
Update README.md
nickmitchko Jan 31, 2023
3983bb4
Update README.md
nickmitchko Jan 31, 2023
69ba063
Changed some settings name
nickmitchko Mar 6, 2023
bff5f09
Update setup.py
nickmitchko Mar 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ dist
*.egg*
.DS_Store
*.zip
make.sh
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
# OctoPrint-FilamentReloaded

## Issue Tracking

I have a day job, so when filing an issue please tag me @nickmitchko in the issue so I get an email.

## Overview

[OctoPrint](http://octoprint.org/) plugin that integrates with a filament sensor hooked up to a Raspberry Pi GPIO pin and allows the filament spool to be changed during a print if the filament runs out.

Future developments are planned to include multiple filament sensors and pop-ups.

Initial work based on the [Octoprint-Filament](https://github.com/MoonshineSG/Octoprint-Filament) plugin by MoonshineSG.
Initial work based on the [Octoprint-Filament](https://github.com/MoonshineSG/Octoprint-Filament) plugin by MoonshineSG and [Octoprint-Reloaded] (https://github.com/kontakt/Octoprint-Filament-Reloaded/archive/master.zip) plugin by kontakt.

## Required sensor

Using this plugin requires a filament sensor. The code is set to use the Raspberry Pi's internal Pull-Up resistors, so the switch should be between your detection pin and a ground pin.

This plugin is using the GPIO.BOARD numbering scheme, the pin being used needs to be selected by the physical pin number.

_A DIY guide is in planned for new sensor users_

## Features

* Configurable GPIO pin.
* Configurable GPIO pin (including the type of resistor on the pin)
* Debounce noisy sensors.
* Support normally open and normally closed sensors.
* Execution of custom GCODE when out of filament detected.
* Optionally pause print when out of filament.
* Icon in the nav bar to reflect filament detection status. (with check frequency in parameters)

An API is available to check the filament sensor status via a GET method to `/plugin/filamentreload/status` which returns a JSON

Expand All @@ -29,7 +38,7 @@ An API is available to check the filament sensor status via a GET method to `/pl
## Installation

* Install via the bundled [Plugin Manager](https://github.com/foosel/OctoPrint/wiki/Plugin:-Plugin-Manager).
* Manually using this URL: https://github.com/kontakt/Octoprint-Filament-Reloaded/archive/master.zip
* Manually using this URL: https://github.com/nickmitchko/Octoprint-Filament-Reloaded/archive/master.zip

## Configuration

Expand Down
189 changes: 155 additions & 34 deletions octoprint_filamentreload/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,65 @@
# coding=utf-8
from __future__ import absolute_import

import octoprint.plugin
from octoprint.events import Events
import RPi.GPIO as GPIO
from time import sleep
from flask import jsonify
from threading import Thread


class FilamentReloadedPlugin(octoprint.plugin.StartupPlugin,
octoprint.plugin.EventHandlerPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.SettingsPlugin,
octoprint.plugin.BlueprintPlugin):
octoprint.plugin.AssetPlugin,
octoprint.plugin.BlueprintPlugin
):
active = 0
class filamentStatusWatcher(Thread):

running = False

def __init__(self):
Thread.__init__(self)
self.wCurrentState = -1

def populate(self, wPluginManager, wIdentifier ,wCheckRate, wLogger):
self._logger=wLogger
self.wPluginManager = wPluginManager
self.wIdentifier = wIdentifier
self.wCheckRate = wCheckRate

def run(self):
self.running= True
while self.running==True:
self.updateIcon()
sleep(self.wCheckRate/1000)

def stopWatch(self):
if self.running==True:
self.running=False

def updateIcon(self):
if self.wCurrentState==0:
self._logger.debug("Thread: Update icon 0")
self.wPluginManager.send_plugin_message(self.wIdentifier, dict(filamentStatus="empty"))
elif self.wCurrentState==1:
self._logger.debug("Thread: Update icon 1")
self.wPluginManager.send_plugin_message(self.wIdentifier, dict(filamentStatus="present"))
elif self.wCurrentState==-1:
self._logger.debug("Thread: Update icon 2")
self.wPluginManager.send_plugin_message(self.wIdentifier, dict(filamentStatus="unknown"))

filamentStatusWatcher = filamentStatusWatcher()

def initialize(self):
self._logger.info("Running RPi.GPIO version '{0}'".format(GPIO.VERSION))
self._logger.info(
"Running RPi.GPIO version '{0}'".format(GPIO.VERSION))
if GPIO.VERSION < "0.6": # Need at least 0.6 for edge detection
raise Exception("RPi.GPIO must be greater than 0.6")
GPIO.setwarnings(False) # Disable GPIO warnings

self.pin_value = -1 # Cache the pin value when we detect out of filament

@octoprint.plugin.BlueprintPlugin.route("/status", methods=["GET"])
def check_status(self):
Expand All @@ -36,6 +76,10 @@ def pin(self):
def bounce(self):
return int(self._settings.get(["bounce"]))

@property
def checkrate(self):
return int(self._settings.get(["checkrate"]))

@property
def switch(self):
return int(self._settings.get(["switch"]))
Expand All @@ -44,6 +88,10 @@ def switch(self):
def mode(self):
return int(self._settings.get(["mode"]))

@property
def pullup(self):
return int(self._settings.get(["pullup"]))

@property
def no_filament_gcode(self):
return str(self._settings.get(["no_filament_gcode"])).splitlines()
Expand All @@ -52,6 +100,10 @@ def no_filament_gcode(self):
def pause_print(self):
return self._settings.get_boolean(["pause_print"])

@property
def prevent_print(self):
return self._settings.get_boolean(["prevent_print"])

@property
def send_gcode_only_once(self):
return self._settings.get_boolean(["send_gcode_only_once"])
Expand All @@ -65,24 +117,51 @@ def _setup_sensor(self):
else:
self._logger.info("Using BCM Mode")
GPIO.setmode(GPIO.BCM)

self._logger.info("Filament Sensor active on GPIO Pin [%s]"%self.pin)
GPIO.setup(self.pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

if self.pullup == 0:
GPIO.setup(self.pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
self._logger.info("Filament Sensor Pin uses pullup")
else:
GPIO.setup(self.pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
self._logger.info("Filament Sensor Pin uses pulldown")

if self.filamentStatusWatcher.running == False:
self.filamentStatusWatcher.populate(self._plugin_manager, self._identifier, self.checkrate,self._logger)
self.filamentStatusWatcher.daemon = True
self.filamentStatusWatcher.start()
else:
self._logger.info("Setting new checkrate")
self.filamentStatusWatcher.wCheckRate = self.checkrate
self.no_filament()#to update the watcher's status

GPIO.remove_event_detect(self.pin)
GPIO.add_event_detect(
self.pin, GPIO.BOTH,
callback=self.sensor_callback,
bouncetime=self.bounce
)
else:
self._logger.info("Pin not configured, won't work unless configured!")
self._logger.info(
"Pin not configured, won't work unless configured!")

def on_after_startup(self):
self._logger.info("Filament Sensor Reloaded started")
self._setup_sensor()

def get_settings_defaults(self):
return dict(
pin = -1, # Default is no pin
bounce = 250, # Debounce 250ms
switch = 0, # Normally Open
mode = 0, # Board Mode
no_filament_gcode = '',
pause_print = True,
send_gcode_only_once = False, # Default set to False for backward compatibility
pin=-1, # Default is no pin
bounce=250, # Debounce 250ms
switch=0, # Normally Open
mode=0, # Board Mode
pullup=0, # Pullup or Pull Down - default is Pull up
no_filament_gcode='',
pause_print=True,
prevent_print=True,
send_gcode_only_once=False, # Default set to False for backward compatibility
checkrate = 1500, #navbar icon check frequency
)

def on_settings_save(self, data):
Expand All @@ -96,54 +175,93 @@ def sensor_enabled(self):
return self.pin != -1

def no_filament(self):
return GPIO.input(self.pin) != self.switch
nofilament = GPIO.input(self.pin) != self.switch
self.filamentStatusWatcher.wCurrentState= int(not(nofilament))
return nofilament

##~~ AssetPlugin mixin
def get_assets(self):
return {
"js": ["js/filamentreload.js"],
"less": ["less/filamentreload.less"],
"css": ["css/filamentreload.css"]
}
# return dict(js=["js/filamentreload.js"],css=["css/filamentreload.css"],less=["less/psucontrol.less"],)


def get_template_configs(self):
return [dict(type="settings", custom_bindings=False)]
return [
dict(type="navbar", custom_bindings=False),
dict(type="settings", custom_bindings=False)
]

def on_event(self, event, payload):
# Early abort in case of out ot filament when start printing, as we
# can't change with a cold nozzle
if event is Events.PRINT_STARTED and self.no_filament():
if event is Events.PRINT_STARTED and self.no_filament() and self.prevent_print:
self._logger.info("Printing aborted: no filament detected!")
self._printer.cancel_print()

# Enable sensor
if event in (
Events.PRINT_STARTED,
Events.PRINT_RESUMED
):
if self.prevent_print and self.no_filament():
self._logger.info(
"Printing paused: request to resume but no filament detected!")
self._printer.pause_print()
self._logger.info("%s: Enabling filament sensor." % (event))
if self.sensor_enabled():
self.triggered = 0 # reset triggered state
self.active = 1
GPIO.remove_event_detect(self.pin)
self._logger.info("Filament present, print starting")
GPIO.add_event_detect(
self.pin, GPIO.BOTH,
callback=self.sensor_callback,
bouncetime=self.bounce
)
self.pin, GPIO.BOTH,
callback=self.sensor_callback,
bouncetime=self.bounce
)
# Disable sensor
elif event in (
Events.PRINT_DONE,
Events.PRINT_FAILED,
Events.PRINT_CANCELLED,
Events.PRINT_PAUSED,
Events.ERROR
):
self._logger.info("%s: Disabling filament sensor." % (event))
GPIO.remove_event_detect(self.pin)
self.active = 0

def sensor_callback(self, _):
sleep(self.bounce/1000)
pin_triggered = GPIO.input(self.pin)

# If we have previously triggered a state change we are still out
self._logger.info("The value of the pin is {}. No filament = {} input = {}".format(pin_triggered, self.no_filament(), _))
if not self.active:
self._logger.debug("Sensor callback but no active sensor.")
return
# If we have previously triggered a state change we are still out
# of filament. Log it and wait on a print resume or a new print job.
if self.sensor_triggered():
self._logger.info("Sensor callback but no trigger state change.")
return
self._logger.info("Sensor callback with triggered set")
#
# Check to see if this is a spurious call back by the GPIO change system. We have cached the
# value of the sensor in self.pin_value. If they are the same then we simply return
if self.pin_value == pin_triggered:
self._logger.info("Looks like we had one spurious callback , nothing to do, return")
return
else:
self._logger.info("The pin is different lets process it.")

# Set the triggered flag to check next callback
self.triggered = 1
self.pin_value = pin_triggered

if self.no_filament():
if self.triggered == 1:
self._logger.info("Waiting for filament...")
return
# Set the triggered flag to check next callback
self.triggered = 1
self._logger.info("Out of filament!")
if self.send_gcode_only_once:
self._logger.info("Sending GCODE only once...")
Expand All @@ -157,8 +275,9 @@ def sensor_callback(self, _):
self._logger.info("Sending out of filament GCODE")
self._printer.commands(self.no_filament_gcode)
else:
self._logger.info("Filament detected!")

self._logger.debug("Filament detected!")
# Set the triggered flag to check next callbacks
self.triggered = 0

def get_update_information(self):
return dict(
Expand All @@ -168,17 +287,19 @@ def get_update_information(self):

# version check: github repository
type="github_release",
user="kontakt",
user="ssorgatem",
repo="Octoprint-Filament-Reloaded",
current=self._plugin_version,

# update method: pip
pip="https://github.com/kontakt/Octoprint-Filament-Reloaded/archive/{target_version}.zip"
)
)
pip="https://github.com/ssorgatem/Octoprint-Filament-Reloaded/archive/{target_version}.zip"
))


__plugin_name__ = "Filament Sensor Reloaded"
__plugin_version__ = "1.0.2"
__plugin_version__ = "1.4.0"
__plugin_pythoncompat__ = ">=2.7,<4"


def __plugin_load__():
global __plugin_implementation__
Expand All @@ -187,4 +308,4 @@ def __plugin_load__():
global __plugin_hooks__
__plugin_hooks__ = {
"octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information
}
}
3 changes: 3 additions & 0 deletions octoprint_filamentreload/static/css/filamentreload.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#filament_indicator.present i{color:#00FF00}
#filament_indicator.empty i{color:#FF8C00}
#filament_indicator.unknown i{color:grey}
Loading