Virtual Motion Sensor Plugin

There have been several threads on the subject of Virtual Motion Sensors but none of them presented a solution that fitted my requirements. I wanted a device that looked and behaved like a normal Motion Sensor but could be tripped by an external unit through an http command and would reset to un-tripped after a defined time period.

Virtual Motion Sensor (VMotion) provides one or more virtual motion sensors that may be tripped using local actions or through remote http requests. The sensors will automatically un-trip after ten seconds.

Update: VMotion is now released in the App Store so I have removed the beta files from this post. See VMotion Instructions for more information.

The Virtual Motion Sensor can be tripped using the SetTripped action. It will un-trip automatically after the period specified in the variable TripTime (default ten seconds).

Using Luup:

local dID = 123 -- DeviceID of Virtual Motion Sensor luup.call_action("urn:dcineco-com:serviceId:VMotion1","SetTripped",{},dID)

Using http:

http://your.vera.ip.address:3480/data_request?id=action&output_format=xml&DeviceNum=123&serviceId=urn:dcineco-com:serviceId:VMotion1&action=SetTripped

Edit: 03:04/2015 10:22 Removed beta files. VMotion is now released in the App Store.
Edit: 06/04/2015 11:49 V1.1 released in App Store. Added TripTime for each device.

The reason I wanted a Virtual Motion sensor is so that I could use the Surveillance Station feature of my Synology NAS to trigger it as a result of camera-detected motion. Surveillance Station can issue http commands through its SMS Notification mechanism.

Once I had the Virtual Motion Sensor in Vera, I set it up to trigger Sonos TTS announcements or Twilio SMS alerts depending on the state of my Home/Away VirtualSwitch which is set by the state of my alarm system.

The only tricky bit was persuading the Synology NAS to make the right http command when motion is detected. This was how I did it:

Surveillance Station → System → Notification → SMS → Add SMS service provider

Provider name: Vera VMotion

SMS URL*: [b]http://192.168.1.250:3480/data_request?id=action&DeviceNum=161&serviceId=urn:dcineco-com:serviceId:VMotion1&action=SetTripped&OnTime=30&phone=123456&message=Hello%20world[/b]

Click Next. Select:

[ul][li]id=action: Others[/li]
[li]DeviceNum=161: Username[/li]
[li]serviceId=urn:dcineco-co…: Others[/li]
[li]action=SetTripped: Others[/li]
[li]OnTime=30: Password[/li]
[li]Phone=123456: Phone number[/li]
[li]message=Hello%20world: Message content[/li][/ul]

Click Finish. Enter:

[ul][li]Username: 161[/li]
[li]Password: 30[/li]
[li]Confirm password: 30[/li]
[li]Primary phone number: 123-4567[/li][/ul]

Clicking Send a test SMS message should trigger the Virtual Motion Sensor for thirty seconds.

Once I set Surveillance Station to notify on camera-detected motion, the path was complete. When my DLink DCS-7010L and DCS-6210 cameras detect motion, the NAS issues the http command and the Virtual Motion Sensor trips.

Rex,
I’m not quite grasping the way you are using it.

I was looking for a way to trigger the recording of the cameras in Surveillance Station based on the ZWave motion sensors - that would be a great plugin! The Zwave motion sensors are much more accurate that the built-in camera ones.

[quote=“RexBeckett, post:2, topic:179671”]The only tricky bit was persuading the Synology NAS to make the right http command when motion is detected. This was how I did it:
Surveillance Station → System → Notification → SMS → Add SMS service provider [/quote]

neat trick! registering Vera as an SMS provider 8)
thanks for the tip…

I'm not quite grasping the way you are using it.
I have two D-Link IP cameras. Each of them is set to record 24/7 on their internal SD cards. They are both set for in-camera, image-based motion-detection.

My Synology NAS is running Surveillance Station with both cameras registered. They are set to record on camera-detected motion. Notfication for detected motion is set to send an SMS using Vera as an SMS Provider. So, it sends the http command I have coerced it to use.

The notification http trips the VirtualMotion device in Vera for thirty seconds and then it resets. I use the Tripped trigger to make a Sonos announcement or to send me an SMS via Twilio depending on whether I am at home or away.

I was looking for a way to trigger the recording of the cameras in Surveillance Station based on the ZWave motion sensors - that would be a great plugin!
I think that would need a plugin on Surveillance Station, wouldn't it? My cameras also accept a contact-closure as an alarm trigger so you could use a wired motion sensor to initiate recording.
The Zwave motion sensors are much more accurate that the built-in camera ones.
Is that always the case? I have the camera's motion-detection areas set right on the doors and windows that an intruder would attack. I haven't seen a Z-Wave sensor that can do that.

Camera motion sensors are not actually motion sensors at all… they are software looking for pixel changes - lighting changes can set them off. Zwave are real PIR. I highly suggest not relying on camera motion-detect. I did and was robbed blind, the cameras did not record anything. The ZWave motion sensors can detect my arm waving even slightly.

Triggering the Surveillance Station to record can be done without any plugin for the NAS. Surveillance Station was a published Web API and accepts simple web commands to start/stop recording.

If you decide to take on the project of a ZWave/Vera motion detect to trigger Surveillance Station recording (which I’d love!) here’s some example code (PHP code attached)…

Start recording:

Synology = Net.FHttp("192.168.2.50",5000) response = Synology:GET("/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=2&account=<USERNAME>&passwd=<PWD>&session=SurveillanceStation&format=sid") -- get sid number jsonTable = json.decode(response) sidID = jsonTable.data.sid -- send start command Synology:GET("/webapi/SurveillanceStation/extrecord.cgi?api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=1&cameraId=1&action=start&_sid="..sidID)

Stop Recording:

Synology = Net.FHttp("192.168.2.50",5000) response = Synology:GET("/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=2&account=<USERNAME>&passwd=<PWD>&session=SurveillanceStation&format=sid") -- get sid number jsonTable = json.decode(response) sidID = jsonTable.data.sid -- send stop command Synology:GET("/webapi/SurveillanceStation/extrecord.cgi?api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=1&cameraId=1&action=stop&_sid="..sidID)

FYI:

@garrettwp has kindly added support for this plugin to AutHomationHD (alpha) 3.3.0.2.

Virtual Motion Sensor activity will be logged by @akbooer’s EventWatcher plugin under category S.

Rex, there is a lot of folks out there that are looking to invert their contact sensors from NO to NC and vice versa. Have you thought about adding to this the ability to create a new device that can invert the ‘child’ device? One could then bury the upside-down sensor.

I don’t think you need a plugin to do that, it just requires a slightly customized json. Unless you want to make the changes for all those devices, you would need to define a different device-type (as you would with a plugin).

So worst case: modified version of json to invert icon and triggers; modified version of device-file with custom device-type and new json.

[quote=“RexBeckett, post:2, topic:179671”]Clicking Send a test SMS message should trigger the Virtual Motion Sensor for thirty seconds.

Once I set Surveillance Station to notify on camera-detected motion, the path was complete. When my DLink DCS-7010L and DCS-6210 cameras detect motion, the NAS issues the http command and the Virtual Motion Sensor trips.[/quote]

This is awesome. I had been posting about a virtual motion detector to use with my cameras and Synology, and this is better than using the http feature of the individual cameras, I think. I will try to replicate this in the next week or so …

Rex, any chance I can convince you to include the code to do the opposite… Use real motion sensor in Vera to start synology cameras to record?

Sent from my SAMSUNG-SGH-I747 using Tapatalk

I don’t see why that would need code in VMotion. Can’t you do that with Lua in a scene?

I don’t see why that would need code in VMotion. Can’t you do that with Lua in a scene?[/quote]

Sure, just like anything else could… but it would be cool & useful to be able to have both in the same plugin… thus, choose if you want to use the camera’s motion sensor or the Zwave sensor. I can see situation where some might even want both.

I don’t see why that would need code in VMotion. Can’t you do that with Lua in a scene?[/quote]

Sure, just like anything else could… but it would be cool & useful to be able to have both in the same plugin… thus, choose if you want to use the camera’s motion sensor or the Zwave sensor. I can see situation where some might even want both.[/quote]
Sorry but I just don’t see the connection. VMotion emulates a motion sensor and is triggered by an external device. You want an external device triggered by a real motion sensor. They could not be more opposite.

BTW: This code works on my Synology and could just be dropped into a scene:

[code]local nasip = “192.168.1.253”
local account = “”
local passwd = “”
local cameraid = 1
local recordtime = 20
local sidurl = “http://”…nasip…“:5000/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=2”…
“&account=”…account…“&passwd=”…passwd…“&session=SurveillanceStation&format=sid”
local status, response = luup.inet.wget(sidurl,5)
local sid = string.match(response,‘{"sid":"(.+)"}’)
if sid == nil then luup.log(“Cannot connect to NAS”) return false end
local starturl = “http://”…nasip…“:5000/webapi/SurveillanceStation/extrecord.cgi?”…
“api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=1&cameraId=”…cameraid…
“&action=start&_sid=”…sid
local stopurl = string.gsub(starturl,“start”,“stop”)
status, response = luup.inet.wget(starturl,5)
local success = (string.match(response,‘{"success":true’) ~= nil)
if success then luup.call_delay(“SSstopRecord”,recordtime - 5,stopurl) end

function SSstopRecord(stopurl)
luup.inet.wget(stopurl)
end[/code]

[quote=“RexBeckett, post:14, topic:179671”]BTW: This code works on my Synology and could just be dropped into a scene:

[code]local nasip = “192.168.1.253”
local account = “”
local passwd = “”
local cameraid = 1
local recordtime = 20
local sidurl = “http://”…nasip…“:5000/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=2”…
“&account=”…account…“&passwd=”…passwd…“&session=SurveillanceStation&format=sid”
local status, response = luup.inet.wget(sidurl,5)
local sid = string.match(response,‘{"sid":"(.+)"}’)
if sid == nil then luup.log(“Cannot connect to NAS”) return false end
local starturl = “http://”…nasip…“:5000/webapi/SurveillanceStation/extrecord.cgi?”…
“api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=1&cameraId=”…cameraid…
“&action=start&_sid=”…sid
local stopurl = string.gsub(starturl,“start”,“stop”)
status, response = luup.inet.wget(starturl,5)
local success = (string.match(response,‘{"success":true’) ~= nil)
if success then luup.call_delay(“SSstopRecord”,recordtime - 5,stopurl) end

function SSstopRecord(stopurl)
luup.inet.wget(stopurl)
end[/code][/quote]

awesome

How can this code be mod’d to start multiple cameras at the same time? Does it require a new SID for each connection or something like a for each loop just on the starturl? I’m more familiar (still mostly a hack) with Python/VB, not sure what works in LUA.

thanks for the help!

How can this code be mod'd to start multiple cameras at the same time? Does it require a new SID for each connection or something like a for each loop just on the starturl? I'm more familiar (still mostly a hack) with Python/VB, not sure what works in LUA.

You should not need a new SID for each camera. You would just need to modify the two urls to change the cameraId field and make another luup.inet.wget(…) call and subsequent luup.call_delay(…).

I’d like to use a loop to minimize code, and making it easier for others to use.

Thanks for the help! How does the below look?

[code]local nasip = “192.168.2.50”
local account = “”
local passwd = “”
local recordtime = 20
local cameraid = {1, 2, 3, 4}
for element in list_iter(cameraid) do
local sidurl = “http://”…nasip…“:5000/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=2”…
“&account=”…account…“&passwd=”…passwd…“&session=SurveillanceStation&format=sid”
local status, response = luup.inet.wget(sidurl,5)
local sid = string.match(response,‘{"sid":"(.+)"}’)
if sid == nil then luup.log(“Cannot connect to NAS”) return false end
local starturl = “http://”…nasip…“:5000/webapi/SurveillanceStation/extrecord.cgi?”…
“api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=1&cameraId=”…cameraid…
“&action=start&_sid=”…sid
local stopurl = string.gsub(starturl,“start”,“stop”)
status, response = luup.inet.wget(starturl,5)
local success = (string.match(response,‘{"success":true’) ~= nil)
if success then luup.call_delay(“SSstopRecord”,recordtime - 5,stopurl) end
end

function SSstopRecord(stopurl)
luup.inet.wget(stopurl)
end[/code]

How does the below look?

I see a few problems:

list_iter() is not a built-in Lua function and you have not defined it anywhere.
You are concatenating the table cameraid in starturl rather than the selected element.
Your loop includes the SID request which is unnecessary and will slow it all down.

Something more like this, perhaps (untested):

[code]local nasip = “192.168.2.50”
local account = “”
local passwd = “”
local cameraid = {1,2,3,4}
local recordtime = 20
local sidurl = “http://”…nasip…“:5000/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=2”…
“&account=”…account…“&passwd=”…passwd…“&session=SurveillanceStation&format=sid”
local status, response = luup.inet.wget(sidurl,5)
local sid = string.match(response,‘{"sid":"(.+)"}’)
if sid == nil then luup.log(“Cannot connect to NAS”) return false end
for i,camerano in ipairs(cameraid) do
local starturl = “http://”…nasip…“:5000/webapi/SurveillanceStation/extrecord.cgi?”…
“api=SYNO.SurveillanceStation.ExternalRecording&method=Record&version=1&cameraId=”…camerano…
“&action=start&_sid=”…sid
local stopurl = string.gsub(starturl,“start”,“stop”)
status, response = luup.inet.wget(starturl,5)
local success = (string.match(response,‘{"success":true’) ~= nil)
if success then luup.call_delay(“SSstopRecord”,recordtime - 5,stopurl) end
end

function SSstopRecord(stopurl)
luup.inet.wget(stopurl)
end
[/code]

hello thanks for your plugin

i use your virtual sensor with armed status and on triped it 's run a scene but with become not triped it’s not run my second scene

i want when a armed sensor become triped run scene 1 and when 60 seconde later when it status become not tripped run a second scene it’s possible ?

thanks

Rex,
Many thanks for the code… Works great!

Sent from my SAMSUNG-SGH-I747 using Tapatalk