you're also missing the binding here:
should be something like elements: ["#settings_plugin_Sla_Timelapse"]
you're also missing the binding here:
should be something like elements: ["#settings_plugin_Sla_Timelapse"]
i have to say that you really have the paciance to put up with this kind of dumb questios and for that THANK YOU
also, capitalization may actually matter. your template file is sla_timelapse_settings.jinja2, but your identifier is Sla_Timelapse
.
edit: or define the template filename in this call:
as
dict(type="settings", custom_bindings=False, template="sla_timelapse_settings.jinja2")
crap my bad.... i had that in an old test.... but still doesn't show... that's way i removed it
anyway just checked the logs and when i activate the GPIO is does trigger a log output
2024-02-10 23:10:31,978 - octoprint.plugins.Sla_Timelapse - INFO - LDR Activated
2024-02-10 23:10:32,501 - octoprint.plugins.Sla_Timelapse - INFO - LDR Deactivated... waiting for photo in 5 seconds
2024-02-10 23:10:51,982 - octoprint.util.comm - INFO - Changing monitoring state from "Offline" to "Opening serial connection"
2024-02-10 23:10:52,004 - octoprint.util.comm - INFO - Connecting to port /dev/ttyS0, baudrate 115200
2024-02-10 23:10:52,022 - octoprint.util.comm - INFO - Changing monitoring state from "Opening serial connection" to "Connecting"
2024-02-10 23:10:52,052 - octoprint.plugins.chituboard - INFO - Replacing ok V4.3.13_LCDC
with ok start
however the 3rd step never happens
def take_snapshot(self):
# Check if the timer has elapsed configured seconds
snapshot_delay = self._settings.get_int(["snapshot_delay"])
if self.snapshot_timer is not None and time.time() - self.snapshot_timer >= snapshot_delay:
self._printer.commands(["@OCTOLAPSE TAKE-SNAPSHOT"])
self.snapshot_timer = None
self._logger.info("Snapshot taken!")
"Snapshot taken!"
an i do have octolapse installed
there's nowhere in your code that you're calling that function, so it's not surprising it's not happening.
so here:
add the line
self.take_snapshot()
although, if you're trying to do what I think you're trying to do and wait x amount of seconds prior to sending the command to take the snapshot, it might be a better use of thread.timer, like this.
def handle_ldr_state(self, channel):
if GPIO.input(channel): # LDR Deactivated
self._logger.info("LDR Deactivated... waiting for photo in {} seconds".format(self._settings.get_int(["snapshot_delay"])))
t = threading.Timer(self._settings.get_int(["snapshot_delay"]), self._printer.commands, ["@OCTOLAPSE TAKE-SNAPSHOT"])
t.start()
once i don't know how to code... it's really a gessing game..... iif and a big IF e get this to work, can e credit you on all the help ?
thank you
h have made the changes and now i get in the log output
2024-02-11 12:06:21,817 - octoprint.plugins.Sla_Timelapse - INFO - LDR Activated
2024-02-11 12:06:23,824 - octoprint.plugins.Sla_Timelapse - INFO - LDR Deactivated... waiting for photo in 5 seconds
2024-02-11 12:06:23,825 - octoprint.cli.server - ERROR - Uncaught exception
Traceback (most recent call last):
File "/home/pi/oprint/lib/python3.9/site-packages/octoprint_Sla_Timelapse/__init__.py", line 26, in handle_ldr_state
t = threading.Timer(self._settings.get_int(["snapshot_delay"]), self._printer.commands, ["@OCTOLAPSE TAKE-SNAPSHOT"])
NameError: name 'threading' is not defined
2024-02-11 12:07:06,793 - octoprint.plugins.Sla_Timelapse - INFO - LDR Activated
for what i can see i need to define "threading" but i don't know what is it about or how to define it
Threading is a Python built in module. You can import it with import threading
.
thank you for reply but no errors and no snapshot
I was curious if sending the command from a plugin would process in other plugins. Do you see the @OCTOLAPSE TAKE-SNAPSHOT
command in the terminal tab during the process or not?
No ... nothing
any idea on how to trigger the snapshot ?
in my stand-alone python code, this does work, could we adapt it ?
def button_released():
global trigger_count
if trigger_count > triggers_to_ignore:
print_with_timestamp("LDR Off... waiting to take photo!")
time.sleep(args.time) # Sleep for the specified time
# Create a timestamp for the filename (including date and time)
photo_timestamp = datetime.now().strftime("%d-%m-%Y_%H:%M:%S")
photo_path = f"{new_folder}/timelapse_{photo_timestamp}.jpg"
try:
# Capture a photo using wget
subprocess.run(["wget", f"http://localhost:8080/?action=snapshot", "-O", photo_path])
print_with_timestamp(f"Photo saved at {photo_path}")
except Exception as e:
print_with_timestamp(f"Error capturing photo: {e}")
i really don't know how to do it
ty
try the changes I submitted in this pull request.
thank you mate for all the help
i have made some progress on my own but i am still stuck
now i am able to take snapshots using the localhost method and with hardcoded settings.
the next part is to be able to set them using the settings template page an i am getting nowhere and i could use some help... again,,,,
here is my progress
working code with hardcoded settings
"""
OctoPrint plugin to automatically take timelapse snapshots
using a light dependent resistor (LDR) sensor. v2 (22/02/2024)
"""
import threading
import datetime
import logging
import os
import requests
import RPi.GPIO as GPIO
from octoprint.plugin import StartupPlugin, TemplatePlugin, SettingsPlugin, AssetPlugin
# Module constants
LDR_PIN = 21
PHOTO_DELAY = 5 # seconds
# Setup logging
log = logging.getLogger("octoprint.plugins." + __name__)
class SlaTimelapsePlugin(StartupPlugin, TemplatePlugin,
SettingsPlugin, AssetPlugin):
"""
OctoPrint plugin to take timelapse snapshots using a LDR sensor.
"""
def __init__(self):
self.photo_in_progress = False
# Initialize settings dictionary
self.settings = dict(
ldr_pin=LDR_PIN,
photo_delay=PHOTO_DELAY,
snapshot_folder="/home/pi/timelapse"
)
def on_after_startup(self):
self._setup_gpio()
def get_settings_defaults(self):
return self.settings
def _setup_gpio(self):
"""Initialize GPIO sensor pin."""
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.settings['ldr_pin'], GPIO.IN, GPIO.PUD_UP)
GPIO.add_event_detect(self.settings['ldr_pin'],
GPIO.BOTH, callback=self._ldr_changed, bouncetime=300)
def _ldr_changed(self, channel):
"""Take snapshot when LDR state changes."""
if GPIO.input(channel) and not self.photo_in_progress:
log.info("LDR deactivated - Waiting to take photo")
self.photo_in_progress = True
threading.Timer(self.settings['photo_delay'], self._take_snapshot).start()
elif not GPIO.input(channel) and self.photo_in_progress:
log.info("LDR activated - Canceling snapshot")
self.photo_in_progress = False
def _take_snapshot(self):
"""Capture and save snapshot image."""
try:
response = requests.get("http://localhost:8080/webcam/?action=snapshot")
if response.status_code == 200:
timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
filename = f"snapshot_{timestamp}.jpg"
# Use context manager to save snapshot
with open(os.path.join(self.settings['snapshot_folder'], filename), "wb") as f:
f.write(response.content)
log.info(f"Saved snapshot to {filename}")
else:
log.warning(f"Failed taking snapshot - status {response.status_code}")
except Exception as e:
log.exception(f"Failed to save snapshot: {e}")
finally:
self.photo_in_progress = False
__plugin_name__ = "Sla Timelapse"
__plugin_pythoncompat__ = ">=3.7,<4"
def __plugin_load__():
global __plugin_implementation__
__plugin_implementation__ = SlaTimelapsePlugin()
here is a sample of the slatimelapse_settingns.jinja2
<h1>SLA Timelapse Settings</h1>
<form action="#" method="post">
<label for="gpio_pin">GPIO Pin:</label>
<select id="gpio_pin" name="gpio_pin">
{% for pin in available_pins %}
<option value="{{ pin }}" {% if plugin_settings.gpio_pin == pin %}selected{% endif %}>{{ pin }}</option>
{% endfor %}
</select>
<button type="submit">Save</button>
</form>
note: i know that in the template i have code to call/read the pins and if is not done in the init.py and that is my problem, how to setup a pin in the template and make the plugin use it
thank you again
The file you have uploaded to GitHub should work properly. Notice the bit data-bind="value: settings.plugins.Sla_Timelapse.gpio_pin"
is what glues the settings and the UI using knockout.
thank you for the reply.
i did try with that and it loads the template howeve 2 questions
how to i handle the submition to save as i am getting
Method Not Allowed
The method is not allowed for the requested URL.
and, i have to remove the hardcoded settings don't i ? what was prioraty ? the hardcoded os the template ?
# Module constants
LDR_PIN = 21
PHOTO_DELAY = 5 # seconds
regards
one other question, is there a way to modify the default octoprint buildin timelapse plugin but to use a pi gpio to trigger it ?
after a small reading across google and by looking at octorelay, a came to realise the octorelay saves the relay settings in config.yalm and i think i have to do the same.
the problem is... how to do it
Ah I see the missing piece. You don't have octoprint.plugin.TemplatePlugin
in your class definition.
I just updated my fork of your plugin with the necessary tweaks but looks like you've since deleted all the files and it's showing conflict.
I noticed you didn't have RPi.GPIO in the serup requires, so added that too. You can see my changes at the link below. I installed on a pi zero and the default port 21 shows in settings as expected.
BIGGG UPSSS
just realised that GITHUB did not update automalicly....
i have just uploaded the latest version (New version)
Changes:
A verry big i'm sorry about that
Issues: