diff --git a/src/Commands/Execute.php b/src/Commands/Execute.php index cb194e8..510b842 100644 --- a/src/Commands/Execute.php +++ b/src/Commands/Execute.php @@ -97,9 +97,11 @@ protected function execute(Input\InputInterface $input, Output\OutputInterface $ $io = new Style\SymfonyStyle($input, $output); - $io->title((string) $this->translator->translate('//viera-connector.cmd.execute.title')); + if ($input->getOption('quiet') === false) { + $io->title((string) $this->translator->translate('//viera-connector.cmd.execute.title')); - $io->note((string) $this->translator->translate('//viera-connector.cmd.execute.subtitle')); + $io->note((string) $this->translator->translate('//viera-connector.cmd.execute.subtitle')); + } if ($input->getOption('no-interaction') === false) { $question = new Console\Question\ConfirmationQuestion( diff --git a/src/Commands/Install.php b/src/Commands/Install.php index 81c379c..afb23ef 100644 --- a/src/Commands/Install.php +++ b/src/Commands/Install.php @@ -988,9 +988,9 @@ private function createDevice(Style\SymfonyStyle $io, Entities\Connectors\Connec array_merge( [ [ - 'TV', - 500, - 500, + Viera\Constants::TV_IDENTIFIER, + Viera\Constants::TV_CODE, + Viera\Constants::TV_CODE, ], ], $hdmi !== [] ? $hdmi : [], diff --git a/src/Constants.php b/src/Constants.php index d66dc50..5800f54 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -57,4 +57,12 @@ class Constants Types\ActionKey::MENU->value => Types\ChannelPropertyIdentifier::KEY_MENU, ]; + public const TV_IDENTIFIER = 'TV'; + + public const TV_CODE = 500; + + public const MAX_HDMI_CODE = 100; + + public const MIN_APPLICATION_CODE = 1_000; + } diff --git a/src/DI/VieraExtension.php b/src/DI/VieraExtension.php index 116330c..bbcb82e 100644 --- a/src/DI/VieraExtension.php +++ b/src/DI/VieraExtension.php @@ -83,12 +83,18 @@ public function loadConfiguration(): void $builder->addFactoryDefinition($this->prefix('writers.event')) ->setImplement(Writers\EventFactory::class) ->getResultDefinition() - ->setType(Writers\Event::class); + ->setType(Writers\Event::class) + ->setArguments([ + 'logger' => $logger, + ]); $builder->addFactoryDefinition($this->prefix('writers.exchange')) ->setImplement(Writers\ExchangeFactory::class) ->getResultDefinition() ->setType(Writers\Exchange::class) + ->setArguments([ + 'logger' => $logger, + ]) ->addTag(ExchangeDI\ExchangeExtension::CONSUMER_STATE, false); /** diff --git a/src/Entities/Devices/Device.php b/src/Entities/Devices/Device.php index f597c7d..fdc4e5f 100644 --- a/src/Entities/Devices/Device.php +++ b/src/Entities/Devices/Device.php @@ -42,7 +42,7 @@ class Device extends DevicesEntities\Devices\Device public const DEFAULT_PORT = 55_000; - public const STATE_READING_DELAY = 5_000.0; + public const STATE_READING_DELAY = 300.0; public function __construct( string $identifier, diff --git a/src/Queue/Consumers/StoreDevice.php b/src/Queue/Consumers/StoreDevice.php index 375d01b..29b45dc 100644 --- a/src/Queue/Consumers/StoreDevice.php +++ b/src/Queue/Consumers/StoreDevice.php @@ -324,9 +324,9 @@ function () use ($message, $connector): Entities\Devices\Device { array_merge( [ [ - 'TV', - 500, - 500, + Viera\Constants::TV_IDENTIFIER, + Viera\Constants::TV_CODE, + Viera\Constants::TV_CODE, ], ], array_map( diff --git a/src/Queue/Consumers/WriteChannelPropertyState.php b/src/Queue/Consumers/WriteChannelPropertyState.php index 3e9efc5..87758f1 100644 --- a/src/Queue/Consumers/WriteChannelPropertyState.php +++ b/src/Queue/Consumers/WriteChannelPropertyState.php @@ -33,12 +33,15 @@ use FastyBird\Module\Devices\Exceptions as DevicesExceptions; use FastyBird\Module\Devices\Models as DevicesModels; use FastyBird\Module\Devices\Queries as DevicesQueries; +use FastyBird\Module\Devices\States as DevicesStates; use FastyBird\Module\Devices\Types as DevicesTypes; use Nette; +use Nette\Utils; use RuntimeException; use Throwable; use TypeError; use ValueError; +use function assert; use function boolval; use function intval; use function React\Async\async; @@ -350,9 +353,9 @@ public function consume(Queue\Messages\Message $message): bool break; case Types\ChannelPropertyIdentifier::INPUT_SOURCE->value: - if (intval($expectedValue) < 100) { + if (intval($expectedValue) < Viera\Constants::MAX_HDMI_CODE) { $result = $client->sendKey('NRC_HDMI' . $expectedValue . '-ONOFF'); - } elseif (intval($expectedValue) === 500) { + } elseif (intval($expectedValue) === Viera\Constants::TV_CODE) { $result = $client->sendKey(Types\ActionKey::AD_CHANGE); } else { $result = $client->launchApplication(strval($expectedValue)); @@ -366,6 +369,43 @@ public function consume(Queue\Messages\Message $message): bool case Types\ChannelPropertyIdentifier::HDMI->value: $result = $client->sendKey('NRC_HDMI' . $expectedValue . '-ONOFF'); + break; + case Types\ChannelPropertyIdentifier::REMOTE->value: + $key = Types\ActionKey::tryFrom(strval($expectedValue)); + + if ($key === null) { + await($this->channelPropertiesStatesManager->setPendingState( + $property, + false, + MetadataTypes\Sources\Connector::VIERA, + )); + + $this->logger->error( + 'Provided property value is not valid', + [ + 'source' => MetadataTypes\Sources\Connector::VIERA->value, + 'type' => 'write-channel-property-state-message-consumer', + 'connector' => [ + 'id' => $connector->getId()->toString(), + ], + 'device' => [ + 'id' => $device->getId()->toString(), + ], + 'channel' => [ + 'id' => $channel->getId()->toString(), + ], + 'property' => [ + 'id' => $property->getId()->toString(), + ], + 'data' => $message->toArray(), + ], + ); + + return true; + } + + $result = $client->sendKey($key); + break; default: if ( @@ -540,7 +580,7 @@ public function consume(Queue\Messages\Message $message): bool } $result->then( - function () use ($message, $connector, $device, $channel, $property, $expectedValue): void { + async(function () use ($message, $connector, $device, $channel, $property, $expectedValue): void { $this->logger->debug( 'Channel state was successfully sent to device', [ @@ -567,20 +607,24 @@ function () use ($message, $connector, $device, $channel, $property, $expectedVa case Types\ChannelPropertyIdentifier::VOLUME->value: case Types\ChannelPropertyIdentifier::MUTE->value: case Types\ChannelPropertyIdentifier::INPUT_SOURCE->value: - case Types\ChannelPropertyIdentifier::APPLICATION->value: case Types\ChannelPropertyIdentifier::HDMI->value: - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\StoreChannelPropertyState::class, - [ - 'connector' => $connector->getId(), - 'device' => $device->getId(), - 'channel' => Types\ChannelType::TELEVISION, - 'property' => $property->getId(), - 'value' => $expectedValue, - ], - ), - ); + case Types\ChannelPropertyIdentifier::APPLICATION->value: + await($this->channelPropertiesStatesManager->set( + $property, + Utils\ArrayHash::from([ + DevicesStates\Property::ACTUAL_VALUE_FIELD => $expectedValue, + DevicesStates\Property::EXPECTED_VALUE_FIELD => null, + ]), + MetadataTypes\Sources\Connector::VIERA, + )); + + break; + case Types\ChannelPropertyIdentifier::REMOTE->value: + await($this->channelPropertiesStatesManager->setPendingState( + $property, + false, + MetadataTypes\Sources\Connector::VIERA, + )); break; default: @@ -588,99 +632,130 @@ function () use ($message, $connector, $device, $channel, $property, $expectedVa Types\ChannelPropertyIdentifier::tryFrom($property->getIdentifier()) !== null && $property->getDataType() === MetadataTypes\DataType::BUTTON ) { - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\StoreChannelPropertyState::class, - [ - 'connector' => $connector->getId(), - 'device' => $device->getId(), - 'channel' => Types\ChannelType::TELEVISION, - 'property' => $property->getId(), - 'value' => $expectedValue, - ], - ), - ); + await($this->channelPropertiesStatesManager->setPendingState( + $property, + false, + MetadataTypes\Sources\Connector::VIERA, + )); } break; } if ($property->getIdentifier() === Types\ChannelPropertyIdentifier::INPUT_SOURCE->value) { - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\StoreChannelPropertyState::class, - [ - 'connector' => $connector->getId(), - 'device' => $device->getId(), - 'channel' => Types\ChannelType::TELEVISION, - 'property' => Types\ChannelPropertyIdentifier::HDMI, - 'value' => intval($expectedValue) < 100 ? $expectedValue : null, - ], - ), - ); + $findChannelPropertyQuery = new Queries\Configuration\FindChannelProperties(); + $findChannelPropertyQuery->forChannel($channel); + $findChannelPropertyQuery->byIdentifier(Types\ChannelPropertyIdentifier::APPLICATION); - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\StoreChannelPropertyState::class, - [ - 'connector' => $connector->getId(), - 'device' => $device->getId(), - 'channel' => Types\ChannelType::TELEVISION, - 'property' => Types\ChannelPropertyIdentifier::APPLICATION, - 'value' => intval($expectedValue) !== 500 ? $expectedValue : null, - ], - ), + $applicationProperty = $this->channelsPropertiesConfigurationRepository->findOneBy( + $findChannelPropertyQuery, + DevicesDocuments\Channels\Properties\Dynamic::class, ); - } - - if ( + assert($applicationProperty instanceof DevicesDocuments\Channels\Properties\Dynamic); + + await($this->channelPropertiesStatesManager->set( + $applicationProperty, + Utils\ArrayHash::from([ + DevicesStates\Property::ACTUAL_VALUE_FIELD => + intval( + MetadataUtilities\Value::toString($expectedValue, true), + ) > Viera\Constants::MIN_APPLICATION_CODE + ? $expectedValue + : null, + DevicesStates\Property::EXPECTED_VALUE_FIELD => null, + ]), + MetadataTypes\Sources\Connector::VIERA, + )); + + $findChannelPropertyQuery = new Queries\Configuration\FindChannelProperties(); + $findChannelPropertyQuery->forChannel($channel); + $findChannelPropertyQuery->byIdentifier(Types\ChannelPropertyIdentifier::HDMI); + + $hdmiProperty = $this->channelsPropertiesConfigurationRepository->findOneBy( + $findChannelPropertyQuery, + DevicesDocuments\Channels\Properties\Dynamic::class, + ); + assert($hdmiProperty instanceof DevicesDocuments\Channels\Properties\Dynamic); + + await($this->channelPropertiesStatesManager->set( + $hdmiProperty, + Utils\ArrayHash::from([ + DevicesStates\Property::ACTUAL_VALUE_FIELD => + intval( + MetadataUtilities\Value::toString($expectedValue, true), + ) < Viera\Constants::MAX_HDMI_CODE + ? $expectedValue + : null, + DevicesStates\Property::EXPECTED_VALUE_FIELD => null, + ]), + MetadataTypes\Sources\Connector::VIERA, + )); + + } elseif ( $property->getIdentifier() === Types\ChannelPropertyIdentifier::APPLICATION->value || $property->getIdentifier() === Types\ChannelPropertyIdentifier::HDMI->value ) { - if ($property->getIdentifier() === Types\ChannelPropertyIdentifier::HDMI->value) { - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\StoreChannelPropertyState::class, - [ - 'connector' => $connector->getId(), - 'device' => $device->getId(), - 'channel' => Types\ChannelType::TELEVISION, - 'property' => Types\ChannelPropertyIdentifier::APPLICATION, - 'value' => null, - ], - ), - ); - } + $findChannelPropertyQuery = new Queries\Configuration\FindChannelProperties(); + $findChannelPropertyQuery->forChannel($channel); + $findChannelPropertyQuery->byIdentifier(Types\ChannelPropertyIdentifier::INPUT_SOURCE); - if ($property->getIdentifier() === Types\ChannelPropertyIdentifier::APPLICATION->value) { - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\StoreChannelPropertyState::class, - [ - 'connector' => $connector->getId(), - 'device' => $device->getId(), - 'channel' => Types\ChannelType::TELEVISION, - 'property' => Types\ChannelPropertyIdentifier::HDMI, - 'value' => null, - ], - ), - ); - } + $inputSourceProperty = $this->channelsPropertiesConfigurationRepository->findOneBy( + $findChannelPropertyQuery, + DevicesDocuments\Channels\Properties\Dynamic::class, + ); + assert($inputSourceProperty instanceof DevicesDocuments\Channels\Properties\Dynamic); + + await($this->channelPropertiesStatesManager->set( + $inputSourceProperty, + Utils\ArrayHash::from([ + DevicesStates\Property::ACTUAL_VALUE_FIELD => $expectedValue, + DevicesStates\Property::EXPECTED_VALUE_FIELD => null, + ]), + MetadataTypes\Sources\Connector::VIERA, + )); + + $findChannelPropertyQuery = new Queries\Configuration\FindChannelProperties(); + $findChannelPropertyQuery->forChannel($channel); + $findChannelPropertyQuery->byIdentifier(Types\ChannelPropertyIdentifier::HDMI); + + $hdmiProperty = $this->channelsPropertiesConfigurationRepository->findOneBy( + $findChannelPropertyQuery, + DevicesDocuments\Channels\Properties\Dynamic::class, + ); + assert($hdmiProperty instanceof DevicesDocuments\Channels\Properties\Dynamic); - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\StoreChannelPropertyState::class, - [ - 'connector' => $connector->getId(), - 'device' => $device->getId(), - 'channel' => Types\ChannelType::TELEVISION, - 'property' => Types\ChannelPropertyIdentifier::INPUT_SOURCE, - 'value' => $expectedValue, - ], - ), + $findChannelPropertyQuery = new Queries\Configuration\FindChannelProperties(); + $findChannelPropertyQuery->forChannel($channel); + $findChannelPropertyQuery->byIdentifier(Types\ChannelPropertyIdentifier::APPLICATION); + + $applicationProperty = $this->channelsPropertiesConfigurationRepository->findOneBy( + $findChannelPropertyQuery, + DevicesDocuments\Channels\Properties\Dynamic::class, ); + assert($applicationProperty instanceof DevicesDocuments\Channels\Properties\Dynamic); + + if ($property->getIdentifier() === Types\ChannelPropertyIdentifier::APPLICATION->value) { + await($this->channelPropertiesStatesManager->set( + $hdmiProperty, + Utils\ArrayHash::from([ + DevicesStates\Property::ACTUAL_VALUE_FIELD => null, + DevicesStates\Property::EXPECTED_VALUE_FIELD => null, + ]), + MetadataTypes\Sources\Connector::VIERA, + )); + + } elseif ($property->getIdentifier() === Types\ChannelPropertyIdentifier::HDMI->value) { + await($this->channelPropertiesStatesManager->set( + $applicationProperty, + Utils\ArrayHash::from([ + DevicesStates\Property::ACTUAL_VALUE_FIELD => null, + DevicesStates\Property::EXPECTED_VALUE_FIELD => null, + ]), + MetadataTypes\Sources\Connector::VIERA, + )); + } } - }, + }), async(function (Throwable $ex) use ($device, $property): void { await($this->channelPropertiesStatesManager->setPendingState( $property, diff --git a/src/Queue/Messages/WriteChannelPropertyState.php b/src/Queue/Messages/WriteChannelPropertyState.php index ba70699..f9687a6 100644 --- a/src/Queue/Messages/WriteChannelPropertyState.php +++ b/src/Queue/Messages/WriteChannelPropertyState.php @@ -43,7 +43,7 @@ public function __construct( new ObjectMapper\Rules\MappedObjectValue(class: State::class), new ObjectMapper\Rules\NullValue(), ])] - private State|null $state, + private State|null $state = null, ) { } diff --git a/src/Services/SocketClientFactory.php b/src/Services/SocketClientFactory.php index f375784..83e39a1 100644 --- a/src/Services/SocketClientFactory.php +++ b/src/Services/SocketClientFactory.php @@ -52,6 +52,7 @@ public function create(): Socket\Connector 'verify_peer' => false, 'verify_peer_name' => false, 'check_hostname' => false, + 'allow_self_signed' => true, ], ], $this->eventLoop, diff --git a/src/Subscribers/Properties.php b/src/Subscribers/Properties.php index 9b34adc..39dc57b 100644 --- a/src/Subscribers/Properties.php +++ b/src/Subscribers/Properties.php @@ -298,9 +298,9 @@ private function configureDeviceInputSource(DevicesEntities\Channels\Properties\ array_merge( [ [ - 'TV', - 500, - 500, + Viera\Constants::TV_IDENTIFIER, + Viera\Constants::TV_CODE, + Viera\Constants::TV_CODE, ], ], $hdmiFormat, diff --git a/src/Writers/Event.php b/src/Writers/Event.php index 644c6eb..fc85b18 100644 --- a/src/Writers/Event.php +++ b/src/Writers/Event.php @@ -16,12 +16,13 @@ namespace FastyBird\Connector\Viera\Writers; use FastyBird\Connector\Viera\Documents; -use FastyBird\Connector\Viera\Exceptions; use FastyBird\Connector\Viera\Queries; use FastyBird\Connector\Viera\Queue; +use FastyBird\Library\Application\Helpers as ApplicationHelpers; +use FastyBird\Library\Metadata\Types as MetadataTypes; use FastyBird\Module\Devices\Events as DevicesEvents; -use FastyBird\Module\Devices\Exceptions as DevicesExceptions; use Symfony\Component\EventDispatcher; +use Throwable; /** * Event based properties writer @@ -44,57 +45,66 @@ public static function getSubscribedEvents(): array ]; } - /** - * @throws DevicesExceptions\InvalidState - * @throws Exceptions\Runtime - */ public function stateChanged( DevicesEvents\ChannelPropertyStateEntityCreated|DevicesEvents\ChannelPropertyStateEntityUpdated $event, ): void { - $state = $event->getGet(); - - if ($state->getExpectedValue() === null || $state->getPending() !== true) { - return; - } - - $findChannelQuery = new Queries\Configuration\FindChannels(); - $findChannelQuery->byId($event->getProperty()->getChannel()); - - $channel = $this->channelsConfigurationRepository->findOneBy( - $findChannelQuery, - Documents\Channels\Channel::class, - ); - - if ($channel === null) { - return; - } - - $findDeviceQuery = new Queries\Configuration\FindDevices(); - $findDeviceQuery->forConnector($this->connector); - $findDeviceQuery->byId($channel->getDevice()); - - $device = $this->devicesConfigurationRepository->findOneBy( - $findDeviceQuery, - Documents\Devices\Device::class, - ); - - if ($device === null) { - return; - } - - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\WriteChannelPropertyState::class, + try { + $state = $event->getGet(); + + if ($state->getExpectedValue() === null || $state->getPending() !== true) { + return; + } + + $findChannelQuery = new Queries\Configuration\FindChannels(); + $findChannelQuery->byId($event->getProperty()->getChannel()); + + $channel = $this->channelsConfigurationRepository->findOneBy( + $findChannelQuery, + Documents\Channels\Channel::class, + ); + + if ($channel === null) { + return; + } + + $findDeviceQuery = new Queries\Configuration\FindDevices(); + $findDeviceQuery->forConnector($this->connector); + $findDeviceQuery->byId($channel->getDevice()); + + $device = $this->devicesConfigurationRepository->findOneBy( + $findDeviceQuery, + Documents\Devices\Device::class, + ); + + if ($device === null) { + return; + } + + $this->queue->append( + $this->messageBuilder->create( + Queue\Messages\WriteChannelPropertyState::class, + [ + 'connector' => $this->connector->getId(), + 'device' => $device->getId(), + 'channel' => $channel->getId(), + 'property' => $event->getProperty()->getId(), + 'state' => $event->getGet()->toArray(), + ], + ), + ); + + } catch (Throwable $ex) { + // Log caught exception + $this->logger->error( + 'Characteristic value could not be prepared for writing', [ - 'connector' => $this->connector->getId(), - 'device' => $device->getId(), - 'channel' => $channel->getId(), - 'property' => $event->getProperty()->getId(), - 'state' => $event->getGet()->toArray(), + 'source' => MetadataTypes\Sources\Connector::VIERA->value, + 'type' => 'event-writer', + 'exception' => ApplicationHelpers\Logger::buildException($ex), ], - ), - ); + ); + } } } diff --git a/src/Writers/Exchange.php b/src/Writers/Exchange.php index e17b132..40cf850 100644 --- a/src/Writers/Exchange.php +++ b/src/Writers/Exchange.php @@ -15,23 +15,28 @@ namespace FastyBird\Connector\Viera\Writers; +use FastyBird\Connector\Viera; use FastyBird\Connector\Viera\Documents; use FastyBird\Connector\Viera\Exceptions; use FastyBird\Connector\Viera\Helpers; use FastyBird\Connector\Viera\Queries; use FastyBird\Connector\Viera\Queue; use FastyBird\DateTimeFactory; +use FastyBird\Library\Application\Helpers as ApplicationHelpers; use FastyBird\Library\Exchange\Consumers as ExchangeConsumers; use FastyBird\Library\Exchange\Exceptions as ExchangeExceptions; use FastyBird\Library\Metadata\Documents as MetadataDocuments; use FastyBird\Library\Metadata\Exceptions as MetadataExceptions; use FastyBird\Library\Metadata\Types as MetadataTypes; use FastyBird\Library\Tools\Exceptions as ToolsExceptions; +use FastyBird\Module\Devices\Constants as DevicesConstants; use FastyBird\Module\Devices\Documents as DevicesDocuments; use FastyBird\Module\Devices\Exceptions as DevicesExceptions; use FastyBird\Module\Devices\Models as DevicesModels; use React\EventLoop; +use Throwable; use function array_merge; +use function str_starts_with; /** * Exchange based properties writer @@ -50,6 +55,7 @@ public function __construct( Documents\Connectors\Connector $connector, Helpers\MessageBuilder $messageBuilder, Queue\Queue $queue, + Viera\Logger $logger, DevicesModels\Configuration\Devices\Repository $devicesConfigurationRepository, DevicesModels\Configuration\Channels\Repository $channelsConfigurationRepository, DevicesModels\Configuration\Channels\Properties\Repository $channelsPropertiesConfigurationRepository, @@ -63,6 +69,7 @@ public function __construct( $connector, $messageBuilder, $queue, + $logger, $devicesConfigurationRepository, $channelsConfigurationRepository, $channelsPropertiesConfigurationRepository, @@ -101,67 +108,79 @@ public function disconnect(): void $this->consumer->disable(self::class); } - /** - * @throws DevicesExceptions\InvalidState - * @throws Exceptions\Runtime - */ public function consume( MetadataTypes\Sources\Source $source, string $routingKey, MetadataDocuments\Document|null $document, ): void { - if ($document instanceof DevicesDocuments\States\Channels\Properties\Property) { - if ( - $document->getGet()->getExpectedValue() === null - || $document->getPending() !== true - ) { - return; + try { + if ($document instanceof DevicesDocuments\States\Channels\Properties\Property) { + if (str_starts_with($routingKey, DevicesConstants::MESSAGE_BUS_DELETED_ROUTING_KEY)) { + return; + } + + if ( + $document->getGet()->getExpectedValue() === null + || $document->getPending() !== true + ) { + return; + } + + $findChannelQuery = new Queries\Configuration\FindChannels(); + $findChannelQuery->byId($document->getChannel()); + + $channel = $this->channelsConfigurationRepository->findOneBy( + $findChannelQuery, + Documents\Channels\Channel::class, + ); + + if ($channel === null) { + return; + } + + $findDeviceQuery = new Queries\Configuration\FindDevices(); + $findDeviceQuery->forConnector($this->connector); + $findDeviceQuery->byId($channel->getDevice()); + + $device = $this->devicesConfigurationRepository->findOneBy( + $findDeviceQuery, + Documents\Devices\Device::class, + ); + + if ($device === null) { + return; + } + + $this->queue->append( + $this->messageBuilder->create( + Queue\Messages\WriteChannelPropertyState::class, + [ + 'connector' => $this->connector->getId(), + 'device' => $device->getId(), + 'channel' => $channel->getId(), + 'property' => $document->getId(), + 'state' => array_merge( + $document->getGet()->toArray(), + [ + 'id' => $document->getId(), + 'valid' => $document->isValid(), + 'pending' => $document->getPending(), + ], + ), + ], + ), + ); } - - $findChannelQuery = new Queries\Configuration\FindChannels(); - $findChannelQuery->byId($document->getChannel()); - - $channel = $this->channelsConfigurationRepository->findOneBy( - $findChannelQuery, - Documents\Channels\Channel::class, - ); - - if ($channel === null) { - return; - } - - $findDeviceQuery = new Queries\Configuration\FindDevices(); - $findDeviceQuery->forConnector($this->connector); - $findDeviceQuery->byId($channel->getDevice()); - - $device = $this->devicesConfigurationRepository->findOneBy( - $findDeviceQuery, - Documents\Devices\Device::class, - ); - - if ($device === null) { - return; - } - - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\WriteChannelPropertyState::class, - [ - 'connector' => $this->connector->getId(), - 'device' => $device->getId(), - 'channel' => $channel->getId(), - 'property' => $document->getId(), - 'state' => array_merge( - $document->getGet()->toArray(), - [ - 'id' => $document->getId(), - 'valid' => $document->isValid(), - 'pending' => $document->getPending(), - ], - ), - ], - ), + } catch (Throwable $ex) { + // Log caught exception + $this->logger->error( + 'Characteristic value could not be prepared for writing', + [ + 'source' => MetadataTypes\Sources\Connector::VIERA->value, + 'type' => 'exchange-writer', + 'exception' => ApplicationHelpers\Logger::buildException($ex), + ], ); } } diff --git a/src/Writers/Periodic.php b/src/Writers/Periodic.php index 37039c1..43a4f49 100644 --- a/src/Writers/Periodic.php +++ b/src/Writers/Periodic.php @@ -16,12 +16,14 @@ namespace FastyBird\Connector\Viera\Writers; use DateTimeInterface; +use FastyBird\Connector\Viera; use FastyBird\Connector\Viera\Documents; use FastyBird\Connector\Viera\Exceptions; use FastyBird\Connector\Viera\Helpers; use FastyBird\Connector\Viera\Queries; use FastyBird\Connector\Viera\Queue; use FastyBird\DateTimeFactory; +use FastyBird\Library\Application\Helpers as ApplicationHelpers; use FastyBird\Library\Metadata\Exceptions as MetadataExceptions; use FastyBird\Library\Metadata\Types as MetadataTypes; use FastyBird\Library\Tools\Exceptions as ToolsExceptions; @@ -31,6 +33,7 @@ use FastyBird\Module\Devices\Queries as DevicesQueries; use Nette; use React\EventLoop; +use Throwable; use function array_key_exists; use function array_merge; use function in_array; @@ -77,6 +80,7 @@ public function __construct( protected readonly Documents\Connectors\Connector $connector, protected readonly Helpers\MessageBuilder $messageBuilder, protected readonly Queue\Queue $queue, + protected readonly Viera\Logger $logger, protected readonly DevicesModels\Configuration\Devices\Repository $devicesConfigurationRepository, protected readonly DevicesModels\Configuration\Channels\Repository $channelsConfigurationRepository, private readonly DevicesModels\Configuration\Channels\Properties\Repository $channelsPropertiesConfigurationRepository, @@ -243,29 +247,43 @@ private function writeProperty(Documents\Devices\Device $device): bool && (float) $now->format('Uv') - (float) $pending->format('Uv') > self::HANDLER_PENDING_DELAY ) ) { - $this->queue->append( - $this->messageBuilder->create( - Queue\Messages\WriteChannelPropertyState::class, + try { + $this->queue->append( + $this->messageBuilder->create( + Queue\Messages\WriteChannelPropertyState::class, + [ + 'connector' => $device->getConnector(), + 'device' => $device->getId(), + 'channel' => $property->getChannel(), + 'property' => $property->getId(), + 'state' => array_merge( + $state->getGet()->toArray(), + [ + 'id' => $state->getId(), + 'valid' => $state->isValid(), + 'pending' => $state->getPending() instanceof DateTimeInterface + ? $state->getPending()->format(DateTimeInterface::ATOM) + : $state->getPending(), + ], + ), + ], + ), + ); + + return true; + } catch (Throwable $ex) { + // Log caught exception + $this->logger->error( + 'Characteristic value could not be prepared for writing', [ - 'connector' => $device->getConnector(), - 'device' => $device->getId(), - 'channel' => $property->getChannel(), - 'property' => $property->getId(), - 'state' => array_merge( - $state->getGet()->toArray(), - [ - 'id' => $state->getId(), - 'valid' => $state->isValid(), - 'pending' => $state->getPending() instanceof DateTimeInterface - ? $state->getPending()->format(DateTimeInterface::ATOM) - : $state->getPending(), - ], - ), + 'source' => MetadataTypes\Sources\Connector::VIERA->value, + 'type' => 'periodic-writer', + 'exception' => ApplicationHelpers\Logger::buildException($ex), ], - ), - ); + ); - return true; + return false; + } } }