/command/` = 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; } }