Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gphoto2 integration #155

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 48 additions & 4 deletions component/timelapse.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def __init__(self, confighelper: ConfigHelper) -> None:
self.byrendermacro = False
self.hyperlapserunning = False
self.printing = False
self.gphoto2Working = False
self.noWebcamDb = False

self.confighelper = confighelper
Expand All @@ -62,6 +63,8 @@ def __init__(self, confighelper: ConfigHelper) -> None:
"frame_path", "/tmp/timelapse/")
self.ffmpeg_binary_path = confighelper.get(
"ffmpeg_binary_path", "/usr/bin/ffmpeg")
self.gphoto2_binary_path = confighelper.get(
"gphoto2_binary_path", "/usr/bin/gphoto2")
self.wget_skip_cert = confighelper.getboolean(
"wget_skip_cert_check", False)

Expand All @@ -71,6 +74,8 @@ def __init__(self, confighelper: ConfigHelper) -> None:
'mode': "layermacro",
'camera': "",
'snapshoturl': "http://localhost:8080/?action=snapshot",
'use_gphoto2': False,
'gphoto2_waittime': 10.0,
'stream_delay_compensation': 0.05,
'gcode_verbose': False,
'parkhead': False,
Expand Down Expand Up @@ -169,6 +174,8 @@ def __init__(self, confighelper: ConfigHelper) -> None:

async def component_init(self) -> None:
await self.getWebcamConfig()
if self.config['use_gphoto2'] == True:
self.gphoto2Working = await self.check_gphoto2()

def overwriteDbconfigWithConfighelper(self) -> None:
blockedsettings = []
Expand Down Expand Up @@ -460,6 +467,28 @@ async def stop_hyperlapse(self) -> None:
logging.exception(msg)
self.hyperlapserunning = False

async def check_gphoto2(self) -> bool:
gphoto2_installed = os.path.isfile(self.gphoto2_binary_path)
if not gphoto2_installed:
logging.info(f"timelapse: {self.gphoto2_binary_path} \
not found please install to use gphoto2 functionality")
return False

cmd = self.gphoto2_binary_path + " --get-config /main/imgsettings/imageformat"
shell_cmd: SCMDComp = self.server.lookup_component('shell_command')
scmd = shell_cmd.build_shell_command(cmd, None)
try:
cmdstatus = await scmd.run(timeout=2., verbose=False)
except Exception:
logging.exception(f"Error running cmd '{cmd}'")
return False

logging.info(f"check_gphoto2: {cmd} -> {cmdstatus}")
if cmdstatus:
return True
else:
return False

async def newframe(self) -> None:
# make sure webcamconfig is uptodate before grabbing a new frame
await self.getWebcamConfig()
Expand All @@ -469,16 +498,27 @@ async def newframe(self) -> None:
options += "--no-check-certificate "

self.framecount += 1
framefile = "frame" + str(self.framecount).zfill(6) + ".jpg"
cmd = "wget " + options + self.config['snapshoturl'] \
+ " -O " + self.temp_dir + framefile
framebasefile = "frame" + str(self.framecount).zfill(6)
framefile = framebasefile + ".jpg"
if self.config['use_gphoto2'] == True and not self.gphoto2Working:
logging.info(f"gphoto2_check failed on startup - using fallback webcam")

waittime = 2.
if self.config['use_gphoto2'] == True and self.gphoto2Working:
cmd = self.gphoto2_binary_path + " --quiet --capture-image-and-download --filename=\"" \
+ self.temp_dir + framebasefile + ".%C\""
waittime = self.config['gphoto2_waittime']
else:
cmd = "wget " + options + self.config['snapshoturl'] \
+ " -O " + self.temp_dir + framefile

self.lastframefile = framefile
logging.debug(f"cmd: {cmd}")

shell_cmd: SCMDComp = self.server.lookup_component('shell_command')
scmd = shell_cmd.build_shell_command(cmd, None)
try:
cmdstatus = await scmd.run(timeout=2., verbose=False)
cmdstatus = await scmd.run(timeout=waittime, verbose=False)
except Exception:
logging.exception(f"Error running cmd '{cmd}'")

Expand Down Expand Up @@ -512,6 +552,10 @@ async def handle_gcode_response(self, gresponse: str) -> None:
# print_started
self.cleanup()
self.printing = True
self.gphoto2Working = False

if self.config['use_gphoto2'] == True:
self.gphoto2Working = await self.check_gphoto2()

# start hyperlapse if mode is set
if self.config['mode'] == "hyperlapse":
Expand Down
10 changes: 10 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Advanced Settings -> Gcode -> Layer Change Gcode -> ``TIMELAPSE_TAKE_FRAME``
## Directory where the temporary frames are saved
#ffmpeg_binary_path: /usr/bin/ffmpeg
## Directory where ffmpeg is installed
#gphoto2_binary_path: /usr/bin/gphoto2
## Directory where gphoto2 is installed


```
Expand Down Expand Up @@ -98,6 +100,14 @@ It depends on the 'webcam' namespace in the moonraker DB and uses the
'snapshoturl', 'flip_x' and 'flip_y' in the moonraker.conf if your frontend doesn't support the webcams
namespace of moonraker DB.

#### use_gphoto2
'true' enables snapshot_cmd processing.
Make sure, that you have gphoto2 installed.

#### gphoto2_waittime
This defines the wait time for the snapshot to be created.
You should increase the 'park_time' setting for better results.

#### gcode_verbose
'true' enables or 'false' disables verbosity of the Macros

Expand Down