Integration : Home assistant - themactep/thingino-firmware GitHub Wiki

To configure camera in home assistant, add onvif integration. Then add a new camera and let it autodiscover. In my case autodiscovery failed but it prompted me for IP address of camera. Once entering auth details it added it correctly.

When manually setting up the camera with ONVIF, the port will be "80" and the default username and password is "thingino". The login credentials can be changed from the settings > RTSP/ONVIF Access page of the Thingino interface.

The URL to get snapshot from camera is

http://thingino:thingino@[ipOfYourCamera]/image.jpg

Add white led in home assistant

For now it requires polling to get status.


light:
  - platform: template
    lights:
      z55_light:
        unique_id: "z55_light"
        turn_on:
          - action: rest_command.z55_camera_light_on
        turn_off:
          - action: rest_command.z55_camera_light_off
        #value_template: "{{ is_state('binary_sensor.z55_light_status', 'on') }}"
        value_template: "{{ states('binary_sensor.z55_light_status') }}"
template:
  - unique_id: z55_light_status_template
    trigger:
      - trigger: time_pattern
        seconds: /30
    action:
      - action: rest_command.z55_camera_light_status
        response_variable: z55_response
    binary_sensor:
      - name: z55_light_status
        unique_id: z55_light_status
        state: >
          {{ z55_response['content']['message']['white'] == 1 }}

rest_command:
  z55_camera_light_on:
    url: "http://z55.home/x/json-imp.cgi?cmd=white&val=1"
    username: root
    password: MyRootPassword
    verify_ssl: false
    method: get

  z55_camera_light_off:
    url: "http://z55.home/x/json-imp.cgi?cmd=white&val=0"
    username: root
    password: MyRootPassword
    verify_ssl: false
    method: get

  z55_camera_light_status:
    url: "http://z55.home/x/json-imp.cgi?cmd=white&val=read"
    username: root
    password: MyRootPassword
    verify_ssl: false
    method: get
    headers:
      Accept: "*/*"

Add a Picture Glance Card with PTZ Controls

The ONVIF implementation in Home Assistant does not expose PTZ controls as entities. You will need to add custom code to add the controls. The following is the full YAML for a Picture Glance Card with PTZ control. Be sure to update with the proper camera entity name.

camera_view: live
fit_mode: cover
type: picture-glance
title: Cinnado T23
image: http://thingino:[email protected]/image.jpg
camera_image: camera.cinnado_profile_1
entities:
  - entity: camera.cinnado_profile_1
    name: Pan Left
    icon: mdi:arrow-left
    tap_action:
      action: call-service
      service: onvif.ptz
      service_data:
        entity_id: camera.cinnado_profile_1
        pan: LEFT
        speed: 1
        distance: 0.01
        move_mode: ContinuousMove
  - entity: camera.cinnado_profile_1
    name: Tilt Up
    icon: mdi:arrow-up
    tap_action:
      action: call-service
      service: onvif.ptz
      service_data:
        entity_id: camera.cinnado_profile_1
        tilt: UP
        speed: 1
        distance: 0.01
        move_mode: ContinuousMove
  - entity: camera.cinnado_profile_1
    name: Tilt Down
    icon: mdi:arrow-down
    tap_action:
      action: call-service
      service: onvif.ptz
      service_data:
        entity_id: camera.cinnado_profile_1
        tilt: DOWN
        speed: 1
        distance: 0.01
        move_mode: ContinuousMove
  - entity: camera.cinnado_profile_1
    name: Pan Right
    icon: mdi:arrow-right
    tap_action:
      action: call-service
      service: onvif.ptz
      service_data:
        entity_id: camera.cinnado_profile_1
        pan: RIGHT
        speed: 1
        distance: 0.01
        move_mode: ContinuousMove
  - entity: binary_sensor.cinnado_motion_alarm

Note for Wuuk camera owners: The PTZ examples using "distance: 0.01" don't seem to work -- the camera ignores distance and moves too far. Using "continuous_duration: 0.07" instead provides accurate, controlled movement.

Set Motion Guard

Since Thingino doesn't expose Motion Guard settings via the ONVIF interface, Home Assistant shows an error when using the built-in Enable/Disable Motion Detection actions. While enabling or disabling the Motion Guard service in Thingino is only possible through a websocket, changing the notification target is possible via a simple HTTP GET request.

The URL is http://[user]:[password]@[camera IP address]/x/json-motion.cgi?target=[target]&state=[true|false]

Where the target is one of: send2email | send2ftp | send2mqtt | send2telegram | send2webhook | send2ntfy | send2gphotos

See also the source in json-motion.cgi

WebRTC integration

Some users may encounter a problem where the WebRTC integration (https://github.com/AlexxIT/WebRTC) unexpectedly falls back to MSE instead of establishing a proper WebRTC stream. This behavior is often caused by the camera streaming audio using the AAC codec. If you run into this issue, update the camera's audio codec from AAC to OPUS via the camera's web interface: "Settings → Streamer/OSD → Audio"

If HTTPS is properly configured in your go2rtc setup (https://github.com/AlexxIT/go2rtc), the configuration below enables two-way audio, provided that the camera’s microphone is turned on in the web interface. (tested with a WUUK camera)

type: custom:webrtc-camera
url: wuuk1   # this is the stream defined in your "streams" session in go2rtc.yaml
mode: webrtc
media: video,audio,microphone

Remark: On my WUUK camera, the built-in speaker wasn’t loud enough, and it seems that there is no speaker volume control exposed in the web UI. I was able to increase the volume by connecting to the camera via SSH and editing /etc/iad.json. In the AO_attributes section, raise the SetVol value (for example, to 90) to make the speaker significantly louder after a reboot.

Tutorial: Dynamic REST Commands for WUUK / Thingino Cameras

Manage multiple WUUK / Thingino cameras in Home Assistant using a single rest_command, while keeping all IP addresses cleanly stored in a separate YAML file.

This example shows how to restart the streamer on several cameras without performing a full device reboot. The same approach can be adapted to trigger any other commands exposed in the webUI. Using this setup, you will be able to:

  • Store all camera IPs in one file
  • Assign each camera a simple alias (wuuk1, wuuk2, etc.)
  • Call a generic REST command dynamically
  • Create buttons that restart the streamer in any camera
  • Avoid duplicating IPs everywhere

To find the URL used by your camera’s Restart streamer button in the web interface, open the camera’s web UI in your browser. Then, move your mouse over the Setting -> Streamer/OSD -> Restart streamer button (without clicking it). Your browser should show the target address, usually at the bottom of the window.

For example, in the web interface of one of my cameras, I click on the Tools menu in the top toolbar and then hover over "Restart streamer." The browser shows the URL: http://192.168.1.2/x/config-streamer.cgi?do=restart

In this case, 192.168.1.2 is the IP address of the camera, and /x/config-streamer.cgi?do=restart is the endpoint we will use in the Home Assistant REST command.


✅ 1. Create ip.yaml (Alias → IP Mapping)

Create a file named ip.yaml in your Home Assistant config directory (usually /config on most installs):

wuuk1: 192.168.1.2
wuuk2: 192.168.1.3
wuuk3: 192.168.1.4

This file contains all camera IPs centrally.
You’ll use these aliases (wuuk1, wuuk2, etc.) everywhere else.


✅ 2. Expose the Mapping Using a Template Sensor

Add this block to your configuration.yaml:

template:
  - sensor:
      - name: "Camera IP Map"
        unique_id: camera_ip_map
        state: "ok"
        attributes: !include ip.yaml

Home Assistant will create an entity:

  • Entity ID: sensor.camera_ip_map
  • Attributes: All camera names and their IPs from ip.yaml

Example attributes (in Developer Tools → States):

wuuk1: 192.168.1.2
wuuk2: 192.168.1.3
wuuk3: 192.168.1.4

✅ 3. Create a Generic REST Command

Add this to configuration.yaml (or your split-out rest_command.yaml if you use one):

rest_command:
  wuuk_restart_streamer:
    url: "http://{{ ip }}/x/config-streamer.cgi?do=restart"
    method: get
    authentication: basic
    username: root
    password: !secret camera_password

Notes:

  • {{ ip }} is a template variable that will be provided when the service is called.
  • camera_password should be defined in your secrets.yaml.

✅ 4. Create a Script to Restart Cameras by Alias

Add this to configuration.yaml or scripts.yaml:

script:
  wuuk_restart_by_alias:
    alias: "Restart WUUK by alias"
    mode: single
    fields:
      alias:
        description: "Camera alias (e.g. wuuk1)"
        example: "wuuk1"
    sequence:
      - variables:
          ip: "{{ state_attr('sensor.camera_ip_map', alias) }}"
      - service: rest_command.wuuk_restart_streamer
        data:
          ip: "{{ ip }}"

What this script does:

  1. Receives an alias (e.g. wuuk1) as input.
  2. Looks up the IP address from sensor.camera_ip_map using that alias.
  3. Calls the REST command rest_command.wuuk_restart_streamer with the resolved IP.

You can call this script manually from the Services panel or trigger it from automations and dashboards.


✅ 5. Add Dashboard Buttons to Control Each Camera

Example Lovelace card using a grid with reboot buttons for three cameras:

type: grid
columns: 3
square: false
cards:
  - type: button
    name: Restart streamer - WUUK1
    icon: mdi:restart
    tap_action:
      action: call-service
      service: script.wuuk_restart_by_alias
      data:
        alias: wuuk1

  - type: button
    name: Restart streamer - WUUK2
    icon: mdi:restart
    tap_action:
      action: call-service
      service: script.wuuk_restart_by_alias
      data:
        alias: wuuk2

  - type: button
    name: Restart streamer - WUUK3
    icon: mdi:restart
    tap_action:
      action: call-service
      service: script.wuuk_restart_by_alias
      data:
        alias: wuuk3

Pressing a button will:

  • Call script.wuuk_restart_by_alias
  • Pass the correct alias (wuuk1, wuuk2, etc.)
  • Automatically resolve the correct IP and send the "Restart streamer" request

🧠 How It Works (Concept Overview)

Component Purpose
ip.yaml Stores alias → IP mapping
Template sensor Makes the map available inside templates
rest_command A generic command with an ip placeholder
Script Converts alias into IP and calls REST command
Lovelace buttons Trigger the script with a chosen alias

This approach:

  • Eliminates duplicated IPs
  • Simplifies maintenance
  • Keeps your Home Assistant YAML clean and organized
  • Lets you add cameras easily without touching automations/scripts

🧼 Updating or Adding Cameras

To add or update a camera, just edit ip.yaml:

wuuk4: 192.168.1.5

Once Home Assistant reloads the template entities (or after a restart), the new alias is automatically available everywhere:

  • No need to change scripts
  • No need to change automations
  • No need to modify UI buttons

Everything continues to work using the new or updated alias → IP mapping.