App-OpenHAP

 view release on metacpan or  search on metacpan

lib/App/OpenHAP/Tasmota/Device.pm  view on Meta::CPAN

	AVAILABILITY_OFFLINE => 2,
};

# The sensor types the walk below knows (H5). Thermostat and Sensor
# share this one list.
use constant SENSOR_TYPES =>
    qw(DS18B20 DHT11 DHT22 AM2301 BME280 BMP280 SHT3X SI7021);

sub new ( $class, %args )
{
	my $self = $class->SUPER::new(%args);

	$self->{mqtt_topic}   = $args{mqtt_topic};
	$self->{mqtt_client}  = $args{mqtt_client};
	$self->{relay_index}  = $args{relay_index} // 0;    # 0 = no index
	$self->{availability} = AVAILABILITY_UNKNOWN;
	$self->{temp_unit}    = 'C';                        # Default to Celsius

	return $self;
}

# $self->subscribe_mqtt():
#	Subscribe to all standard Tasmota topics.
#	Subclasses must call SUPER::subscribe_mqtt() first.
sub subscribe_mqtt ($self)
{
	return unless $self->{mqtt_client}->is_connected();

	Fugu::Log->default->debug(
		'Tasmota %s subscribing to MQTT topics for %s',
		ref($self), $self->{name} );

	# C1: Subscribe to LWT for device availability
	$self->{mqtt_client}->subscribe(

lib/App/OpenHAP/Tasmota/Device.pod  view on Meta::CPAN


=back

Every topic follows the default Tasmota C<FullTopic> pattern,
C<%prefix%/%topic%/>. OpenHAP requires the device to run with that
default.

=head1 THE MQTT TOPIC CONTRACT

C<subscribe_mqtt> subscribes to five topics of the device. A subclass
that overrides the method must call C<SUPER::subscribe_mqtt> first.

=over 4

=item C<tele/LWT>

The availability of the device. C<Online> also triggers
C<query_initial_state>.

=item C<tele/STATE>

lib/App/OpenHAP/Tasmota/Heater.pm  view on Meta::CPAN

our $VERSION = '0.1.0';

use Fugu::Log;
require App::OpenHAP::Tasmota::Device;
our @ISA = qw(App::OpenHAP::Tasmota::Device);
use Protocol::HAP::Service;
use Protocol::HAP::Characteristic;

sub new ( $class, %args )
{
	my $self = $class->SUPER::new(
		%args,
		model        => 'Tasmota Switch',
		manufacturer => 'OpenHAP',
		serial       => $args{serial} // 'HEAT-001',
	);

	$self->{power_state} = 0;

	# Add the Switch/Outlet service
	my $switch = Protocol::HAP::Service->new(

lib/App/OpenHAP/Tasmota/Heater.pm  view on Meta::CPAN


	$self->add_service($switch);

	return $self;
}

sub subscribe_mqtt ($self)
{
	# Call the base class to set up the standard subscriptions
	# (C1, C2, C3)
	$self->SUPER::subscribe_mqtt();

	return unless $self->{mqtt_client}->is_connected();

	Fugu::Log->default->debug(
		'Heater %s subscribing to additional MQTT topics',
		$self->{name} );

	# M2: The plain-text POWER response (SetOption4 support)
	$self->_subscribe_plain_power( power_state => 11 );
}

lib/App/OpenHAP/Tasmota/Lightbulb.pm  view on Meta::CPAN

};

# The Tasmota color-temperature range in mireds (M4)
use constant {
	CT_MIN => 153,
	CT_MAX => 500,
};

sub new ( $class, %args )
{
	my $self = $class->SUPER::new(
		%args,
		model        => 'Tasmota Light',
		manufacturer => 'OpenHAP',
		serial       => $args{serial} // 'LIGHT-001',
	);

	# Light state
	$self->{power_state} = 0;
	$self->{brightness}  = 100;
	$self->{hue}         = 0;

lib/App/OpenHAP/Tasmota/Lightbulb.pm  view on Meta::CPAN


	$self->add_service($lightbulb);

	return $self;
}

sub subscribe_mqtt ($self)
{
	# Call the base class to set up the standard subscriptions
	# (C1, C2, C3)
	$self->SUPER::subscribe_mqtt();

	return unless $self->{mqtt_client}->is_connected();

	Fugu::Log->default->debug(
		'Lightbulb %s subscribing to additional MQTT topics',
		$self->{name} );

	# M2: The plain-text POWER response (SetOption4 support)
	$self->_subscribe_plain_power( power_state => 11 );

lib/App/OpenHAP/Tasmota/Lightbulb.pm  view on Meta::CPAN

					$self->notify_change(15);
				}
			} );
	}
}

# Override the base method to process the state data from
# periodic STATE messages
sub _process_state_data ( $self, $data )
{
	$self->SUPER::_process_state_data($data);

	# Extract the light-specific state
	$self->_extract_light_state($data);
}

# Override the base method to process the command results
sub _process_result_data ( $self, $data )
{
	$self->SUPER::_process_result_data($data);

	# Extract the light-specific state
	$self->_extract_light_state($data);
}

# Override _on_power_update to update the power state
sub _on_power_update ( $self, $state )
{
	if ( $self->{power_state} != $state ) {
		$self->{power_state} = $state;

lib/App/OpenHAP/Tasmota/Sensor.pm  view on Meta::CPAN

our $VERSION = '0.1.0';

use Fugu::Log;
require App::OpenHAP::Tasmota::Device;
our @ISA = qw(App::OpenHAP::Tasmota::Device);
use Protocol::HAP::Service;
use Protocol::HAP::Characteristic;

sub new ( $class, %args )
{
	my $self = $class->SUPER::new(
		%args,
		model        => 'Tasmota Sensor',
		manufacturer => 'OpenHAP',
		serial       => $args{serial} // 'SENS-001',
	);

	$self->{sensor_type}      = $args{sensor_type};    # undef = auto-detect
	$self->{sensor_index}     = $args{sensor_index};   # For indexed sensors
	$self->{current_temp}     = 20.0;
	$self->{current_humidity} = undef;

lib/App/OpenHAP/Tasmota/Sensor.pm  view on Meta::CPAN

		$self->add_service($humidity_sensor);
	}

	return $self;
}

sub subscribe_mqtt ($self)
{
	# Call the base class to set up the standard subscriptions
	# (C1, C2, C3)
	$self->SUPER::subscribe_mqtt();

	return unless $self->{mqtt_client}->is_connected();

	Fugu::Log->default->debug(
		'Sensor %s subscribing to additional MQTT topics',
		$self->{name} );

	# STATUS8 answers an active query; the spec recommends STATUS10
	$self->_subscribe_status_sns($_) for qw(STATUS8 STATUS10);
}

lib/App/OpenHAP/Tasmota/Thermostat.pm  view on Meta::CPAN


use Fugu::Log;
require App::OpenHAP::Tasmota::Device;
our @ISA = qw(App::OpenHAP::Tasmota::Device);
use Protocol::HAP::Service;
use Protocol::HAP::Characteristic;

sub new ( $class, %args )
{

	my $self = $class->SUPER::new(
		%args,
		model        => 'Tasmota Thermostat',
		manufacturer => 'OpenHAP',
		serial       => $args{serial} // 'TSTAT-001',
	);

	# Sensor configuration (H5)
	$self->{sensor_type}  = $args{sensor_type};     # undef = auto-detect
	$self->{sensor_index} = $args{sensor_index};    # For indexed sensors

lib/App/OpenHAP/Tasmota/Thermostat.pm  view on Meta::CPAN


	$self->add_service($thermostat);

	return $self;
}

sub subscribe_mqtt ($self)
{
	# Call the base class to set up the standard subscriptions
	# (C1, C2, C3)
	$self->SUPER::subscribe_mqtt();

	return unless $self->{mqtt_client}->is_connected();

	Fugu::Log->default->debug(
		'Thermostat %s subscribing to additional MQTT topics',
		$self->{name} );

	# M2: The plain-text POWER response (SetOption4 support)
	$self->_subscribe_plain_power( heating_state => 11 );

lib/Protocol/HAP/Bridge.pm  view on Meta::CPAN

package Protocol::HAP::Bridge;
our $VERSION = '0.1.0';

use Protocol::HAP::Accessory;
use Protocol::HAP::Service;
use Protocol::HAP::Characteristic;
our @ISA = qw(Protocol::HAP::Accessory);

sub new ( $class, %args )
{
	my $self = $class->SUPER::new(
		aid               => 1,    # The bridge is always accessory 1
		name              => $args{name}         // 'OpenHAP Bridge',
		manufacturer      => $args{manufacturer} // 'OpenBSD',
		model             => $args{model}        // 'OpenHAP',
		serial            => $args{serial}       // 'BRIDGE-001',
		firmware_revision => $args{firmware_revision} // '1.0.0',
		logger            => $args{logger},
	);

	$self->{bridged_accessories} = [];

lib/Protocol/HAP/Bridge.pm  view on Meta::CPAN

	}

	return;
}

sub to_json ($self)
{
	my @accessories;

	# Add the bridge itself
	push @accessories, $self->SUPER::to_json();

	# Add the bridged accessories
	for my $acc ( @{ $self->{bridged_accessories} } ) {
		push @accessories, $acc->to_json;
	}

	return { accessories => \@accessories };
}

1;



( run in 1.079 second using v1.01-cache-2.11-cpan-54e63673c56 )