Pack a .gif from camera snapshot

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Pack a .gif from camera snapshot

Post by emme »

Ciao

I finally found my way to have Domoticz send me a telegram with a gif from my camera snapshot! (sorry, but I'm quite pround of it :lol: :lol: )

Here is how I did it:

REQUIREMENTS
Linux Based Hardware
imagemagick software (install via sudo apt-get update && sudo apt-get install imagemagick -y )
a dedicated folder where to store frames (ie (home/pi/dzGif)

SCRIPT
you can choose to send messages via telegram as you like o wish, I use my method but feel free to use whatever you prefer

You will need 2 User Variables:
TELEGRAM_Interval - integer (default 2) - Time interval (in seconds) between capured frames
TELEGRAM_Frames - integer - The numbers of frame to capture - Note this is the SCRIPT TRIGGER

HOW IT WORKS
Once updated the Frame variable the script will start to counting down the frames by updating the variable (so it will keep updating and triggering it)
Once counted to 0 it will start the pack process and will send the doc
once finished it will delete all the clues :P

dzVents:

Code: Select all

package.path = package.path .. ';' .. '/home/pi/domoticz/scripts/lua/?.lua'
local telegram   = require('Telegram')
local destId     = 'your ChatID'
local filePath   = '/home/pi/dzGif/frame'
local domoReq    = 'http://127.0.0.1:8080/camsnapshot.jpg?idx='
local frameDigit = 4
local frameDelay = 300

return {
	on = {
		variables = { 'TELEGRAM_Frames' },
	},
	logging = {
        level = domoticz.LOG_FORCE,
        marker = '[Telegram Multi Image]'
        },
	execute = function(dz, varTrig, trgInfo)
        local varInterval = dz.variables('TELEGRAM_Inverval').value 
        if varTrig.value > 0 then
            filler = string.rep('0',frameDigit - string.len(varTrig.value))
            os.execute('wget -O "'..filePath..filler..varTrig.value..'.jpg" "'..domoReq..'2"')
            varTrig.set(varTrig.value - 1).afterSec(varInterval)
        elseif varTrig.value == 0 then
            os.execute('convert -delay '..frameDelay..' -reverse -loop 0 '..filePath..'*.jpg '..filePath..'.gif')
            risp = telegram.sendDoc(destId, filePath..'.gif')
            os.execute('rm '..filePath..'*.*')        
        end
	end
}
few notes about the local variables and commands used in the script:
destIdthe ChatID where to send the file
filePath the working directory included the filename prefix
domoReqAPI address to request the snapshot
frameDigit this is a wired trick I used to sort correctly the frames:
if you are using more than 10 frames they will be nemaned frame1, frame2, frame3...... frame9, frame10... but when you order them frame10 cames before frame1, so I use a fixed lengs numbering (4 digits) to name frames like frame0001, frame0002.... frame0010
frameDelay delay in msec between frames in the Gif file
in the line os.execute('wget -O "'..filePath..filler..varTrig.value..'.jpg" "'..domoReq..'2"') the last 2 identify the camera IDX

HOW TO TRIGGER IT
Update the TELEGRAM_Frames with the amount of frames you want...

KNOWN ISSUES
You could get the warning that the script is taking longer than 10sec... that is ok... the convert command could takes longer
...I'm not so far familiar with ImageMagick... the result GIF file is quite big and I did not found a way to compress it without loosing quality yet

I really hope you like, feel free to comment and improove it!!!
ciao
M
The most dangerous phrase in any language is:
"We always done this way"
User avatar
EdddieN
Posts: 510
Joined: Wednesday 16 November 2016 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.9700
Location: Scotland
Contact:

Re: Pack a .gif from camera snapshot

Post by EdddieN »

Love this! Tagging so I can test! Already have photos but animation even better!
11101101 - www.machinon.com
User avatar
EdddieN
Posts: 510
Joined: Wednesday 16 November 2016 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.9700
Location: Scotland
Contact:

Re: Pack a .gif from camera snapshot

Post by EdddieN »

emme wrote: Thursday 04 January 2018 8:20 Ciao

I finally found my way to have Domoticz send me a telegram with a gif from my camera snapshot! (sorry, but I'm quite pround of it :lol: :lol: )

Ok, finally managed to get some time to test this. I barely got this working, testing with a simple text: https://www.domoticz.com/forum/viewtopi ... 61&t=21213

but not the images bit... this is what I get in my log, Gif if the name of the script
2019-01-27 22:25:08.770 Status: dzVents: Info: [Telegram Multi Image]: ------ Start internal script: Gif: Variable: "TELEGRAM_Frames" Index: 4
2019-01-27 22:25:08.789 Status: Incoming connection from: 127.0.0.1
2019-01-27 22:25:08.792 Status: dzVents: Info: [Telegram Multi Image]: ------ Finished Gif
2019-01-27 22:25:08.841 Status: EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2019-01-27 22:25:10.895 Status: Set UserVariable TELEGRAM_Frames = 1
2019-01-27 22:25:11.026 Status: dzVents: Info: Handling variable-events for: "TELEGRAM_Frames", value: "1"
2019-01-27 22:25:11.027 Status: dzVents: Info: [Telegram Multi Image]: ------ Start internal script: Gif: Variable: "TELEGRAM_Frames" Index: 4
2019-01-27 22:25:11.046 Status: Incoming connection from: 127.0.0.1
2019-01-27 22:25:11.049 Status: dzVents: Info: [Telegram Multi Image]: ------ Finished Gif
2019-01-27 22:25:11.099 Status: EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2019-01-27 22:25:13.105 Status: Set UserVariable TELEGRAM_Frames = 0
2019-01-27 22:25:13.191 Status: dzVents: Info: Handling variable-events for: "TELEGRAM_Frames", value: "0"
2019-01-27 22:25:13.191 Status: dzVents: Info: [Telegram Multi Image]: ------ Start internal script: Gif: Variable: "TELEGRAM_Frames" Index: 4
2019-01-27 22:25:13.420 Status: dzVents: Info: [Telegram Multi Image]: ------ Finished Gif
11101101 - www.machinon.com
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Pack a .gif from camera snapshot

Post by emme »

does the .gif file is generated?

it could be related to rights issue in the sendDoc
I once had to add a chmod 777 to the .gif file and then I were able to send it
The most dangerous phrase in any language is:
"We always done this way"
User avatar
EdddieN
Posts: 510
Joined: Wednesday 16 November 2016 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.9700
Location: Scotland
Contact:

Re: Pack a .gif from camera snapshot

Post by EdddieN »

No I cannot see it. How do you change the rights of the file is not there?
11101101 - www.machinon.com
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Pack a .gif from camera snapshot

Post by emme »

mh... quite wired....
do you have imagemagick installed?
once saved the frames, can you tru to run manually the convert command and check if it gives you error?

the problem seems related to the GIF creation rather than the telegram portion
The most dangerous phrase in any language is:
"We always done this way"
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Pack a .gif from camera snapshot

Post by emme »

try this updated code....

Code: Select all

package.path     = package.path .. ';' .. '/home/pi/domoticz/scripts/lua/?.lua'
local telegram   = require('Telegram')

local filePath   = '/home/pi/temp/dzGif'
local domoReq    = 'http://127.0.0.1:8080/camsnapshot.jpg?idx='

local frameDigit = 4
local frameDelay = 100

return {
	on = {
		variables = { 'telegramGifFrames' },
	},
	logging = {
        level = domoticz.LOG_INFO,
        marker = '[GIF PACKER]'
        },
	execute = function(dz, varTrig)

        local varInterval = dz.variables('telegramGifInterval').value 
        if varTrig.value > 0 then
            filler = string.rep('0',frameDigit - string.len(varTrig.value))
            os.execute('wget -O "'..filePath..filler..varTrig.value..'.png" "'..domoReq..'2"')
            varTrig.set(varTrig.value - 1).afterSec(varInterval)
        elseif varTrig.value == 0 then
            os.execute('convert -delay '..frameDelay..' -reverse -loop 0 '..filePath..'*.png '..filePath..'.gif &&'..
                       'convert '..filePath..'.gif -gravity South -background Plum -splice 0x50 -pointsize 30 -annotate +0+13 "Casa - Ingresso" '..filePath..'.gif')
            telegram.sendDoc(telegram.getId('Marco'), filePath..'.gif')
            os.execute('sudo rm '..filePath..'*.*')
        end
	end
}
The most dangerous phrase in any language is:
"We always done this way"
User avatar
EdddieN
Posts: 510
Joined: Wednesday 16 November 2016 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.9700
Location: Scotland
Contact:

Re: Pack a .gif from camera snapshot

Post by EdddieN »

Thanks! but still no luck.

It creates the jpegs now but fails to make a gif, chatId is missing. I think the issue is that form the original code here:
https://www.domoticz.com/forum/viewtopi ... 46#p164446

to what you are using today... the code has evolved quite a bit :D

Would be nice if you could 'clean' it so it can be added here:
https://www.domoticz.com/wiki/index.php ... arch&go=Go

I would do it if I knew more than just copy and pasting things :lol:

I'm sure people would love to use it
11101101 - www.machinon.com
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Pack a .gif from camera snapshot

Post by emme »

Ed, we need to work and findout what's wrong :P

I've understood the .gif is NOT created, if so telegram of course will not send anything (and probably will return a false :P )
My latest script works fine and even the telegram library works good, so the issue must be somewhere in your configuration (or in mine :D :D :D )

from my latest script tru to remove the:
os.execute('sudo rm '..filePath..'*.*')

and relounch it...
in the folder you MUST see the 10 images and the .gif....
is you're getting them then we will findout what's wrong with Telegram

if you're in trouble detecting your chatID, I have a bot who imform me about anauthorized accesses giving me the ID... :P
The most dangerous phrase in any language is:
"We always done this way"
User avatar
EdddieN
Posts: 510
Joined: Wednesday 16 November 2016 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.9700
Location: Scotland
Contact:

Re: Pack a .gif from camera snapshot

Post by EdddieN »

Can you explain a bit how the program works and also how the Telegram.lua works?

I hopefully can find my way around it if I understand it a bit more

I have chat I’d and bot talked, I use them on telegram.lua but then the dzVents complain of null chatid value or non existent
11101101 - www.machinon.com
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Pack a .gif from camera snapshot

Post by emme »

Sure!!

.GIF script:

it works using 2 variables:
Frames = number of frames and current working frame (it act like a countdown)
interval = fixed value interval between snapshots (and crerate the file), ie: 1 sec

the script is triggered by changing the Frames variable:
example: set it to 10
the script will run the first time, get the snapshot form the camera and store in the specified folder by naming it with a fixed prefix and dd the frame number (snap0001.jpg)
then will update the frames variable by subtracting 1 after the interval value.
so the variable is updated to 9 after 1 sec.

the script runs again, take the snap and set 8 after 1 sec

....
when the Frames is set to 0 (end of snaps) it gets all the frames and crerate the GIF.

Once finish, it uses the telegram library to send the file.

this is how GIF works... now let's see telegram:

Telegram library is a file recalled by your script
it has 3 main function
sendText
sendImage (static, not a gif)
sendDoc (everything)

it also has a sort of adddressbook with name and chatId
the main goal is to have a single place where putting bot, token, chatID without copying them in each script.

it uses http api provided by telegram and it needs to be configured with:
- a Telegram Bot already configured
- The Bot Token
- ChatID of anyone you want to send message to

once reclaimed the library in your script... using the require statement
simply use telegram like a function:

telegram.sendText(<chatID>,<Message>)
ot.. for the gif
telegram.sendDoc(<chatID>,<filePath>)
The most dangerous phrase in any language is:
"We always done this way"
User avatar
EdddieN
Posts: 510
Joined: Wednesday 16 November 2016 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.9700
Location: Scotland
Contact:

Re: Pack a .gif from camera snapshot

Post by EdddieN »

Thanks emme!

I need a bit of time to give it a go to see if I can make it work. I still think it deserves a space on the Wiki, just need to see if I can understand the code myself so it is easy for anyone to replicate from zero. I'll keep you posted!
11101101 - www.machinon.com
User avatar
EdddieN
Posts: 510
Joined: Wednesday 16 November 2016 11:31
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.9700
Location: Scotland
Contact:

Re: Pack a .gif from camera snapshot

Post by EdddieN »

Ok, let's focus on the sending the images form dzVents. I got the Telegram.lua to work, however I have to manually change the chatId on the string:

Code: Select all

local teleTok   = 'Enter your Bot Token here'
local snapFile  = '/home/pi/domoticzSnap'
local domoReq   = 'http://localhost:8080/camsnapshot.jpg?idx='
local tgAb = {}
tgAb['myName1']     = 222222222
tgAb['myName2']     = 111111111
tgAb['myGroup'] = -00000000

local telegram ={};

    function telegram.getId(nome)
        return tgAb[nome]
    end
    
    function telegram.sendText(chatId, message)
        return os.execute('curl --data chat_id='..chatId..' --data parse_mode=Markdown --data-urlencode "text='..message..'"  "https://api.telegram.org/bot'..teleTok..'/sendMessage" ')
    end

    function telegram.sendImage(chatId, camChannel)
        os.execute('wget -O "'..snapFile..camChannel..'.jpg" "'..domoReq..camChannel..'"')
        return os.execute('curl -s -X POST "https://api.telegram.org/bot'..teleTok..'/sendPhoto?chat_id='..chatId..'" -F photo="@'..snapFile..camChannel..'.jpg"')
    end

    function telegram.sendDoc(chatId, filePath)
        return os.execute('curl -s -X POST "https://api.telegram.org/bot'..teleTok..'/sendDocument?chat_id='..chatId..'" -F document="@'..filePath..'"')
    end
return telegram
On
function telegram.sendDoc(chatId, filePath)
return os.execute('curl -s -X POST "https://api.telegram.org/bot'..teleTok. ... ='..chatId..'" -F document="@'..filePath..'"')
end
I 'teleTok' works ok from the local variable, however the chatId is missing. I think this is where it is failing when used from dzVents. As the log complains about missing chatId. Can you clarify that part?
11101101 - www.machinon.com
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Pack a .gif from camera snapshot

Post by emme »

Ciao Ed,
telegram.sendDoc(chatId, filePath) needs 2 parameters:

chatID and the full file name and path...
let's focus on chatID that seems to be the problem:
the function is called in the Gif Script with the following:

telegram.sendDoc( telegram.getId('Marco'), filePath..'.gif')
in my case the ChatID recall another telegram function, the GetID that uses the addressBook function (the local array defined in the telegram Library:

Code: Select all

local tgAb = {}
tgAb['Marco']     = 222222222
tgAb['Eddie']     = 111111111
tgAb['myGroup'] = -00000000
so, in this case the line will became:
telegram.sendDoc( 222222222, filePath..'.gif')

my question would be....
have you setted up your chatId in the tgAb array? :P :P
The most dangerous phrase in any language is:
"We always done this way"
hoeby
Posts: 531
Joined: Saturday 02 June 2018 11:05
Target OS: Raspberry Pi / ODroid
Domoticz version: V2022.1
Location: Echt, Netherlands
Contact:

Re: Pack a .gif from camera snapshot

Post by hoeby »

thinking about adding this to my domoticz.
sending camera images by telegram already Works. not by your telegram.lua but my own dzvents script. need to copy/paste parts from your script. not a big problem, love it to play with scripts.

but you are writting, that .gif files are big files.
what is big? how much kb or mb?
Thin-client --> Docker Domoticz main environment
Pi3A+ --> Google home (GAssistPi)
Pi3B+ --> Docker (P1monitor, Domoticz test environment, Ubiquity controller)
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: Pack a .gif from camera snapshot

Post by emme »

they are almost the sum of each frame... a bit less...

gif should be sent ad documents, not as images... I use my library to do that and it works quite fine... maybe you have to configure both the token and the addessbook (if you use it)
ciao
M
The most dangerous phrase in any language is:
"We always done this way"
hoeby
Posts: 531
Joined: Saturday 02 June 2018 11:05
Target OS: Raspberry Pi / ODroid
Domoticz version: V2022.1
Location: Echt, Netherlands
Contact:

Re: Pack a .gif from camera snapshot

Post by hoeby »

Started with your script.
Doing it step by step. By found a error in your script.
I am working with the script of post 1

Your dz.variables is written wrong. It is written as TELEGRAM_InVerval, but needs to be TELEGRAM_InTerval.
Of course with small letter, but made it big, so it easier to see where the error is.

Code: Select all

local varInterval = dz.variables('TELEGRAM_Inverval').value 
In your other thread the discription about sending documents is not written right.
thread; https://www.domoticz.com/forum/viewtopi ... 46#p164446
The info is correct, but the result says telegram.sendImage, which is not a document

Code: Select all

Send a document (useful to send animated GIF also!!)
usage:
telegram.sendDoc(chatId, full_file_path_and_name)
example 
Code: Select all
result = telegram.sendImage(123456789, '/home/pi/domoticz/domoticz.db')
Thin-client --> Docker Domoticz main environment
Pi3A+ --> Google home (GAssistPi)
Pi3B+ --> Docker (P1monitor, Domoticz test environment, Ubiquity controller)
hoeby
Posts: 531
Joined: Saturday 02 June 2018 11:05
Target OS: Raspberry Pi / ODroid
Domoticz version: V2022.1
Location: Echt, Netherlands
Contact:

Re: Pack a .gif from camera snapshot

Post by hoeby »

Your script works.
I modified it a little, for my personal use.

This is my triggering script, which modifies the variable.
Need to look over, how to make it in 1 script. But quick and dirty, it works

Code: Select all

return {
	on = {
	   	devices = {'Camera voordeur'},
	   	},
	
	execute = function(domoticz, device)
	    if device.state == 'On' then
	         local GIFUrl = "http://xxx.xxx.xxx.xxx:xxxx/json.htm?type=command&param=updateuservariable&vname=TELEGRAM_Frames&vtype=0&vvalue="
             myGIF = GIFUrl.."5"
	         domoticz.openURL({
	             url = myGIF,
	             })
	         domoticz.log(myGIF, domoticz.LOG_INFO)
	    end
	end 
}
The modified script, which doesn't need the telegram.lua

Code: Select all

--You will need 2 User Variables:
--TELEGRAM_Interval - integer (default 2) - Time interval (in seconds) between capured frames
--TELEGRAM_Frames - integer - The numbers of frame to capture - Note this is the SCRIPT TRIGGER

--imagemagick software (install via sudo apt-get update && sudo apt-get install imagemagick -y )
--a dedicated folder where to store frames (ie (home/pi/dzGif)

local teleTok   = 'your telegram token' -- replace the text with your telegram token
local destId     = 'your telegram chat ID' -- replace the tekst with your telegram ID
local filePath   = '/home/pi/dzGif/frame_' -- file path on your PI
local camName    = 'voordeur' -- Camera name, so it is possible to use this script in Multi, but still using the same filePath
local domoReq    = 'http://192.168.178.246/jpg/1/image.jpg' -- This is the string for an axis camera
local frameDigit = 4
local frameDelay = 300

return {
	on = {
	   	variables = { 'TELEGRAM_Frames' },
	},
	
    logging = {
        level = domoticz.LOG_FORCE,
        marker = '[Telegram Multi Image]'
        },

	execute = function(dz, varTrig, trgInfo)
	    local varInterval = dz.variables('TELEGRAM_Interval').value 
        if varTrig.value > 0 then
            filler = string.rep('0',frameDigit - string.len(varTrig.value))
            os.execute('wget -O "'..filePath..camName..filler..varTrig.value..'.jpg" "'..domoReq..'"')
            varTrig.set(varTrig.value - 1).afterSec(varInterval)
        elseif varTrig.value == 0 then
            os.execute('convert -delay '..frameDelay..' -reverse -loop 0 '..filePath..camName..'*.jpg '..filePath..camName..'.gif')
            os.execute('curl -s -X POST "https://api.telegram.org/bot'..teleTok..'/sendDocument?chat_id='..destId..'" -F document="@'..filePath..camName..'.gif"')
            os.execute('rm '..filePath..camName..'*.*')        
        end
	end 
}
Thin-client --> Docker Domoticz main environment
Pi3A+ --> Google home (GAssistPi)
Pi3B+ --> Docker (P1monitor, Domoticz test environment, Ubiquity controller)
hoeby
Posts: 531
Joined: Saturday 02 June 2018 11:05
Target OS: Raspberry Pi / ODroid
Domoticz version: V2022.1
Location: Echt, Netherlands
Contact:

Re: Pack a .gif from camera snapshot

Post by hoeby »

do you know a option to make the interval smaller than 1? every second works. but the interval is still big when getting a nice gif file. would like to try 0.5, but that value is not allowed as STRING.

Do you know a solution?
Thin-client --> Docker Domoticz main environment
Pi3A+ --> Google home (GAssistPi)
Pi3B+ --> Docker (P1monitor, Domoticz test environment, Ubiquity controller)
User avatar
felix63
Posts: 244
Joined: Monday 07 December 2015 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.1
Location: Gouda
Contact:

Re: Pack a .gif from camera snapshot

Post by felix63 »

hoeby wrote: Monday 04 March 2019 14:09 Your script works.
I modified it a little, for my personal use.

This is my triggering script, which modifies the variable.
Need to look over, how to make it in 1 script. But quick and dirty, it works

Code: Select all

return {
	on = {
	   	devices = {'Camera voordeur'},
	   	},
	
	execute = function(domoticz, device)
	    if device.state == 'On' then
	         local GIFUrl = "http://xxx.xxx.xxx.xxx:xxxx/json.htm?type=command&param=updateuservariable&vname=TELEGRAM_Frames&vtype=0&vvalue="
             myGIF = GIFUrl.."5"
	         domoticz.openURL({
	             url = myGIF,
	             })
	         domoticz.log(myGIF, domoticz.LOG_INFO)
	    end
	end 
}
Wouldn't this be simpler?

Code: Select all

return {
	on = {
	   	devices = {'Camera voordeur'},
	   	},
	
	execute = function(domoticz, device)
	    if device.state == 'On' then
		domoticz.variables('TELEGRAM_Frames').set(5)
	    end
	end 
}
You can't set the timer interval to less than one second due to how the script works... (afterSec requires integer value as a function).
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest