Skip to content

Commit

Permalink
CBus->CGate Socket checks
Browse files Browse the repository at this point in the history
Test the CGate Talker and Monitor sockets for activity (i.e. health) on each loop. If one is inactive, try to reconnect it (but not on every loop, to minimise log clutter.) Reduce the frequency of CBus network sync queries when the network is not in sync, from every loop, to every 100 loops, to allow low power hardware to catch up. This makes the CBus module more robust, accomodates connections to CGate going away, and better accomodates startup where the CBUs network has not yet attained sync.
  • Loading branch information
jonwhitear committed Sep 7, 2018
1 parent 826441e commit 8ea9c6f
Showing 1 changed file with 70 additions and 5 deletions.
75 changes: 70 additions & 5 deletions lib/Clipsal_CBus/CGate.pm
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,22 @@ sub new {
$$self{cbus_app_list} => {};
$$self{CBus_Sync} = new Generic_Item();
$$self{sync_in_progress} = 0;
$$self{network_sync} = 0;
$$self{network_sync_counter} = 0;
$$self{network_sync_limit} = 100;
$$self{DELAY_CHECK_SYNC} = 10;
$$self{cbus_group_idx} = undef;
$$self{cbus_unit_idx} = undef;
$$self{request_cgate_scan} = 0;

$$self{monitor_check_loop_counter} = 0;
$$self{monitor_check_loop_limit} = 100;
$$self{talker_check_loop_counter} = 0;
$$self{talker_check_loop_limit} = 100;

bless $self, $class;

$self->debug( "Clipsal CBus controller v4.0.1 Initializing...", $notice );

$self->monitor_start();
$self->talker_start();
Expand Down Expand Up @@ -373,6 +383,20 @@ sub monitor_status {

sub monitor_check {
my ($self) = @_;

#Check the monitor socket status once every "limit" loops (rather than every loop, to
#reduce log clutter) and restart it if inactive.

if ( !$Clipsal_CBus::Monitor->active() ) {
if ($$self{monitor_check_loop_counter} == $$self{monitor_check_loop_limit}) {
$self->monitor_start();
$$self{monitor_check_loop_counter} = 0;
}
else {
$$self{monitor_check_loop_counter}++;
}
}


# Monitor Voice Command / Menu processing
if ( my $data = $::CBus_Monitor_v->said() ) {
Expand All @@ -386,13 +410,13 @@ sub monitor_check {

#Process monitor socket input
if ( my $monitor_msg = $Clipsal_CBus::Monitor->said() ) {
$self->debug( "Monitor message: $monitor_msg", $debug );
$self->debug( "Monitor message: $monitor_msg", $trace );

my @cg = split / /, $monitor_msg;
my $cg_code = $cg[1];

unless ( $cg_code == 730 ) { # only code 730 are of interest
$self->debug( "Monitor ignoring uninteresting message type $cg_code", $debug );
$self->debug( "Monitor ignoring uninteresting message type $cg_code", $trace );
return;
}

Expand Down Expand Up @@ -554,9 +578,15 @@ sub talker_start {
$$self{talker_retry} = 0;
if ( $Clipsal_CBus::Talker->start() ) {
$self->debug( "Talker started", $notice );

#reinitialise CBus global variables
%Clipsal_CBus::Groups = ();
%Clipsal_CBus::Units = ();
$Clipsal_CBus::Command_Counter = 0;
$Clipsal_CBus::Command_Counter_Max = 100;
}
else {
$self->debug( "Talker failed to start", $notice );
$self->debug( "Talker failed to start", $warn );
}
}
}
Expand Down Expand Up @@ -595,6 +625,19 @@ sub talker_status {

sub talker_check {
my ($self) = @_;

#Check the talker socket status once every "limit" loops (rather than every loop, to
#reduce log clutter) and restart it if inactive.

if ( !$Clipsal_CBus::Talker->active() ) {
if ($$self{talker_check_loop_counter} == $$self{talker_check_loop_limit}) {
$self->talker_start();
$$self{talker_check_loop_counter} = 0;
}
else {
$$self{talker_check_loop_counter}++;
}
}

# Talker Voice Command / Menu processing
if ( my $data = $::CBus_Talker_v->said() ) {
Expand All @@ -610,6 +653,22 @@ sub talker_check {
$self->debug( "Talker: command $data is not implemented", $warn );
}
}

#If the CBus network is still in SYNC or NEW modes, query CGate for a status update
#every 100 loops.

if ( !$$self{network_sync} ) {
$$self{network_sync_counter}++;
$self->debug( "CBus network NOT in sync. Incremented sync counter", $trace );

if ( $$self{network_sync_counter} == $$self{network_sync_limit} ) {
$Clipsal_CBus::Talker->set( "get " . $self->{cbus_net_list}[0] . " state" );
$Clipsal_CBus::Talker_last_sent = "get " . $self->{cbus_net_list}[0] . " state";
$$self{network_sync_counter} = 0;
$self->debug( "Talker: Get state command sent, sync counter reset", $debug );
}
}


# Process data returned from CBus server after a command is sent
#
Expand Down Expand Up @@ -637,6 +696,7 @@ sub talker_check {

# Newly started comms, therefore find the networks available
# then we will wait until CGate has sync'ed with the network
$$self{network_sync} = 0;
$$self{request_cgate_scan} = 0;
$Clipsal_CBus::Talker->set("session_id");
$Clipsal_CBus::Talker_last_sent = "session_id";
Expand Down Expand Up @@ -690,10 +750,11 @@ sub talker_check {
my $network_state = $1;
$self->debug( "Talker CGate Status - $talker_msg", $debug );
if ( $network_state ne "ok" ) {
$Clipsal_CBus::Talker->set( "get " . $self->{cbus_net_list}[0] . " state" );
$Clipsal_CBus::Talker_last_sent = "get " . $self->{cbus_net_list}[0] . " state";
#Do nothing - sync queries moved to top of Talker check loop.
}
else {
#The CBus network is in sync (i.e. OK)
$$self{network_sync} = 1;
if ( $$self{request_cgate_scan} ) {

# This state request was part of scanning startup
Expand Down Expand Up @@ -1014,6 +1075,10 @@ sub talker_check {
Refactor cbus.pl into Clipsal_CBus.pm, CGate.pm, Group.pm, and Unit.pm, and
make CBus support more MisterHouse "native".
V4.0.1 2018-09-05
Make connectivity to CGate more robust by detecting failed sockets, attempting to restart them, and when
they've come back, reinitialising the CBus objects.
=head1 LICENSE
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
Expand Down

0 comments on commit 8ea9c6f

Please sign in to comment.