Files
api/services/nginx/app/classes/shelly.php
T
Jeppe Bundgaard c775ca7b19 Expand Shelly module capabilities with POST requests and device switch management
- Updated `shelly` class to support POST request handling (`sendPostRequest`) and server URL validation.
- Adjusted `shelly_device_state` to handle object-based `status` and `settings`, adding a `populate` method for data initialization.
- Added `shelly_device_switch` helper to manage switching operations via Shelly API.
- Removed unused `api_url` property in `shelly` class.
- Modified `shelly_i` interface with definitions for `requireValidServerUrl` and `sendPostRequest`.
2025-10-15 13:08:27 +02:00

188 lines
5.5 KiB
PHP

<?php
namespace classes;
require_once WD . '/modules/shelly/shelly_c.php';
/** Actions */
require_once WD . '/modules/shelly/actions/shelly_search_a.php';
use Exception;
use interfaces\shelly_i;
use shelly\actions\shelly_search_a;
use shelly\shelly_c;
class shelly implements shelly_i
{
/**
* Configuration of the shelly module
* @var shelly_c
*/
public shelly_c $config;
/**
* ACTION: shelly_SEARCH
* @see shelly_search_a
* @notation This action is when a company search request is made, and logs the request in the database
* @var shelly_search_a $shelly_search
*/
private shelly_search_a $shelly_search;
public function __construct()
{
$this->config = new shelly_c();
/** Actions */
$this->shelly_search = new shelly_search_a();
}
/**
* @inheritDoc
* @throws Exception If the module is not enabled, the license plate is invalid, the daily limit is exceeded, or the secret key is invalid
*/
function sendRequest(
string $endpoint,
array $data = [],
string $method = 'GET'
): object
{
// Validate the module is enabled
self::requireModuleEnabled();
// Validate the secret key
self::requireValidSecretKey();
// Send the request
$response = match ($method) {
//'GET' => self::sendGetRequest($endpoint, $data),
'POST' => self::sendPostRequest($endpoint, $data),
//'PUT' => self::sendPutRequest($endpoint, $data),
//'DELETE' => self::sendDeleteRequest($endpoint, $data),
default => self::exception(
[
'method' => $method,
'endpoint' => $endpoint,
'data' => $data,
'response' => null,
'status_code' => 400,
'error' => 'Invalid request method',
],
500
),
};
// Add the usage to the request log
$this->shelly_search->shelly_search($response, 200);
// Return the response
return $response;
}
/**
* @inheritDoc
*/
function requireModuleEnabled(): void
{
// Check if the module is enabled
if (!$this->config->enabled->isTrue()) {
throw new Exception('The shelly module is not enabled');
}
}
/**
* @inheritDoc
*/
function requireValidSecretKey(): void
{
// Check if the secret key is valid
if ($this->config->secret_key->getVariableValue() === null) {
self::exception(
[
'status_code' => 500,
'error' => 'Invalid secret key defined in the config (shelly_secret_key_c)',
],
500
);
}
}
/**
* @throws Exception
*/
function exception(array $data, int $status_code = 500): object
{
// Check if the response is valid JSON
if (!json_decode($data['response'])) {
throw new Exception('Invalid response');
}
// Add the request to the log
$this->shelly_search->shelly_search($data, $status_code);;
return throw new Exception($data['error'] ?? 'An error occurred while processing the request, in ' . $this->config->getModuleName() . ' module');
}
/**
* @inheritDoc
* @throws Exception
*/
function requireValidServerURL(): void
{
// Check if the server URL is valid
if ($this->config->server_url->getVariableValue() === null) {
self::exception(
[
'status_code' => 500,
]
);
}
}
/**
* @inheritDoc
* @throws Exception
*/
function sendPostRequest(string $endpoint, array $data): array|object|null
{
/**
* curl -X POST 'https://<HOST>/v2/devices/api/get?auth_key=<AUTH_KEY>' \
* -H 'Content-Type: application/json' \
* -d '<BODY>'
*/
// Require the module to be enabled
self::requireModuleEnabled();
self::requireValidSecretKey();
self::requireValidServerURL();
// Send the request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::appendAuthKeyToQuery($this->config->server_url->getVariableValue() . $endpoint));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
]);
// Execute the request
$response = curl_exec($ch);
// Get the status code
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Check for errors
if (curl_errno($ch)) {
self::exception(
[
'method' => 'POST',
'endpoint' => $endpoint,
'data' => $data,
'response' => $response,
],
$status_code
);
}
// Close the cURL session
curl_close($ch);
// Check if there is a response (some endpoints don't return a response)
if ($response === false) {
return null;
}
// Return the response
return json_decode($response);
}
function appendAuthKeyToQuery(string $url): string
{
return $url . '?auth_key=' . $this->config->secret_key->getVariableValue();
}
}