Skip to content

Commit 2159489

Browse files
authored
Merge pull request #4 from llm-agents-php/feature/smart-home-status
Improves Smart home control
2 parents b2e855c + 3825204 commit 2159489

15 files changed

+416
-79
lines changed

app/src/Agents/SmartHomeControl/ControlDeviceInput.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public function __construct(
1414
public string $deviceId,
1515

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

1919
/**
2020
* @var array<DeviceParam>

app/src/Agents/SmartHomeControl/ControlDeviceTool.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ public function __construct(
2626

2727
public function execute(object $input): string
2828
{
29-
$result = $this->smartHome->controlDevice($input->deviceId, $input->action, $input->params);
30-
31-
if (isset($result['error'])) {
32-
return json_encode(['error' => $result['error']]);
29+
try {
30+
$result = $this->smartHome->controlDevice($input->deviceId, $input->action, $input->params);
31+
32+
return json_encode([
33+
'id' => $input->deviceId,
34+
'action' => $input->action->value,
35+
'result' => $result,
36+
]);
37+
} catch (\InvalidArgumentException $e) {
38+
return json_encode(['error' => $e->getMessage()]);
3339
}
34-
35-
return json_encode([
36-
'id' => $input->deviceId,
37-
'action' => $input->action,
38-
]);
3940
}
4041
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Agents\SmartHomeControl;
6+
7+
enum DeviceAction: string
8+
{
9+
case TurnOn = 'turnOn';
10+
case TurnOff = 'turnOff';
11+
case SetBrightness = 'setBrightness';
12+
case SetColor = 'setColor';
13+
case SetTemperature = 'setTemperature';
14+
case SetMode = 'setMode';
15+
case SetVolume = 'setVolume';
16+
case SetInput = 'setInput';
17+
case SetAttribute = 'setAttribute';
18+
}

app/src/Agents/SmartHomeControl/DeviceParam.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
final class DeviceParam
1010
{
1111
public function __construct(
12-
#[Field(title: 'Param name', description: 'The name of the parameter')]
12+
#[Field(title: 'Attribute name', description: 'The name of the parameter')]
1313
public string $name,
14-
#[Field(title: 'Param value', description: 'The value of the parameter')]
14+
#[Field(title: 'Attribute value', description: 'The value of the parameter')]
1515
public string $value,
1616
) {}
1717
}

app/src/Agents/SmartHomeControl/GetDeviceDetailsTool.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ final class GetDeviceDetailsTool extends PhpTool
1515
public const NAME = 'get_device_details';
1616

1717
public function __construct(
18-
private SmartHomeSystem $smartHome,
18+
private readonly SmartHomeSystem $smartHome,
1919
) {
2020
parent::__construct(
2121
name: self::NAME,
@@ -38,6 +38,7 @@ public function execute(object $input): string
3838
'room' => $device->room,
3939
'type' => get_class($device),
4040
'params' => $device->getDetails(),
41+
'controlSchema' => $device->getControlSchema(),
4142
]);
4243
}
4344
}

app/src/Agents/SmartHomeControl/ListRoomDevicesTool.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public function execute(object $input): string
3535
'name' => $device->name,
3636
'type' => get_class($device),
3737
'status' => $device->getStatus() ? 'on' : 'off',
38+
'params' => $device->getDetails(),
39+
'controlSchema' => $device->getControlSchema(),
3840
];
3941
}
4042

app/src/Agents/SmartHomeControl/SmartHome/Devices/Light.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
namespace App\Agents\SmartHomeControl\SmartHome\Devices;
66

7-
final class Light extends SmartDevice
7+
use App\Agents\SmartHomeControl\DeviceAction;
8+
9+
class Light extends SmartDevice
810
{
911
public function __construct(
1012
string $id,
@@ -37,4 +39,42 @@ public function getDetails(): array
3739
'color' => $this->color,
3840
];
3941
}
42+
43+
public function getControlSchema(): array
44+
{
45+
return [
46+
'type' => 'object',
47+
'properties' => [
48+
'action' => [
49+
'type' => 'string',
50+
'enum' => [
51+
DeviceAction::TurnOn->value,
52+
DeviceAction::TurnOff->value,
53+
DeviceAction::SetBrightness->value,
54+
DeviceAction::SetColor->value,
55+
],
56+
],
57+
'brightness' => [
58+
'type' => 'integer',
59+
'minimum' => 0,
60+
'maximum' => 100,
61+
],
62+
'color' => [
63+
'type' => 'string',
64+
],
65+
],
66+
'required' => ['action'],
67+
];
68+
}
69+
70+
public function executeAction(DeviceAction $action, array $params): static
71+
{
72+
match ($action) {
73+
DeviceAction::SetBrightness => $this->setBrightness($params['brightness']),
74+
DeviceAction::SetColor => $this->setColor($params['color']),
75+
default => parent::executeAction($action, $params)
76+
};
77+
78+
return $this;
79+
}
4080
}

app/src/Agents/SmartHomeControl/SmartHome/Devices/SmartAppliance.php

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,37 @@
44

55
namespace App\Agents\SmartHomeControl\SmartHome\Devices;
66

7-
final class SmartAppliance extends SmartDevice
7+
use App\Agents\SmartHomeControl\DeviceAction;
8+
use App\Agents\SmartHomeControl\DeviceParam;
9+
10+
class SmartAppliance extends SmartDevice
811
{
912
public function __construct(
1013
string $id,
1114
string $name,
1215
string $room,
1316
public readonly string $type,
1417
protected array $attributes = [],
18+
bool $status = false,
1519
) {
16-
parent::__construct($id, $name, $room);
20+
parent::__construct($id, $name, $room, $status);
1721
}
1822

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

28+
/**
29+
* @param array<DeviceParam> $attributes
30+
*/
31+
public function setAttributes(array $attributes): void
32+
{
33+
foreach ($attributes as $attribute) {
34+
$this->setAttribute($attribute->name, $attribute->value);
35+
}
36+
}
37+
2438
public function getAttribute(string $key)
2539
{
2640
return $this->attributes[$key] ?? null;
@@ -29,8 +43,86 @@ public function getAttribute(string $key)
2943
public function getDetails(): array
3044
{
3145
return array_merge(
32-
['status' => $this->status ? 'on' : 'off', 'type' => $this->type],
3346
$this->attributes,
47+
[
48+
'status' => $this->status ? 'on' : 'off',
49+
'type' => $this->type,
50+
],
3451
);
3552
}
53+
54+
public function getControlSchema(): array
55+
{
56+
$schema = [
57+
'type' => 'object',
58+
'properties' => [
59+
'action' => [
60+
'type' => 'string',
61+
'enum' => [
62+
DeviceAction::TurnOn->value,
63+
DeviceAction::TurnOff->value,
64+
DeviceAction::SetAttribute->value,
65+
],
66+
],
67+
'params' => [
68+
'type' => 'object',
69+
'properties' => [
70+
'name' => [
71+
'type' => 'string',
72+
],
73+
'value' => [
74+
'type' => ['string', 'number', 'boolean'],
75+
],
76+
],
77+
'required' => ['name', 'value',],
78+
],
79+
],
80+
'required' => ['action'],
81+
];
82+
83+
// Add specific schemas based on the appliance type
84+
switch ($this->type) {
85+
case 'fireplace':
86+
$schema['properties']['intensity'] = [
87+
'type' => 'integer',
88+
'minimum' => 1,
89+
'maximum' => 5,
90+
];
91+
break;
92+
case 'speaker':
93+
$schema['properties']['volume'] = [
94+
'type' => 'integer',
95+
'minimum' => 0,
96+
'maximum' => 100,
97+
];
98+
$schema['properties']['radio_station'] = [
99+
'type' => 'string',
100+
'enum' => ['rock', 'pop', 'jazz', 'classical', 'news', 'talk', 'sports'],
101+
];
102+
$schema['properties']['playback'] = [
103+
'type' => 'string',
104+
'enum' => ['play', 'pause', 'stop', 'next', 'previous'],
105+
];
106+
break;
107+
case 'fan':
108+
$schema['properties']['speed'] = [
109+
'type' => 'integer',
110+
'minimum' => 0,
111+
'maximum' => 5,
112+
];
113+
break;
114+
}
115+
116+
return $schema;
117+
}
118+
119+
public function executeAction(DeviceAction $action, array $params): static
120+
{
121+
match ($action) {
122+
DeviceAction::SetAttribute => $this->setAttributes($params),
123+
default => parent::executeAction($action, $params),
124+
};
125+
126+
return $this;
127+
}
36128
}

app/src/Agents/SmartHomeControl/SmartHome/Devices/SmartDevice.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace App\Agents\SmartHomeControl\SmartHome\Devices;
66

7+
use App\Agents\SmartHomeControl\DeviceAction;
8+
79
abstract class SmartDevice
810
{
911
public function __construct(
@@ -29,4 +31,17 @@ public function getStatus(): bool
2931
}
3032

3133
abstract public function getDetails(): array;
34+
35+
abstract public function getControlSchema(): array;
36+
37+
public function executeAction(DeviceAction $action, array $params): static
38+
{
39+
match ($action) {
40+
DeviceAction::TurnOn => $this->turnOn(),
41+
DeviceAction::TurnOff => $this->turnOff(),
42+
default => throw new \InvalidArgumentException("Unsupported action: {$action->value}"),
43+
};
44+
45+
return $this;
46+
}
3247
}

app/src/Agents/SmartHomeControl/SmartHome/Devices/TV.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
namespace App\Agents\SmartHomeControl\SmartHome\Devices;
66

7-
final class TV extends SmartDevice
7+
use App\Agents\SmartHomeControl\DeviceAction;
8+
9+
class TV extends SmartDevice
810
{
911
public function __construct(
1012
string $id,
@@ -34,4 +36,43 @@ public function getDetails(): array
3436
'input' => $this->input,
3537
];
3638
}
39+
40+
public function getControlSchema(): array
41+
{
42+
return [
43+
'type' => 'object',
44+
'properties' => [
45+
'action' => [
46+
'type' => 'string',
47+
'enum' => [
48+
DeviceAction::TurnOn->value,
49+
DeviceAction::TurnOff->value,
50+
DeviceAction::SetVolume->value,
51+
DeviceAction::SetInput->value,
52+
],
53+
],
54+
'volume' => [
55+
'type' => 'integer',
56+
'minimum' => 0,
57+
'maximum' => 100,
58+
],
59+
'input' => [
60+
'type' => 'string',
61+
'enum' => ['HDMI 1', 'HDMI 2', 'HDMI 3', 'TV', 'AV'],
62+
],
63+
],
64+
'required' => ['action'],
65+
];
66+
}
67+
68+
public function executeAction(DeviceAction $action, array $params): static
69+
{
70+
match ($action) {
71+
DeviceAction::SetVolume => $this->setVolume($params['volume']),
72+
DeviceAction::SetInput => $this->setInput($params['input']),
73+
default => parent::executeAction($action, $params),
74+
};
75+
76+
return $this;
77+
}
3778
}

0 commit comments

Comments
 (0)