Skip to content

BATCAM FX Overview

BATCAM FX Development Overview

1. Introduction

BATCAM FX is a real-time acoustic camera from SM Instruments. It provides 1600×1200 optical video together with a 40×30 beamforming (BF) map, so you can visualize where sound occurs on top of the video.

This document is the starting point for BATCAM FX integration development. It introduces the device’s interfaces at a glance and walks through the data flow and connection steps for the most common integration task: overlay video compositing. Detailed topics such as parameter control, ROS 2 integration, and firmware updates are covered in their own documents. For the overall developer center structure and documentation for other products (BATCAM FX2, FX Viewer), see Getting Started with the Developer Center.

2. Interfaces at a Glance

InterfacePurposeRelated Documents
RTSPReceive the raw camera video stream. On firmware 1.0.3 and later, the device can also serve a self-composited overlay video over RTSP.Overlay Parameters
WebSocket + ProtobufReal-time streaming of beamforming (BF Map), audio, and AI partial discharge (PRPD) classification resultsThis document, Python Protobuf Example
REST APIAccount management, device settings (network, firmware, reboot, device info), event triggers, beamforming and overlay parameters, ROS Domain IDBATCAM FX API Playground
ROS 2Topic/action-based data reception and configuration (supported from development firmware v1.0.3b)ROS Integration
Firmware updateInstall firmware via the web page or a shell (SSH)Web Update, Shell Update

The full REST API endpoint specification is available in the API Playground, where you can also call the endpoints directly from your browser. For the format of messages sent over WebSocket, see the fx-stream-protocol schema and the Python Protobuf Example document.

3. Overlay Video Compositing Data Flow

BATCAM FX transmits its data as raw camera video over RTSP and as Protobuf-encoded data over WebSocket. To obtain the overlaid video yourself, composite the video in the following order.

BATCAM FX overlay video compositing data flow diagram: combining raw RTSP video with WebSocket/Protobuf beamforming data

  1. Receive the raw video from RTSP (rtsp://{device_ip}/raw).

  2. Receive Beamforming messages encoded in Protobuf over WebSocket and decode them into an array of 1200 Float values (Float Array). This array is the 40x30 BF Map flattened into a 1x1200 layout, and it is transmitted at 25Hz.

  3. Interpolate the Float Array to generate the image to overlay. The 40×30 BF Map is mapped onto the 1600×1200 optical video.

  4. Combine the RTSP video stream with the received sound-source data to generate a real-time Beamforming overlay video.

💡 Note: On firmware 1.0.3 and later, BATCAM FX can serve an RTSP stream with the overlay image composited on the device, so a setup without client-side compositing is also possible. For configuration, see the Overlay Parameters document; for the BF Map coordinate system and Listening Point selection, see the Listening Point Coordinates document.

4. Connection Details and Authentication

In the table below, {device_ip} is the IP address of the device. Query and change the IP settings via the REST API (/setting/ip), and check the device firmware version via the device info API (/setting/status). For the full specification, see the API Playground.

ItemValueNotes
RTSP video streamrtsp://{device_ip}/rawUser authentication required
WebSocket streamingws://{device_ip}/wsSubProtocol must be specified
WebSocket SubProtocolSubscribeSome examples also use the lowercase subscribe form
REST APIhttp://{device_ip}Served directly by the device
Firmware update pagehttp://{device_ip}/firmwareWeb Update guide
Firmware update logws://{device_ip}/firmware/wsReceive update progress logs
AuthenticationHTTP BasicCommon to REST, RTSP, and WebSocket

BATCAM FX ships with two preconfigured accounts, admin and user. Create accounts with /auth/create, list all accounts with /auth/all, and query, remove, or reset the password of an individual account with the /auth/account endpoint.

⚠️ Warning: Always change the factory default passwords before use.

Building the Authorization header — If your WebSocket library supports authentication, provide the Username and Password. If it does not, add an Authorization key to the WebSocket connection request header and include the {username}:{password} string encoded in base64.

Authorization: Basic base64({username}:{password})
# Example: username=admin, password=password
Authorization: Basic YWRtaW46cGFzc3dvcmQ=

Starting a subscription (Subscribe) — Messages do not start arriving as soon as the WebSocket is connected. You must send the camera a subscription for the data streams you want, using the Subscribe object provided by the pregenerated Protobuf code. The Subscribe IDs per stream are as follows.

Subscribe IDMessageContentRate
0Beamforming40×30 BF Map (1×1200 Float array)25 Hz
1WsAudio8000-sample Float audio (200 kHz × 40 ms)25 Hz
2LPointAudio3-channel Listening Point beamforming audio25 Hz
3PrpdAI partial discharge classification results (firmware v1.0.3c and later; see AI PRPD Classification)4 Hz

5. Example Code and Protobuf Schema

An example that exchanges data using Protobuf and WebSocket is available on our GitHub (C# example). It covers the entire overlay compositing process described above and also includes a GUI example.

The following Python example shows the flow from connecting over WebSocket and sending a subscription to decoding the first message.

import asyncio
import base64
import websockets
import fx_protocol_pb2 as pb # pregenerated file from fx-stream-protocol
async def stream(ip: str, user: str, password: str):
cred = base64.b64encode(f"{user}:{password}".encode()).decode()
headers = {
"Authorization": f"Basic {cred}",
"Sec-WebSocket-Protocol": "subscribe",
}
uri = f"ws://{ip}/ws"
async with websockets.connect(uri, additional_headers=headers, subprotocols=["subscribe"]) as ws:
# Start subscribing to Beamforming (ID 0)
sub = pb.Subscribe()
sub.id = 0
sub.type = pb.Subscribe.SUBSCRIBE
await ws.send(sub.SerializeToString())
async for raw in ws:
event = pb.Event()
event.ParseFromString(raw)
if event.WhichOneof("data") == "beamforming":
bf = event.beamforming
print(f"bf count={len(bf.bf)} gain={bf.gain}") # bf count=1200
asyncio.run(stream("192.168.0.30", "admin", "password"))

For environment setup, generating the Python bindings, and detailed examples for each message type, see the step-by-step Python Protobuf Example guide.

The schema and pregenerated files required to encode/decode Protobuf are available on our OSS GitLab (fx-stream-protocol). This document is based on the pregenerated files from the v0.0.2 tag; for other versions, check the repository’s tag list.

6. Troubleshooting

SymptomCauseResolution
WebSocket connection cannot be establishedSubProtocol not specifiedAlways set the WebSocket SubProtocol to Subscribe when connecting (the subprotocols option of your library).
Connected but no messages are receivedSubscribe message not sentRight after connecting, send a Subscribe object (id, type) to start the subscription. (C# reference link)
Connection rejected with an authentication error (401)Missing credentials or incorrect account informationProvide the Username/Password through your library’s authentication feature (C# reference link), or build the Authorization header directly in the format above. Verify that the account and password are correct.

7. Next Steps