# Dahua Camera Overlay Product Name

**URL:** <https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211>\
**Category:** Ignition\
**Created:** [August 27, 2025, 2:06pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211 "2025-08-27T14:06:09Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 27, 2025, 2:06pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/1 "2025-08-27T14:06:09Z")

</div>

Hello.

We Have a sorting system that sorts planks into bins. I would like a Camera to record the conveyor with an overlay on the camera showing the bin it’s on its way to.

This Url in a browser does change the overlay

```python
http://IG:IG123456@192.168.1.108/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=IG%20IS%20Test

```

I have tried

```python
IP = "192.168.1.108"
url = "http://"+IP+"/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=TESTignitionURL1"
user = 'IG'
passwd = 'IG123456'

client = system.net.httpClient(bypass_cert_validation = True,cookie_policy = "ACCEPT_ALL",redirect_policy="ALWAYS")
client.get(url,username=user, password=passwd)

```

> I keep Getting \<Response@951780780 '[http://192.168.1.108/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=TESTignitionURL1](http://192.168.1.108/cgi-bin/configManager.cgi?action=setConfig&VideoWidget%5B0%5D.CustomTitle%5B1%5D.Text=TESTignitionURL1)' [401]\>

I have very little experience with what I’m trying to accomplish any help would be appreciated

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 27, 2025, 4:27pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/2 "2025-08-27T16:27:16Z")

</div>

You'll have to provide more context, but assuming:

1. This is Perspective
2. You're trying to embed this camera view on the Perspective session
3. Your camera is accessible over the network from wherever you're running these Perspective sessions

You _probably_ want the iframe component. A script, such as `system.net.httpClient`, is running on the **gateway** , not wherever you're using the Perspective session, so whatever authentication and anything it's doing with the camera are not going to be easy to pass back to the actual front end.

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 27, 2025, 4:59pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/3 "2025-08-27T16:59:01Z")

</div>

I would like a script to run every time a product arrives at the first bin.

To add an overlay to the camera recording. I would like to add data to the camera recording.

I have tried to stand there with my phone and check. But the problem is so random and always comes when you not paying attention. When I’m there 400-500 planks will pass without issue.

When the complaints roll in, I can go back to the recording and see why it happened.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 27, 2025, 5:24pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/4 "2025-08-27T17:24:09Z")

</div>

Got it. Ultimately what you probably want is to perform an HTTP **POST** to the endpoint in the URL. Open your browser's network tab and watch the requests initiated when you do this in the web browser. You will want to duplicate the (probably) POST request with to indicate that you want the server to perform an action; GET is the HTTP 'verb' for reading data, not writing it.

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 27, 2025, 5:25pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/5 "2025-08-27T17:25:17Z")

</div>

![No_overlay](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/1/f1df13e0ff4004d90645def29bc6f1c68ce6eabe.jpeg)

 ![With_Overlay](https://us1.discourse-cdn.com/inductiveautomation/original/3X/7/1/71e39bfae5a1c157f340c8d2762092dea804e05c.jpeg)

I have same type of camera at home I can change the overlay with windows cmd.

```python
curl -s -g --digest -u admin:*passw* "http://111.111.111.111/cgi-bin/configManager.cgi?action=setConfig&ChannelTitle[0].Name=1234|5678

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 27, 2025, 6:14pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/6 "2025-08-27T18:14:55Z")

</div>

Got it. Based on the screenshot you sent me, this is in fact a GET request (somewhat odd, not the weirdest thing in the world).

The real problem doing this from Ignition scripting is going to be replicating the `--digest` flag. There's no built in support in the native HTTP client for digest authentication, so you'll have to script it yourself.

This LLM guided output **might** get you there?

```python
# Imports for hashing, URL encoding, and random number generation
from java.security import MessageDigest, SecureRandom
from java.math import BigInteger
from urllib import urlencode
import re

# --- Helper Functions ---

def md5(text):
    """Calculates the MD5 hash of a string and returns a lowercase hex digest."""
    md = MessageDigest.getInstance("MD5")
    md.update(text.encode('utf-8'))
    digest = md.digest()
    return BigInteger(1, digest).toString(16).zfill(32)

def parse_auth_header(header_value):
    """Parses a WWW-Authenticate header string into a dictionary."""
    if header_value.lower().startswith('digest '):
        header_value = header_value[7:]
    
    # Regex to find all key="value" or key=value pairs
    parts = re.findall(r'(\w+)="([^"]*)"|(\w+)=([^\s,]+)', header_value)
    
    auth_dict = {}
    for key1, val1, key2, val2 in parts:
        if key1: # Quoted value match
            auth_dict[key1] = val1
        else: # Unquoted value match
            auth_dict[key2] = val2
            
    return auth_dict

# --- Main Script ---

# 1. Define Request Details
base_url = "http://111.111.111.111/cgi-bin/configManager.cgi"
uri_path = "/cgi-bin/configManager.cgi" # The path portion of the URL
username = "admin"
password = "*passw*" # <-- IMPORTANT: Replace with your actual password

queryParams = {
    "action": "setConfig",
    "ChannelTitle[0].Name": "1234|5678"
}

# 2. Perform Initial Request to Get the Server Challenge
client = system.net.httpClient()
initial_response = client.get(url=base_url, params=queryParams)

# 3. Extract Challenge Details from the Header
auth_header = initial_response.getHeaders().get("WWW-Authenticate")
challenge = parse_auth_header(auth_header)

realm = challenge['realm']
qop = challenge['qop']
nonce = challenge['nonce']
opaque = challenge.get('opaque', '') # Use .get() as opaque is optional

# 4. Generate Client Values and Calculate Hashes
nc = '00000001' # Nonce count, starts at 1
cnonce = BigInteger(130, SecureRandom()).toString(16)[:16] # Random client nonce
full_uri = uri_path + "?" + urlencode(queryParams)

# Calculate the three required hashes
HA1 = md5(username + ":" + realm + ":" + password)
HA2 = md5("GET:" + full_uri)
response_hash = md5(HA1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + HA2)

# 5. Construct the Final Authorization Header
auth_string = (
    'Digest username="{username}", realm="{realm}", nonce="{nonce}", uri="{uri}", '
    'qop={qop}, nc={nc}, cnonce="{cnonce}", response="{response}", opaque="{opaque}"'
).format(
    username=username, realm=realm, nonce=nonce, uri=full_uri, qop=qop,
    nc=nc, cnonce=cnonce, response=response_hash, opaque=opaque
)

# 6. Make the Final, Authenticated Request
# This request will throw an error if it fails, as requested.
final_response = client.get(
    url=base_url,
    params=queryParams,
    headers={'Authorization': auth_string}
)

# If the script reaches this point, the request was successful.
# You can now work with the response, for example:
print "Request successful. Response Body:"
print final_response.text

```

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 27, 2025, 6:23pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/7 "2025-08-27T18:23:59Z")

</div>

I tried it and got

Traceback (most recent call last):  
File "", line 53, in  
File "", line 19, in parse\_auth\_header  
AttributeError: 'java.util.ImmutableCollections$List12' object has no attribute 'lower'

> > >

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 27, 2025, 6:35pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/8 "2025-08-27T18:35:29Z")

</div>

Try:

```python
# Imports for hashing, URL encoding, and random number generation
from java.security import MessageDigest, SecureRandom
from java.math import BigInteger
from urllib import urlencode
import re

# --- Helper Functions ---

def md5(text):
    """Calculates the MD5 hash of a string and returns a lowercase hex digest."""
    md = MessageDigest.getInstance("MD5")
    md.update(text.encode('utf-8'))
    digest = md.digest()
    return BigInteger(1, digest).toString(16).zfill(32)

def parse_auth_header(header_value):
    """Parses a WWW-Authenticate header string into a dictionary."""
    if header_value.lower().startswith('digest '):
        header_value = header_value[7:]
    
    # Regex to find all key="value" or key=value pairs
    parts = re.findall(r'(\w+)="([^"]*)"|(\w+)=([^\s,]+)', header_value)
    
    auth_dict = {}
    for key1, val1, key2, val2 in parts:
        if key1: # Quoted value match
            auth_dict[key1] = val1
        else: # Unquoted value match
            auth_dict[key2] = val2
            
    return auth_dict

# --- Main Script ---

# 1. Define Request Details
base_url = "http://111.111.111.111/cgi-bin/configManager.cgi"
uri_path = "/cgi-bin/configManager.cgi" # The path portion of the URL
username = "admin"
password = "*passw*" # <-- IMPORTANT: Replace with your actual password

queryParams = {
    "action": "setConfig",
    "ChannelTitle[0].Name": "1234|5678"
}

# 2. Perform Initial Request to Get the Server Challenge
client = system.net.httpClient()
initial_response = client.get(url=base_url, params=queryParams)

# 3. Extract Challenge Details from the Header
auth_header = initial_response.headers.get("WWW-Authenticate")
challenge = parse_auth_header(auth_header[0])

realm = challenge['realm']
qop = challenge['qop']
nonce = challenge['nonce']
opaque = challenge.get('opaque', '') # Use .get() as opaque is optional

# 4. Generate Client Values and Calculate Hashes
nc = '00000001' # Nonce count, starts at 1
cnonce = BigInteger(130, SecureRandom()).toString(16)[:16] # Random client nonce
full_uri = uri_path + "?" + urlencode(queryParams)

# Calculate the three required hashes
HA1 = md5(username + ":" + realm + ":" + password)
HA2 = md5("GET:" + full_uri)
response_hash = md5(HA1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + HA2)

# 5. Construct the Final Authorization Header
auth_string = (
    'Digest username="{username}", realm="{realm}", nonce="{nonce}", uri="{uri}", '
    'qop={qop}, nc={nc}, cnonce="{cnonce}", response="{response}", opaque="{opaque}"'
).format(
    username=username, realm=realm, nonce=nonce, uri=full_uri, qop=qop,
    nc=nc, cnonce=cnonce, response=response_hash, opaque=opaque
)

# 6. Make the Final, Authenticated Request
# This request will throw an error if it fails, as requested.
final_response = client.get(
    url=base_url,
    params=queryParams,
    headers={'Authorization': auth_string}
)

# If the script reaches this point, the request was successful.
# You can now work with the response, for example:
print "Request successful. Response Body:"
print final_response.text

```

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 27, 2025, 6:42pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/9 "2025-08-27T18:42:34Z")

</div>

I got this now

Request successful. Response Body:  
Error

Not Implemented!

> > >

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 27, 2025, 6:45pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/10 "2025-08-27T18:45:16Z")

</div>

🤷

Try printing `response` instead of just `response.text` to see if there's more info.

Or hook up Wireshark and compare a successful operation from curl with what's happening when you invoke the script.

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 27, 2025, 7:08pm UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/11 "2025-08-27T19:08:57Z")

</div>

Thanks. will test everything tomorrow on site.

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 28, 2025, 6:36am UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/13 "2025-08-28T06:36:16Z")

</div>

I have found a manual if it helps any.

3.2Authentication  
The IP Camera supplies two authentication ways: basic authentication and digest authentication. Client can login through:  
http:///cgi-bin/global.login?userName=admin. The IP camera returns 401. Then the client inputs a username and password to authorize.  
For example:

1. When basic authentication, the IP camera response:  
401 Unauthorized  
WWW-Authenticate: Basic realm=”XXXXXX”  
Then the client encode the username and password with base64, send the following request:  
Authorization: Basic VXZVXZ.
2. When digest authentication, the IP camera response:  
WWW-Authenticate: Digest realm="DH\_00408CA5EA04", nonce="000562fdY631973ef04f77a3ede7c1832ff48720ef95ad",  
stale=FALSE, qop="auth";  
The client calculates the digest using username, password, nonce, realm and URI with MD5, then send the following request:  
Authorization: Digest username="admin", realm="DH\_00408CA5EA04", nc=00000001,cnonce="0a4f113b",qop="auth"  
nonce="000562fdY631973ef04f77a3ede7c1832ff48720ef95ad",uri="cgi-bin/global.login?userName=admin",  
response="65002de02df697e946b750590b44f8bf"

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 28, 2025, 8:21am UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/14 "2025-08-28T08:21:14Z")

</div>

Here is something else I found

[Dahua API | IP Cam Talk](https://ipcamtalk.com/threads/dahua-api.77767/)

```python
import hashlib
import requests
from requests.auth import HTTPDigestAuth

# Parameters
username = "admin"
password = "autvix123456"
url = "http://192.168.1.108/cgi-bin/magicBox.cgi?action=getLanguageCaps%20HTTP/1.1"

# Get the initial challenge
response = requests.get(url, auth=HTTPDigestAuth(username, password), verify=False)

# Check if the challenge requires digest authentication
if response.status_code == 401:
    headers = response.headers
    auth_header = headers.get('www-authenticate', '')
    
    # Extract parameters from the WWW-Authenticate header
    # This parsing might need adjustment based on the actual header format
    import re
    match = re.search(r'realm="([^"]+)"', auth_header)
    realm = match.group(1) if match else ""
    match = re.search(r'nonce="([^"]+)"', auth_header)
    nonce = match.group(1) if match else ""
    match = re.search(r'qop="([^"]+)"', auth_header)
    qop = match.group(1) if match else ""
    
    # Generate HA1, HA2, and Response
    HA1 = hashlib.md5(f"{username}:{realm}:{password}".encode()).hexdigest()
    HA2 = hashlib.md5(f"GET:{url}".encode()).hexdigest()
    response_digest = hashlib.md5(f"{HA1}:{nonce}:00000001:0a4f113b:{qop}:{HA2}".encode()).hexdigest()
    
    # Send the authenticated request
    headers = {
        'Authorization': f'Digest username="{username}", realm="{realm}", nonce="{nonce}", uri="{url}", response="{response_digest}", qop="{qop}", nc=00000001, cnonce="0a4f113b"'
    }
    final_response = requests.get(url, headers=headers, verify=False)
    
    if final_response.status_code == 200:
        print("Access successful!")
        print(final_response.json())
    else:
        print(f"Failed to access the URL. Status code: {final_response.status_code}")
else:
    print(response.content)
    print(f"Failed to obtain challenge. Status code: {response.status_code}")

```

Also On the forum

[How to use digest authentication in httpBinding - Ignition - Inductive Automation Forum](https://forum.inductiveautomation.com/t/how-to-use-digest-authentication-in-httpbinding/83786/13)

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 28, 2025, 9:23am UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/15 "2025-08-28T09:23:33Z")

</div>

```python
>>> 
Request successful. Response Body:
<Response@2100990679 'http://10.0.3.103/cgi-bin/configManager.cgi?ChannelTitle%5B0%5D.Name=1234%7C5678&action=setConfig' [400]>
Error

Bad Request!

>>> 

```

[http://10.0.3.103/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=Testing](http://10.0.3.103/cgi-bin/configManager.cgi?action=setConfig&VideoWidget%5B0%5D.CustomTitle%5B1%5D.Text=Testing)

---

<div class="post-metadata">

**Author:** ![gjw\_rfg](https://avatars.discourse-cdn.com/v4/letter/g/9dc877/32.png) [@gjw\_rfg](https://forum.inductiveautomation.com/u/gjw_rfg)\
**Post date:** [August 28, 2025, 11:59am UTC](https://forum.inductiveautomation.com/t/dahua-camera-overlay-product-name/110211/16 "2025-08-28T11:59:27Z")

</div>

> ```python
> queryParams = {
> "action": "setConfig",
> "VideoWidget[0].UserDefinedTitle[0].Text": PlankName
> 
> ```

Its Working Now Thanks for the help
