openLuup: Cameras

The latest release of openLuup (v18.3.14) includes a built-in SMTP server to handle email messages, and a special implementation file for cameras which use this to trigger an associated motion detector device.

SMTP (Simple Mail Transfer Protocol) server:

This is a minimal implementation of an RFC 5321 compliant server (essentially, an original RFC 821 implementation) without authentication or Transport Layer Security. It only handles messages within the LAN sent to a specific TCP port (2525 by default) and does not relay them further, except to pass them to internal handlers, each of which may be registered to receive emails from a specific email address.

I_openLuupCamera1.xml implementation file:

A camera device created with this implementation file will create an associated child Motion Sensor device which is triggered when the camera’s own motion detection algorithm sends an email.

Configuration:

Out of the box, openLuup will start the SMTP server on port 2525. This can be changed in Lua Startup code with the following line:

luup.attr_set ("openLuup.SMTP.Port", 1234)    -- use port 1234 instead

The camera’s device implementation file may be set on the openLuup device’s Attributes page, followed by a Luup reload. The only other significant parameters are the usual: [tt]ip[/tt] attribute, and the [tt]URL[/tt] and [tt]DirectStreamingURL[/tt] device variables.

Camera configuration is obviously device-specific. For my Foscam camera (thanks to @Spanners) the important parameters are:

[ul][li]Enable - ticked[/li]
[li]SMTP Server - the IP address of openLuup on your LAN eg. 172.16.42.156[/li]
[li]SMTP Port - 2525, or whatever other port number you configured in openLuup startup[/li]
[li]Need Authentication - No[/li]
[li]SMTP Username / Password - not used[/li]
[li]Sender Email - must include the form [tt]xxx@yyy[/tt], for example [tt]Foscam@Study.local[/tt][/li]
[li]First Receiver - [tt]openLuup@openLuup.local[/tt][/li][/ul]

My camera (FI9831P) also sends three snapshots as email attachments. These are currently ignored, but could easily be written to a folder accessible from openLuup.

The Motion Sensor device will remain triggered for 30 seconds (or longer if the camera is re-triggered within that time.) In keeping with the latest security sensor service file, in addition to the [tt]Tripped[/tt] variable, there is also an [tt]ArmedTripped[/tt] variable which is only set/reset when the device is armed. This makes AltUI device watch triggers easy to write when wanting only to respond when the device is actually armed.

The latest master release of openLuup (v18.3.23) includes some enhancements to the [tt]I_openLuupCamera1.xml[/tt] implementation file, and some additional openLuup plugin actions to support file management.

The [tt]ArchiveVideo[/tt] action may be used to save single camera snapshots to openLuup’s images/ folder. At present, the Format and Duration parameters are unused (since this is currently only implemented for single frames.)

A new openLuup email address [tt]images@openLuup.local[/tt] may be used as a destination address for camera trigger emails, instead of openLuup@openLuup.local. Messages sent to this address will be examined for attachments, and any images written to the image/ folder in the openLuup home directory.

This has been tested with a Foscam camera, which attaches three images per trigger event. The filenames are specified by the camera in the multipart [tt]ContentType[/tt] header of the email message, which includes a clause like [tt]name=“Snap_20180323-115529-0.jpg”[/tt]. Other cameras may use a different approach, but I’m more than happy to try and accommodate any different formats.

This feature brings with it the possibility of generating quite a large number of files, in due course. As a result I’ve found it helpful to include some sort of file retention policy implementation. There are two new openLuup plugin actions:

serviceId = “openLuup”, action = “SendToTrash”

This action moves selected files to openLuup’s trash/ folder, and has four parameters:

[ul][li]Folder - the path of a folder below the openLuup home directory. For the application described here, this should be [tt]images[/tt][/li]
[li]MaxDays - the maximum age in days of files which should be retained[/li]
[li]MaxFiles - the maximum number of files that should be retained[/li]
[li]FileTypes - a string listing the types the types of files to which this applies, for example [tt]jpg gif bmp[/tt]. It may also be set to [tt]*[/tt] in which case, any file is applicable. Note that this does not act on subfolders or their contents.[/li][/ul]

One or both of MaxDays and MaxFiles may be specified. If either of the conditions is true, then the file is moved to trash.

Moving files to the trash folder is reversible (manually!) but to delete them permanently, you may use the following action.

serviceId = “openLuup”, action = “EmptyTrash”

This action has one parameter:

[ul][li]AreYouSure - needs to have the value “yes” (case-insensitive) to delete all the files in openLuup’s [tt]trash/[/tt] folder.[/li][/ul]

The purpose of the AreYouSure parameter is to avoid accidental presses of the EmptyTrash button on the device actions page having any effect.

The above actions are easily included into scheduled scenes which might, for example, run the SendToTrash action early in the morning every day, and the EmptyTrash every weekend.


Edit: corrected implementation file name!

I’m missing something obvious: where is the I_openLuupCamera.xml file? I’ve loaded the latest master release, but I don’t see that file? I don’t see it in github either.

I can see my Amcrest try to connect to the SMTP server. Amcrest thinks it failed, but that’s probably because I’m missing the implementation file.

It’s not a physical file.

Just specify it in the create device process and openLuup will find it.

To convince yourself that it’s there, try the following URL in your browser (with the appropriate IP address):

http://openLuupIP:3480/I_openLuupCamera1.xml

Without that file for the device, no motion sensor will be created.


Edit: it probably didn’t help that I left out the trailing ‘1’ in my second post below!

You can test the SMTP server easily from any unix-like machine on the network (here, I’m doing it on the same machine)…

% nc 127.0.0.1 2525
220 (openLuup.smtp v18.3.24) [0.0.0.0] Service ready
helo
250 OK
mail from:akb@here
250 OK
rcpt to:test@openLuup.local
250 OK
data
354 Start mail input; end with <CRLF>.<CRLF>
this is a test message.
.
250 OK
quit
221 (openLuup.smtp v18.3.24) [0.0.0.0] Service closing transmission channel
% 

The all lower-case lines are user input. You have to mail TO: a recognised email address - the console SMTP server page will list those. The FROM: address can be anything of the form xxx@yyy.

Entries in the log file should be something like this:

2018-03-24 21:52:25.218   openLuup.smtp:: new SMTP client connection from 127.0.0.1: tcp{client}: 0x1999978
2018-03-24 21:53:07.328   openLuup.smtp:: EMAIL delivered to handler for: test@openLuup.local
2018-03-24 21:53:10.968   openLuup.smtp:: SMTP QUIT received tcp{client}: 0x1999978

Needs some sort of device file too, right? Do you use D_DigitalSecurityCamera1.xml? Or another custom version?

The standard version is fine. Sorry about not being specific on that.

My camera seems to connect to the smtp port, but apparently it doesn’t like the interaction. The camera says the test email fails, but openLuup doesn’t seem unhappy. All I see in the log is this:

2018-03-25 14:55:09.108 openLuup.smtp:: new SMTP client connection from 192.168.1.202: tcp{client}: 0x1d6f360 2018-03-25 14:55:09.119 openLuup.smtp:: SMTP QUIT received tcp{client}: 0x1d6f360 2018-03-25 14:55:20.790 openLuup.smtp:: new SMTP client connection from 192.168.1.202: tcp{client}: 0x2261360 2018-03-25 14:55:20.800 openLuup.smtp:: SMTP QUIT received tcp{client}: 0x2261360

Need to switch on full debugging for the module to see the handshake.

The latest version (not yet released to the development branch) would then write each step to the log. There’s also a test@openLuup.local destination which would dump the whole of the delivered message. I’ll post that tomorrow.

Right now, though, what does the console / Servers / SMTP page show?

Another thought…

…I’ve just remembered that the test from my camera also failed, because it tried to send email to its own address via the server. Since the camera’s own email is not one of the defined openLuup mailboxes, this fails.

Have you tried with an actual video trigger event (which seems to use the supplied destination address correctly)?

console log below. Tried a real trigger, but the log remains the same. I wonder if my camera is trying to login even if not needed so the handshake fails? I don’t have any option to not login - it says “anonymous login” or the user/password boxes. Of course there is no information on exactly what the camera means by “anonymous login”.

[code]SMTP eMail Server, Sun Mar 25 15:30:50 2018

Received connections:
IP address #connects date time

 192.168.1.202                         17   2018-03-25 15:28:56  

Registered email sender IPs:
IP address #messages for device

 192.168.1.202                          0   [22] Deck Camera  

Registered destination mailboxes:
eMail address #messages for device

 test@openLuup.local                    0   [0] system  
 images@openLuup.local                  0   [2] openLuup  
 postmaster@openLuup.local              0   [0] system  
 openLuup@openLuup.local                0   [2] openLuup [/code]

You may be right, perhaps I will have to add authorization to the server. This should not be so if the camera SMTP client is RFC compliant.

So we need a little more debug info. Please update to the development branch latest (18.3.26) and add the following to your Lua Startup, then reload.

do -- SMTP debug
    local smtp = require "openLuup.smtp"
    smtp.ABOUT.DEBUG = true 
end

Repeat the test (both the test button and an actual camera trigger) and let’s see what ends up in the log.

It may be that the client gives up the moment that it discovers the server doesn’t support the authorization extension, or we may get a little further into the transaction and discover that a destination email address in not accepted. Or something else …?

Sorry for the trouble, but only having one Foscam camera, I can’t test this myself.

I have added a basic SMTP authentication method to the latest development branch (18.3.26b)

I’ve been playing with the authentication on my Foscam and it turns out that it works with this method.

Changes include:

  • SMTP basic AUTH LOGIN authentication
  • In DEBUG mode (described in previous post) the STMP module will accept email to any mailbox address
  • Any Username and Password will be accepted
  • Does not use Transport Layer Security (TLS / SSL)

With these changes, the TEST mode on the camera’s email setup page works and authentication works for actual triggers.

Of course, your mileage may vary, but the enhanced debugging should point the way if further changes are needed. The most likely thing is that I have to implement further protocols, the PLAIN one being the most likely. But please give it a go and see if it works. If not, then the logs should be useful. Thanks.

Much better so far. The test email works fine. Unfortunately I am no longer physically near this camera so I can’t make it trigger, but I left it pointing out a window at a high traffic area so it should get a trigger tomorrow and we’ll see how it does. I’m guessing it will work!

Oh, that’s good news!

Did you use anonymous login, or just pick a username and password?

If it continues to go well, then don’t forget to remove the debug statement in your Lua Startup.

I get the child device to trip, but no images. Log file below. Doesn’t seem like the debug is enabled? VERSION : 2018.03.26 in console, but plugin page says 26b.

2018-03-27 21:37:57.095 openLuup.smtp:: SMTP new client connection from 192.168.1.202: tcp{client}: 0xad8650 2018-03-27 21:37:57.220 openLuup.smtp:: EMAIL delivered to handler for: images@openLuup.local 2018-03-27 21:37:57.222 openLuup.smtp:: EMAIL delivered to handler for: openLuup@openLuup.local 2018-03-27 21:37:57.231 luup.variable_set:: 23.urn:micasaverde-com:serviceId:SecuritySensor1.Tripped was: 0 now: 1 #hooks:0 2018-03-27 21:37:57.240 luup.variable_set:: 23.urn:micasaverde-com:serviceId:SecuritySensor1.LastTripped was: 1522208824 now: 1522211877 #hooks:0 2018-03-27 21:37:57.243 luup.variable_set:: 23.urn:micasaverde-com:serviceId:SecuritySensor1.ArmedTripped was: 0 now: 1 #hooks:0 2018-03-27 21:37:57.244 openLuup.smtp:: EMAIL delivered to handler for: 192.168.1.202 2018-03-27 21:37:57.245 openLuup.smtp:: SMTP QUIT received tcp{client}: 0xad8650

No, you’re right. Debug logging is not enabled. You HAVE put the debug code into Lua Startup, and then reloaded, rather than just running this in Lua Test?

You seem to be sending to both [tt]openLuup@openLuup.local[/tt] AND [tt]images@openLuup.local[/tt]? That’s not a problem, but there’s no point in doing it, just [tt]images[/tt] would suffice, either will still trigger the motion sensor. It’s good to see that this, at least, is working.

Also, from the timing of the logs, it would suggest that the trigger email does not have any attached images. Is there extra configuration in your camera which enables sending image attachment? What exactly is the model? I’ll take a look at the manual online.

Yes, I cut and pasted the debug into the startup Lua and reloaded. I can see it in the user_data.json, but perhaps I missed something. I’ll try again. Yes, the camera sends an image - when I use my own email, I get an image. I put part of the headers below from a sample message. Perhaps this will help? I’ll check again on the debug setting. The camera is an Amcrest IPM-721.

[code]Received: by pinelakepi (sSMTP sendmail emulation); Tue, 27 Mar 2018 12:00:02 -0700
From: pi@raspberrypi
Date: Tue, 27 Mar 2018 12:00:02 -0700
Content-Type: multipart/mixed; boundary=“1499846546-1522177202=:25280”
MIME-Version: 1.0
Subject: Street Image
To: me@gmail.com
X-Mailer: mail (GNU Mailutils 3.1.1)
X-CMAE-Envelope: MS4wfOKYd83FzLkvi0IPSYHjs8kJRfIjOEh6kisRmYZDc94t04plL30UeXobrlDR7McH8cFkoUDekC+Yc6dn8y05gqt4ksCXFfMQWnDflkhVfHiuGzxsIp5M Okf5uzwdT3cxMRkEhdXJ+Z+SS/GmhCOft2GTyx8JHaTFo7W3w+OpK9uk

–1499846546-1522177202=:25280
Content-ID: 20180327120002.25280@raspberrypi
Content-Type: text/plain

–1499846546-1522177202=:25280
Content-ID: 20180327120002.25280.1@raspberrypi
Content-Type: application/octet-stream; name=streetImage.jpg
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=streetImage.jpg

–1499846546-1522177202=:25280–[/code]

This should definitely work… but only if you clicked the blue Submit button on the bottom of the page before reloading…

Yes, the camera sends an image - when I use my own email, I get an image. I put part of the headers below from a sample message. Perhaps this will help?

Good call! Yes, that helps a lot. The problem is here:

Content-Type: application/octet-stream; name=streetImage.jpg
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=streetImage.jpg

…since the Content-Type is marked as “application”, not image.

I’ll need to read up more about attachments to work around this, but it seems wrong to me ATM.

OK, I have added [tt]Content-Type: application[/tt] to the images mail handler.

Available in the latest development branch commit: v18.3.28