69 lines
1.7 KiB
PHP
69 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace App\Support\Drivers;
|
|
|
|
use App\Models\Device;
|
|
use App\Models\Entity;
|
|
use App\Support\Mqtt\ShellyTopics;
|
|
use PhpMqtt\Client\Facades\MQTT;
|
|
|
|
/**
|
|
* Controls Shelly Gen2+ devices over MQTT via the simple command topic
|
|
* `<prefix>/command/<component>` = on|off|toggle. Vendor specifics stay here (H3).
|
|
*/
|
|
class ShellyMqttDriver implements DeviceDriver
|
|
{
|
|
public function turnOn(Entity $entity): void
|
|
{
|
|
$this->publishCommand($entity, 'on');
|
|
}
|
|
|
|
public function turnOff(Entity $entity): void
|
|
{
|
|
$this->publishCommand($entity, 'off');
|
|
}
|
|
|
|
public function setState(Entity $entity, array $state): void
|
|
{
|
|
if (array_key_exists('on', $state)) {
|
|
$state['on'] ? $this->turnOn($entity) : $this->turnOff($entity);
|
|
}
|
|
}
|
|
|
|
public function reboot(Device $device): void
|
|
{
|
|
$prefix = $this->prefixOf($device);
|
|
|
|
MQTT::connection()->publish(
|
|
ShellyTopics::rpcTopic($prefix),
|
|
json_encode(['id' => 1, 'src' => 'homeos', 'method' => 'Shelly.Reboot']),
|
|
0,
|
|
);
|
|
}
|
|
|
|
public function capabilities(): array
|
|
{
|
|
return ['switch', 'light'];
|
|
}
|
|
|
|
private function publishCommand(Entity $entity, string $value): void
|
|
{
|
|
MQTT::connection()->publish(
|
|
ShellyTopics::commandTopic($this->prefixOf($entity->device), $entity->key),
|
|
$value,
|
|
0,
|
|
);
|
|
}
|
|
|
|
private function prefixOf(Device $device): string
|
|
{
|
|
$prefix = data_get($device->config, 'mqtt_prefix');
|
|
|
|
if (blank($prefix)) {
|
|
throw new \RuntimeException("Device {$device->id} has no mqtt_prefix configured.");
|
|
}
|
|
|
|
return $prefix;
|
|
}
|
|
}
|