Advertisement
Guest User

Foscam EventGhost Plugin

a guest
Aug 1st, 2011
1,145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 32.47 KB | None | 0 0
  1. import eg
  2. import urllib2
  3. import time
  4.  
  5. eg.RegisterPlugin(
  6.     name = "Foscam",
  7.     author = "DaF",
  8.     version = "1.0.2",
  9.     canMultiLoad = True,
  10.     kind = "external",
  11.     createMacrosOnAdd = True,
  12.     description = (
  13.         "Plugin to control and add features to"
  14.         '<br\n><br\n>'
  15.         "FOSCAM FI8908W FI8918W"
  16.         '<br\n>'
  17.         "HEDEN VisionCam"
  18.         '<br\n><br\n>'
  19.         '<center><img src="foscam.png" /></center>'
  20.     ),
  21.     help = """
  22.             <br/><b>Notice:</b>
  23.             Check carefully every settings
  24.     """,
  25.     url = "http://forum.hardware.fr/hfr/HardwarePeripheriques/Webcam/fi8908w-fi8918w-visioncam-sujet_50586_1.htm",
  26.     icon = (
  27.         "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEA"
  28.         "mpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iA"
  29.         "lEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKO"
  30.         "g6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEK"
  31.         "JHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThL"
  32.         "CIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCR"
  33.         "ACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUp"
  34.         "AAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2"
  35.         "YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+r"
  36.         "cEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ"
  37.         "2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc"
  38.         "5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+"
  39.         "AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQk"
  40.         "LlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiG"
  41.         "zbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggX"
  42.         "mYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGy"
  43.         "UT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAu"
  44.         "xsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKgg"
  45.         "HCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQ"
  46.         "AkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJA"
  47.         "caT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJ"
  48.         "S6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3"
  49.         "GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XL"
  50.         "VI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGg"
  51.         "sV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H"
  52.         "45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1F"
  53.         "u1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5M"
  54.         "b6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX"
  55.         "4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN"
  56.         "1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l"
  57.         "1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N"
  58.         "/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dn"
  59.         "F2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0"
  60.         "nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5y"
  61.         "n+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8"
  62.         "Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGL"
  63.         "w34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6"
  64.         "P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIs"
  65.         "OpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkk"
  66.         "xTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+"
  67.         "xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zv"
  68.         "n//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0m"
  69.         "ek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3Hjl"
  70.         "G4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7"
  71.         "g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttV"
  72.         "AVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cO"
  73.         "xx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptT"
  74.         "mvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ7"
  75.         "52PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLua"
  76.         "rrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn"
  77.         "7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbr"
  78.         "njg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv"
  79.         "28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMz"
  80.         "LdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAzxJ"
  81.         "REFUeNpskk2IVWUAhp/v+875zrnn595z78y984NK2uiEo021LCec/oxSx4JWRqsWLQrc"
  82.         "ZAshgpIWrSthwCJCpE2QIRkxjuhGY/oBIZmRJqcYRa3x3jv35/x+LaaFi154di8PvPCK"
  83.         "K79cRAhIkgIlNUrJA0aIj5rN1uZWu5umeWbVwkozqlUP29qdd7WLEAAwvnUrkvsipTxW"
  84.         "GPNNtxuP55nwHNup+E7Jj9N0tNePTxhjnhBCgGAD2BAYA1rrt6RSH3T7CWvtdf66c4fl"
  85.         "1ZusdXoYS9MvzPh6ksz14/jFPCnIkwIAK0tBa3vCcb33ut0+WZrTi2OEtGg0hoiiClFY"
  86.         "xtMuUkkdJ9nJNM33CCGWAKTnBYHnBe8oKWtKKgpjwBgCz6NSDikHIWU/oBIG1KIKQ/XB"
  87.         "hu3aR4T13wTb1nu17RwKgwDf8yiKAstSeJ6H5/uE5ZBqucpANWKgHDAQhVTK5ZeQKgSw"
  88.         "XEdPO1qHUVQmjhMwhjzL6XQ6SCXRWlOyHGwtkLaLqxTVMKi0u5060Ja2VJNGFMT9HnmW"
  89.         "YUxBURi0o6nWqgw1GgzX61SDECUl/TShIPe0ZY0BWLYllaUtapUaSSIYHS4YGZW4jovn"
  90.         "ebhSkPa7aMvHlgrbVuSqwCu5u4DvrbVWi0LYXLu+SqvQfPftGb76bJY07mGyFGNAas0D"
  91.         "O3YwPradfQdfZmbfU+RZGgFw9sL5c5+c+tKMPjZl5lfa5vUPPzUozwD/S2XLdnPl9xvZ"
  92.         "jVurh4wxWLsnJt6812y/0Wp2jnxx+pS89PVpEPl997TYtuc52rdv83dQxlQ3JUVv/Um3"
  93.         "OnIZQLaazaWFhYVjVpEvnrywwHJuI50SAKrkUaoM8vDuRxh99HG8Z16hvnn44sezn18+"
  94.         "+8PcRkcHVc7PX8okprfmDsy8/f5xDr76Gj/+ukjv5jIlUbB67Sp365voWw57/exoI/J/"
  95.         "W/rjT2aefRrVjA22beO7zs+ife9BE0WTxw8/z/QLB2iN7KLpD/HPwDDFyDYeSm69u3Nk"
  96.         "8ESOjbI1+6enUFvGxhFCkAOD0pxZWVpcmbt6fWfDt52+6/d/urueuCI/N2nWjzZ8e7ZU"
  97.         "KqGkBAz7p6f4dwCIn0Irf0Ct0gAAAABJRU5ErkJggg=="
  98.     ),
  99. )
  100.  
  101. from threading import Event, Thread
  102. from os.path import basename, dirname, abspath
  103.  
  104. #test
  105. import os, sys, time, string, select, re
  106. from socket import *
  107. from datetime import timedelta, datetime
  108.  
  109. # Used for opening external app
  110. from eg.WinApi.Dynamic import (
  111.     sizeof, byref, CreateProcess, WaitForSingleObject, FormatError,
  112.     CloseHandle, create_unicode_buffer,
  113.     STARTUPINFO, PROCESS_INFORMATION,
  114.     CREATE_NEW_CONSOLE, STARTF_USESHOWWINDOW, INFINITE,
  115.     GetExitCodeProcess, DWORD
  116. )
  117.  
  118. WINSTATE_FLAGS = (
  119.     1, # SW_SHOWNORMAL
  120.     6, # SW_MINIMIZE | SW_HIDE
  121.     3, # SW_SHOWMAXIMIZED
  122.     0, # SW_HIDE
  123. )
  124.  
  125. PRIORITY_FLAGS = (
  126.     64,    # IDLE_PRIORITY_CLASS
  127.     16384, # BELOW_NORMAL_PRIORITY_CLASS
  128.     32,    # NORMAL_PRIORITY_CLASS
  129.     32768, # ABOVE_NORMAL_PRIORITY_CLASS
  130.     256,   # REALTIME_PRIORITY_CLASS
  131. )      
  132.  
  133. class Text:        
  134.         ipArea = "Foscam IP settings"          
  135.         textBoxIPCamCtrl = "IP"
  136.         textBoxPortCtrl = "Port"
  137.         textBoxLoginCtrl = "User"
  138.         textBoxPwdCtrl = "Password"
  139.         mediaArea = "External viewers settings"        
  140.         textBoxBrowserPathCtrl = "Jpeg viewer app path"
  141.         textBoxcodecCtrl = "Codec (h264,mp4v,x264,mp1v,mp2v)"
  142.         textBoxbitrateCtrl = "Bitrate"
  143.         checkBoxStreamPlayerFullScreenCtrl = "Full screen video"   
  144.         checkBoxSafeHttpModeCtrl = "Solve the Error 10013 (urlopen)"
  145.         checkBoxDebugCtrl = "Show debug in log"    
  146.         patrolSleepArea = "Patrol settings"    
  147.         patrolSleepCtrl = "Sleep time (in seconds)"
  148.         patrolPos1 = "First preset"
  149.         patrolPos2 = "Second preset"
  150.         patrolLoopInfo = "Foscam : patrol every {0}s until {1}"
  151.         patrolLoopEndInfo = "Foscam : stopped patrol"
  152.         presetGotoArea = "Select a preset value"
  153.         presetCtrl = "Preset number"
  154.         presetRecordArea = "Select a preset value to record"
  155.         switchIR = "Activate IR LEDs"
  156.         commandNumber = "Command number"
  157.         troubleShootArea = "Troubleshooting (only in case of troubles!)"
  158.         alarmArea = "Alarm settings"
  159.         alarmMotionCtrl = "Activate alarm yes/no = 1/0"
  160.         alarmSensitivityCtrl = "Sensivity"
  161.         alarmInputCtrl = "Input armed y/n"
  162.         alarmIOCtrl = "IO linkage y/n"
  163.         alarmMailCtrl = "Send email y/n"
  164.         alarmIntervalCtrl = "Upload interval (seconds)"
  165.         alarmMiscArea = "Miscellaneous"
  166.         timerSnapshotInfo = "Foscam : Snapshots every {0}s until {1}"
  167.         timerArea = "Select interval and folder path"
  168.         intervalTimeCtrl = "Interval (second)"
  169.         durationCtrl = "Duration (minute. 0 = unlimited)"
  170.         folderCtrl = "Folder path"
  171.         timerSnapshotEndInfo = "Foscam : stopped timed snapshots"      
  172.         videoArea = "Video features"
  173.         checkBoxShowCtrl = "Display the video"
  174.         checkBoxRecordCtrl = "Record video"
  175.         checkBoxAudioRecordCtrl = "Record audio"
  176.         durationVideoCtrl = "Duration (second)"
  177.         protocolCtrl = "Protocol (rtsp,mmsh)"
  178.         portCtrl = "Port"
  179.         pageNameCtrl = "URL page name"
  180.  
  181.        
  182. class Foscam(eg.PluginBase):
  183.     name = "FOSCAM FI8908W FI8918W / HEDEN VisionCam"
  184.     description = "Take control of your ipcam, and get new features (patrolling, etc)."
  185.    
  186.     def __start__(self,ip="",port=8100, browserPath='C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe', login="admin",pwd="",safeHTTPMode = False, debug= False):     
  187.         self.debug = debug
  188.         self.ip = ip
  189.         self.port = port
  190.         self.browserPath = browserPath
  191.         self.login = login
  192.         self.pwd = pwd
  193.         self.safeHTTPMode = safeHTTPMode
  194.         self.__SetFoscamMainCommands__()
  195.    
  196.     def __init__(self):
  197.         self.AddAction(StartPatrolling)
  198.         self.AddAction(SnapshotTimer)      
  199.         self.AddAction(StopPatrolling)
  200.         self.AddAction(StopTimedSnapshot)      
  201.         self.AddAction(SaveSnapshot)
  202.         self.AddAction(ShowSnapshot)
  203.         self.AddAction(VideoStream)
  204.         self.AddAction(GoToPreset)
  205.         self.AddAction(RecordPreset)
  206.         self.AddAction(SwitchIR)
  207.         self.AddAction(SwitchAlarm)
  208.         self.AddAction(SendRawCommand)
  209.         self.AddAction(VideoBroadcast)
  210.        
  211.     def __stop__(self):
  212.         if hasattr(self, "stopPatrolThreadEvent") :
  213.             self.StopPatrolling()
  214.         if hasattr(self, "stopSnapshotTimerThreadEvent") :
  215.             self.StopTimedSnapshot()
  216.            
  217.     def __SetFoscamMainCommands__(self) :
  218.         self.CMDS = {'IpCamURL': "http://{0}:{1}/".format(self.ip,self.port)}
  219.         self.CMDS['UserLogin'] = "user={0}&pwd={1}".format(self.login,self.pwd)
  220.         self.CMDS['SnapshotUrl'] =  self.CMDS['IpCamURL'] + "snapshot.cgi?" + self.CMDS['UserLogin']
  221.         self.CMDS['VideoStreamUrl'] =  self.CMDS['IpCamURL'] + "videostream.asf?" + self.CMDS['UserLogin']
  222.         self.CMDS['SetCommandUrl'] =  self.CMDS['IpCamURL'] + "decoder_control.cgi?command={0}&" + self.CMDS['UserLogin']
  223.         self.CMDS['SwitchAlarmUrl'] =  self.CMDS['IpCamURL'] +"set_alarm.cgi?motion_armed={0}&motion_sensitivity={1}&input_armed={2}&iolinkage={3}&mail={4}&upload_interval={5}&schedule_enable=0&schedule_sun_0=0&schedule_sun_1=0&schedule_sun_2=0&schedule_mon_0=0&schedule_mon_1=0&schedule_mon_2=0&schedule_tue_0=0&schedule_tue_1=0&schedule_tue_2=0&schedule_wed_0=0&schedule_wed_1=0&schedule_wed_2=0&schedule_thu_0=0&schedule_thu_1=0&schedule_thu_2=0&schedule_fri_0=0&schedule_fri_1=0&schedule_fri_2=0&schedule_sat_0=0&schedule_sat_1=0&schedule_sat_2=0&" + self.CMDS['UserLogin']
  224.        
  225.     def SwitchAlarm(self, motion_armed=0,motion_sensitivity=10,input_armed=0,iolinkage=0,mail=0,upload_interval=10) :
  226.         if(self.debug):
  227.             print("Foscam debug : " + self.CMDS['SwitchAlarmUrl'].format(motion_armed,10-motion_sensitivity,input_armed,iolinkage,mail,upload_interval))
  228.         self.SendHTTP(self.CMDS['SwitchAlarmUrl'].format(motion_armed,10-motion_sensitivity,input_armed,iolinkage,mail,upload_interval))
  229.    
  230.     def GotoPreset(self,preset):
  231.         # Stopping patrol before any action
  232.         if hasattr(self, "stopPatrolThreadEvent") :
  233.             self.StopPatrolling()
  234.         self.SendHTTP(self.CMDS['SetCommandUrl'].format(30 + preset * 2  -1))
  235.        
  236.     def RecordPreset(self,preset):
  237.         # Stopping patrol before any action
  238.         if hasattr(self, "stopPatrolThreadEvent") :
  239.             self.StopPatrolling()
  240.         self.SendHTTP(self.CMDS['SetCommandUrl'].format(30 + preset * 2 -2 ))
  241.  
  242.     def StopPatrolling(self):
  243.         self.stopPatrolThreadEvent.set()
  244.        
  245.     def StopTimedSnapshot(self):
  246.         self.stopSnapshotTimerThreadEvent.set()
  247.        
  248.     def SwitchIR(self,bSwitchIR)    :
  249.         if(bSwitchIR) :
  250.             self.SendHTTP(self.CMDS['SetCommandUrl'].format(95))
  251.         else :
  252.             self.SendHTTP(self.CMDS['SetCommandUrl'].format(94))
  253.        
  254.     def SendRawCommand(self,command)    :
  255.         self.SendHTTP(self.CMDS['SetCommandUrl'].format(command))
  256.    
  257.     def SaveSnapshot(self, folder):
  258.             # saving a snapshot
  259.             opener1 = urllib2.build_opener()
  260.             page1 = opener1.open(self.CMDS['SnapshotUrl'])
  261.             my_picture = page1.read()
  262.             now = datetime.now()
  263.             filename = folder + "%i%i%i_%ih%i-%i.jpg" % (now.year,now.month, now.day, now.hour,now.minute,now.second)          
  264.             fout = open(filename, "wb")
  265.             fout.write(my_picture)
  266.             fout.close()
  267.             print "Foscam : saved " + "%i%i%i_%ih%i-%i.jpg" % (now.year,now.month, now.day, now.hour,now.minute,now.second)        
  268.        
  269.     def SnapshotTimer(self, stopSnapshotTimerThreadEvent, interval=None, duration=1440, folder = None):
  270.         if duration <>  0 :
  271.             self.timerEndTime = datetime.now()  + timedelta( minutes = duration)
  272.             Text.timerSnapshotInfo.format(interval, self.timerEndTime.isoformat(' '))
  273.         while not stopSnapshotTimerThreadEvent.isSet():
  274.             # saving snapshot
  275.             opener1 = urllib2.build_opener()
  276.             page1 = opener1.open(self.CMDS['SnapshotUrl'])
  277.             my_picture = page1.read()
  278.             now = datetime.now()
  279.             filename = folder + "%i%i%i_%ih%i-%i.jpg" % (now.year,now.month, now.day, now.hour,now.minute,now.second)          
  280.             fout = open(filename, "wb")
  281.             fout.write(my_picture)
  282.             fout.close()
  283.             print "Foscam : saved " + "%i%i%i_%ih%i-%i.jpg" % (now.year,now.month, now.day, now.hour,now.minute,now.second)        
  284.             # Let's stop the thread if necessary
  285.             if duration <>  0 :
  286.                 if datetime.now() > self.timerEndTime :
  287.                     self.stopSnapshotTimerThreadEvent.set()
  288.                     print Text.timerSnapshotEndInfo
  289.            
  290.             # Wait n seconds before looping
  291.             stopSnapshotTimerThreadEvent.wait(int(interval))
  292.    
  293.     def LoopPatrolling(self, stopPatrolThreadEvent, sleepTime, firstPosition, secondPosition,duration=1440):
  294.         if duration <>  0 :
  295.             self.patrolEndTime = datetime.now()  + timedelta( minutes = duration)
  296.             print Text.patrolLoopInfo.format(sleepTime, self.patrolEndTime.isoformat(' '))
  297.         self.currentPosition = firstPosition
  298.         while not stopPatrolThreadEvent.isSet():
  299.             # Preset call
  300.             self.SendHTTP(self.CMDS['SetCommandUrl'].format(30 + self.currentPosition  * 2 -1 ))
  301.             print "Foscam : patrolling to {0}".format(self.currentPosition)
  302.             # Switch from one preset to the other
  303.             if self.currentPosition == firstPosition :
  304.                 self.currentPosition = secondPosition
  305.             else :
  306.                 self.currentPosition = firstPosition
  307.             # Let's stop the thread if necessary
  308.             if duration <>  0 :
  309.                 if datetime.now() > self.patrolEndTime :
  310.                     self.stopPatrolThreadEvent.set()
  311.                     # Going back to the first preset
  312.                     self.SendHTTP(self.CMDS['SetCommandUrl'].format(30 + firstPosition  * 2 -1 ))
  313.                     print Text.patrolLoopEndInfo
  314.            
  315.             # Wait n seconds before looping
  316.             stopPatrolThreadEvent.wait(int(sleepTime))
  317.            
  318.     # This method was taken from the Execute.py file that comes with eventghost
  319.     def LaunchApp(
  320.         self,
  321.         application,
  322.         argument=''    
  323.     ):
  324.         returnValue = None
  325.         winState=0
  326.         waitForCompletion=False
  327.         priority=2
  328.         workingDir=""
  329.         #pathname = eg.ParseString(pathname)
  330.         pathname = eg.ParseString(application)
  331.         if not workingDir:
  332.             workingDir = dirname(abspath(pathname))
  333.         argument = eg.ParseString(argument)
  334.         commandLine = create_unicode_buffer('"%s" %s' % (pathname, argument))
  335.         startupInfo = STARTUPINFO()
  336.         startupInfo.cb = sizeof(STARTUPINFO)
  337.         startupInfo.dwFlags = STARTF_USESHOWWINDOW
  338.         startupInfo.wShowWindow = WINSTATE_FLAGS[winState]
  339.         priorityFlag = PRIORITY_FLAGS[priority]
  340.         processInformation = PROCESS_INFORMATION()
  341.         if(self.debug) :
  342.             print ("Foscam debug : launching " + application + " " + argument)
  343.         res = CreateProcess(
  344.             None,              # lpApplicationName
  345.             commandLine,       # lpCommandLine
  346.             None,              # lpProcessAttributes
  347.             None,              # lpThreadAttributes
  348.             False,             # bInheritHandles
  349.             priorityFlag|CREATE_NEW_CONSOLE, # dwCreationFlags
  350.             None,              # lpEnvironment
  351.             workingDir,        # lpCurrentDirectory
  352.             startupInfo,       # lpStartupInfo
  353.             processInformation # lpProcessInformation
  354.         )
  355.         if res == 0:
  356.             raise self.Exception(FormatError())
  357.         if waitForCompletion:
  358.             WaitForSingleObject(processInformation.hProcess, INFINITE)
  359.             exitCode = DWORD()
  360.             if not GetExitCodeProcess(
  361.                 processInformation.hProcess,
  362.                 byref(exitCode)
  363.             ):
  364.                 raise self.Exception(FormatError())
  365.             returnValue = exitCode.value
  366.         CloseHandle(processInformation.hProcess)
  367.         CloseHandle(processInformation.hThread)
  368.         return returnValue
  369.        
  370.     def LaunchSnapshot(self):
  371.         self.LaunchApp(self.browserPath , self.CMDS['SnapshotUrl'])
  372.    
  373.     def SendHTTP(self, url) :
  374.         if(self.safeHTTPMode) :
  375.             self.LaunchApp(self.browserPath , url)
  376.         else :
  377.             urllib2.urlopen(url)
  378.    
  379.     def LaunchVideoStream(self, bShow = True, bRecord = False, folder = "c:\\temp\\",vCodec="mp4v", bitrate = 2048, bAudioRecord = True, bFullScreenVideo = True, duration = 60 ):
  380.         now = datetime.now()
  381.         file = "%i%i%i_%ih%i-%i.avi" % (now.year,now.month, now.day, now.hour,now.minute,now.second)   
  382.         filename = folder + "\\" + file
  383.         appArgument = " --extraintf=rc --rc-host=localhost:1234 --rc-quiet --rc-show-pos --run-time %i --stop-time=%i --no-qt-privacy-ask --no-qt-error-dialogs "%(duration,duration) #  --extraintf logger --verbose=0 --logmode=text --file-logging --save-config --logfile=%s
  384.         if(not bShow):
  385.             appArgument = " -I" + appArgument
  386.         if(bAudioRecord) :
  387.             audioArgument = "acodec=mp3,ab=64,channels=1,samplerate=8000"
  388.         else :
  389.             audioArgument = "noaudio"
  390.             appArgument += " --volume 0 "          
  391.            
  392.         if(bShow and not bRecord):
  393.             appArgument += self.CMDS['VideoStreamUrl']
  394.             if bFullScreenVideo :
  395.                 appArgument += "--fullscreen"
  396.         elif (bShow and bRecord):
  397.             appArgument += "\"" + self.CMDS['VideoStreamUrl'] + "\" --sout=#transcode{{vcodec=" + vCodec + ",vb=%i"%bitrate + "," + audioArgument +"}:duplicate{{dst=display,dst=std{{access=file,mux=ts,dst='" + filename + "'}}'"
  398.             if bFullScreenVideo :
  399.                 appArgument += " --fullscreen"
  400.         elif (not bShow and bRecord):
  401.             appArgument += "\"" + self.CMDS['VideoStreamUrl'] + "\" --sout=#transcode{{vcodec=" + vCodec + ",vb=%i"%bitrate + ',' + audioArgument +'}:std{{access=file,mux=ts,dst=' + filename
  402.             appArgument += "}"
  403.        
  404.         if (bRecord) :
  405.             self.lastVideoRecord = filename
  406.        
  407.         appArgument += "  vlc://quit"
  408.        
  409.         if not hasattr(self, "videoRecordCount") :
  410.             self.videoRecordCount = 1
  411.        
  412.         try :
  413.             eg.plugins.VLC.Start(appArgument)
  414.         except Exception as exc :
  415.             print("Foscam Error : VLC's eventghost plugin is not installed. Please add the VLC plugin (and check that VLC is installed).")
  416.             print(exc)
  417.             pass       
  418.         else :
  419.             # The following code detects and compensates a possible vlc/stream failure.
  420.             time.sleep(5)
  421.             try :
  422.                 os.remove(folder + "\\" + file)            
  423.                 if(self.debug):
  424.                     print("Foscam debug : Getting camera stream failed, trying again (%i)"%self.videoRecordCount)              
  425.                 self.videoRecordCount += 1
  426.                 if(self.videoRecordCount < 6):
  427.                     self.LaunchVideoStream(bShow, bRecord, folder,vCodec, bitrate, bAudioRecord, bFullScreenVideo, duration )              
  428.             except WindowsError as wError :
  429.                 print("Foscam : Recording " + file + " (%is)"%duration)
  430.                 self.videoRecordCount = 0
  431.                 pass
  432.             except Exception as exc :
  433.                 print("Foscam error : ")               
  434.                 print type(exc)            
  435.                 print exc
  436.                 pass   
  437.  
  438.     def BroadcastVideo(self, bShow = True, protocol = "rtsp", port = "5554", pageName="stream.sdp"):
  439.         if not hasattr(self, "lastVideoRecord") :
  440.             print ("Foscam : Broadcast can't start because there is no new record")
  441.             return
  442.        
  443.         if(not bShow) :
  444.             appArgument = " -I "
  445.         else :
  446.             appArgument = ""
  447.            
  448.         # In case of problems, add this to the argument : --extraintf logger --verbose=2 --logmode=text --file-logging --save-config --logfile=C:\\temp\\My_Broadcast_vlc_log.txt
  449.         appArgument += "--sout=#transcode{soverlay,no-audio,vcodec=mp4v,width=160,height=90,vfilter=\"canvas{width=160,height=90,aspect=16:9}\",fps=15,vb=200,venc=x264{vbv-bufsize=500,partitions=all,level=12,no-cabac,subme=7,threads=4,ref=2,mixed-refs=1,bframes=0,min-keyint=1,keyint=50,trellis=2,direct=auto,qcomp=0.0,qpmax=51}}:gather:rtp{mp4a-latm,sdp=rtsp://0.0.0.0:%i/%s}' \"%s\"  vlc://quit"%(port,pageName,self.lastVideoRecord)
  450.         if(self.debug) :
  451.             print("Foscam debug:argument:" + appArgument)
  452.         eg.plugins.VLC.Start(appArgument)
  453.         print("Foscam : Streaming to rtsp://localhost:%i/%s the file %s"%(port,pageName,self.lastVideoRecord)   )
  454.        
  455.     def Configure(self, ip="",port=8100, browserPath="C:\\Program Files (x86)\\Mozilla Firefox\\Firefox.exe",  login="admin",pwd="",bSafeHTTPMode = False, bDebug = False):
  456.         panel = eg.ConfigPanel()
  457.         IPCamCtrl = panel.TextCtrl(ip)
  458.         PortCtrl = panel.SpinIntCtrl(port, max=65535)
  459.         LoginCtrl = panel.TextCtrl(login)
  460.         PwdCtrl = wx.TextCtrl(panel, 1, size=(150, -1), style=wx.TE_PASSWORD)
  461.         PwdCtrl.SetValue(pwd)
  462.         IPBox = panel.BoxedGroup(
  463.             Text.ipArea,
  464.             (Text.textBoxIPCamCtrl, IPCamCtrl),
  465.             (Text.textBoxPortCtrl, PortCtrl),
  466.             (Text.textBoxLoginCtrl, LoginCtrl),
  467.             (Text.textBoxPwdCtrl, PwdCtrl),
  468.         )
  469.         eg.EqualizeWidths(IPBox.GetColumnItems(0))
  470.         panel.sizer.Add(IPBox, 0, wx.EXPAND)
  471.        
  472.         BrowserPathCtrl = panel.TextCtrl(browserPath)
  473.  
  474.         MediaBox = panel.BoxedGroup(
  475.             Text.mediaArea,
  476.             (Text.textBoxBrowserPathCtrl, BrowserPathCtrl),
  477.         )
  478.         eg.EqualizeWidths(MediaBox.GetColumnItems(0))
  479.         panel.sizer.Add(MediaBox,10,wx.EXPAND)
  480.        
  481.         checkBoxSafeHttpModeCtrl = wx.CheckBox(panel, -1, "")
  482.         checkBoxSafeHttpModeCtrl.SetValue(bSafeHTTPMode)
  483.        
  484.         checkBoxDebugCtrl = wx.CheckBox(panel, -1, "")
  485.         checkBoxDebugCtrl.SetValue(bDebug)
  486.        
  487.         TroubleShootingBox = panel.BoxedGroup(
  488.             Text.troubleShootArea,
  489.             (Text.checkBoxSafeHttpModeCtrl,checkBoxSafeHttpModeCtrl),
  490.             (Text.checkBoxDebugCtrl,checkBoxDebugCtrl),        
  491.         )
  492.         eg.EqualizeWidths(TroubleShootingBox.GetColumnItems(0))
  493.         panel.sizer.Add(TroubleShootingBox,10,wx.EXPAND)
  494.        
  495.         while panel.Affirmed():
  496.             panel.SetResult(IPCamCtrl.GetValue(),PortCtrl.GetValue(),BrowserPathCtrl.GetValue(),LoginCtrl.GetValue(),PwdCtrl.GetValue(),checkBoxSafeHttpModeCtrl.GetValue(),checkBoxDebugCtrl.GetValue())
  497.  
  498.            
  499. class StopPatrolling(eg.ActionBase):
  500.     name = "Stop patrolling"
  501.     description = "Camera won't patrol anymore."
  502.  
  503.     def __call__(self):
  504.         self.plugin.StopPatrolling()
  505.        
  506. class SwitchIR(eg.ActionBase):
  507.     name = "IR (switch)"
  508.     description = "Switch IR LEDs ON or OFF."
  509.     iconFile = "ir"
  510.  
  511.     def __call__(self,bSwitchIR):
  512.         self.plugin.SwitchIR(bSwitchIR)    
  513.    
  514.     def Configure(self, bFullScreenVideo = True):
  515.         panel = eg.ConfigPanel()
  516.         checkBoxSwitchIRCtrl = wx.CheckBox(panel, -1, "")
  517.         checkBoxSwitchIRCtrl.SetValue(bFullScreenVideo)
  518.         IRBox = panel.BoxedGroup(
  519.             Text.switchIR,
  520.             (Text.switchIR,checkBoxSwitchIRCtrl),
  521.         )
  522.         eg.EqualizeWidths(IRBox.GetColumnItems(0))
  523.         panel.sizer.Add(IRBox,10,wx.EXPAND)
  524.  
  525.         while panel.Affirmed():
  526.             panel.SetResult(checkBoxSwitchIRCtrl.GetValue())
  527.            
  528. class StartPatrolling(eg.ActionBase):
  529.     name = "Start patrolling"
  530.     description = "Camera will switch from one preset to the other every n seconds."
  531.     iconFile = "patrol"
  532.  
  533.     def __call__(self, sleepTime=None, pos1 = 1, pos2 = 2, duration = 1440):
  534.         self.plugin.stopPatrolThreadEvent = Event()
  535.         self.plugin.threadPatrol = Thread(
  536.             target=self.plugin.LoopPatrolling,
  537.             args=(self.plugin.stopPatrolThreadEvent,sleepTime,pos1, pos2,duration  )
  538.         )
  539.         self.plugin.threadPatrol.start()
  540.        
  541.     def Configure(self, sleepTime=120, pos1 = 1, pos2 = 2, duration = 1440):
  542.         panel = eg.ConfigPanel()
  543.         sleepCtrl = panel.SpinIntCtrl(sleepTime, max=65535)
  544.         pos1Ctrl = panel.SpinIntCtrl(pos1, min=1, max=16)
  545.         pos2Ctrl = panel.SpinIntCtrl(pos2, min=1, max=16)
  546.         durationCtrl = panel.SpinIntCtrl(duration, min=0, max=65535)
  547.         PatrolBox = panel.BoxedGroup(
  548.             Text.patrolSleepArea,
  549.             (Text.patrolSleepCtrl, sleepCtrl),
  550.             (Text.patrolPos1, pos1Ctrl),
  551.             (Text.patrolPos2, pos2Ctrl),
  552.             (Text.durationCtrl, durationCtrl),
  553.         )
  554.         eg.EqualizeWidths(PatrolBox.GetColumnItems(0))
  555.         panel.sizer.Add(PatrolBox, 1, wx.EXPAND)
  556.         while panel.Affirmed():
  557.             panel.SetResult(sleepCtrl.GetValue(),pos1Ctrl.GetValue(),pos2Ctrl.GetValue(), durationCtrl.GetValue())
  558.  
  559. class GoToPreset(eg.ActionBase):
  560.     name = "Go to preset"
  561.     description = "Camera will move to a specific preset."
  562.     iconFile = "preset"
  563.  
  564.     def __call__(self, preset=1):
  565.         self.plugin.GotoPreset(preset)
  566.        
  567.     def Configure(self, preset=1):
  568.         panel = eg.ConfigPanel()
  569.         presetCtrl = panel.SpinIntCtrl(preset, min=1, max=16)
  570.         presetBox = panel.BoxedGroup(
  571.             Text.presetGotoArea,
  572.             (Text.presetCtrl, presetCtrl),
  573.         )
  574.         panel.sizer.Add(presetBox, 1, wx.EXPAND)
  575.         while panel.Affirmed():
  576.             panel.SetResult(presetCtrl.GetValue())             
  577.            
  578. class RecordPreset(eg.ActionBase):
  579.     name = "Set preset"
  580.     description = "Selected preset will be replaced by the current camera position. Beware that you will lose the previous setting."
  581.  
  582.     def __call__(self, preset=1):
  583.         self.plugin.RecordPreset(preset)
  584.        
  585.     def Configure(self, preset=1):
  586.         panel = eg.ConfigPanel()
  587.         presetCtrl = panel.SpinIntCtrl(preset, min=1, max=16)
  588.         presetBox = panel.BoxedGroup(
  589.             Text.presetRecordArea,
  590.             (Text.presetCtrl, presetCtrl),
  591.         )
  592.         panel.sizer.Add(presetBox, 1, wx.EXPAND)
  593.         while panel.Affirmed():
  594.             panel.SetResult(presetCtrl.GetValue())                 
  595.            
  596. class ShowSnapshot(eg.ActionBase):
  597.     name = "Snapshot (show)"
  598.     description = "Open a snapshot in the predefined browser."
  599.     iconFile = "snapshot"
  600.  
  601.     def __call__(self):
  602.         self.plugin.LaunchSnapshot()
  603.  
  604. class VideoStream(eg.ActionBase):
  605.     name = "Video (show/record)"
  606.     description = "Open the media app and show or record the camera video stream. VLC is mandatory in order to record."
  607.     iconFile = "video"
  608.  
  609.     def __call__(self, bShow = True, bRecord = False, folder = "c:\\temp\\",vCodec="mp4v", bitrate = 2048, bAudioRecord = True, bFullScreenVideo = True, duration = 60):
  610.         self.plugin.LaunchVideoStream(bShow, bRecord, folder,vCodec, bitrate, bAudioRecord, bFullScreenVideo, duration)    
  611.  
  612.     def Configure(self, bShow = True, bRecord = False, folder = "c:\\temp\\",vCodec="mp4v", bitrate = 2048, bAudioRecord = True, bFullScreenVideo = True, duration = 60):
  613.         panel = eg.ConfigPanel()
  614.        
  615.         checkBoxShowCtrl = wx.CheckBox(panel, -1, "")
  616.         checkBoxShowCtrl.SetValue(bShow)
  617.        
  618.         checkBoxRecordCtrl = wx.CheckBox(panel, -1, "")
  619.         checkBoxRecordCtrl.SetValue(bRecord)       
  620.         folderCtrl = panel.TextCtrl(folder)
  621.         codecCtrl = panel.TextCtrl(vCodec)
  622.         bitrateCtrl = panel.SpinIntCtrl(bitrate)
  623.         checkBoxAudioRecordCtrl = wx.CheckBox(panel, -1, "")
  624.         checkBoxAudioRecordCtrl.SetValue(bAudioRecord)
  625.         checkBoxStreamPlayerFullScreenCtrl = wx.CheckBox(panel, -1, "")
  626.         checkBoxStreamPlayerFullScreenCtrl.SetValue(bFullScreenVideo)
  627.         durationCtrl = panel.SpinIntCtrl(duration, min=5, max=65535)
  628.        
  629.         videoBox = panel.BoxedGroup(
  630.             Text.videoArea,
  631.             (Text.checkBoxShowCtrl, checkBoxShowCtrl),
  632.             (Text.checkBoxRecordCtrl, checkBoxRecordCtrl),
  633.             (Text.checkBoxAudioRecordCtrl,checkBoxAudioRecordCtrl),        
  634.             (Text.folderCtrl, folderCtrl),
  635.             (Text.textBoxcodecCtrl, codecCtrl),
  636.             (Text.textBoxbitrateCtrl, bitrateCtrl),
  637.             (Text.checkBoxStreamPlayerFullScreenCtrl,checkBoxStreamPlayerFullScreenCtrl),
  638.             (Text.durationVideoCtrl, durationCtrl),
  639.         )
  640.         eg.EqualizeWidths(videoBox.GetColumnItems(0))
  641.         panel.sizer.Add(videoBox, 1, wx.EXPAND)
  642.         while panel.Affirmed():
  643.             panel.SetResult(checkBoxShowCtrl.GetValue(),checkBoxRecordCtrl.GetValue(),folderCtrl.GetValue(),codecCtrl.GetValue(),bitrateCtrl.GetValue(),checkBoxAudioRecordCtrl.GetValue(),checkBoxStreamPlayerFullScreenCtrl.GetValue(),durationCtrl.GetValue())
  644.  
  645. class VideoBroadcast(eg.ActionBase):
  646.     name = "Video (broadcast)"
  647.     description = "Broadcast the last recorded file to a specific URL."
  648.     iconFile = "video"
  649.  
  650.     def __call__(self, bShow = True, protocol = "rtsp", port = "5554", pageName="stream.sdp"):
  651.         self.plugin.BroadcastVideo(bShow, protocol, port,pageName)     
  652.  
  653.     def Configure(self, bShow = True, protocol = "rtsp", port = "5554", pageName="stream.sdp"):
  654.         panel = eg.ConfigPanel()
  655.        
  656.         protocolCtrl = panel.TextCtrl(protocol)
  657.         pageNameCtrl = panel.TextCtrl(pageName)
  658.         portCtrl = panel.SpinIntCtrl(port)
  659.         checkBoxShowCtrl = wx.CheckBox(panel, -1, "")
  660.         checkBoxShowCtrl.SetValue(bShow)
  661.        
  662.         videoBox = panel.BoxedGroup(
  663.             Text.videoArea,
  664.             (Text.checkBoxShowCtrl, checkBoxShowCtrl),
  665.             (Text.protocolCtrl, protocolCtrl),
  666.             (Text.portCtrl, portCtrl),
  667.             (Text.pageNameCtrl, pageNameCtrl)
  668.         )
  669.         eg.EqualizeWidths(videoBox.GetColumnItems(0))
  670.         panel.sizer.Add(videoBox, 1, wx.EXPAND)
  671.         while panel.Affirmed():
  672.             panel.SetResult(checkBoxShowCtrl.GetValue(),protocolCtrl.GetValue(),portCtrl.GetValue(),pageNameCtrl.GetValue())           
  673.            
  674. class SendRawCommand(eg.ActionBase):
  675.     name = "Custom command"
  676.     description = "Any Foscam command using the 'decoder_control.cgi?command={commandNumber}' schema can be sent."
  677.  
  678.     def __call__(self, command=1):
  679.         self.plugin.SendRawCommand(command)
  680.        
  681.     def Configure(self, command=1):
  682.         panel = eg.ConfigPanel()
  683.         presetCtrl = panel.SpinIntCtrl(command, min=0, max=65535)
  684.         presetBox = panel.BoxedGroup(
  685.             Text.commandNumber,
  686.             (Text.commandNumber, presetCtrl),
  687.         )
  688.         panel.sizer.Add(presetBox, 1, wx.EXPAND)
  689.         while panel.Affirmed():
  690.             panel.SetResult(presetCtrl.GetValue())     
  691.  
  692. class   SwitchAlarm(eg.ActionBase):
  693.     name = "Alarm (switch)"
  694.     description = "Switch ON/OFF the alarm with all parameters."
  695.     iconFile = "alarm"
  696.    
  697.     def __call__(self, motion_armed=0,motion_sensitivity=10,input_armed=0,iolinkage=0,mail=0,upload_interval=10):
  698.         self.plugin.SwitchAlarm(motion_armed,motion_sensitivity,input_armed,iolinkage,mail,upload_interval)
  699.  
  700.     def Configure(self, motion_armed=0,motion_sensitivity=10,input_armed=0,iolinkage=0,mail=0,upload_interval=10):
  701.         panel = eg.ConfigPanel()
  702.         MotionCtrl = panel.SpinIntCtrl(motion_armed,min=0, max=1)
  703.         SensitivityCtrl = panel.SpinIntCtrl(motion_sensitivity,min=1, max=10)
  704.         InputCtrl = panel.SpinIntCtrl(input_armed,min=0, max=1)
  705.         IOCtrl = panel.SpinIntCtrl(iolinkage,min=0, max=1)
  706.         MailCtrl = panel.SpinIntCtrl(mail,min=0, max=1)
  707.         IntervalCtrl = panel.SpinIntCtrl(upload_interval,min=0, max=65535)
  708.  
  709.         AlarmBox = panel.BoxedGroup(
  710.             Text.alarmArea,
  711.             (Text.alarmMotionCtrl, MotionCtrl),        
  712.             (Text.alarmMailCtrl, MailCtrl),
  713.         )
  714.        
  715.         eg.EqualizeWidths(AlarmBox.GetColumnItems(0))
  716.         panel.sizer.Add(AlarmBox, 0, wx.EXPAND)
  717.        
  718.         AlarmMiscBox = panel.BoxedGroup(
  719.             Text.alarmMiscArea,
  720.             (Text.alarmSensitivityCtrl, SensitivityCtrl),
  721.             (Text.alarmInputCtrl, InputCtrl),
  722.             (Text.alarmIOCtrl, IOCtrl),
  723.             (Text.alarmIntervalCtrl, IntervalCtrl),
  724.         )
  725.        
  726.         eg.EqualizeWidths(AlarmMiscBox.GetColumnItems(0))
  727.         panel.sizer.Add(AlarmMiscBox, 0, wx.EXPAND)
  728.                
  729.         while panel.Affirmed():
  730.             panel.SetResult(MotionCtrl.GetValue(),SensitivityCtrl.GetValue(),InputCtrl.GetValue(),IOCtrl.GetValue(),MailCtrl.GetValue(),IntervalCtrl.GetValue())
  731.  
  732. class SnapshotTimer(eg.ActionBase):
  733.     name = "Snapshot (timer)"
  734.     description = "Chose an interval (seconds) and multiple snapshots will be created in the save folder."
  735.     iconFile = "snapshot"
  736.  
  737.     def __call__(self, interval=None, duration=1440, folder = None):
  738.         self.plugin.stopSnapshotTimerThreadEvent = Event()
  739.         self.plugin.threadTimer = Thread(
  740.             target=self.plugin.SnapshotTimer,
  741.             args=(self.plugin.stopSnapshotTimerThreadEvent,interval, duration,folder )
  742.         )
  743.         self.plugin.threadTimer.start()
  744.        
  745.     def Configure(self, interval=120, duration=1440, folder = "c:\\temp\\"):
  746.         panel = eg.ConfigPanel()
  747.         intervalTimeCtrl = panel.SpinIntCtrl(interval, min=1, max=65535)
  748.         durationCtrl = panel.SpinIntCtrl(duration, min=0, max=65535)
  749.         folderCtrl = panel.TextCtrl(folder)
  750.         TimerBox = panel.BoxedGroup(
  751.             Text.timerArea,
  752.             (Text.intervalTimeCtrl, intervalTimeCtrl),
  753.             (Text.durationCtrl, durationCtrl),
  754.             (Text.folderCtrl, folderCtrl),
  755.         )
  756.         panel.sizer.Add(TimerBox, 1, wx.EXPAND)
  757.         while panel.Affirmed():
  758.             panel.SetResult(intervalTimeCtrl.GetValue(),durationCtrl.GetValue(),folderCtrl.GetValue())
  759.  
  760. class StopTimedSnapshot(eg.ActionBase):
  761.     name = "Stop timed snapshots"
  762.     description = "Snapshots won't be saved anymore."
  763.  
  764.     def __call__(self):
  765.         self.plugin.StopTimedSnapshot()
  766.  
  767. class SaveSnapshot(eg.ActionBase):
  768.     name = "Snapshot (save)"
  769.     description = "Chose the save folder."
  770.     iconFile = "snapshot"
  771.  
  772.     def __call__(self, folder = None):
  773.         self.plugin.SaveSnapshot(folder)
  774.        
  775.     def Configure(self, folder = "c:\\temp\\"):
  776.         panel = eg.ConfigPanel()
  777.         folderCtrl = panel.TextCtrl(folder)
  778.         SnapBox = panel.BoxedGroup(
  779.             "",
  780.             (Text.folderCtrl, folderCtrl),
  781.         )
  782.         panel.sizer.Add(SnapBox, 1, wx.EXPAND)
  783.         while panel.Affirmed():
  784.             panel.SetResult(folderCtrl.GetValue())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement