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

webremote/livemotion.txt · Last modified: 2017/08/20 14:42 by James Sentman
CC Attribution-No Derivative Works 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0