Updating IPCam image in openhab

I have a IPCam generating snapshots, if motion is detected.
The camera uploads them onto my Raspberry running Openhab.
What I would like to do is:
Check for new uploaded file.
Get time stamp.
If file newer than the previous, update both above (image and timestamp).
Set a timer for “ignore motion for xx minutes”.
After timer expired, check again for new files (there will be new files even in the meantime (during ignore time), because the camera will upload constantly.

My Problem: The time stamp is somtimes overwritten even if the script echos “none”.
The Switch “Abus_Motion” (to ignore motion for xx minutes) is not set properly.

The script to check whether a new file arrived looks like this:
#!/bin/bash
Latest_File=ls /var/www/upload/abus/ -t1 | head -n 1

# check if the latest file is NOT the same like "latest.jpg"
if ! cmp /var/www/upload/abus/$Latest_File /usr/share/openhab/webapps/abus/latest.jpg >/dev/null 2>&1
then
    timestamp=`stat -c %y /var/www/upload/abus/$Latest_File | cut -d '.' -f1`
    cp /var/www/upload/abus/$Latest_File /usr/share/openhab/webapps/abus/latest.jpg
     echo $timestamp
else
    echo "none"
fi

this script is executed by the following rule:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*

var Timer timer_OFF = null
var Timer timer_MO = null

    rule "copy motion detection image"
    when
        Time cron "40 0/5 * * * ?" // aktiviert die IPCAM einen Output bei Bewegung?
    then
    var timestamp_tmp = executeCommandLine("/etc/openhab/configurations/scripts/copyLatestABUS.sh", 5000)
        if (timestamp_tmp != "none") {
            if (Abus_Motion.state == OFF) {
                postUpdate(Abus_Motion_tmstmp, timestamp_tmp)
                logInfo("TeleEye PIR: ", "Motion detected")
                sendTelegram("OH_TeleBot", "TeleEye:\nBewegung detektiert!")
            }
            if (timer_MO == null) {
                  sendCommand(Abus_Motion, ON)
                  timer_MO = createTimer(now.plusMinutes(28)) [| sendCommand(Abus_Motion, OFF) ] // ignore movement for 20 minutes
                  logInfo("Abus_Motion", "activated")
            }
            else {
                  timer_MO.cancel
                  timer_MO = null
                  sendCommand(Abus_Motion, OFF)
                  logInfo("Abus_Motion", "DEACTIVATED")
            }
        }
    end

Log out the value actually returned by your script to see what your script is actually returning. You are assuming that it is echoing “none” and not something like an empty string (does it take longer than 5 seconds for some reason?), or an error message. In either of those cases it would treat the return value as a timestamp.

Have a look at what @PolishBen has worked up. Hopefully he will share his work. :smile:

Thanks, @watou.
I have seen it and hope so, too :wink:

If I run the script manually the console returns >none<.
In the beginning I tried it without specifying the return value for the negative result and thought I must check for !=null in my rules. But this didn’t work.
The approach above seems to work every now and then, but I don’t have a clue why it’s not reliable.
So there is no obvious typo?

I see nothing wrong with the code as it is which is why I’m focusing on what the script is actually returning.

Running it by hand from the console is not enough. When you run it from openHAB it is running from a different user and in a different environment so your script may not behave the same for it as it does for you. That is why I think you need to log out what the script is returning and see what it returned in the cases where it didn’t work. I’m guessing you will find it is something not expected. Perhaps an empty string…

Thanks for not giving up on me :wink:
The returned string is definitely not empty.
Even if I try to “translate” the returned value with “.toString” it doesn’t help (see the two different lowinfo entries below).

I am currently running:

rule "check for new image and copy"
when
    Time cron "40 0/2 * * * ?"
then
    var timestamp_tmp = executeCommandLine("/etc/openhab/configurations/scripts/copyLatestABUS.sh", 5000)
    logInfo("TeleEye PIR: ", "timestamp_tmp.toString: " + timestamp_tmp.toString)
    logInfo("TeleEye PIR: ", "timestamp_tmp: " + timestamp_tmp)
//    Abus_Motion_tmstmp.postUpdate(timestamp_tmp.toString)
    if (Abus_Motion.state == OFF) {
        if (timestamp_tmp == "none") {
            logInfo("TeleEye PIR: ", "Motion detection: " + Abus_Motion_tmstmp)
            sendTelegram("OH_TeleBot", "TeleEye:\n KEINE Bewegung detektiert!")
        }
        else {     
//            postUpdate(Abus_Motion_tmstmp, timestamp_tmp.toString)
            Abus_Motion_tmstmp.postUpdate(timestamp_tmp)
            logInfo("TeleEye PIR: ", "Motion detected: " + Abus_Motion_tmstmp)
            sendTelegram("OH_TeleBot", "TeleEye:\nBewegung detektiert!")
        }
    }    
end

In the log I see:
2015-12-22 17:04:40.586 [INFO ] [hab.model.script.TeleEye PIR: ] - timestamp_tmp.toString: none
2015-12-22 17:04:40.820 [INFO ] [hab.model.script.TeleEye PIR: ] - timestamp_tmp: none

And when you see it log “timestamp_tmp: none” it still executes the else clause instead of if (timestamp_tmp == "none")?

If that is the case, try using the .equals method instead of ==

if(timestamp_tmp.equals("none")) {

I don’t think you should have to do this but I can’t think of any other reason why the if would be failing.

Oh, also add some characters around timestamp_tmp in your log statement so we can be sure it doesn’t have a trailing space or something that could be gumming up the works.

logInfo("TeleEye PIR: ", "timestamp_tmp: >" + timestamp_tmp + "<")

Thanks - I will try (both suggestions).
Actually the response in the log for the latter suggestion is:

2015-12-22 18:46:40.711 [INFO ] [hab.model.script.TeleEye PIR: ] - timestamp_tmp: >none<

if you declared the variable

val String timestamp_tmp = executeCommandLine("/etc/openhab/configurations/scripts/copyLatestABUS.sh", 5000)

then would the string comparison

"none".equals(timestamp_tmp)

work?

Sorry, is this a question or a suggestion?
You mean
var (not val), right?
and
if(“none”.equals(timestamp_tmp)) {

Does is matter, if it’s really equal?

It is a suggestion.

Nope, he means val. If you are not going to reassign a variable is it good coding practice to make it final (i.e. use val instead of var). It is a good habit to get into and can save you some heartache later on. Honestly 75-90% of all the variables in a typical rule should be vals, not vars.

We don’t know, that’s the point. If the if statement is not running even when timestamp_tmp appears to be set to “none” then clearly it isn’t really equal. Swapping the comparison around like @watou suggests is a way to figure out if the Rules engine is doing something odd and unexpected with the type that timestamp_tmp is being set to.

I have a working version:

rule "check for new image and copy"
when
    Time cron "40 0/1 * * * ?"
then
    val String timestamp_tmp = executeCommandLine("/etc/openhab/configurations/scripts/copyLatestABUS.sh", 5000)
    if (Abus_Motion.state == OFF) {
        if(timestamp_tmp.equals("none")) {
            logInfo("TeleEye PIR: ", "New file timestamp: >" + timestamp_tmp + "<")
        }
        else {     
            Abus_Motion_tmstmp.postUpdate(timestamp_tmp)
            logInfo("TeleEye PIR: ", "Motion detected - Timestamp: >" + Abus_Motion_tmstmp.state + "<")
            sendTelegram("OH_TeleBot", "TeleEye:\nBewegung detektiert!")
        }
    }
    else {
        logInfo("TeleEye PIR: ", "Motion ignored: Abus_Motion.state: " + Abus_Motion.state)
    }    
end

But I encountered an issue with my timer, which I moved into another separate rule.
I will check it out a lottle closer and will post the new issue in another post.
Thank you very much!
@rlkoshak, @watou