App-OpenHAP
view release on metacpan or search on metacpan
lib/App/OpenHAP/Host.pm view on Meta::CPAN
mqtt_tick_interval => 0.1, # MQTT poll interval in seconds
# For the uptime in a control status. Time::HiRes::time
# is imported here, and it gives a float; a whole second
# is all an uptime needs.
started => int time,
}, $class;
$self->{storage} = Protocol::HAP::Store::File->new(
path => $self->{storage_path},
logger => Fugu::Log->default,
);
# Build the engine over the host contracts: the storage, the
# process logger, writes through the connection map, and the
# one-shot timers of the loop.
$self->{engine} = Protocol::HAP::Server->new(
name => $args{name},
pin => $args{pin},
setup_id => $args{setup_id},
store => $self->{storage},
logger => Fugu::Log->default,
output => sub ( $session, $bytes ) {
$self->_write( $session, $bytes );
},
after => sub ( $seconds, $code ) {
return $self->loop->after( $seconds, $code );
},
cancel => sub ($handle) {
$self->loop->cancel($handle);
},
on_pairing_changed => sub ($paired) {
$self->_refresh_mdns($paired);
},
);
return $self;
}
# $self->engine:
# The Protocol::HAP engine of this host.
sub engine ($self)
{
return $self->{engine};
}
# --- delegation to the engine ---------------------------------------------
sub add_accessory ( $self, $accessory )
{
$self->{engine}->add_accessory($accessory);
return;
}
sub is_paired ($self)
{
return $self->{engine}->is_paired;
}
sub update_config_number ($self)
{
return $self->{engine}->update_config_number;
}
# $self->mdns_txt_string:
# The TXT records of the engine, in the format that mdnsd
# publishes.
sub mdns_txt_string ($self)
{
return Fugu::Mdnsd::format_txt(
%{ $self->{engine}->mdns_txt_records } );
}
# --- the connection plumbing ----------------------------------------------
# $self->loop:
# The event loop of this server. The server makes one on demand,
# so a caller that only wants to drive timers by hand does not
# have to build one.
sub loop ($self)
{
$self->{loop} //= Fugu::EventLoop->new;
return $self->{loop};
}
# $self->listen:
# Open the HAP listener and register it with the loop. The method
# returns the socket. It dies when the port is not available:
# a HAP server that cannot listen has no reason to run.
sub listen ($self)
{
return $self->{server} if $self->{server};
my $server = IO::Socket::INET->new(
LocalPort => $self->{port},
Type => SOCK_STREAM,
Reuse => 1,
Listen => 10,
)
or do {
Fugu::Log->default->error(
'Cannot create server socket on port %d: %s',
$self->{port}, $! );
die "Cannot create server: $!";
};
$self->{server} = $server;
$self->loop->add_fd( $server, read => sub ($) { $self->_accept } );
Fugu::Log->default->info( 'OpenHAP server listening on port %d',
$self->{port} );
return $server;
}
# $self->run:
# Serve until the loop stops. The method returns when a signal
# interrupted the loop or a callback stopped it. Thus the caller
# runs its own shutdown, and nothing has to exit from inside a
( run in 0.896 second using v1.01-cache-2.11-cpan-145b269f2f3 )