homeos/app/Livewire/Modals/CreateAutomation.php

130 lines
3.7 KiB
PHP

<?php
namespace App\Livewire\Modals;
use App\Models\Automation;
use App\Models\Entity;
use LivewireUI\Modal\ModalComponent;
class CreateAutomation extends ModalComponent
{
public string $name = '';
public string $triggerType = 'state_change';
/** "deviceUuid|entityKey" of the entity whose change fires the rule. */
public string $triggerEntity = '';
public string $triggerEquals = '1';
public string $triggerAt = '';
public string $actionType = 'switch';
/** "deviceUuid|entityKey" of the entity to switch. */
public string $actionEntity = '';
public string $actionOn = '1';
public string $actionMessage = '';
public int $cooldownSeconds = 0;
public bool $dryRun = false;
public static function modalMaxWidth(): string
{
return 'lg';
}
/** @return array<int, array{value:string,label:string,controllable:bool}> */
public function getEntityOptionsProperty(): array
{
return Entity::with('device')->get()
->filter(fn (Entity $e) => $e->device !== null)
->map(fn (Entity $e) => [
'value' => $e->device->uuid.'|'.$e->key,
'label' => trim(($e->device->name ?? '?').' · '.($e->name ?: $e->key)),
'controllable' => in_array($e->type, ['switch', 'light'], true),
])
->sortBy('label', SORT_NATURAL | SORT_FLAG_CASE)
->values()->all();
}
public function save()
{
$rules = [
'name' => 'required|string|max:100',
'triggerType' => 'required|in:state_change,time',
'actionType' => 'required|in:switch,notify',
'cooldownSeconds' => 'integer|min:0|max:86400',
];
if ($this->triggerType === 'state_change') {
$rules['triggerEntity'] = 'required|string';
} else {
$rules['triggerAt'] = ['required', 'regex:/^\d{2}:\d{2}$/'];
}
if ($this->actionType === 'switch') {
$rules['actionEntity'] = 'required|string';
} else {
$rules['actionMessage'] = 'required|string|max:200';
}
$this->validate($rules);
Automation::create([
'name' => $this->name,
'enabled' => true,
'trigger_type' => $this->triggerType,
'trigger_config' => $this->buildTriggerConfig(),
'conditions' => [],
'actions' => [$this->buildAction()],
'cooldown_seconds' => $this->cooldownSeconds,
'dry_run' => $this->dryRun,
]);
$this->closeModal();
return redirect()->route('automations.index');
}
/** @return array<string, mixed> */
private function buildTriggerConfig(): array
{
if ($this->triggerType === 'time') {
return ['at' => $this->triggerAt];
}
[$device, $key] = $this->split($this->triggerEntity);
return ['device' => $device, 'entity_key' => $key, 'field' => 'on', 'equals' => $this->triggerEquals === '1'];
}
/** @return array<string, mixed> */
private function buildAction(): array
{
if ($this->actionType === 'notify') {
return ['type' => 'notify', 'message' => $this->actionMessage];
}
[$device, $key] = $this->split($this->actionEntity);
return ['type' => 'switch', 'device' => $device, 'entity_key' => $key, 'on' => $this->actionOn === '1'];
}
/** @return array{0:?string,1:?string} */
private function split(string $value): array
{
$parts = explode('|', $value, 2);
return [$parts[0] ?? null, $parts[1] ?? null];
}
public function render()
{
return view('livewire.modals.create-automation');
}
}