Live Motion Report
This is a tutorial for creating a live motion report display on a WebRemote page. This is a very useful display for seeing whats going on in your system right now live. While this is currently designed for use with motion or perimeter events, it could easily be adapted for use with any events you wished to keep a list of in the interface.
The display can be embedded into the web remote, the mobile web remote or an XTension view for use inside the program.
Setting it up is very simple. Create a new Group. In the ON script of the group copy the text of the the applescript below. Lastly drag any units that you would like to track in the list into the group and save it. To embed it into a view or a web page create a new “Unit Description as HTML” control and select the group you just created as the unit it points to.
While you’re viewing the interface if any unit in the group has an update the displays will all update live with the new information. Since the date is truncated to just the time events from previous days will be drawn with a darker background.
--Latest Motion Activity script James Sentman MacHomeAutomation.com
--Version 2.0 8/20/2017
--list format {{sensorname, count, date}, {sensorname, count, date}, ...}
-- change this entry to keep more or fewer entries in the database list
-- this is not how many are actually written out to the unit description that is set below
property entriesToKeep : 30
-- change this property to put more or fewer of those lines into the
-- HTML output
property linesToOutput : 30
property DataList:{}
-- since there is not that much room in a display you may wish to edit the unit names that are displayed
-- in my case I always have the word “MOTION” or the word “PERIMETER” in front of the door or place name
-- and displaying that takes too much room. This function will filter the words in the list from the names
-- before displaying them in the list.
on FilterUnitName(TheName)
--add or remove items from this list to filter your unit names so
--that you dont display whats not necessary and it fits properly in the
--page or view display
set WordsToFilter to {"MOTION", "PERIMETER"}
set FirstWord to the 1st word of TheName
if FirstWord is in WordsToFilter then
set AllWords to words 2 through (count of words in TheName) of TheName
else
return TheName
end if
set AppleScript's text item delimiters to " "
set FilteredName to AllWords as text
set AppleScript's text item delimiters to ""
return FilteredName
end FilterUnitName
--
-- This is what actually gets called when a unit in the group gets a new value
-- it causes the HTML to be updated and sent to any watching display
--
on GroupMemberChanged(TheUnit, TheValue)
set IgnoreOff to true
--if we want to ignore offs and this is an off, then ignore it
if (IgnoreOff = true) and (TheValue = 0) then
return
end if
-- try to get the first item to compare with the current one being added
-- if it's the same then increment the counter, else add a new entry
try
set DataList to (Get Unit Property "DataList")
set FirstEntry to first item of DataList
if item 1 of FirstEntry is TheUnit then
--increment the counter
set newcount to (second item of FirstEntry) + 1
-- put the new number in the second element of the entry
set second item of FirstEntry to newcount
set the third item of FirstEntry to (current date)
set the first item of DataList to FirstEntry
else
copy {TheUnit, 1, (current date)} to the beginning of DataList
end if
on error
--unable to get the first element of the list so just add it
set DataList to {{TheUnit, 1, (current date)}}
end try
if (count of DataList) is greater than entriesToKeep then
set DataList to items 1 through entriesToKeep of DataList
end if
Set Unit Property "DataList" to DataList
set description of (thisUnit) to GetHTMLDataList(linesToOutput)
end GroupMemberChanged
on GetHTMLDataList(NumToShow)
set theoutput to {"<html><head><style> table, th, tr, td {font-family:verdana; font-size:11px; padding:1px;border-collapse: collapse;}", ¬
"tr:nth-child(odd){background-color:#DDDDDD}", ¬
"table{width:100%}", ¬
"</style></head><body style=\"margin:0;padding:0;\"><table>"}
set TheCount to count of DataList
if TheCount is greater than NumToShow then
set TheCount to NumToShow
end if
repeat with i from 1 to TheCount
set ThisEntry to (item i of DataList)
set ThisLine to {"<td>", (time string of (item 3 of ThisEntry)), "</td><td>", ¬
FilterUnitName(item 1 of ThisEntry)}
if (item 2 of ThisEntry) is greater than 1 then
copy {"(", (item 2 of ThisEntry), ")</td>"} to the end of ThisLine
else
copy "</td>" to the end of ThisLine
end if
-- if the date is not today then give it a darker background to signify that it's not
-- on the same day since we only show the time as there isn't room.
if date string of (current date) is equal to (date string of (item 3 of ThisEntry)) then
copy {"<tr>", ThisLine, "</tr>"} to the end of theoutput
else
copy {"<tr style=\"background-color:#7777AA\">", ThisLine, "</tr>"} to the end of theoutput
end if
end repeat
copy {"</table></body></html>"} to the end of theoutput
return theoutput as text
end GetHTMLDataList
