I’ve then set this camera to stream to a Google Home Hub upon the press of a doorbell with the following code, will probably expand to include streaming to chromecast on TV. The camera’s also take a snapshot and send it to my phone via Telegram.
- alias: Doorbell
trigger:
platform: event
event_type: xiaomi_aqara.click
event_data:
entity_id: binary_sensor.switch_158d0002134e55
click_type: single
action:
- service: xiaomi_aqara.play_ringtone
data:
gw_mac: 78:11:DC:B1:EF:85
ringtone_id: 10
ringtone_vol: 25
- service: camera.snapshot
data:
entity_id: camera.porch_ffmpeg
filename: "/tmp/porch.jpg"
- service: notify.notify
data:
message: "The doorbell was rang at {{now().strftime('%H:%M %d-%m-%Y')}}."
data:
photo:
- file: /tmp/porch.jpg
caption: The doorbell was rang at {{now().strftime('%H:%M %d-%m-%Y')}}.
- service: notify.name
data:
message: "The doorbell was rang at {{now().strftime('%H:%M %d-%m-%Y')}}."
data:
photo:
- file: /tmp/porch.jpg
caption: The doorbell was rang at {{now().strftime('%H:%M %d-%m-%Y')}}.
- service: media_player.turn_on
entity_id: media_player.kitchen_display
- delay:
seconds: 3
- service: camera.play_stream
data:
entity_id: camera.porch_ffmpeg
media_player: media_player.kitchen_display
- delay:
seconds: 60
- service: media_player.turn_off
entity_id: media_player.kitchen_display
Camera’s are also exposed to Google Home via Home Assistant Cloud, so asking to show the stream on the Home Hub/Chromecast will show up.
Thanks but my understanding is this exactly what the stream component should be doing. From Stream - Home Assistant
The integration currently only supports proxying H.264 source streams to the HLS format and requires at least FFmpeg >= 3.2.
One thing I realized might be an issue is I have an nginx reverse proxy, protected by oauth, in front of my Home Assistant instance. Im guessing the chromecast may be hitting Home Assistant to get the stream and failing due to requiring oauth. However, there is no documentation of what endpoints its needs. I “unprotected” /api/hls/ which it seems to use to provide the stream, but it still isnt working.
Does anyone else have oauth in front of their Home Assistant and successfully using streams? Would you mind sharing your nginx config if so?
hello
i have a escam g02… i cannot make PTZ work with HA but it works with all the apps available on internet.
how can i discover the commands to make ptz work on HA?
thanks a lot
After more research and experimenting, I don’t think the proxy is the issue. I configured ngnix to allow all traffic from my local networks but the behavior is still the same.
I’m going to have to give up on this feature unless someone can provide guidance on how to debug. I still am seeing nothing in the logs
hello
someone had apparently made escam G02 with the following script
how can it be adapted for homeassistant?
# ==========================================================================
#
# ZoneMinder IPCAM2MP Control Protocol Module, $Date: 2009-11-25 09:20:00 +0000 (Wed, 04 Nov 2009) $, $Revision: 0003 $
# Copyright (C) 2001-2008 Philip Coombes
#
# Modified for China 2MP NetIpCam camera by Radmilo Feliox n 2015-05-05 00:03:00
# Modified for ESCAM G02 / IPCAMERA / C9F0SeZ0N0P2L0 / FW: V9.1.6.1.24-20170925 BY PETER ZARGLIS n 2018-06-09 13:45:00
# For more information/cgi-bin commands see https://www.themadhermit.net/wp-content/uploads/2013/03/FI9821W-CGI-Commands.pdf
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of the China 2MP NetIpCam camera
# control protocol.
#
# ==========================================================================
package ZoneMinder::Control::IPCAM2MP;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
our $VERSION = $ZoneMinder::Base::VERSION;
# ==========================================================================
#
# China 2MP NetIpCam Control Protocol
#
# ==========================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
my $loopfactor=100000;
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
my $logindetails = "";
bless( $self, $class );
srand( time() );
return $self;
}
our $AUTOLOAD;
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift;
$self->loadMonitor();
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
# $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION );
$self->{ua}->agent( "ZoneMinder Control Agent" );
$self->{state} = 'open';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $result = undef;
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = $res->decoded_content;
}
else
{
Error( "Error check failed: '".$res->status_line()."'" );
}
return( $result );
}
# Reboot camera
sub reset
{
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "cgi-bin/hi3510/sysreboot.cgi";
$self->sendCmd( $cmd );
}
# Flip image on vertically
sub wake
{
my $self = shift;
Debug( "Flip on" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-flip=on";
$self->sendCmd( $cmd );
}
# Flip image off vertically
sub sleep
{
my $self = shift;
Debug( "Flip off" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-flip=off";
$self->sendCmd( $cmd );
}
sub moveConUp
{
my $self = shift;
my $params = shift;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=up";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
else
{
$self->moveStop( $params );
}
}
sub moveConDown
{
my $self = shift;
my $params = shift;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=down";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
else
{
$self->moveStop( $params );
}
}
sub moveConRight
{
my $self = shift;
my $params = shift;
Debug( "Move Right" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=right";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
else
{
$self->moveStop( $params );
}
}
sub moveConLeft
{
my $self = shift;
my $params = shift;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=left";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
else
{
$self->moveStop( $params );
}
}
# The camera can not move diagonally, so we will implement those movements in the next 4 subroutines:
sub moveConUpLeft
{
my $self = shift;
my $params = shift;
my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
while ( $loopcount )
{
$loopcount--;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=up";
$self->sendCmd( $cmd );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=left";
$self->sendCmd( $cmd );
}
$self->moveStop( $params );
}
}
sub moveConUpRight
{
my $self = shift;
my $params = shift;
my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
while ( $loopcount )
{
$loopcount--;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=up";
$self->sendCmd( $cmd );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=right";
$self->sendCmd( $cmd );
}
$self->moveStop( $params );
}
}
sub moveConDownRight
{
my $self = shift;
my $params = shift;
my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
while ( $loopcount )
{
$loopcount--;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=down";
$self->sendCmd( $cmd );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=right";
$self->sendCmd( $cmd );
}
$self->moveStop( $params );
}
}
sub moveConDownLeft
{
my $self = shift;
my $params = shift;
my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
while ( $loopcount )
{
$loopcount--;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=down";
$self->sendCmd( $cmd );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=left";
$self->sendCmd( $cmd );
}
$self->moveStop( $params );
}
}
sub moveStop
{
my $self = shift;
print("autostop\n");
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=stop";
$self->sendCmd( $cmd );
}
sub getDisplayAttr
{
my $self = shift;
my $param = shift;
my $cmdget = "cgi-bin/hi3510/param.cgi?cmd=getvdisplayattr&-brightness";
my $resp = $self->sendCmd( $cmdget );
my @buffer=split(';',$resp);
my $response=$buffer[$param];
my @buffer=split('"',$response);
my $response=$buffer[1];
return ($response);
}
# presetHome is used to normalize the brightness/contrast/hue/saturation values
sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-brightness=50&-contrast=50&-saturation=50&-hue=50";
$self->sendCmd( $cmd );
}
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset " );
my $cmd = "cgi-bin/hi3510/preset.cgi?-act=set&-status=1&-number=$preset";
$self->sendCmd( $cmd );
}
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = "/cgi-bin/hi3510/preset.cgi?-act=goto&-number=$preset";
$self->sendCmd( $cmd );
}
# Contrast control
sub whiteAbsIn
{
my $self = shift;
my $params = shift;
Debug( "Contrast up" );
my $dvalue=$self->getDisplayAttr(6);
if ( $dvalue < 100 )
{
$dvalue=$dvalue+5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-contrast=$dvalue";
$self->sendCmd( $cmd );
}
}
# Contrast control
sub whiteAbsOut
{
my $self = shift;
my $params = shift;
Debug( "Contrast down" );
my $dvalue=$self->getDisplayAttr(6);
if ( $dvalue > 0 )
{
$dvalue=$dvalue-5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-contrast=$dvalue";
$self->sendCmd( $cmd );
}
}
# Brightness control
sub irisAbsOpen
{
my $self = shift;
my $params = shift;
Debug( "Brightness up" );
my $dvalue=$self->getDisplayAttr(4);
if ( $dvalue < 100 )
{
$dvalue=$dvalue+5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-brightness=$dvalue";
$self->sendCmd( $cmd );
}
}
# Brightness control
sub irisAbsClose
{
my $self = shift;
my $params = shift;
Debug( "Brightness down" );
my $dvalue=$self->getDisplayAttr(4);
if ( $dvalue > 0 )
{
$dvalue=$dvalue-5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-brightness=$dvalue";
$self->sendCmd( $cmd );
}
}
# Saturation control
sub zoomAbsTele
{
my $self = shift;
my $params = shift;
Debug( "Saturation up" );
my $dvalue=$self->getDisplayAttr(5);
if ( $dvalue < 100 )
{
$dvalue=$dvalue+5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-saturation=$dvalue";
$self->sendCmd( $cmd );
}
}
# Saturation control
sub zoomAbsWide
{
my $self = shift;
my $params = shift;
Debug( "Saturation down" );
my $dvalue=$self->getDisplayAttr(5);
if ( $dvalue > 0 )
{
$dvalue=$dvalue-5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-saturation=$dvalue";
$self->sendCmd( $cmd );
}
}
# Hue control
sub focusAbsNear
{
my $self = shift;
my $params = shift;
Debug( "Hue up" );
my $dvalue=$self->getDisplayAttr(7);
if ( $dvalue < 100 )
{
$dvalue=$dvalue+5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-hue=$dvalue";
$self->sendCmd( $cmd );
}
}
# Hue control
sub focusAbsFar
{
my $self = shift;
my $params = shift;
Debug( "Hue down" );
my $dvalue=$self->getDisplayAttr(7);
if ( $dvalue > 0 )
{
$dvalue=$dvalue-5;
my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-hue=$dvalue";
$self->sendCmd( $cmd );
}
}
1;
It’s awesome that the “stream” component allows live streaming and visibility to Chromecasts and Google Smart Displays, however when it enabled it crashes my Home Assistant.
This problem appears widespread based on the thread below. Any ideas for a fix?
Same issue as @Peter_Iliev and @Fernando_Castro but i am using 2 different brand camera’s.
"google cast blue icon changed and a blue vertical bar started to move. However, I never see anything. "
VLC and HA just working fine, but no stream in google chromecast. using the chromecast 4k.
Running four cameras; back garden, side entrance, front drive & porch.
I’ve currently also got all four cameras running through MotionEye with motion detection, with plans at a later date to use the stream from MotionEye with this component (however first attempts were unsuccessful and haven’t got around to playing with it again).
CPU load idles at around 2.0-2.4 on an AMD Turion II Neo N40L Dual Core with 4GB RAM. (Looking at upgrading, but there’s also a bit of a clean up on the server needed.)
This would provide a screenshot of the camera that would periodically update.
Clicking this would bring up the livestream and the option to pre-load the stream for quicker switchover to the livestream. Normally takes a couple of seconds to load the livestream.
As for Google streaming, I’ve exposed them via Nabu Casa and then added them in Google Home to the relevant rooms. I ask the Google Home Hub to “show me the porch camera” and after a few seconds it pops up.
I experienced exactly this issue with hassio on a tinkerboard s and also later in a virtualbox install. I removed stream: and it has been rock solid since then. I won’t be adding the stream: option back to my config until I see a specific confirmation of a fix in a future release. I rely on hassio too much for the heating system, security, lights etc to risk it hanging every 0.5 to 4 days.
I have been away for a while but would like to revisit this project. Has anyone been able to stream a Blue Iris h264 feed to a Chromecast device using the generic camera component and HA HLS stream?