Turning a webcam into a home security monitor while you’re away
Due to security concerns in our vicinity last year, I needed a way to keep tabs on our home while the whole family was away on vacation. The idea was to be able to view images of your home, live over the internet from whereever we were. CCTV solutions weren’t an option as they were expensive and none seemed to have a remote viewing option. I believe now there are advanced Logitech webcams in the market that also pivot and stream images to the net, but again they come at a price, and don’t take care of a few things like problems with your internet connection or laptop power when you’re not available to take care of them.
However, there are freeware/shareware solutions on the internet that allow you to capture your webcam and stream it online, even at a particular schedule.The software that I used was a super little app called Active Webcam from Pysoft.
Further, I needed a software that would take care of laptop restarts/windows crashes/net connection blips (and also auto logging into the net account if the login expires every 24 hrs) and that would automatically start Active Webcam every time the system started up – I decided to code that in VB.
Apart from the software I also needed my personal laptop, regular webcam and a DSL internet connection. I had gprs activated on my phone as well, in order to view the images uploaded.
First, i installed Active Webcam and set it up so it would stream images from the webcam to my website at a specific URL. (Yes, you need a website host that offers FTP where the images will be uploaded to – possibly there are options to upload to photo services like flickr/photobucket too, or to send emails to you with attached images)
Second, compile the code below into an exe and include that exe in the Windows Startup so it runs at system startup.
When this program runs, it will
- check for internet connection availability, and if not available will to restart the local modem
- if the internet connection doesn’t come up after 3 modem restarts, it will restart Windows. It won’t restart windows more than once in 15 mins though.
- log the laptop’s battery status
- log everything to a remote php file so the logs can be viewed remotely too
Download the entire VB project.
This VB project has :
1. a form called frmMain
2. a module called Module1.bas
The code for both is shown below – a lot of the sections came from various sources on the net, so no claims there and a big thanks to them. Also, it all seemed to work at the time.
Also there are certain urls – while most are simply used to check the internet connection, the ’192.168.1.1′ is my modem’s local admin page that you may need to change accordingly. (In order to restart the modem, I used the code here to login to the local admin at 192.168.1.1 and post my username/password etc to the appropriate file (restartmodem.htm))
————————————————————————————————————
frmMain.frm – code
Private Declare Function InternetGetConnectedState Lib “wininet.dll” (ByRef dwFlags As Long, ByVal dwReserved As Long) As Long
Private Declare Function InternetCheckConnection Lib “wininet.dll” Alias “InternetCheckConnectionA” (ByVal lpszUrl As String, ByVal dwFlags As Long, ByVal dwReserved As Long) As Long
Private Declare Function SendMessage Lib “user32″ Alias “SendMessageA” (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function OpenProcess Lib “kernel32″ (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib “kernel32″ (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib “kernel32″ (ByVal hObject As Long) As LongPrivate Declare Function GetExitCodeProcess Lib “kernel32″ _
(ByVal hProcess As Long, lpExitCode As Long) As LongPrivate Declare Function TerminateProcess Lib “kernel32″ _
(ByVal hProcess As Long, ByVal uExitCode As Long) As LongPrivate Const FLAG_ICC_FORCE_CONNECTION = &H1
Private Declare Function NetUserGetInfo Lib “netapi32″ (lpServer As Any, lpUserName As Any, ByVal Level As Long, lpBuffer As Any) As Long
Private Declare Function GetUserName Lib “advapi32.dll” Alias “GetUserNameA” (ByVal lpBuffer As String, nSize As Long) As Long
Private Declare Function GetComputerName Lib “kernel32″ Alias “GetComputerNameA” (ByVal lpBuffer As String, nSize As Long) As Long
Private Declare Sub CopyMemory Lib “kernel32″ Alias “RtlMoveMemory” (Destination As Any, Source As Any, ByVal Length As Long)Private Const UNLEN As Long = 256 ‘ Maximum username length
Private Const CNLEN As Long = 31 ‘ Maximum computer name length
Private Const NERR_Success As Long = 0&Dim actcamShellID As Long
Dim nwErrorCounter As Integer
Const nwErrorThreshold = 1Dim WinHttpReq As WinHttp.WinHttpRequest
Const HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0
Const HTTPREQUEST_SETCREDENTIALS_FOR_PROXY = 1Public Enum shutdownTypes
Logoff = 0
Shutdown = 1
Reboot = 2
Force = 4
PowerOff = 8End Enum
Private Type LUID
UsedPart As Long
IgnoredForNowHigh32BitPart As LongEnd Type
Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
TheLuid As LUID
Attributes As LongEnd Type
‘
‘The function used to actually send the request to shutdown windows. Set the ‘shutdownTypes’
‘parameter to whether you want windows to “shutdown, reboot, logOff, ect…”
Private Declare Function ExitWindowsEx Lib “user32″ (ByVal shutdownType As Long, ByVal dwReserved As _
Long) As Long
‘
‘Will get a handle to the process this function is called.
Private Declare Function GetCurrentProcess Lib “kernel32″ () As Long
‘
‘
‘The functions below are all used to give the application that the library is bound to the proper privilege so
‘the OS will allow the app to Shutdown Windows.
‘
‘
Private Declare Function OpenProcessToken Lib “advapi32″ (ByVal ProcessHandle As Long, ByVal _
DesiredAccess As Long, ByRef TokenHandle As Long) As Long
‘
Private Declare Function LookupPrivilegeValue Lib “advapi32″ Alias “LookupPrivilegeValueA” (ByVal _
lpSystemName As String, ByVal lpName As String, ByRef lpLuid As LUID) As Long
‘
Private Declare Function AdjustTokenPrivileges Lib “advapi32″ (ByVal TokenHandle As Long, ByVal _
DisableAllPrivileges As Boolean, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As _
Long, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef ReturnLength As Long) As LongPrivate Sub cmdStart_Click()
‘ moved below 2 to formm load now
‘Log “Starting timer…”
‘Timer1.Enabled = True‘In my case I started Active Webcam using the windows startup options – if you want this healthchecker to start the app, uncomment this line and also the one cmdStop_Click()
‘actcamShellID = Shell(“C:\Program Files\Active WebCam\WebCam.exe”, vbMinimizedNoFocus)
End SubPrivate Sub cmdStop_Click()
Timer1.Enabled = False
Log “Stopped timer.”‘Debug.Print EndShelledProcess(actcamShellID)
End SubPrivate Sub Form_Load()
Set WinHttpReq = New WinHttpRequest
Log “Application started…”, 1Log “Starting timer…”
Timer1.Enabled = TruenwErrorCounter = 0
End SubPrivate Sub Form_Terminate()
Log “Application terminated.”, 1
End SubPrivate Sub Timer1_Timer()
DoEvents
Dim nwTrulyBad As IntegerIf (nwErrorCounter > nwErrorThreshold) Then
‘ too many times nw error – just restart network
Log “Timer off…”
Timer1.Enabled = False
Log “restarting network”nwTrulyBad = 0
While (nwTrulyBad < 3)
Log “… restart attempt ” & (nwTrulyBad + 1)
restartModem
If (InternetCheckConnection(“http://web1219.ixwebhosting.com”, FLAG_ICC_FORCE_CONNECTION, 0&) <> 0) Then
Log “… restart attempt succeeded ”
nwTrulyBad = 0
‘Exit Do
Else
nwTrulyBad = nwTrulyBad + 1
Log “… restart attempt failed.”
End If
WendIf (nwTrulyBad >= 3) Then
Log “… Modem restart failed. Need to restart system”
‘ Network did nost cmoe up even after restarting modem 3 times. Should restart system now.
‘ however do not restart if last system reboot time was less than 15 mins ago
If ((Now – LastLogon2()) > 0.0104) Then
shutdownWindowsOS shutdownTypes.Reboot Or Force
Log “PC RESTARTING”
Else
Log “TOO SOON TO RESTART”
End If
End IfnwErrorCounter = 0
End IfTimer1.Enabled = True
If InternetCheckConnection(“http://web1219.ixwebhosting.com”, FLAG_ICC_FORCE_CONNECTION, 0&) = 0 Then
nwErrorCounter = nwErrorCounter + 1
Timer1.Interval = 15000
Log “No internet connection detected…nw counter: ” & nwErrorCounter
Else
nwErrorCounter = 0
Timer1.Interval = 10000
Log “Internet connection detected…”
End IfLog “Battery status: ” & GetBatteryStatus()
If (InStr(1, GetBatteryStatus(), “Low”)) Then
Log “BatteryRed” & GetBatteryStatus(), 1
End If
End SubPrivate Sub restartModem()
DoEvents
‘ Assemble an HTTP request.s
WinHttpReq.Open “POST”, “http://192.168.1.1/cgi-bin/webcm”, False‘ Set the user name and password.
WinHttpReq.SetCredentials “admin”, “admin”, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER‘Set Content-Type header
WinHttpReq.SetRequestHeader “Content-Type”, “application/x-www-form-urlencoded”On Error GoTo nextpt
‘Send the form data To URL As POST binary request
WinHttpReq.Send “getpage=”"http://192.168.1.1/cgi-bin/html/tools/restartmodem.htm”"&var:com=”"restart”"&var:ip=”"”"&var:restart=”"1″”&logic:command/ppp_disconnect=”"”"”‘ Display the status code and response headers.
Debug.Print WinHttpReq.Status & ” ” & WinHttpReq.StatusText
Debug.Print WinHttpReq.GetAllResponseHeaders & “ ” & WinHttpReq.ResponseTextnextpt:
End SubPublic Sub Log(txt As String, Optional priority As Integer)
‘txtLog.Text = txtLog.Text & vbNewLine & txt‘Open “c:\hclog.txt” For Append As #2
‘Print #2, Now
‘Print #2, txt
‘Print #2, String(91, “*”)
‘Close #2If (priority = 1) Then
WinHttpReq.Open “GET”, “http://www.YOURSITE.com/log.php?txtlog=” & Now & “, ” & txt, True
WinHttpReq.Send
On Error Resume Next
End If
End Sub
Public Function EndShelledProcess(ShellReturnValue As Long) _
As Boolean‘PURPOSE: End a process started with VB’s Shell Statement
‘INPUT: Task ID returned by Shell
‘RETURNS: True if succesful, false otherwiseOn Error Resume Next
Dim hInst As Long
Dim hProcess As Long
Dim lExitCode As Long
Dim lRet As LonghInst = ShellReturnValue
If hInst = 0 Then Exit Function‘Get handle to process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, hInst)
If hProcess <> 0 Then
‘get exit code
GetExitCodeProcess hProcess, lExitCode
If lExitCode <> 0 Then
‘bye-bye
lRet = TerminateProcess(hProcess, lExitCode)
EndShelledProcess = lRet > 0
End If
End IfEnd Function
Private Sub AdjustToken()
Const TOKEN_ADJUST_PRIVILEGES = &H20
Const TOKEN_QUERY = &H8
Const SE_PRIVILEGE_ENABLED = &H2
Dim hdlProcessHandle As Long
Dim hdlTokenHandle As Long
Dim tmpLuid As LUID
Dim tkp As TOKEN_PRIVILEGES
Dim tkpNewButIgnored As TOKEN_PRIVILEGES
Dim lBufferNeeded As LonghdlProcessHandle = GetCurrentProcess()
OpenProcessToken hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or _
TOKEN_QUERY), hdlTokenHandle‘ Get the LUID for shutdown privilege.
LookupPrivilegeValue “”, “SeShutdownPrivilege”, tmpLuidtkp.PrivilegeCount = 1 ‘ One privilege to set
tkp.TheLuid = tmpLuid
tkp.Attributes = SE_PRIVILEGE_ENABLED‘ Enable the shutdown privilege in the access token of this process.
AdjustTokenPrivileges hdlTokenHandle, False, _
tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeededEnd Sub
Public Function LastLogon2() As Date
Dim nRet As Long
Dim Server As String
Dim User As String
Dim ui3(1 To 29) As Long
Dim lpBuffer As Long
Const evServer = “LOGONSERVER”
‘ Retrieve current user and logon server names.
User = CurrentUserName()
Server = Environ$(evServer)
If Len(Server) = 0 Then Server = CurrentMachineName()
If InStr(Server, “\\”) <> 1 Then Server = “\\” & Server
‘ Retrieve Level3 information on current user.
nRet = NetUserGetInfo(ByVal StrPtr(Server), ByVal StrPtr(User), 3, lpBuffer)
If nRet = NERR_Success Then
‘ Results are returned as a pointer to buffer.
‘ Copy 29 dwords/pointers into array of Longs.
CopyMemory ui3(1), ByVal lpBuffer, UBound(ui3) * 4&
‘ Return last logon date/time, which is 14th element.
LastLogon2 = NetTimeToVbTime(ui3(14))
End If
End FunctionPrivate Function CurrentUserName() As String
Dim Buffer As String
Dim nLen As Long
Const NameLength = UNLEN + 1
‘ ANSI method.
nLen = NameLength
Buffer = Space$(nLen)
Call GetUserName(Buffer, nLen)
‘ Trim results and return.
If nLen > 1 Then CurrentUserName = Left$(Buffer, nLen – 1)
End FunctionPrivate Function NetTimeToVbTime(NetDate As Long) As Double
Const BaseDate# = 25569 ‘DateSerial(1970, 1, 1)
Const SecsPerDay# = 86400
NetTimeToVbTime = BaseDate + (CDbl(NetDate) / SecsPerDay)
End FunctionPrivate Function CurrentMachineName() As String
Dim Buffer As String
Dim nLen As Long
Const NameLength = CNLEN + 1
‘ Fall back to the ANSI method.
nLen = NameLength
Buffer = Space$(nLen)
Call GetComputerName(Buffer, nLen)
‘ Trim results and return.
If nLen > 0 Then CurrentMachineName = Left$(Buffer, nLen)
End FunctionFunction shutdownWindowsOS(ByVal shutdownType As shutdownTypes) As Integer
‘
‘This function will call the ExitWindowsEx function to request the system to shutdown/reboot or
‘whatever is specified in the “shutdownType” parameter. It of course, will call the “AdjustToken”
‘sub to give your app the privilege to use that function first.
‘
AdjustToken
‘
‘Calls the function to begin executing.
shutdownWindowsOS = ExitWindowsEx(shutdownType, 0)End Function
————————————————————————————————————
Module1.bas
ByRef lpSystemPowerStatus As SYSTEM_POWER_STATUS) As Long
Public Function GetBatteryStatus() As String ‘ Get the status of the laptop’s battery
Dim btFlag As Byte
Dim SPS As SYSTEM_POWER_STATUS
Dim lReturn As Long
Dim sRet As String
Dim lFlag As LonglReturn = GetSystemPowerStatus(SPS)
btFlag = SPS.BatteryFlaglFlag = CLng(btFlag)
Select Case lFlag
Case BATTERY_FLAG_CHARGING
sRet = “Now Charging…”
Case BATTERY_FLAG_CRITICAL
sRet = “Critically Low !!”
Case BATTERY_FLAG_HIGH
sRet = “High Charged!”
Case BATTERY_FLAG_LOW
sRet = “Low Charged!”
Case BATTERY_FLAG_NO_BATTERY
sRet = “(No Battery)”
Case BATTERY_FLAG_UNKNOWN
sRet = “Unknown”
End SelectIf (SPS.ACLineStatus = 1) Then
sRet = “[On AC] ” & sRet
Else
sRet = “[On Battery] ” & sRetEnd If
GetBatteryStatus = sRet
End Function
————————————————————————————————————
