The Trendnet TV-IP400 / TV-IP400W protocol
development, Home Automation August 20th, 2007The Trendnet TV-IP400 is a fun little camera that will work great for home surveillance, as a controllable web cam, etc. The only problem is that the software that comes with it really sucks. I reverse engineered the protocol that is used to control the camera, and wrote a ZoneMinder driver for it… go here for more information. This follow up describes the control protocol that I reverse engineered, and contains most information that you’ll need if you want to write your own driver. I’m assuming that you are familiar with HTTP requests and that you know how to send GET and POST requests to an IP address.
Feel free to use the information in this page in any way you want. I make no guarantees as to its accuracy or completeness. If you write any software based on this info, please let me know!
control commands:
The following CGIs are supported.
/PANTILTCONTROL.CGI
This is the main CGI for camera movement control, and should always be a POST request. The commands are very simple, there’s one parameter for specifying the direction of movement, and both for horizontal and vertical movement you need to set the degree at which it should move. This degree should be an integer of 1 or higher. (The web control interface never submits values higher than 10, and I haven’t tested any either).
I don’t think these commands can be used to do absolute movement.
Theoretically, if you move 3 degrees up and 3 degrees left, then 5 degrees up and 9 degrees right, then 8 degrees down and 6 degrees left, you should be exactly at the point you started - I’m not sure how accurately this would work, but you might be pleasantly surprised. (preset positions don’t seem to wander over time, so moving relative distances might be accurate too).
On to the commands now. To move the camera 1 degree up and 1 left, you should send the following command in the POST body:
PanSingleMoveDegree=1&TiltSingleMoveDegree=1&PanTiltSingleMove=1
To send the camera 3 degrees to the right, send the following:
PanSingleMoveDegree=3&TiltSingleMoveDegree=0&PanTiltSingleMove=5
I hope you’re catching on. Here’s the complete table of movement directions that should be set with the PanTiltSingleMove parameter:
0 up left
1 up
2 up right
3 left
4 home
5 right
6 down left
7 down
8 down right
If you’re just tilting the camera (vertically), you can leave out the PanSingleMoveDegree parameter. Likewise, if you’re only panning the camera (horizontally), you can leave out the TiltSingleMoveDegree parameter. If you’re sending the camera to the Home position, you can leave out both.
Note that there’s no way to control the zoom! The IP400’s zoom is digital only. The java/activex interface and windows application all implement the zoom on the client side; the camera itself doesn’t know how to do this. So if you need the zoom (or the suggestion of a zoom), you’ll have to implement this yourself by cropping and resize the center of the video stream.
SWING MODES:
There are two swing modes that can be activated simply by passing the PanTiltSwingMode parameter and value to PANTILTCONTROL.CGI. The first scan mode will simply scan the room horizontally by panning it one step in every approx 1 second intervals until it reaches it’s left or right limit, then reverse direction. The swing mode will simply scan all preset positions and hold each position for a few seconds. I don’t think there’s any way to change the interval time for either swing mode, at least the decompiled camera java applet didn’t reveal any such options to me.
values for swing mode:
0 stop
1 horizontal scan, move every second
2 scan all preset positions
example:
to put the camera into horizontal scan mode, send:
PanTiltSwingMode=2
PRESET POSITIONS:
To move to a preset position, send the following command:
PanTiltPresetPositionMove=3
substitute 3 for the position number that you want to move to. The camera supports 25 preset positions, 0 to 24.
To clear a position, send:
ClearPosition=12
this would clear position 12 (which is the 13th preset)
To set a preset position:
send the following command.
PanTiltHorizontal=a&PanTiltVertical=b&SetName=myPosition&SetPosition=12
Where a and b would be the absolute values for the horizonal resp. vertical positions. There is some numbers juggling going on in the java applet of the webcam control application, and I haven’t made any attempts yet to reverse engineer this. All movement (except for movement to preset positions) is relative with this camera, and I am not sure that an absolute position can be calculated accurately from relative movements. As far as I know there’s only one way to get the current absolute position, which is actually through the mjpeg cgi, see below.
———————————–
/IOCONTROL.CGI
It appears that this CGI can be called to trigger the camera to upload or email a current camera snapshot. I only know this from decompiling the xplug class, and haven’t played around with it at at all.
The parameter string should look like this (or at least that’s how the java applet sends it)
Trigger1=0&Trigger2=1&ImageUpload=0&ImageEmail=1
where values of all 4 parameters should be either 0 or 1. You should call the CGI with the POST method, however, if you use the GET method (eg by simply entering the CGI url in your browser), it will answer with the current values of these parameters, like this:
Trigger1=0&Trigger2=0&ImageUpload=0&ImageEmail=0&CurrentTime=2007-08-16 15:27:34
(There’s no point in trying to set those properties in the GET request (with something like /IOCONTROL.CGI?ImageUpload=1) as the IP400 seems to ignore those: the camera apparently needs a POST request to receive parameters. )
/MJPEG.CGI
/VIDEO.CGI
(use GET request)
Both these urls appear to return a MJPEG stream, which is basically just an endless stream of jpeg images with a short header in between. That header data looks like this:
--video boundary--Content-length: 10089 Date: 2007-08-16 14:56:19 IO_00000000_PT_136_046 Content-type: image/jpeg
but the ‘Date’ header isn’t present when using the VIDEO.CGI variant. The interesting thing about this Date header is that the last bit, the PT_136_046 actually indicates the current absolute Pan/Tilt position. The Ruby driver I’ve written for this camera can grab those coordinates from the stream, which is really only useful when you want to set a preset position.
You should be able to view the stream in a browser simply by using the address http://192.168.0.50/MJPEG.CGI (substitute the correct IP address of course).
Other than the missing Date header in the VIDEO.CGI response, there don’t seem to be any differences between these two streams. If you find any, please let me know.
By the way, the exact request that Trendnet’s xplug java applet sends to get the video stream is:
GET /MJPEG.CGI HTTP/1.0\r\n User-Agent: user\r\n Authorization: Basic abcdefgrn\r\n
where the authentication token is optional (but needed when you have user access control enabled in the camera). This token abcdefg should be the base64 encoded string of ‘username:password’ as is standard for http basic authentication. It’s probably best if your request look exactly the same, and do make sure you end those headers with double carriage return and line feed, as illustrated.
/IMAGE.JPG
simply returns a jpeg of the current camera view, which is handy if you want to save a snapshot or display on clients that can’t handle streaming video.
If you need to grab a bunch of frames, want to convert the stream to another format or do any other magic with your camera view, I recommend you look at ffmpeg and imagemagick.
Here’s an example of how to save the first image from the mjpeg stream to an image:
ffmpeg -f mjpeg -i http://192.168.0.50/MJPEG.CGI -vframes 1 -an -s 320x240 cam%d.jpg
It will save multiple jpgs if you increase the vframes value, but if you want to do that it would be better to output to another video format then to output to jpg.
Having written all this: you may not need to know any of this since I’ve written two drivers, one Ruby and one ZoneMinder driver that can be used on any platform that supports Perl or Ruby. I’ll post the code for the ruby driver as soon as it’s ready.
August 21st, 2007 at 8:37 am
[…] After that first little hump I figured I should probably first email Trendnet and ask them nicely for the protocol specs, but as I more or less expected they weren’t able to give me that info (booo). So my only chance would be to reverse engineer the protocol and write my control script with what I learned from that. Here’s what I did.. and if you’re not interested in how I did it you can scroll straight down to find out how to get your own Trendnet camera working in ZoneMinder. If you just want to know more about the details of the protocol so you can write your own driver, check out the specs here. […]
October 12th, 2007 at 12:19 am
Hello,
I have recently purchased the TV IP-400 expecting something more standard from the software point of view. I like to use it on my PC’s (Window XP, Vista, 2000, …) from various location in the home as standard web cam and not only from the tools provided by trendnet.
As you have done I sent an e-mail to Trendnet asking for a Window driver to turn on the net video cam into a standard webcam, or at least a protocol decription and get a noway answer from them. Not very commercial open.
I went to the web to try to find some help, and the unique page I found concerning this camera was yours, thank you very much. I just checked the information provided was accurate on my IP400 and all GET/POST information work fine.
So now, the question is to build the piece of software to turn your information in something that work on my PCs. I have in mind to build a Window driver using the standard usb drivers source code as a template and replace usb call by tcp/ip ones, three steps in mind :
1 - simple driver to implement the video stream (with ip+tcp port parameter or url to be open to other kind of camera)
2 - full driver to implement stream + pan/tilt function
3 - some tool to send camera orders through a bluetooth remote control (the one I have for Intervideo Home Theater)
HArd work to do, but I expect to provide you some feed back before christmas …
Thank you very much to have shared the information.
Best Regards
Laurent.
October 22nd, 2007 at 6:07 pm
Did you get the Rails app finished? Would love to see it. Thank you.
December 16th, 2007 at 4:59 am
Hi Peter,
while surfing around to search ideas for a remote access webcam I came across your site and found also this one:
http://techwiki.oliverbaltz.de/index.php?title=RoboCam&printable=yes&printable=yes#Features
Its in german, but I guess the PHP-script for the webcam is readable though ;-)
bye
Wolfgang
March 6th, 2008 at 2:59 am
How do i view zoneminder motion images and videos captured within misterhouse? In other words how can l link the two together.
Thanks in advance.
November 1st, 2008 at 10:39 pm
Hi
I bolt a trendnet TV-IP400W. Now I hafe a problem with the cgi commmands.
First: sorry for my bad english, I speak swissgerman.
the support send me the cgi commads, but ther is no support on the cgi commands.
to turn the cam right the command mus be:
http://“IPADRESSES”/cgi/admin/ptctrl.cgi?action=move&Cmd=right
so for me ist it now:
http://192.168.1.20/cgi/admin/ptctrl.cgi?action=move&Cmd=right
When I but this commad into the webbroser the cam must turn right. Is it correct?
The answer in the window is: 501 Method Not Implemented.
(I enable the user.View the picture works.)
When I look on your website it must be:
http://“IPADRESSE”/pantiltcontrol?pantiltsinglemove=5
but it does not work.
Do I not understand how I can move the cam?
Firmeware is 3.36 the latest on
thanks for answer.
Andreas
November 2nd, 2008 at 10:16 am
if the command to move the camera is http://“IPADRESSES”/cgi/admin/ptctrl.cgi?action=move&Cmd=right for you, then I don’t think you have the IP400W. Perhaps you have the IP410? That camera has new firmware and a completely different control protocol.
If you do have the IP400W, you need to use POST to submit the control parameters, not get. You can write a simple script to submit the HTTP POST request, use a html page with a simple form, or use my Ruby driver to control the camera.
November 3rd, 2008 at 1:11 pm
Hi
I have TV-IP400W cam.
her a part from the CGI Commands. This dokument sned me the support from Trendnet….
15. Pan & Tilt
Making the Pan & Tilt commands ,
Also check the [PanTilt] in the param.cgi to make additional pan&tilt configuration
15.1 Pan Tilt and position related
Method: Get/Post
Syntax:
http:// /cgi/admin/ptctrl.cgi?action=move&Cmd=
with the following parameters and values
parameter Value Description
action= move Specifies the action to take. .
Cmd A String(updownleftrighthomestop) PanTilt move command .
A String(panscan) Do Pan scan command
A String(autopatrol) Do Auto Patrol command
A String(calibration) Adjust PT motor
A String(Position1Position2Position3Position4Position5Position6Position7Position8) Move to preset position
Example:
1. Move up
http://myserver/cgi/ admin /ptctrl.cgi?action=move&Cmd=up
2. Make a pan scan
http://myserver/cgi/ admin /ptctrl.cgi?action=move&Cmd=panscan
3. Go to position 5
http://myserver/cgi/ admin /ptctrl.cgi?action=move&Cmd=Position5
Return:
A successful HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: \r\n\r\n
Failed HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: \r\n\r\nRequest failed: \r\n
November 16th, 2008 at 9:51 pm
That’s strange - those commands all return ‘501 Method not implemented’ for me. They must have sent you either the wrong document, (perhaps for the TV-IP410) or perhaps later models of the TV-IP400 have new firmware with a completely redesigned command protocol… but I would think the latter is unlikely.
So my guess is that those commands will work for the TV-IP410 only.