Disclosure
By day I’m the Development Lead for a small group of folks responsible for the Pelco SDK. This post is not an official Pelco article, just something I wanted to share.
Background
Last August I rejoined Pelco to help design a new object oriented version of the SDK and that’s what we’ve been doing for the last year plus. We’ve released four revisions of the SDK over that time period and are working on our fifth.
Something I’ve wanted to share for a very long time is how simple it is to work with our new Object Model to collect devices and play video. We’ve simplified the entire process. The original version of the SDK evolved from need, as a lot of things do, but over time it becomes more and more difficult to maintain and enhance that code without breaking backward compatibility. In the new Object Model we’ve worked very hard to make it easy and give you the power you need to code new solutions and give us a platform to build on in the future.
I plan on sharing a sample application after a very brief overview of our Object Model. The application, called EnumDevices, is a C++ application. You can find it on GitHub. I’d be happy to create the same application in C#/.Net. If you’re interested get in touch, rob@crabapples.net.
Overview
The Object Model is pretty simple, here are a few objects, just to get us started. You can view the entire list on PDN(it’s a PDF file.)
- SystemCollection
- System
- DeviceCollection
- Device
- Camera
- Display
- Stream
Of those we’ll discuss System, DeviceCollection, and Device
in the sample. There is some boilerplate code you’ll need to write, but we’ll skip that for now, so we can get on with the sample. Look at main() in the EnumDevices sample, the boilerplate happens prior to calling the EnumDevices function. Something to note. This sample uses version 3.3.1 of the SDK, which introduced an explicit Startup() and Shutdown() function, keep that in mind if you’re using version 3.0 through 3.3, these functions don’t exist in those releases.
EnumDevices C++ Sample
On to the sample code. If you haven’t grabbed the code yet, head over to GitHub and pull it down, I’ll wait.
Some things to note about the sample code. It’s only available for Visual Studio 2010. Our SDK only supports Visual Studio 2008 and Visual Studio 2010 for the time being. I have no idea how it will behave in Visual Studio 2012 or Visual Studio 2013.
Ok, on with the code. We’re going to focus on one function in the sample; EnumDevices. This little bit of code will add, or get, a System, get the DeviceCollection and enumerate it. As it does it will print out the Device Friendly Name. That’s it.
Here’s the code, we’ll break it down below.
static void EnumDevices()
{
// Create or get an existing system
PelcoSDK::System system("admin:admin@pelcosystem://[insert your ip and port here]?alias=Enum Devices Sample System");
// Get the Device Collection from the system
PelcoSDK::DeviceCollection devices(system.GetDeviceCollection());
// Iterate over the DeviceCollection and print out the device friendly name.
devices.Reset();
while (devices.MoveNext())
{
PelcoSDK::Device device(devices.Current());
printf("Device Friendly Name: %s\n", device.GetFriendlyName().c_str());
}
}
PelcoSDK::System
Dissecting the code. I’m sure the first line of code, where we create the System, will have folks asking questions. When we were trying to decide our model for creation and access of Systems we wanted to make it as easy as possible and provide a great deal of power without forcing the user to jump through a lot of hoops. In the end it was decided we’d fashion it after a URI Scheme. Today most people know what a web address looks like.
Here’s the line of code in question:
PelcoSDK::System system("admin:admin@pelcosystem://1.2.3.4:80?alias=Alias");
The interesting portion of that line is "admin:admin@pelcosystem://1.2.3.4:80?alias=Alias"
. In our scheme “pelcosystem” represents the scheme name, we’ve put the username and password information to the left of the scheme, before the @. Following the :// is the host name, followed by the port, and a query string. We use the query string for arguments, in this example we’re assigning an alias name to the System so we can use that to look it up later, or display it in our user interface.
Something else to note about the use of the scheme in the sample. It serves to do the initial add of the System to the SystemCollection and works to look the System up later, without going to the SystemCollection. Our sample could have also added the System to the SystemCollection by using the Add method directly on the SystemCollection, but it’s not required. That said, the first time you run this code it will be a bit slower than subsequent runs. The first time through the System and all its devices will be added to a local device cache so the next time you startup will be much quicker.
PelcoSDK::DeviceCollection
The second line of code is pretty straight forward. After we’ve created, or retrieved, a System we’d like to get the DeviceCollection so we can do something interesting. Maybe we’d like to populate a tree control with a list of devices, or just dump out device information to a simple console application, like this sample.
PelcoSDK::DeviceCollection devices(system.GetDeviceCollection());
There’s not a lot to talk about here. We’re constructing a C++ object of type PelcoSDK::DeviceCollection using the results of a call to system.GetDeviceCollection(). Now we have a DeviceCollection Object we can enumerate.
All of the collection classes in the SDK implement an interface called IEnumerator, it’s a template class that exposes three methods; Current, MoveNext, and Reset
. These methods make it really easy to iterate all collections in the SDK with a simple while loop.
devices.Reset();
while (devices.MoveNext())
{
PelcoSDK::Device device(devices.Current());
printf("Device Friendly Name: %s\n", device.GetFriendlyName().c_str());
}
After getting our collection it should be in a “reset” state, but the first line of code above shows how to reset the internal iterator back to the beginning of the collection. Notice the while loop checks the result of the devices.MoveNext()
. The MoveNext
method will move the iterator to the next item in the collection and returns a boolean value, true if it has a next device, false if it doesn’t. Once there are no longer devices in the collection we’ll break out of the loop.
If we do have a device in the collection you can retrieve it by asking the DeviceCollection for its Current()
object. Since IEnumerator is a C++ template the type of object returned is a PelcoSDK::Device
. You can read more about the Device
Object on the Pelco Developer Network(PDN).
EOL
Hopefully this sheds a bit of light on the direction of the Pelco SDK. We’re off to a nice start, but we have a long way to go, and we’d love to hear back from developers and partners. Please, reach out. Let us know how we’re doing, where we need to improve, and share your stories.
Until next time, happy coding.