Skip to content

Commit

Permalink
Merge pull request #4 from llm-agents-php/feature/smart-home-status
Browse files Browse the repository at this point in the history
Improves Smart home control
  • Loading branch information
butschster authored Aug 29, 2024
2 parents b2e855c + 3825204 commit 2159489
Show file tree
Hide file tree
Showing 15 changed files with 416 additions and 79 deletions.
2 changes: 1 addition & 1 deletion app/src/Agents/SmartHomeControl/ControlDeviceInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function __construct(
public string $deviceId,

#[Field(title: 'Action', description: 'The action to perform on the device (e.g., turnOn, turnOff, setBrightness)')]
public string $action,
public DeviceAction $action,

/**
* @var array<DeviceParam>
Expand Down
19 changes: 10 additions & 9 deletions app/src/Agents/SmartHomeControl/ControlDeviceTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@ public function __construct(

public function execute(object $input): string
{
$result = $this->smartHome->controlDevice($input->deviceId, $input->action, $input->params);

if (isset($result['error'])) {
return json_encode(['error' => $result['error']]);
try {
$result = $this->smartHome->controlDevice($input->deviceId, $input->action, $input->params);

return json_encode([
'id' => $input->deviceId,
'action' => $input->action->value,
'result' => $result,
]);
} catch (\InvalidArgumentException $e) {
return json_encode(['error' => $e->getMessage()]);
}

return json_encode([
'id' => $input->deviceId,
'action' => $input->action,
]);
}
}
18 changes: 18 additions & 0 deletions app/src/Agents/SmartHomeControl/DeviceAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\Agents\SmartHomeControl;

enum DeviceAction: string
{
case TurnOn = 'turnOn';
case TurnOff = 'turnOff';
case SetBrightness = 'setBrightness';
case SetColor = 'setColor';
case SetTemperature = 'setTemperature';
case SetMode = 'setMode';
case SetVolume = 'setVolume';
case SetInput = 'setInput';
case SetAttribute = 'setAttribute';
}
4 changes: 2 additions & 2 deletions app/src/Agents/SmartHomeControl/DeviceParam.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
final class DeviceParam
{
public function __construct(
#[Field(title: 'Param name', description: 'The name of the parameter')]
#[Field(title: 'Attribute name', description: 'The name of the parameter')]
public string $name,
#[Field(title: 'Param value', description: 'The value of the parameter')]
#[Field(title: 'Attribute value', description: 'The value of the parameter')]
public string $value,
) {}
}
3 changes: 2 additions & 1 deletion app/src/Agents/SmartHomeControl/GetDeviceDetailsTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class GetDeviceDetailsTool extends PhpTool
public const NAME = 'get_device_details';

public function __construct(
private SmartHomeSystem $smartHome,
private readonly SmartHomeSystem $smartHome,
) {
parent::__construct(
name: self::NAME,
Expand All @@ -38,6 +38,7 @@ public function execute(object $input): string
'room' => $device->room,
'type' => get_class($device),
'params' => $device->getDetails(),
'controlSchema' => $device->getControlSchema(),
]);
}
}
2 changes: 2 additions & 0 deletions app/src/Agents/SmartHomeControl/ListRoomDevicesTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public function execute(object $input): string
'name' => $device->name,
'type' => get_class($device),
'status' => $device->getStatus() ? 'on' : 'off',
'params' => $device->getDetails(),
'controlSchema' => $device->getControlSchema(),
];
}

Expand Down
42 changes: 41 additions & 1 deletion app/src/Agents/SmartHomeControl/SmartHome/Devices/Light.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace App\Agents\SmartHomeControl\SmartHome\Devices;

final class Light extends SmartDevice
use App\Agents\SmartHomeControl\DeviceAction;

class Light extends SmartDevice
{
public function __construct(
string $id,
Expand Down Expand Up @@ -37,4 +39,42 @@ public function getDetails(): array
'color' => $this->color,
];
}

public function getControlSchema(): array
{
return [
'type' => 'object',
'properties' => [
'action' => [
'type' => 'string',
'enum' => [
DeviceAction::TurnOn->value,
DeviceAction::TurnOff->value,
DeviceAction::SetBrightness->value,
DeviceAction::SetColor->value,
],
],
'brightness' => [
'type' => 'integer',
'minimum' => 0,
'maximum' => 100,
],
'color' => [
'type' => 'string',
],
],
'required' => ['action'],
];
}

public function executeAction(DeviceAction $action, array $params): static
{
match ($action) {
DeviceAction::SetBrightness => $this->setBrightness($params['brightness']),
DeviceAction::SetColor => $this->setColor($params['color']),
default => parent::executeAction($action, $params)
};

return $this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,37 @@

namespace App\Agents\SmartHomeControl\SmartHome\Devices;

final class SmartAppliance extends SmartDevice
use App\Agents\SmartHomeControl\DeviceAction;
use App\Agents\SmartHomeControl\DeviceParam;

class SmartAppliance extends SmartDevice
{
public function __construct(
string $id,
string $name,
string $room,
public readonly string $type,
protected array $attributes = [],
bool $status = false,
) {
parent::__construct($id, $name, $room);
parent::__construct($id, $name, $room, $status);
}

public function setAttribute(string $key, $value): void
{
$this->attributes[$key] = $value;
}

/**
* @param array<DeviceParam> $attributes
*/
public function setAttributes(array $attributes): void
{
foreach ($attributes as $attribute) {
$this->setAttribute($attribute->name, $attribute->value);
}
}

public function getAttribute(string $key)
{
return $this->attributes[$key] ?? null;
Expand All @@ -29,8 +43,86 @@ public function getAttribute(string $key)
public function getDetails(): array
{
return array_merge(
['status' => $this->status ? 'on' : 'off', 'type' => $this->type],
$this->attributes,
[
'status' => $this->status ? 'on' : 'off',
'type' => $this->type,
],
);
}

public function getControlSchema(): array
{
$schema = [
'type' => 'object',
'properties' => [
'action' => [
'type' => 'string',
'enum' => [
DeviceAction::TurnOn->value,
DeviceAction::TurnOff->value,
DeviceAction::SetAttribute->value,
],
],
'params' => [
'type' => 'object',
'properties' => [
'name' => [
'type' => 'string',
],
'value' => [
'type' => ['string', 'number', 'boolean'],
],
],
'required' => ['name', 'value',],
],
],
'required' => ['action'],
];

// Add specific schemas based on the appliance type
switch ($this->type) {
case 'fireplace':
$schema['properties']['intensity'] = [
'type' => 'integer',
'minimum' => 1,
'maximum' => 5,
];
break;
case 'speaker':
$schema['properties']['volume'] = [
'type' => 'integer',
'minimum' => 0,
'maximum' => 100,
];
$schema['properties']['radio_station'] = [
'type' => 'string',
'enum' => ['rock', 'pop', 'jazz', 'classical', 'news', 'talk', 'sports'],
];
$schema['properties']['playback'] = [
'type' => 'string',
'enum' => ['play', 'pause', 'stop', 'next', 'previous'],
];
break;
case 'fan':
$schema['properties']['speed'] = [
'type' => 'integer',
'minimum' => 0,
'maximum' => 5,
];
break;
}

return $schema;
}

public function executeAction(DeviceAction $action, array $params): static
{
match ($action) {
DeviceAction::SetAttribute => $this->setAttributes($params),
default => parent::executeAction($action, $params),
};

return $this;
}
}
15 changes: 15 additions & 0 deletions app/src/Agents/SmartHomeControl/SmartHome/Devices/SmartDevice.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace App\Agents\SmartHomeControl\SmartHome\Devices;

use App\Agents\SmartHomeControl\DeviceAction;

abstract class SmartDevice
{
public function __construct(
Expand All @@ -29,4 +31,17 @@ public function getStatus(): bool
}

abstract public function getDetails(): array;

abstract public function getControlSchema(): array;

public function executeAction(DeviceAction $action, array $params): static
{
match ($action) {
DeviceAction::TurnOn => $this->turnOn(),
DeviceAction::TurnOff => $this->turnOff(),
default => throw new \InvalidArgumentException("Unsupported action: {$action->value}"),
};

return $this;
}
}
43 changes: 42 additions & 1 deletion app/src/Agents/SmartHomeControl/SmartHome/Devices/TV.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace App\Agents\SmartHomeControl\SmartHome\Devices;

final class TV extends SmartDevice
use App\Agents\SmartHomeControl\DeviceAction;

class TV extends SmartDevice
{
public function __construct(
string $id,
Expand Down Expand Up @@ -34,4 +36,43 @@ public function getDetails(): array
'input' => $this->input,
];
}

public function getControlSchema(): array
{
return [
'type' => 'object',
'properties' => [
'action' => [
'type' => 'string',
'enum' => [
DeviceAction::TurnOn->value,
DeviceAction::TurnOff->value,
DeviceAction::SetVolume->value,
DeviceAction::SetInput->value,
],
],
'volume' => [
'type' => 'integer',
'minimum' => 0,
'maximum' => 100,
],
'input' => [
'type' => 'string',
'enum' => ['HDMI 1', 'HDMI 2', 'HDMI 3', 'TV', 'AV'],
],
],
'required' => ['action'],
];
}

public function executeAction(DeviceAction $action, array $params): static
{
match ($action) {
DeviceAction::SetVolume => $this->setVolume($params['volume']),
DeviceAction::SetInput => $this->setInput($params['input']),
default => parent::executeAction($action, $params),
};

return $this;
}
}
Loading

0 comments on commit 2159489

Please sign in to comment.