diff options
-rw-r--r-- | backends/visca.c | 30 | ||||
-rw-r--r-- | backends/visca.md | 50 |
2 files changed, 75 insertions, 5 deletions
diff --git a/backends/visca.c b/backends/visca.c index f8bdae1..ae586a7 100644 --- a/backends/visca.c +++ b/backends/visca.c @@ -44,7 +44,7 @@ static int ptz_configure_instance(instance* inst, char* option, char* value){ data->cam_address = strtoul(value, NULL, 10); return 0; } - if(!strcmp(option, "connect")){ + else if(!strcmp(option, "connect")){ if(data->fd >= 0){ LOGPF("Instance %s already connected", inst->name); return 1; @@ -67,6 +67,24 @@ static int ptz_configure_instance(instance* inst, char* option, char* value){ } return 0; } + else if(!strcmp(option, "device")){ + if(data->fd >= 0){ + LOGPF("Instance %s already connected", inst->name); + return 1; + } + + #ifdef _WIN32 + LOGPF("Direct device connections are not possible on Windows"); + return 1; + #else + data->fd = open(value, O_NONBLOCK); + if(data->fd < 0){ + LOGPF("Failed to connect instance %s to device %s", inst->name, value); + return 1; + } + return 0; + #endif + } LOGPF("Unknown instance configuration parameter %s for instance %s", option, inst->name); return 1; @@ -109,6 +127,7 @@ static channel* ptz_channel(instance* inst, char* spec, uint8_t flags){ return NULL; } + //store the memory to be called above the command type if(ident == call){ ident |= (strtoul(spec + strlen(ptz_channels[call].name), NULL, 10) << 8); } @@ -118,8 +137,8 @@ static channel* ptz_channel(instance* inst, char* spec, uint8_t flags){ static size_t ptz_set_pantilt(instance* inst, channel* c, channel_value* v, uint8_t* msg){ ptz_instance_data* data = (ptz_instance_data*) inst->impl; - uint32_t* x = (uint32_t*) msg + 6; - uint32_t* y = (uint32_t*) msg + 10; + uint32_t* x = (uint32_t*) (msg + 6); + uint32_t* y = (uint32_t*) (msg + 10); if(c->ident == pan){ data->x = ((ptz_channels[pan].max - ptz_channels[pan].min) * v->normalised) + ptz_channels[pan].min; @@ -144,17 +163,18 @@ static size_t ptz_set_ptspeed(instance* inst, channel* c, channel_value* v, uint else{ data->tiltspeed = ((ptz_channels[tiltspeed].max - ptz_channels[tiltspeed].min) * v->normalised) + ptz_channels[tiltspeed].min; } + return 0; } static size_t ptz_set_zoom(instance* inst, channel* c, channel_value* v, uint8_t* msg){ - uint32_t* position = (uint32_t*) msg + 4; + uint32_t* position = (uint32_t*) (msg + 4); *position = htobe32(((ptz_channels[zoom].max - ptz_channels[zoom].min) * v->normalised) + ptz_channels[zoom].min); return ptz_channels[zoom].bytes; } static size_t ptz_set_focus(instance* inst, channel* c, channel_value* v, uint8_t* msg){ - uint32_t* position = (uint32_t*) msg + 4; + uint32_t* position = (uint32_t*) (msg + 4); *position = htobe32(((ptz_channels[focus].max - ptz_channels[focus].min) * v->normalised) + ptz_channels[focus].min); return ptz_channels[focus].bytes; } diff --git a/backends/visca.md b/backends/visca.md new file mode 100644 index 0000000..26e523a --- /dev/null +++ b/backends/visca.md @@ -0,0 +1,50 @@ +### The `visca` backend + +The VISCA backend provides control of compatible PTZ (Pan, Tilt, Zoom) controllable cameras +via the network. This protocol has, with some variations, been implemented by multiple manufacturers +in their camera equipment. There may be some specific limits on the command set depending on make +and model of your equpipment. + +This backend can connect to both UDP and TCP based cameras. + +#### Global configuration + +The `visca` backend does not take any global configuration. + +#### Instance configuration + +| Option | Example value | Default value | Description | +|---------------|-----------------------|-----------------------|---------------------------------------------------------------| +| `id` | `5` | `1` | VISCA Camera address (normally 1 for network communication | +| `connect` | `10.10.10.1 5678` | none | Camera network address and port. Default connection is TCP, when optionally suffixed with the `udp` keyword, connection will be UDP | +| `device` | `/dev/ttyUSB0` | none | (Linux only) Device node for a serial port adapter connecting to the camera | + +#### Channel specification + +Each instance exposes the following channels + +* `pan`: Pan axis +* `tilt`: Tilt axis +* `panspeed`: Pan speed +* `tiltspeed`: Tilt speed +* `zoom`: Zoom position +* `focus`: Focus position +* `memory<n>`: Call memory <n> (if incoming event value is greater than 0.9) + +Example mappings: + +``` +control.pan > visca.pan +control.tilt > visca.tilt +control.btn1 > visca.memory1 +``` + +#### Known bugs / problems + +Value readback / Inquiry is not yet implemented. This backend currently only does output. + +Some manufacturers use VISCA, but require special framing for command flow control. This may be implemented +in the future if there is sufficient interest. + +Please file a ticket if you can confirm this backend working/nonworking with a new make or model +of camera so we can add it to the compatability list! |