Skip to content

Commit

Permalink
Merge pull request #1 from fabianonline/master
Browse files Browse the repository at this point in the history
update from base
  • Loading branch information
giloser authored Jan 14, 2021
2 parents 8b1ad8d + cc54b75 commit c492512
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 54 deletions.
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
This plugin integrates Telegram Messenger with Octoprint. It sends messages (with photos if available) on print start, end and failure. Also it sends messages during the print at configurable intervals. That way you don't have to remember to regularly have a look at the printing process.
Also, you can control Octoprint via messages (settings, start a print and much more). Send `/status` to get the current printer status or `/abort` to abort the current print. Send `/help` for a list of all recognized commands. You may also use this bot in groups.

**Latest release: [1.6.0](https://github.com/fabianonline/OctoPrint-Telegram/releases)**
**Latest release: [1.6.2](https://github.com/fabianonline/OctoPrint-Telegram/releases)**

<!-- omit in toc -->
## Contents
Expand Down Expand Up @@ -68,14 +68,16 @@ If you already have a bot, you only need your bot token to proceed. GOTO `4.` (o
print - Lets you start a print. A confirmation is required.
togglepause - Pause/Resume current Print.
con - Connect/disconnect printer.
upload - You can just send me a gcode file to save it to my library.
upload - You can just send me a gcode file to save it to my library. Also accept zip file.
sys - Execute Octoprint System Commands.
ctrl - Use self defined controls from Octoprint.
tune - Set feed- and flowrate. Control temperatures.
user - get user info.
help - show list of commands.
gif - send a gif of 5 seconds
supergif - send a gif of 10 seconds
on - Turns on the printer power via the PSUControl plugin API. Requires PSU Control plugin installation.
off - Turns off the printer power via the PSUControl plugin API. Requires PSU Control plugin.
```
<img src="https://raw.githubusercontent.com/fabianonline/OctoPrint-Telegram/screenshots/bot_optional.png" alt="Optional bot settings" width="60%" align="center"/> <br><br><br>

Expand All @@ -96,6 +98,8 @@ If you already have a bot, you only need your bot token to proceed. GOTO `4.` (o
5. Hit "Save" at the bottom of the settings dialog.

6. If you want to create gif and receive them as notification we use ffmpeg like timelapse (if problem please check timelapse is configured).
you'll have to install CpuLimit to be able to create gif so please for raspberry connect to your raspberry with putty (for exemple) and execute
sudo apt-get install cpulimit

Congratulations! Your printer is now connected to your Telegram bot.

Expand Down Expand Up @@ -231,7 +235,7 @@ In this section you can configure the content of the notification messages.

**`/con`** - Connect/disconnect printer. Choose between auto connect, use defaults to connect or manual connect (select port/baudrate/printer profile). You are also able to change the connection defaults and turn auto connect on/off.

**`/upload`** - You can just send a gcode file to the bot to save it in upload folder of Octoprint. If you send this command, the bot will tell you the same :) NOTE: This will NOT work in groups.
**`/upload`** - You can just send a gcode file or a zip file to the bot to save it in upload folder of Octoprint. If you send this command, the bot will tell you the same :) NOTE: This will NOT work in groups.

**`/sys`** - Execute Octoprint System Comamnds you defined in *config.yaml*. If a confirmation is defined for the system command, it will be displayed before execution. See [Octoprint documentation](http://docs.octoprint.org/en/master/configuration/config_yaml.html#system) for details on setting up system commands. There is also a [plugin](http://plugins.octoprint.org/plugins/systemcommandeditor/) for doing this.

Expand All @@ -243,9 +247,15 @@ In this section you can configure the content of the notification messages.

**`/help`** - Displays a help message with all accepted commands and a short description.

**`/gif`** - Send a gif create from 20 images.
**`/gif`** - Send a gif create from 20 images. You'll have to install CpuLimit to be able to create gif so please for raspberry connect to your raspberry with putty (for exemple) and execute
sudo apt-get install cpulimit

**`/supergif`** - Send a gif create from 60 images.
**`/supergif`** - Send a gif create from 60 images. You'll have to install CpuLimit to be able to create gif so please for raspberry connect to your raspberry with putty (for exemple) and execute
sudo apt-get install cpulimit

**`/on`** - Turns on the Printer power via the PSUControl plugin API. Requires the [PSU Control plugin](https://github.com/kantlivelong/OctoPrint-PSUControl).

**`/off`** - Turns off the Printer power via the PSUControl plugin API. Requires the [PSU Control plugin](https://github.com/kantlivelong/OctoPrint-PSUControl).

<!-- omit in toc -->
#### Notes:
Expand All @@ -272,3 +282,4 @@ If you want to talk to other users of this plugin and maybe have some influence
you can join the [Octoprint-Telegram-Users-Group](https://telegram.me/joinchat/CXFirQjl9XTp5dr4OZqH9Q).

This software is licensed under [AGPLv3](http://www.gnu.org/licenses/agpl-3.0.txt)

137 changes: 96 additions & 41 deletions octoprint_telegram/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import unicode_literals
from PIL import Image
from subprocess import Popen, PIPE
import threading, requests, urllib3, re, time, datetime, io, json, random, logging, traceback, io, collections, os, flask,base64,PIL, pkg_resources,subprocess,zipfile,glob,resource,sys
import threading, requests, urllib3, re, time, datetime, io, json, random, logging, traceback, io, collections, os, flask,base64,PIL, pkg_resources,subprocess,zipfile,glob,resource,sys,multiprocessing
import octoprint.plugin, octoprint.util, octoprint.filemanager
from flask_babel import gettext
from flask_login import current_user
Expand Down Expand Up @@ -1101,6 +1101,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
if not self.send_messages:
return

self._logger.debug("start _send_msg")
if delay > 0:
time.sleep(delay)
try:
Expand All @@ -1118,7 +1119,8 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
t = threading.Thread(target=self._send_msg, kwargs = args).run()
return

self._logger.info("Sending a message: " + message.replace("\n", "\\n") + " with_image=" + str(with_image) + " with_gif=" + str(with_gif) + " chatID= " + str(chatID))
self._logger.debug("log instead log sending message ")
#self._logger.info("Sending a message: " + message.replace("\n", "\\n") + " with_image=" + str(with_image) + " with_gif=" + str(with_gif) + " chatID= " + str(chatID))
data = {}
# Do we want to show web link previews?
data['disable_web_page_preview'] = not showWeb
Expand All @@ -1145,20 +1147,32 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
try:
curr = self._settings.global_get(["plugins","multicam","multicam_profiles"])
self._logger.debug("multicam_profiles : "+ str(curr))
ListGif = []
for li in curr:
try:
self._logger.debug("multicam profile : "+ str(li))
url = li.get("URL")
self._logger.debug("multicam URL : "+ str(url))
ret = self.create_gif_new(chatID,0,li)
if ret != "":
if not sendOneInLoop:
self.send_file(chatID, ret,message)
else:
self.send_file(chatID, ret,"")
sendOneInLoop = True
ListGif.append(ret)
#if not sendOneInLoop:
# self.send_file(chatID, ret,message)
#else:
# self.send_file(chatID, ret,"")
#sendOneInLoop = True
except Exception as ex:
self._logger.exception("Exception loop multicam URL to create gif: "+ str(ex) )
ret = ListGif[-1]
self._logger.debug("ListGif: "+str(ListGif))
for x in ListGif:
try:
if x != ret:
self._logger.debug("send_file whithout message: "+str(x))
self.send_file(chatID, x,"")
except Exception as ex:
self._logger.exception("Exception loop multicam URL to send gif: "+ str(ex) )

except Exception as ex:
self._logger.exception("Exception occured on getting multicam options: "+ str(ex) )
else:
Expand All @@ -1168,6 +1182,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
ret = self.create_gif_new(chatID,0,0)

if ret != "" and not sendOneInLoop:
self._logger.debug("send_file whith message: "+str(ret))
self.send_file(chatID, ret,message)
#ret = self.create_gif_new(chatID,0,0)
#if ret != "":
Expand Down Expand Up @@ -1196,24 +1211,6 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
message = "[ERR GET IMAGE]\n\n" + message
image_data = None

r = None

if image_data:
self._logger.debug("Sending with image.. " + str(chatID))
files = {'photo':("image.jpg", image_data)}
self._logger.debug("files so far: " + str(files))
if message is not "":
data['caption'] = message
r = requests.post(self.bot_url + "/sendPhoto", files=files, data=data)

self._logger.debug("Sending finished. " + str(r.status_code))
else:
self._logger.debug("Sending without image.. " + str(chatID))
data['text'] = message
r =requests.post(self.bot_url + "/sendMessage", data=data)
self._logger.debug("Sending finished. " + str(r.status_code))

if with_image:
try:
files={}
sendOneInLoop = False
Expand All @@ -1237,10 +1234,10 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,

self._logger.debug("Snapshot URL: " + str(snapshot_url))
if snapshot_url != self._settings.global_get(["webcam", "snapshot"]):
image_data = self.take_image(snapshot_url)
if image_data != "":
image_data2 = self.take_image(snapshot_url)
if image_data2 != "":
self._logger.debug("Image for " + str(li.get("name")))
files = {'photo':("image.jpg", image_data)}
files = {'photo':("image.jpg", image_data2)}
data2 = data
data2['caption'] = ""
r = requests.post(self.bot_url + "/sendPhoto", files=files, data=data2)
Expand All @@ -1256,6 +1253,24 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
except Exception as ex:
self._logger.exception("Exception occured on getting multicam plugin: "+ str(ex) )

r = None

if image_data:
self._logger.debug("Sending with image.. " + str(chatID))
files = {'photo':("image.jpg", image_data)}
self._logger.debug("files so far: " + str(files))
if message is not "":
data['caption'] = message
r = requests.post(self.bot_url + "/sendPhoto", files=files, data=data)

self._logger.debug("Sending finished. " + str(r.status_code))
else:
self._logger.debug("Sending without image.. " + str(chatID))
data['text'] = message
r =requests.post(self.bot_url + "/sendMessage", data=data)
self._logger.debug("Sending finished. " + str(r.status_code))


if r is not None and inline:
r.raise_for_status()
myJson = r.json()
Expand Down Expand Up @@ -1472,16 +1487,22 @@ def create_gif_new(self,chatID,sec=7,multicam_prof=0):
stream_url = multicam_prof.get("URL")

try:
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
try:
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
except Exception as ex:
self._logger.error("Caught an exception trying sending action:record_video : " + str(ex))
# saveDir = os.getcwd()
# os.chdir(self.get_plugin_data_folder()+"/tmpgif")

outPath = self.get_plugin_data_folder()+"/tmpgif/gif.mp4"
if multicam_prof != 0:
outPath = self.get_plugin_data_folder()+"/tmpgif/gif_"+multicam_prof.get("name").replace(" ", "_") + ".mp4"
else:
outPath = self.get_plugin_data_folder()+"/tmpgif/gif.mp4"

try:
os.remove(outPath)
except Exception as ex:
self._logger.info("Caught an exception trying clean previous images : " + str(ex))
self._logger.error("Caught an exception trying clean previous images : " + str(ex))
# self._logger.info("will try to save image in path " + os.getcwd())

params = []
Expand All @@ -1501,7 +1522,10 @@ def create_gif_new(self,chatID,sec=7,multicam_prof=0):
self.send_msg(self.gEmo('dizzy face') + " Problem creating gif, please check log file, and make sure you have installed ffmpeg with following command : `sudo apt-get install ffmpeg`",chatID=chatID)
return ""

requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
try:
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
except Exception as ex:
self._logger.error("Caught an exception trying sending action:record_video : " + str(ex))
#os.nice(20) # force this to use less CPU

if stream_url == 0:
Expand All @@ -1528,24 +1552,46 @@ def create_gif_new(self,chatID,sec=7,multicam_prof=0):
#timout = 4*sec
#ffmpeg -i http://192.168.1.56/webcam/?action=stream -t 00:00:05 -vf scale=320x240 -y -c:a copy out.mkv
#params = ['ffmpeg', '-y', '-i' ,stream_url, '-t', "00:00:05",'-c:v','copy', '-c:a' ,'copy']
used_cpu = 1
limit_cpu = 65

try:
nb_cpu = multiprocessing.cpu_count()
if(nb_cpu > 1):
used_cpu = nb_cpu / 2
limit_cpu = (65 * used_cpu)
except Exception as ex:
self._logger.error("Caught an exception trying to get number of cpu : " + str(ex))

self._logger.info("limit_cpu="+str(limit_cpu) + " | used_cpu=" + str(used_cpu) + " | because nb_cpu=" + str(nb_cpu))
params.append('cpulimit')
params.append( '-l')
params.append( '65')
params.append( str(limit_cpu))
params.append( '-f')
params.append( '-z')
params.append( '--')
params.append( 'ffmpeg')
params.append( '-y' )
params.append( '-threads')
params.append( '1')
params.append( str(used_cpu))
params.append( '-i')
params.append( stream_url)
params.append( '-t')
params.append( timeSec)
params.append( '-c:v')
params.append( 'mpeg4')
params.append( '-c:a' )
params.append( 'mpeg4')
params.append( '-pix_fmt')
params.append( 'yuv420p')
#work on android but seems to be a problem on some Iphone
#params.append( '-c:v')
#params.append( 'mpeg4')
#params.append( '-c:a' )
#params.append( 'mpeg4')
#works on iphone but seems to be a problem on some android
#params.append( '-b:v')
#params.append( '0')
#params.append( '-crf')
#params.append( '25')
#params.append( '-movflags')
#params.append( 'faststart')

if multicam_prof != 0:
flipH = multicam_prof.get("flipH")
Expand Down Expand Up @@ -1586,17 +1632,26 @@ def create_gif_new(self,chatID,sec=7,multicam_prof=0):
params.append( outPath)

self._logger.info("will now create the video " + str(params).strip('[]') )
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
try:
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
except Exception as ex:
self._logger.error("Caught an exception trying sending action:record_video : " + str(ex))

myproc = Popen(params, shell=False, stdout=PIPE, stderr=PIPE)
while True:
if myproc.poll() is not None:
break
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
try:
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
except Exception as ex:
self._logger.error("Caught an exception trying sending action:record_video : " + str(ex))
time.sleep(0.5)

self._logger.info("Finish the video")
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
try:
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
except Exception as ex:
self._logger.error("Caught an exception trying sending action:record_video : " + str(ex))
ret = outPath
except Exception as ex:
self._logger.info("Caught an exception trying create gif general error : " + str(ex))
Expand Down
Loading

0 comments on commit c492512

Please sign in to comment.