<?php
namespace MiotApi\Api;
use MiotApi\Contract\Instance\Instance;
use MiotApi\Exception\ApiErrorException;
class Api extends BaseApi
{
public function devicesList()
{
$devicesList = [];
$devices = $this->devices();
if (isset($devices['devices'])) {
if (!empty($devices['devices'])) {
foreach ($devices['devices'] as $device) {
$dids[] = $device['did'];
$device['serialNumber'] = null;
$devicesList[$device['did']] = $device;
}
$deviceInformations = $this->deviceInformation($dids);
if (isset($deviceInformations['device-information'])) {
foreach ($deviceInformations['device-information'] as $deviceInformation) {
if (isset($devicesList[$deviceInformation['id']])) {
$devicesList[$deviceInformation['id']]['serialNumber'] = $deviceInformation['serialNumber'];
}
}
}
return array_values($devicesList);
} else {
return [];
}
} else {
return $devices;
}
}
public function getPropertyGraceful($did, $type, $data)
{
$propertyData = [
$did => [
'type' => $type,
'data' => $data,
],
];
return $this->getPropertiesGraceful($propertyData);
}
public function getPropertiesGraceful($data)
{
if (!empty($data)) {
$properties = [];
$attributes = [];
$instances = [];
foreach ($data as $did => $datum) {
if (isset($datum['type'])) {
$instance = new Instance($datum['type']);
$propertiesNodes = $instance->getPropertiesNodes();
$instances[$did] = $propertiesNodes;
if (!empty($datum['data'])) {
foreach ($datum['data'] as $name) {
list($sids, $pids) = $instance->getSidPidByName($name);
if (!$sids || !$pids) {
throw new ApiErrorException('Invalid property! did:'.$did.',name: '.$name);
}
foreach ($sids as $sindex => $sid) {
$property = $propertiesNodes[($sid.'.'.$pids[$sindex])];
if (!$property->canRead()) {
throw new ApiErrorException(
'The property does\'t has the read access! did:'.$did.',name: '.$name
);
}
$properties[] = $did.'.'.$sid.'.'.$pids[$sindex];
}
}
} else {
foreach ($propertiesNodes as $property) {
$name = $property->getUrn()->getName();
list($sids, $pids) = $instance->getSidPidByName($name);
if (!$sids || !$pids) {
throw new ApiErrorException('Invalid property! did:'.$did.',name: '.$name);
}
foreach ($sids as $sindex => $sid) {
$property = $propertiesNodes[($sid.'.'.$pids[$sindex])];
if (!$property->canRead()) {
throw new ApiErrorException(
'The property does\'t has the read access! did:'.$did.',name: '.$name
);
}
$properties[] = $did.'.'.$sid.'.'.$pids[$sindex];
}
}
}
} else {
throw new ApiErrorException('Properties data and device type required');
}
}
$response = $this->properties(array_unique($properties));
if (isset($response['properties']) && !empty($response['properties'])) {
foreach ($response['properties'] as $res) {
$pidArr = explode('.', $res['pid']);
if (isset($res['value']) && isset($res['status']) && $res['status'] == 0 && isset($pidArr[0]) && isset($pidArr[1]) && isset($pidArr[2]) && isset($instances[$pidArr[0]][($pidArr[1].'.'.$pidArr[2])])) {
$attributeName = $instances[$pidArr[0]][($pidArr[1].'.'.$pidArr[2])]->getUrn()->getName();
if (isset($attributes[$pidArr[0]][$attributeName])) {
if (is_array($attributes[$pidArr[0]][$attributeName])) {
$attributes[$pidArr[0]][$attributeName][] = $res['value'];
} else {
$attributes[$pidArr[0]][$attributeName] = [
$attributes[$pidArr[0]][$attributeName],
$res['value'],
];
}
} else {
$attributes[$pidArr[0]][$attributeName] = $res['value'];
}
}
}
}
return $attributes;
} else {
throw new ApiErrorException('devices data required');
}
}
public function setPropertyGraceful($did, $type, $data)
{
if (!empty($data)) {
$propertyData = [
$did => [
'type' => $type,
'data' => $data,
],
];
return $this->setPropertiesGraceful($propertyData);
} else {
throw new ApiErrorException('Properties data required');
}
}
public function setPropertiesGraceful($data)
{
if (!empty($data)) {
$properties = [];
foreach ($data as $did => $datum) {
if (!empty($datum['data']) && isset($datum['type'])) {
$instance = new Instance($datum['type']);
$propertiesNodes = $instance->getPropertiesNodes();
foreach ($datum['data'] as $name => $value) {
list($sids, $pids) = $instance->getSidPidByName($name);
if (!$sids || !$pids) {
throw new ApiErrorException('Invalid property! did:'.$did.',name: '.$name);
}
foreach ($sids as $sindex => $sid) {
$property = $propertiesNodes[($sid.'.'.$pids[$sindex])];
if (!is_array($value)) {
$tmpValue = $value;
} else {
if (!isset($value[$sindex])) {
throw new ApiErrorException(
'Invalid property value! did:'.$did.',name: '.$name
);
}
$tmpValue = $value[$sindex];
}
if (!$property->verify($tmpValue)) {
throw new ApiErrorException('Invalid property value! did:'.$did.',name: '.$name);
}
if (!$property->canWrite()) {
throw new ApiErrorException(
'The property does\'t has the write access! did:'.$did.',name: '.$name
);
}
$properties[] = [
'pid' => $did.'.'.$sid.'.'.$pids[$sindex],
'value' => $tmpValue,
];
}
}
} else {
throw new ApiErrorException('Properties data and device type required');
}
}
return $this->setProperties([
'properties' => $properties,
]);
} else {
throw new ApiErrorException('devices data required');
}
}
public function subscriptByDevices($devices, $receiverUrl)
{
$subscriptProperties = $this->getPropertiesByDevices($devices, ['notify']);
return $this->subscript($subscriptProperties, $receiverUrl);
}
public function unSubscriptByDevices($devices)
{
$subscriptProperties = $this->getPropertiesByDevices($devices, ['notify']);
return $this->unSubscript($subscriptProperties);
}
protected function getPropertiesByDevices($devices, $access = [])
{
try {
$properties = [];
if (!empty($devices) && !isset($devices['status'])) {
foreach ($devices as $device) {
$instance = new Instance($device['type']);
$propertiesNodes = $instance->getPropertiesNodes();
if (!empty($propertiesNodes)) {
foreach ($propertiesNodes as $index => $property) {
if (in_array('read', $access)) {
if ($property->canRead()) {
$properties[] = $device['did'].'.'.$index;
}
}
if (in_array('write', $access)) {
if ($property->canWrite()) {
$properties[] = $device['did'].'.'.$index;
}
}
if (in_array('notify', $access)) {
if ($property->canNotify()) {
$properties[] = $device['did'].'.'.$index;
}
}
}
}
}
} else {
throw new ApiErrorException('invalid devices lists');
}
return $properties;
} catch (ApiErrorException $exception) {
return false;
}
}
}