[Release] - an app for AI camera/webcam motion/object detection/recognition (motion, person, pet, vehicle, face using tinyCam)

In case anyone else wants to try this, put your cameras into the tinyCam app. The app covers a huge range of ip/web cams (including Arlo, Wyze etc).

Once you have your cams set up, go into the camera settings for each and activate motion sensing (which happens in the app, so no special camera functionality is needed - yes you can cancel your expensive motion recognition subscriptions now :smile:). You can set up zones, adjust sensitivity etc.

You then get this panel allowing you to activate the various motion types and allowing a Webhook to be set up, near the bottom of the page (click the image to expand).

My example Webhook is shown in orange in the panel, and works with the test app that @markus put together (above in this thread). Put your own oauth token into the Webhook of course, once you've installed the app in HE.

Then open your log and see the reported motion type...

Very cool!
And thank you very much to Alex at tinyCam for responding to the request to add this additional functionality to the Webhook!

1 Like

We now have a working interface with tinyCam that enables all sorts of possibilities with camera motion/object sensing across a wide range of ip/web cams!

Some tweaks to the code to:

  • allow virtual motion sensors to be selected for each motion type (motion, person, pet, vehicle face) - nb. face is non-specific/personal
  • rename the app on-save (since you need an instance for each camera - a parent/child structure would be better, but not sure yet how to do this)
  • drive the sensors to active when motion is sensed
  • added some info at the top (trust this is appropriate)

@markus graciously suggested I put my name on this (he did all the work but it was my original app idea I guess :smile: ). Since I have little clue what I'm doing, thats very kind. I've also copied some formatting from @bptworld apps and intend to try to emulate his use of parent/child structure in the future too.

/**

   Hubitat App to allow ip/web cameras in tinyCam to drive Hubitat Virtual Motion Sensors

   tinyCam is an app available on Android/IOS/PC and can discriminate between different types of motion:
    - motion
    - person
    - pet
    - vehicle
    - face (non specific/personal)

   Set-Up:

   In tinyCam:
   - install the tinyCam Monitor Pro app (there is a free add-supported version)
   - add your cameras
   - in camera settings, motion detection, enable all the motion types
   - add a webhook http://[your_hub_ip/apps/api/XXXX/?access_token=YYYY&motion=%MOTION_TYPE%
     (where XXXX is the ID of this app once installed and YYYY is the access code reported in this app (remember to activate oath when installing)

   In Hubitat:
   - simply set-up virtual motion sensor devices (1 for each motion type)
   - then select these when you run the app
   - rename the app to be unique for your chosen camera (will move to Parent/Child format soon)
   - you can also use an html tile in a dashboard to view the live webcam (if you activate the webserver function in tinyCam)

 -----------------------------------------------------------------------------------------------------------------------------
   Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
   in compliance with the License. You may obtain a copy of the License at:
 
       http://www.apache.org/licenses/LICENSE-2.0
 
   Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
   on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
   for the specific language governing permissions and limitations under the License. 
 ------------------------------------------------------------------------------------------------------------------------------
 
   If modifying this project, please keep the above header intact and add your comments/credits below - Thank you!
 
 ------------------------------------------------------------------------------------------------------------------------------

  Changes:

  0.0.2 - 20th June 2020 - Added selection of virtual motion sensors, simplified url/params, code to activate motion sensors,
                           code to rename the app [Angus Marshall]
  0.0.1 - 18th June 2020 - Initial code [Markus Liljergren]

**/

def setVersion(){
    state.name = "tinyCam Connector"
	state.version = "0.0.2"
}

definition(
    name: "tinyCam Connector",
    namespace: "Angus_M",
    author: "Angus Marshall (Angus_M)",
    description: "set virtual motion sensors to active when http received from tinyCam (or other similar webcam app)",
    category: "Convenience",
    installOnOpen: true,
    //TODO: Replace these icons???
    iconUrl:   "",
    iconX2Url: "",
    iconX3Url: "",
    documentationLink: ""
) {
}

preferences {
    page(name: "pageMain", title: "Main Page", install: true, uninstall: true)
    page(name: "pageEnableAPI")
    page(name: "pageDisableAPI")

    mappings {
        path("/") {
            action: [
            GET: "getDevice"
            ]
        }
    }
}

void installed() {
    log.debug "Installed with settings: ${settings}"
    initializeAPIEndpoint()
}

def updated() {
    log.debug "Updated with settings: ${settings}"
    unsubscribe()
    initializeAPIEndpoint()
}

String initializeAPIEndpoint() {
    if(!state.accessToken) {
        if(createAccessToken() != null) {
            state.endpoint = getApiServerUrl()
            state.localAPIEndpoint = getFullLocalApiServerUrl()
            state.remoteAPIEndpoint = getFullApiServerUrl()
        }
    }
    return state.accessToken
}

/* Pages */
Map pageDisableAPI() {
    dynamicPage(name: "pageDisableAPI") {
        section() {
            if (state.accessToken != null) {
                state.accessToken = null
                state.endpoint = null
                paragraph("SUCCESS: API Access Token REVOKED! Tap Done to continue")
            }
        }
    }
}

Map pageEnableAPI() {
    dynamicPage(name: "pageEnableAPI", title: "") {
        section() {
            if(state.accessToken == null) {
                initializeAPIEndpoint()
            }
            if (state.accessToken == null){
                paragraph("FAILURE: API NOT Initialized!")
            } else {
                paragraph("SUCCESS: API Initialized! Tap Done to continue")
            }
        }
    }
}

Map pageMain() {
    dynamicPage(name: "pageMain") {        
        section() {
            if(state.accessToken == null) {
                paragraph("API is not yet Initialized!")
                href(name: "hrefPageEnableAPI", title: "Enable API", description: "", page: "pageEnableAPI")
            } else {
                String localURL = "${state.localAPIEndpoint}/?access_token=${state.accessToken}"
                String remoteURL = "${state.remoteAPIEndpoint}/?access_token=${state.accessToken}"
                paragraph("LOCAL API (devices): <a href=\"$localURL\" target=\"_blank\">$localURL</a>")
                paragraph("REMOTE API: <a href=\"$remoteURL\" target=\"_blank\">$remoteURL</a>")
                
                input "motionDevice", "capability.motionSensor", title: "Motion: Which motion sensor to control?", multiple: false, required: true
                input "personDevice", "capability.motionSensor", title: "Person: Which motion sensor to control?", multiple: false
                input "petDevice", "capability.motionSensor", title: "Pet: Which motion sensor to control?", multiple: false
                input "vehicleDevice", "capability.motionSensor", title: "Vehicle: Which motion sensor to control?", multiple: false
                input "faceDevice", "capability.motionSensor", title: "Face: Which motion sensor to control?", multiple: false
                label title: "Enter a name for this app", required: false
                
            }
        }
    }
}

Map getDevice() {
    log.debug("Running getDevice() $params")
    
    if (params.motion == "Motion") {
        motionDevice.active()
    } else if (params.motion == "Person") {
        personDevice.active()
    } else if (params.motion == "Pet") {
        petDevice.active()
    } else if (params.motion == "Vehicle") {
        vehicleDevice.active()
    } else if (params.motion == "Face") {
        faceDevice.active()
    }
    
}

Still to do:

  • Move to a parent/child structure

  • Create the virtual motion sensor devices automatically instead of selecting them (probably makes sense and saves the user having to do this prior to running the app)

  • Put into HPM

Enjoy!

5 Likes

Changed thread title to reflect "alpha" release of the app :sunglasses:

1 Like

You know...this would be a good use case for MQTT. Then all those attributes could be sent....just sayin...

2 Likes

Interesting project, I look forward to seeing how it develops. Thanks for posting.

1 Like

Making some progress with this (by heavily leveraging @bptworld's work, namely parent/child layout and nice formatting). Trust this is ok and of course noted in the code. So now a child can be created for each camera. Use the URL generated for the webhook in tinyCam with the form:

http://hub_ip/apps/api/app_number_generated_by_child_app/?access_token=your_oauth_token_generated_by_the_child_app&motion=%MOTION_TYPE%

tinyCam will put the appropriate motion type into %MOTION_TYPE% for you (eg. Motion, Person, Vehicle, Pet, Face) and the child app will identify that and activate the selected virtual motion sensor for you (to use in whatever RM rule you want).

To do still:

  • automatically create the virtual motion devices (although in a way its nicer I think to allow the user to select whichever devices they want (not all are necessarily necessary if the various AI-motion types are not all needed for a specific camera))
  • put into HPM

Parent App:

/**
 *  ****************  tinyCam Connector  ****************
 *
 *  Description:
 *  Manage child apps which enable webhooks from tinyCam to drive virtual motion sensors in Hubitat.
 *
 *  Copyright 2020-> Angus Marshall (@Angus_M)
 *
 *  Thanks to Markus (@markus) for the original code and Bryan (@bptworld) for much of the code layout and child/parent structure
 *  
 *  This App is free.  If you like and use this app, please be sure to mention it on the Hubitat forums!  Thanks.
 *
 *-------------------------------------------------------------------------------------------------------------------
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 * ------------------------------------------------------------------------------------------------------------------------------
 *
 *  If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! -  @Angus_M
 *
 * ------------------------------------------------------------------------------------------------------------------------------
 *
 *  Changes:
 *
 *  0.0.1 - 27th June 2020 - Initial alpha release - Angus Marshall
 *
 */

def setVersion(){
    state.name = "tinyCam Connector"
	state.version = "0.0.1"
}

definition(
	name: "tinyCam Connector",
	namespace: "Angus_M",
	author: "Angus Marshall",
	description: "Manage child apps which enable webhooks from tinyCam to drive virtual motion sensors in Hubitat.",
	category: "Convenience",
	iconUrl: "",
	iconX2Url: "",
	iconX3Url: "",
)

preferences {
     page name: "mainPage", title: "", install: true, uninstall: true
} 

def installed() {
    log.debug "Installed with settings: ${settings}"
    initialize()
}

def updated() {
    log.debug "Updated with settings: ${settings}"
    unsubscribe()
    initialize()
}

def initialize() {
    log.info "There are ${childApps.size()} child apps"
    childApps.each {child ->
    log.info "Child app: ${child.label}"
    }
}

def mainPage() {
    dynamicPage(name: "mainPage") {
    	installCheck()
		if(state.appInstalled == 'COMPLETE'){
			section("Instructions:", hideable: true, hidden: true) {
				paragraph "<b>Notes:</b>"
				paragraph "This app manages child apps, each of which can connect to a specific camera in tinyCam using the webhook generated by tinyCam."
                paragraph "Each child app will provide a url containing a unique oauth code. Put the url into the webhook for the camera, in the motion settings in tinyCam."
			}
  			section(getFormat("header-blue", "Child Apps")) {
				app(name: "anyOpenApp", appName: "tinyCam Connector Child", namespace: "Angus_M", title: "<b>Add a new 'tinyCam Connector' child</b>", multiple: true)
			}
            
			section(getFormat("header-blue", "General")) {
       			label title: "Enter a name for parent app (optional to change)", required: false
 			}
			display2()
		}
	}
}

def installCheck(){  
    display()
	state.appInstalled = app.getInstallationState() 
	if(state.appInstalled != 'COMPLETE'){
		section{paragraph "Please hit 'Done' to install '${app.label}' parent app "}
  	}
  	else{
    	log.info "Parent Installed OK"
  	}
}

def getFormat(type, myText="") {			// Modified from @Stephack Code   
	if(type == "header-blue") return "<div style='color:#ffffff;font-weight: bold;background-color:#5da2c2;border: 1px solid;box-shadow: 2px 3px 5px 5px #5da2c2'>${myText}</div>"
    if(type == "line") return "<hr style='background-color:#5da2c2; height: 1px; border: 0;'>"
    if(type == "title") return "<h2 style='color:#5da2c2;font-weight: bold'>${myText}</h2>"
}

def display() {
    setVersion()
    getHeaderAndFooter()
    theName = app.label
    if(theName == null || theName == "") theName = "New Child App"
    section (getFormat("title", "${state.name} (${theName})")) {
        paragraph "${state.headerMessage}"
		paragraph getFormat("line")
	}
}

def display2() {
	section() {
		paragraph getFormat("line")
		paragraph "<div style='color:#5da2c2;text-align:center;font-size:20px;font-weight:bold'>${state.name} - ${state.version}</div>"
        paragraph "${state.footerMessage}"
	}       
}

def getHeaderAndFooter() {
    if(logEnable) log.debug "In getHeaderAndFooter (${state.version})"
    def params = [
		timeout: 30
	]
    
    try {
        def result = null
        httpGet(params) { resp ->
            state.headerMessage = resp.data.headerMessage
            state.footerMessage = resp.data.footerMessage
        }
        if(logEnable) log.debug "In getHeaderAndFooter - headerMessage: ${state.headerMessage}"
        if(logEnable) log.debug "In getHeaderAndFooter - footerMessage: ${state.footerMessage}"
    }
    catch (e) {
        state.headerMessage = "<div style='color:#5da2c2'>@Angus_M Apps and Drivers</div>"
        state.footerMessage = "<div style='color:#5da2c2;text-align:center'>Angus Marshall<br><a href='https://paypal.me/angusmarshall' target='_blank'><img src='https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg' border='0' alt='PayPal Logo'><br>Paypal contributions welcome!</a></div>"
    }
}

Child App:

/**

   Hubitat App to allow ip/web cameras in tinyCam to drive Hubitat Virtual Motion Sensors

   tinyCam is an Android​app that can discriminate between different types of motion:
    - motion
    - person
    - pet
    - vehicle
    - face (non specific/personal)

   Set-Up:

   In tinyCam:
   - install the tinyCam Monitor Pro app (there is a free add-supported version)
   - add your cameras
   - in camera settings, motion detection, enable all the motion types
   - add a webhook http://[your_hub_ip/apps/api/XXXX/?access_token=YYYY&motion=%MOTION_TYPE%
     (where XXXX is the ID of this app once installed and YYYY is the access code reported in this app (remember to activate oath when installing)

   In Hubitat:
   - simply set-up virtual motion sensor devices (1 for each motion type)
   - then select these when you run the app
   - you can also use an html tile in a dashboard to view the live webcam (if you activate the webserver function in tinyCam)

 -----------------------------------------------------------------------------------------------------------------------------
   Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
   in compliance with the License. You may obtain a copy of the License at:
 
       http://www.apache.org/licenses/LICENSE-2.0
 
   Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
   on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
   for the specific language governing permissions and limitations under the License. 
 ------------------------------------------------------------------------------------------------------------------------------
 
   If modifying this project, please keep the above header intact and add your comments/credits below - Thank you!
 
 ------------------------------------------------------------------------------------------------------------------------------

  Changes:

  0.0.3 - 27th June 2020 - Set up parent/child structure (heavily leveraging @bptworld's great work - thank you!) [Angus Marshall]
  0.0.2 - 20th June 2020 - Added selection of virtual motion sensors, simplified url/params, code to activate motion sensors,
                           code to rename the app [Angus Marshall]
  0.0.1 - 18th June 2020 - Initial code [Markus Liljergren]

**/

def setVersion(){
    state.name = "tinyCam Connector"
	state.version = "0.0.3"
}

definition(
    name: "tinyCam Connector Child",
    namespace: "Angus_M",
    author: "Angus Marshall (Angus_M)",
    description: "set virtual motion sensors to active when http received from tinyCam (or other similar webcam app)",
    category: "Convenience",
	parent: "Angus_M:tinyCam Connector",
    iconUrl:   "",
    iconX2Url: "",
    iconX3Url: "",
    documentationLink: ""
) {
}

preferences {
    page(name: "pageMain", title: "Main Page", install: true, uninstall: true)
    page(name: "pageEnableAPI")
    page(name: "pageDisableAPI")

    mappings {
        path("/") {
            action: [
            GET: "getDevice"
            ]
        }
    }
}

void installed() {
	display()
    log.debug "Installed with settings: ${settings}"
    initializeAPIEndpoint()
}

def updated() {
	display()
    log.debug "Updated with settings: ${settings}"
    unsubscribe()
    initializeAPIEndpoint()
}

String initializeAPIEndpoint() {
    if(!state.accessToken) {
        if(createAccessToken() != null) {
            state.endpoint = getApiServerUrl()
            state.localAPIEndpoint = getFullLocalApiServerUrl()
            state.remoteAPIEndpoint = getFullApiServerUrl()
        }
    }
    return state.accessToken
}

/* Pages */
Map pageDisableAPI() {
    dynamicPage(name: "pageDisableAPI") {
	    display()
        section() {
            if (state.accessToken != null) {
                state.accessToken = null
                state.endpoint = null
                paragraph("SUCCESS: API Access Token REVOKED! Tap Done to continue")
            }
        }
    }
}

Map pageEnableAPI() {
    dynamicPage(name: "pageEnableAPI", title: "") {
	    display()
        section() {
            if(state.accessToken == null) {
                initializeAPIEndpoint()
            }
            if (state.accessToken == null){
                paragraph("FAILURE: API NOT Initialized!")
            } else {
                paragraph("SUCCESS: API Initialized! Tap Done to continue")
            }
        }
    }
}

Map pageMain() {
    dynamicPage(name: "pageMain") {
        display()
        section() {
            if(state.accessToken == null) {
                paragraph("API is not yet Initialized!")
                href(name: "hrefPageEnableAPI", title: "Enable API", description: "", page: "pageEnableAPI")
            } else {
		        section("Instructions:", hideable: true, hidden: true) {
                    paragraph("Put the following URL into the tinyCam webhook for motion on the selected camera. This app will read the webhook when transmitted by tinyCam and activate the virtual motion sensor selected below depending on the motion type (eg. simple motion, or AI-identified motion from Person, Vehicle, Pet, or (non-personal) face).")
                }
                
  		        section(getFormat("header-blue", "URLs")) {
                    String localURL = "${state.localAPIEndpoint}/?access_token=${state.accessToken}&motion=%MOTION_TYPE%"
                    String remoteURL = "${state.remoteAPIEndpoint}/?access_token=${state.accessToken}&motion=%MOTION_TYPE%"
                    paragraph("LOCAL API (devices): <a href=\"$localURL\" target=\"_blank\">$localURL</a>")
                    paragraph("REMOTE API: <a href=\"$remoteURL\" target=\"_blank\">$remoteURL</a>")
                }
            
  		        section(getFormat("header-blue", "Virtual Motion Devices")) {
                    input "motionDevice", "capability.motionSensor", title: "Motion: Which motion sensor to control?", multiple: false, required: true
                    input "personDevice", "capability.motionSensor", title: "Person: Which motion sensor to control?", multiple: false
                    input "petDevice", "capability.motionSensor", title: "Pet: Which motion sensor to control?", multiple: false
                    input "vehicleDevice", "capability.motionSensor", title: "Vehicle: Which motion sensor to control?", multiple: false
                    input "faceDevice", "capability.motionSensor", title: "Face: Which motion sensor to control?", multiple: false
                }
                
  		        section(getFormat("header-blue", "Child App name (optional to change)")) {
                    label title: "Enter a name for this app", required: false
                }
                
            }
        }
			display2()
    }
}

void getDevice() {
    log.debug("Running getDevice() $params")
    
    if (params.motion == "Motion") {
        motionDevice.active()
    } else if (params.motion == "Person") {
        personDevice.active()
    } else if (params.motion == "Pet") {
        petDevice.active()
    } else if (params.motion == "Vehicle") {
        vehicleDevice.active()
    } else if (params.motion == "Face") {
        faceDevice.active()
    }
    
}

def getFormat(type, myText="") {			// Modified from @Stephack Code   
	if(type == "header-blue") return "<div style='color:#ffffff;font-weight: bold;background-color:#5da2c2;border: 1px solid;box-shadow: 2px 3px 5px 5px #5da2c2'>${myText}</div>"
    if(type == "line") return "<hr style='background-color:#5da2c2; height: 1px; border: 0;'>"
    if(type == "title") return "<h2 style='color:#5da2c2;font-weight: bold'>${myText}</h2>"
}

def display() {
    setVersion()
    getHeaderAndFooter()
    theName = app.label
    if(theName == null || theName == "") theName = "New Child App"
    section (getFormat("title", "${state.name} (${theName})")) {
        paragraph "${state.headerMessage}"
		paragraph getFormat("line")
	}
}

def display2() {
	section() {
		paragraph getFormat("line")
		paragraph "<div style='color:#5da2c2;text-align:center;font-size:20px;font-weight:bold'>${state.name} - ${state.version}</div>"
        paragraph "${state.footerMessage}"
	}       
}

def getHeaderAndFooter() {
    if(logEnable) log.debug "In getHeaderAndFooter (${state.version})"
    def params = [
		timeout: 30
	]
    
    try {
        def result = null
        httpGet(params) { resp ->
            state.headerMessage = resp.data.headerMessage
            state.footerMessage = resp.data.footerMessage
        }
        if(logEnable) log.debug "In getHeaderAndFooter - headerMessage: ${state.headerMessage}"
        if(logEnable) log.debug "In getHeaderAndFooter - footerMessage: ${state.footerMessage}"
    }
    catch (e) {
        state.headerMessage = "<div style='color:#5da2c2'>@Angus_M Apps and Drivers</div>"
        state.footerMessage = "<div style='color:#5da2c2;text-align:center'>Angus Marshall<br><a href='https://paypal.me/angusmarshall' target='_blank'><img src='https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg' border='0' alt='PayPal Logo'><br>Paypal contributions welcome!</a></div>"
    }
}

Tip: I've found it best to set up the virtual motion sensors with an auto timeout - of, say, 30 seconds. tinyCam will continue to monitor for motion/objects and will retrigger every 30 seconds as needed. This means you can sit in a room, as an example use case, without moving and have the virtual motion sensor retrigger your lights as the AI finds a "person" or "face" (eg. in your rule, add the virtual motion sensor(s) to cancel auto-off lighting). It works!

(Please note I'm learning on this and by no means a coder, so proceed with caution and any feedback is very welcome :smile:)

Enjoy!

2 Likes

I cannot get this to work with my virtual motion devices is there a special driver that I need for the motion sensor as they are not detecting motion? I have set up the following and have install TinyCam with the webhook? do I need to install any thing else? I use the parent and child version only app?

Nothing else is needed. Just the parent app and as many child apps as you have cameras to control. Standard virtual motion sensors. And tinyCam of course running on a pc/tablet/phone on your network. Did you put the local url provided by the child app into tinyCam Motion Webhook for the camera?

it should be something like this...

http://your_he_hub_ip/apps/api/1234/?access_token=blah-de-blah&motion=%MOTION_TYPE%

Make sure you have all the motion types you want activated in tinyCam by ticking the checkboxes in the camera settings, under motion detection (in-app motion detection, object detection, face detection).

Does tinyCam show the motion in its Live View ok? Pls show me the Webhook you are using (but delete out your token of course). Sorry if it's not working. I will try to help you get it set up!

A good way to test is to make sure tinyCam is showing the motion on the screen of the computer running tinyCam and then view the logs on HE on another device accessing your HE hub. You should see 2 logs on motion - first the webhook command and then your virtual motion sensor will fire (the one to fire will depend on whether tinyCam sees a person, face or just motion etc.). Make sure that you set up tinyCam background mode on the camera(s) if you want to run another app on that computer and are not keeping tinyCam live/to the front of your session.

I've suggested to Alex that he change the little red man in his live view that shows the motion to an icon that represents the motion type (eg. person, vehicle, pet, face, or just plain motion). He is considering it I think for a future release. I'm doing it like this on my custom dashboard...

this is motion:

2020-06-24 21_12_55-192.168.0.102_index.htm#

this is person:

2020-06-24 20_54_47-192.168.0.102_index.htm#

etc....

Here is my api etc and on my phone it is showing motion dectection by the picture come up and an icon of motion? Still no change on virtual devices??

do I have to use maker api? if so how would I set it up?

So you put the local url into tinyCam? Pls show me screen shot of the url in tinyCam camera motion settings.

Also remember if you are running tinyCam on your mobile phone to switch on the tinyCam background mode for that camera otherwise it will stop sending the motion notification webhook once you open another app (like a browser to work on HE) and tinyCam goes into the background. Click on background mode, select the camera and press the orange play icon. It will use a lot of battery/cpu and your phone may get warm. So it's best really to run the tinyCam app on a tablet or PC in the house ideally.

No need to set that up for this. The app does all the inbound processing needed.

@Angus_M I'm really intrigued by this and trying to figure out what components I need to make it work. Understanding the overall architecture is a little above my level. Ideally, I'd like to re-purpose an unused Android (Nexus 5) phone as a camera and host for tinyCam.

Might it be as simple as putting tinyCam on the phone and mounting it to give the phone camera the proper field of view; then install your HE app to receive the alerts to RM?

Thank you for putting this together.

Yes that should absolutely work.

The steps are:

Install tinyCam and get this working on your spare mobile phone. Just select your phone when you set up the new camera in Manage Cameras in tinyCam...

If you are using a web/ip cam then you can use the other options to connect your camera.

That's the first step. Make sure it is sensing motion, person, face etc just within the tinyCam app first. It will display motion on the Live View. If you don't want to keep tinyCam running as the live view on your mobile, make sure to activate Background Mode so that it continues to work even if the app is in the background. Select the camera(s) and start the background mode running.

Decide which motion types you want to activate on this camera and set up virtual motion sensors in HE accordingly. You can name them anything you like but maybe something like this...

Cam 1 - Living Room - motion
Cam 1 - Living Room - person
Cam 1 - Living Room - face
Etc.

Set each of these to have a timeout of 30 seconds in the device preferences in HE.

Then install the parent app and then the child app in HE. The child app will generate a local url for you with unique app number and token. Take that local url and stick it into the Webhook for the camera in tinyCam (in camera settings, motion settings). Make sure you activate the motion and object tracking options in tinyCam of course (in Camera Settings).

Now open your HE log on another device and watch for the motion types to be activated and the virtual motion sensors to be triggered.

Then finally use those motion sensors in your rules. I don't use them to trigger lights but I use them to help keep them on. It works perfectly. Even when my Xiaomi motion sensors don't register movement because I'm sat watching TV, the camera will sense me as a "person" and keep the lights on :grinning:

It may seem a bit daunting but is actually quite straightforward to set up :grinning: pls try it and I will try to help if you get stuck.

1 Like

@Angus_M sorry I didn't send this to you yesterday but I change from my phone and put it on TinyCam on a pc and I still have the same issue? It still not triggering the Motion?

hi @leeonestop
Just wanted to ask how you run Tinycam on a pc, I used the Bluestack software, but it ran under a different ip range and I was unable to access my local network cameras? I could not find a way to make it run with the same ip as the local network?

@greglsh I'm using Bluestack and it working good and I'm using the regular IP of my camera? I using IP cam and no issues? When you say a different IP range as I put in the ip of my camera so not sure about the different range issue?

@Angus_M I also notice in the direction about you circle the android camera and I'm using the ip camera does that make a difference? Thanks

Hi, no you can use any camera supported by tinyCam. Just make sure it is sensing motion/objects in tinyCam first using the live view. Then it should be sending the webhook to HE for the child app to read.