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

Telegram optimizations #2698

Open
wants to merge 1 commit into
base: dev
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
53 changes: 21 additions & 32 deletions motioneye/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ def main_dict_to_ui(data):


def motion_camera_ui_to_dict(ui, prev_config=None):

prev_config = dict(prev_config or {})
main_config = get_main() # needed for surveillance password

Expand Down Expand Up @@ -930,6 +931,12 @@ def motion_camera_ui_to_dict(ui, prev_config=None):
'mask_file': '',
'picture_output_motion': ui['create_debug_media'],
'movie_output_motion': ui['create_debug_media'],
# telegram notifications
'@telegram_notifications_enabled': ui['telegram_notifications_enabled'],
'@telegram_notifications_api' : ui['telegram_notifications_api'],
'@telegram_notifications_chat_id' : ui['telegram_notifications_chat_id'],
'@telegram_notifications_max_pictures' : int(ui['telegram_notifications_max_pictures']),

# working schedule
'@working_schedule': '',
# events
Expand Down Expand Up @@ -1179,7 +1186,7 @@ def motion_camera_ui_to_dict(ui, prev_config=None):
data['@working_schedule_type'] = ui['working_schedule_type']

# event start
on_event_start = [f"{meyectl.find_command('relayevent')} start %t"]
on_event_start = [f"{meyectl.find_command('relayevent')}" + " start %t"]
if ui['email_notifications_enabled']:
emails = sub('\\s', '', ui['email_notifications_addresses'])

Expand All @@ -1201,18 +1208,6 @@ def motion_camera_ui_to_dict(ui, prev_config=None):
}
)

on_event_start.append(line)
if ui['telegram_notifications_enabled']:
line = (
"%(script)s '%(api)s' '%(chatid)s' '%%t' '%%Y-%%m-%%dT%%H:%%M:%%S' '%(timespan)s'"
% {
'script': meyectl.find_command('sendtelegram'),
'api': ui['telegram_notifications_api'],
'chatid': ui['telegram_notifications_chat_id'],
'timespan': ui['telegram_notifications_picture_time_span'],
}
)

on_event_start.append(line)

if ui['web_hook_notifications_enabled']:
Expand All @@ -1232,7 +1227,7 @@ def motion_camera_ui_to_dict(ui, prev_config=None):
data['on_event_start'] = '; '.join(on_event_start)

# event end
on_event_end = [f"{meyectl.find_command('relayevent')} stop %t"]
on_event_end = [f"{meyectl.find_command('relayevent')}" + " stop %t ' ' %{eventid} '%Y-%m-%dT%H:%M:%S'"]

if ui['web_hook_end_notifications_enabled']:
url = sub(r'\s', '+', ui['web_hook_end_notifications_url'])
Expand Down Expand Up @@ -1271,7 +1266,7 @@ def motion_camera_ui_to_dict(ui, prev_config=None):
data['on_movie_end'] = '; '.join(on_movie_end)

# picture save
on_picture_save = [f"{meyectl.find_command('relayevent')} picture_save %t %f"]
on_picture_save = [f"{meyectl.find_command('relayevent')}" + " picture_save %t %f %{eventid} '%Y-%m-%dT%H:%M:%S'"]

if ui['web_hook_storage_enabled']:
url = sub('\\s', '+', ui['web_hook_storage_url'])
Expand Down Expand Up @@ -1311,6 +1306,7 @@ def motion_camera_ui_to_dict(ui, prev_config=None):


def motion_camera_dict_to_ui(data):

ui = {
# device
'name': data['camera_name'],
Expand Down Expand Up @@ -1404,11 +1400,15 @@ def motion_camera_dict_to_ui(data):
or data['picture_output_motion'],
# motion notifications
'email_notifications_enabled': False,
'telegram_notifications_enabled': False,
'web_hook_notifications_enabled': False,
'web_hook_end_notifications_enabled': False,
'command_notifications_enabled': False,
'command_end_notifications_enabled': False,
# telegram notifications
'telegram_notifications_enabled': data['@telegram_notifications_enabled'],
'telegram_notifications_api' : data['@telegram_notifications_api'],
'telegram_notifications_chat_id' : data['@telegram_notifications_chat_id'],
'telegram_notifications_max_pictures' : data['@telegram_notifications_max_pictures'],
# working schedule
'working_schedule': False,
'working_schedule_type': 'during',
Expand Down Expand Up @@ -1673,7 +1673,6 @@ def motion_camera_dict_to_ui(data):
on_event_start = utils.split_semicolon(on_event_start)

ui['email_notifications_picture_time_span'] = 0
ui['telegram_notifications_picture_time_span'] = 0
command_notifications = []
for e in on_event_start:
if ' sendmail ' in e:
Expand Down Expand Up @@ -1702,21 +1701,6 @@ def motion_camera_dict_to_ui(data):
except (TypeError, ValueError):
ui['email_notifications_picture_time_span'] = 0

elif ' sendtelegram ' in e:
e = split(e)

if len(e) < 6:
continue

ui['telegram_notifications_enabled'] = True
ui['telegram_notifications_api'] = e[-5]
ui['telegram_notifications_chat_id'] = e[-4]
try:
ui['telegram_notifications_picture_time_span'] = int(e[-1])

except (TypeError, ValueError):
ui['telegram_notifications_picture_time_span'] = 0

elif ' webhook ' in e:
e = split(e)

Expand Down Expand Up @@ -2279,6 +2263,11 @@ def _set_default_motion_camera(camera_id, data):
data.setdefault('movie_output', False)
data.setdefault('movie_passthrough', False)

data.setdefault('@telegram_notifications_enabled', False)
data.setdefault('@telegram_notifications_max_pictures', '2')
data.setdefault('@telegram_notifications_api', '')
data.setdefault('@telegram_notifications_chat_id', '')

if motionctl.has_h264_omx_support():
data.setdefault('movie_codec', 'mp4:h264_omx') # will use h264 codec

Expand Down
14 changes: 4 additions & 10 deletions motioneye/handlers/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,27 +721,21 @@ async def test(self, camera_id):
return self.finish_json({'error': str(msg)})

elif what == 'telegram':
from motioneye import sendtelegram
from motioneye.handlers import telegram

logging.debug('testing telegram notification')

try:
message = 'This is a test of motionEye\'s telegram messaging'
sendtelegram.send_message(
data['api'], int(data['chatid']), message=message, files=[]
)

self.finish_json()
th = telegram.TelegramHandler.get_instance()
await th.send_test_message(api_key = data["api"], chat_id = data["chatid"])

logging.debug('telegram notification test succeeded')
self.finish_json()

except Exception as e:
msg = str(e)

msg_lower = msg.lower()
logging.error(
'telegram notification test failed: %s' % msg, exc_info=True
)
self.finish_json({'error': str(msg)})

elif what == 'network_share':
Expand Down
27 changes: 26 additions & 1 deletion motioneye/handlers/relay_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
import logging

from motioneye import config, mediafiles, motionctl, tasks, uploadservices, utils
from motioneye.handlers import telegram
from motioneye.handlers.base import BaseHandler

__all__ = ('RelayEventHandler',)


class RelayEventHandler(BaseHandler):
@BaseHandler.auth(admin=True)
def post(self):
async def post(self):
event = self.get_argument('event')
motion_camera_id = int(self.get_argument('motion_camera_id'))

Expand All @@ -50,6 +51,10 @@ def post(self):
)
return self.finish_json()

# needed for specific motion event recognition
event_id = self.get_argument('event_id')
moment = self.get_argument('moment')

if event == 'start':
if not camera_config['@motion_detection']:
logging.debug(
Expand All @@ -63,6 +68,9 @@ def post(self):
elif event == 'stop':
motionctl.set_motion_detected(camera_id, False)

# notify telegram handler event stop
await self.handle_telegram_notification(camera_id, camera_config, moment, event, event_id, "")

elif event == 'movie_end':
filename = self.get_argument('filename')

Expand All @@ -86,6 +94,9 @@ def post(self):
if camera_config['@upload_enabled'] and camera_config['@upload_picture']:
self.upload_media_file(filename, camera_id, camera_config)

# send media to telegram
await self.handle_telegram_notification(camera_id, camera_config, moment, event, event_id, filename)

else:
logging.warning('unknown event %s' % event)

Expand All @@ -105,3 +116,17 @@ def upload_media_file(self, filename, camera_id, camera_config):
and camera_config['target_dir'],
filename=filename,
)

async def handle_telegram_notification(self, camera_id, camera_config, moment, event, event_id, filename):

# telegram notifications should only be triggered when motion detects well, motion :)
# below checks should allow media only when capture mode in GUI is set to "Motion Triggered" and "Motion Triggered (one picture)"

if (camera_config["picture_output"] != False and camera_config['emulate_motion'] != True and camera_config['snapshot_interval'] == 0):
if (camera_config['@telegram_notifications_enabled']):
if (camera_config['@telegram_notifications_api'] and camera_config['@telegram_notifications_chat_id']):
th = telegram.TelegramHandler.get_instance()
await th.add_media({"camera_id" : camera_id, "camera_config" : camera_config, "moment" : moment, "event" : event, "event_id" : event_id, "file_name" : filename})
else:
logging.warning("telegram notifications are enabled, but some of telegram_notifications parameters are not set")
return self.finish_json()
Loading