Pairing a Vistacam

Has anyone had any luck pairing a MiCasaVerde Vistacam RC8021? It worked with my Vera Lite, however I would like to use it with my Smart Things hub if possible. I have excluded it from the Vera, but can’t figure out how to put it into pairing mode.

Thanks for your help.

The Vistacams are just rebranded Foscam cameras (I am pretty sure it is a F8918W). They are Wifi devices so you don’t necessarily “pair” them. You can run through both Vera and SmartThings at the same time no problem (my Foscams are hooked to both).

Support for Foscams on SmartThings is fairly limited and very manual at this point. More robust support is coming though. For now check out this topic: http://build.smartthings.com/forums/topic/foscam-recommended-model/

@imbrian has created a great custom device type and app which give a good amount of functionality through SmartThings

This is the device controller that I worked on (with lots and lots of referencing work from others): https://github.com/imbrianj/foscam

The main added feature of this one is the ability to poll for alarm state and (de)activate it.

I built this simple app to enable and disable the alarm - and I have it installed for Home and Away modes to turn the camera on and off: https://github.com/imbrianj/secure_my_foscam

I’ll soon be working on foscam again trying to add some more features and get local access working. Input for requests for a foscam device controller is greatly appreciated.

And here is a private message I had sent to another user on how to get his foscam set up using the above code:

Yes – you first need to add a custom device type. That will define what your inputted device is and how it works.

  • Visit https://graph.api.smartthings.com/ide/devices and click ”New SmartDevice” in the upper right corner.

  • Give it the Name of ”Foscam” – author can be whatever you want. In ”Capabilities”, select ”Image Capture” and ”Polling”.

  • Under ”Custom” enter these attributes: ”setStatus” and ”alarmStatus”.

  • Under ”Custom” enter these commands: ”alarmOn”, ”alarmOff”, ”left”, ”right”, ”up”, ”down”, ”pause”, ”set”, ”preset1”, ”preset2”, ”preset3”, ”toggleAlarm” and ”preset”.

  • Click ”Create” – it’ll drop you to the coding IDE. Just paste in this source code: https://raw2.github.com/imbrianj/foscam/master/foscam.groovy

  • Save and Publish

  • You now have the custom Foscam device type installed – you’ll need to install your specific device. You’ll need to have a port open to access it from the ST cloud. Once it’s configured to accept connections externally, go to ”My Devices” and click ”New Device”.

  • Enter the ”Name”: ”Foscam”, ”Device Network ID”: ”Foscam”, ”Type”: ”Foscam”, ”Location”: wherever the device lives, ”Hub”: LEAVE EMPTY.

  • When you’re a the details page for this devices, there’s a ”Preferences” section near the bottom. Click ”edit” and enter your username, password, IP address (or dns address) of the camera as well as the port used.

  • You should now have the device installed and it should be able to respond to events.

The foscam.groovy is used to tell SmartThings how to turn the alarm on – but you’ll need a smart app (or direct interaction with the app in the menu) to actually arm it. You can create a new smart app and take my code here: https://raw2.github.com/imbrianj/secure_my_foscam/master/secure_my_foscam.groovy and configure the app to arm or disarm based on a particular mode (the most logical being ”arm” for away, ”disarm” for home).

Hope this helps – let me know if you have any questions.

@ImBrian
Will this work with any Foscam camera? I am looking at picking up a couple of the Foscam FI9821W V2 model.

@stickstickly - I’m unsure. I’ve only tested with the 8910w, but I expect it should work with most non-HD cameras. If it does not work, it probably wouldn’t be a big deal to create a new device controller.

The 9821 that I am buying is foscams 720p version. Are you saying that definitely won’t work since its an hd version?

@stickstickly

I have worked with enough different Foscams to tell you it definitely won’t work with your 9821 without some modifications. The MJPEG cameras (8910, 8907, 8918, etc…) use a very different set of command URLs than the HD H.264 models. There is also quite a bit of variation in the command URLs for the HD models. If you can find the command URLs for your camera (I would start at the forums at foscam.us), it would be relatively simple to find and replace the command URLs in @imbrian Foscam device to make it work with you camera.

http://www.ispyconnect.com/man.aspx?n=foscam

That link my help.

I’ve set it up, and configured both the new device type and the new smart app. I haven’t turned on the smart app, and I understand that I can turn on and off alarm status with it.

One thing, from the things page can I control the camera and take snapshots etc?

I was considering using your template, and having my foscam go to different presets depending upon a motion detection or vibration sensor.

Have you done any of that yet?

If anyone is curious, I got it to work with a FI8910W cam, I had to make one change to the Device type specific by @ImBrian to get it to work with that cam, the snapshots were coming across. If anyone wants that code change I can send it to them if they were curious.

I wouldn’t mind seeing that code. I have that cam. Thanks.

This is the change i made for the get request, ONLY to the device type so the take method would work.

/**
 *  Foscam  - FI8910W 
 *
 *  Author: danny@smartthings.com
 *  Author: brian@bevey.org
 *  Author: morgan@jedifan.com
 *  Date: 01/29/2014
 *
 *  Modified this to work with FI8910W
 *
 *  Modified example Foscam device type to support dynamic input of credentials
 *  and enable / disable motion alarm to easily integrate into homemade
 *  security systems (when away, mark "alarmStatus" as "on", when present, mark
 *  "alarmStatus" as "off".  For use with email or FTP image uploading built
 *  into Foscam cameras.
 *
 *  Capability: Image Capture, Polling
 *  Custom Attributes: setStatus, alarmStatus
 *  Custom Commands: alarmOn, alarmOff, toggleAlarm, left, right, up, down,
 *                   pause, set, preset, preset1, preset2, preset3
 */
 
preferences {
  input("username", "text", title: "Username", description: "Your Foscam username")
  input("password", "password", title: "Password", description: "Your Foscam password")
  input("ip", "text", title: "IP address", description: "The IP address of your Foscam")
  input("port", "text", title: "Port", description: "The port of your Foscam")
}

// for the UI
metadata {
  tiles {
    carouselTile("cameraDetails", "device.image", width: 3, height: 2) { }

    standardTile("camera", "device.image", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false) {
      state "default", label: "", action: "Image Capture.take", icon: "st.camera.dropcam-centered", backgroundColor: "#FFFFFF"
    }

    standardTile("take", "device.image", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false, decoration: "flat") {
      state "take", label: "", action: "Image Capture.take", icon: "st.secondary.take", nextState:"taking"
    }

    standardTile("up", "device.image", width: 1, height: 1, canChangeIcon: false,  canChangeBackground: false, decoration: "flat") {
      state "take", label: "up", action: "up", icon: ""
    }

    standardTile("alarmStatus", "device.alarmStatus", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false) {
      state "off", label: "off", action: "toggleAlarm", icon: "st.camera.dropcam-centered", backgroundColor: "#FFFFFF"
      state "on", label: "on", action: "toggleAlarm", icon: "st.camera.dropcam-centered",  backgroundColor: "#53A7C0"
    }

    standardTile("left", "device.image", width: 1, height: 1, canChangeIcon: false,  canChangeBackground: false, decoration: "flat") {
      state "take", label: "left", action: "left", icon: ""
    }

    standardTile("pause", "device.image", width: 1, height: 1, canChangeIcon: false,  canChangeBackground: false, decoration: "flat") {
      state "pause", label: "pause", action: "pause", icon: ""
    }
    
    standardTile("right", "device.image", width: 1, height: 1, canChangeIcon: false,  canChangeBackground: false, decoration: "flat") {
      state "take", label: "right", action: "right", icon: ""
    }

    standardTile("blank", "device.image", width: 1, height: 1, canChangeIcon: false,  canChangeBackground: false, decoration: "flat") {
      state "pause", label: "", action: "pause", icon: ""
    }

    standardTile("down", "device.image", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
      state "down", label: "down", action: "down", icon: ""
    }

    standardTile("set", "device.setStatus", width: 1, height: 1, canChangeIcon: false, inactiveLabel: true, canChangeBackground: false) {
      state "set", label: "set", action: "set", icon: "",  backgroundColor: "#FFFFFF"
      state "setting", label: "set mode", action: "set", icon: "", backgroundColor: "#53A7C0"
    }

    standardTile("preset1", "device.image", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
      state "preset1", label: "preset 1", action: "preset1", icon: ""
    }

    standardTile("preset2", "device.image", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
      state "preset2", label: "preset 2", action: "preset2", icon: ""
    }

    standardTile("preset3", "device.image", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
      state "preset3", label: "preset 3", action: "preset3", icon: ""
    }

    standardTile("refresh", "device.alarmStatus", inactiveLabel: false, decoration: "flat") {
      state "default", action:"polling.poll", icon:"st.secondary.refresh"
    }

    main "alarmStatus"
      details(["cameraDetails", "take", "up", "alarmStatus", "left", "pause", "right", "blank", "down", "set", "preset1", "preset2", "preset3", "refresh"])
  }
}

def parseCameraResponse(def response) {
  if(response.headers.'Content-Type'.contains("image/jpeg")) {
    def imageBytes = response.data
    if(imageBytes) {
      storeImage(getPictureName(), imageBytes)
    }
  } 
}

private getPictureName() {
  def pictureUuid = java.util.UUID.randomUUID().toString().replaceAll('-', '')
  "image" + "_$pictureUuid" + ".jpg"
}

private take() {
  log.debug("Take a photo")

  httpGet("http://${settings.ip}:${settings.port}/snapshot.cgi?user=${settings.username}&pwd=${settings.password}&resolution=32&rate=0") {response ->        
    log.debug("Image captured")
    parseCameraResponse(response)
  }
}

def toggleAlarm() {
  if(device.currentValue("alarmStatus") == "on") {
    alarmOff()
  }

  else {
    alarmOn()
  }
}

private alarmOn() {
  api("set_alarm", "motion_armed=1") {
    log.debug("Alarm changed to: on")
    sendEvent(name: "alarmStatus", value: "on");
  }
}

private alarmOff() {
  api("set_alarm", "motion_armed=0") {
    log.debug("Alarm changed to: off")
    sendEvent(name: "alarmStatus", value: "off");
  }
}

def left() {
  api("decoder_control", "command=6") {
    log.debug("Executing 'left'")
  }
}

def right() {
  api("decoder_control", "command=4") {
    log.debug("Executing 'right'")
  }
}

def up() {
  api("decoder_control", "command=0") {
    log.debug("Executing 'up'")
  }
}

def down() {
  api("decoder_control", "command=2") {
    log.debug("Executing 'down'")
  }
}

def pause() {
  api("decoder_control", "command=1") {}
}

def preset1() {
  preset(1)
}

def preset2() {
  preset(2)
}

def preset3() {
  preset(3)
}

//go to a preset location
def preset(def num) {
  if(num == null) return

  if(device.currentValue("setStatus") == "setting") {
    setPreset(num)
  }

  else {
    log.debug("Go To Preset Location")
    //1 is 31, 2 is 33, 3 is 35
    def cmd = 30 + (num * 2) - 1

    api("decoder_control", "command=${cmd}") {}
  }
}

//set the preset number to the current location
def setPreset(def num) {
  log.debug("Set Preset")
  //1 is 30, 2 is 32, 3 is 34... 8 is 44
  int cmd = 28 + (num * 2)
  sendCmd(cmd)

  log.debug("Exit Set Mode")
  sendEvent(name: "setStatus", value: "set");
}

//toggle the the mode to set the preset
def set() {
  if(device.currentValue("setStatus") == "set") {
    log.debug("Entering Set Mode")
    sendEvent(name: "setStatus", value: "setting");
  }

  else {
    log.debug("Exit Set Mode")
    sendEvent(name: "setStatus", value: "set");
  }
}

def api(method, args = [], success = {}) {
  def methods = [
    "decoder_control": [uri: "http://${ip}:${port}/decoder_control.cgi${login()}&${args}", type: "post"],
    "snapshot": [uri: "http://${ip}:${port}/snapshot.cgi${login()}&${args}", type: "post"],
    "set_alarm": [uri: "http://${ip}:${port}/set_alarm.cgi${login()}&${args}", type: "post"],
    "reboot": [uri: "http://${ip}:${port}/reboot.cgi${login()}&${args}", type: "post"],
    "camera_control": [uri: "http://${ip}:${port}/camera_control.cgi${login()}&${args}", type: "post"],
    "get_params": [uri: "http://${ip}:${port}/get_params.cgi${login()}", type: "get"],
    "videostream": [uri: "http://${ip}:${port}/videostream.cgi${login()}", type: "get"]
  ]

  def request = methods.getAt(method)

  doRequest(request.uri, request.type, success)
}

private doRequest(uri, type, success) {
  log.debug(uri)

  if(type == "post") {
    httpPost(uri , "", success)
  }

  else if(type == "get") {
    httpGet(uri, success)
  }
}

private login() {
  return "?user=${username}&pwd=${password}"
}

def poll() {
  api("get_params", []) {
    def params = ""

    it.data.eachLine {
      if(it.startsWith("var alarm_motion_armed=0")) {
        log.info("Polled: Alarm off")
        sendEvent(name: "alarmStatus", value: "off");
      }

      if(it.startsWith("var alarm_motion_armed=1")) {
        log.info("Polled: Alarm on")
        sendEvent(name: "alarmStatus", value: "on");
      }
    }
  }
}

@ImBrian thanks for all your work with Foscam. Long story short, I had mine work for a few months using the code you’d written and securemyfoscam, then I broke it all trying to make securemyfoscam also change the preset.
So, I tried to rebuild it, then start from scratch using your instructions in this post. I could not make it work, and noticed it was the new auto added metadata. After tinkering and searching around the site, I found what to add, but thought you might want to update your github file for future users (until ST rolls out Foscam in labs…)

If anyone else needs it, just copy this code in (someone better than me might make sure it’s all correct…it does work though)

metadata {
	definition (name: "Foscam", author: "unknown") {
    	capability "Image Capture"
		capability "Polling"

		attribute "setStatus", "string"
		attribute "alarmStatus", "string"
        
		command "alarmOn"
		command "alarmOff"
		command "toggleAlarm"
		command "left"
		command "right"
		command "up"
		command "down"
        command "pause"
		command "set"
		command "preset"
		command "preset1"
        command "preset2"
		command "preset3"
	}

@erikmichael - it’s funny you should mention this today. Two days ago, I had to reconfigure my foscam and ran into this same issue. I hadn’t had a chance to try and troubleshoot it - so I ended up just disabling it in the meantime. Thanks for your notes - I’ll try and get this set up and update my device controller on github this weekend!

@ImBrian that’s awesome! You haven’t perhaps used securemyfoscam to change your preset, have you? I haven’t gotten back to working that out since I got the foscam working again.

@erikmichael - I did have it working before I made an edit and everything stopped working. I’ll make your suggested device controller changes and see if I can get it working.

My big use case is that when I’m at home, I think the camera is creepy - it points to the wall. If everyone is gone, there’s nobody to creep out - so it turns to the door.

@erikmichael - I’ve updated the foscam device controller per your recommendations (a huge thank-you for that, btw). I’ve just tested and it seems to work fine - and “Secure My Foscam” works as well - arms and disarms, pans to the correct preset.

If you’re having trouble with the panning to preset - it may be that the preset is never actually assigned. May be a bug there. Try setting a preset in the web UI for the camera itself and see if that remedies?

Now, to just get this to have local IP control instead having to have a hole in my firewall. Hrmm…

@imbrian

Updated code works well for me. Thank you!

If you look at the “Foscam” device type in the “Device Type Examples”, the very bottom appears to be what you need to get local IP access. Taking this code unaltered, I can get access to one of my Foscam’s that is not accessible through my firewall by using the local IP address in hex for the Device Network ID. The stock device type is very limited in that it only takes a picture.

I tried merging this with your device type but it is beyond my programming abilities.

@trotsky40 - My previous attempts at local foscam control kept (silently) failing. I’m wondering if those failures were due to the lack of the meta data just added. Without that meta data, my normal foscam controller worked, but inconsistently.

I have a “work in progress” device controller I’ll try again this weekend.