130 lines
3.7 KiB
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');
|
|
}
|
|
}
|