ProjectBACnetService.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. namespace App\Services\Project;
  3. use GuzzleHttp\Client;
  4. use GuzzleHttp\Promise;
  5. use Illuminate\Support\Facades\Http;
  6. use Illuminate\Support\Facades\Log;
  7. class ProjectBACnetService {
  8. protected string $baseProxyUrl;
  9. protected string $username;
  10. protected string $password;
  11. protected array $siteDataMap = [];
  12. public function __construct()
  13. {
  14. $this->baseProxyUrl = config('bacnet.base_proxy_url');
  15. $this->username = config('bacnet.auth.username');
  16. $this->password = config('bacnet.auth.password');
  17. $this->siteDataMap = config('bacnet.site_data_map');
  18. }
  19. private function getBasicAuth(): array
  20. {
  21. return [
  22. 'auth' => [
  23. $this->username,
  24. $this->password
  25. ]
  26. ];
  27. }
  28. public function fetchDeviceObjects($siteId, $deviceId): array
  29. {
  30. $objectList = $this->siteDataMap[$siteId]['objects'][$deviceId] ?? [];
  31. if (empty($objectList)) {
  32. return [];
  33. }
  34. $resData = [];
  35. $client = new Client();
  36. // 创建一个包含所有请求的数组
  37. $promises = [];
  38. for ($i = 0; $i < count($objectList); $i++) {
  39. $objectRef = $objectList[$i];
  40. $url = $this->baseProxyUrl."/.bacnet/$siteId/$objectRef?alt=json";
  41. $promises[$objectRef] = $client->getAsync($url, $this->getBasicAuth());
  42. }
  43. try {
  44. // 发送并发请求并等待所有响应
  45. $responses = Promise\Utils::settle($promises)->wait();
  46. foreach ($responses as $response) {
  47. if ($response['state'] == "fulfilled") {
  48. $data = json_decode($response['value']->getBody()->getContents(), true);
  49. $resData[] = [
  50. 'displayName' => $data['displayName'],
  51. 'present-value' => $data['present-value']['value'],
  52. 'units' => $data['units']['value'],
  53. ];
  54. }
  55. }
  56. } catch (\Throwable $e) {
  57. Log::error('[fetchDeviceObjects] One of the batch requests failed: ' . $e->getMessage());
  58. }
  59. return $resData;
  60. }
  61. public function fetchObjectsValueMulti($siteId, $dataKey): array
  62. {
  63. $targetData = $this->siteDataMap[$siteId][$dataKey] ?? [];
  64. if (empty($targetData)) {
  65. return [];
  66. }
  67. $responseData = [];
  68. $data = [
  69. '$base' => 'Object',
  70. 'lifetime' => [
  71. '$base' => 'Unsigned',
  72. 'value' => 120,
  73. ],
  74. 'values' => [
  75. '$base' => 'List',
  76. ],
  77. ];
  78. foreach ($targetData as $dataRef) {
  79. $nameKey = "$dataRef/object-name";
  80. $valueKey = "$dataRef/present-value";
  81. $unitsKey = "$dataRef/units";
  82. $data['values'][$nameKey] = [
  83. '$base' => 'Any',
  84. 'via' => "/.bacnet/$siteId/$nameKey",
  85. ];
  86. $data['values'][$valueKey] = [
  87. '$base' => 'Any',
  88. 'via' => "/.bacnet/$siteId/$valueKey",
  89. ];
  90. $data['values'][$unitsKey] = [
  91. '$base' => 'Any',
  92. 'via' => "/.bacnet/$siteId/$unitsKey",
  93. ];
  94. }
  95. $url = $this->baseProxyUrl."/.multi?alt=json";
  96. $presentValueMap = $this->siteDataMap[$siteId]["{$dataKey}-present-value-map"] ?? [];
  97. $response = Http::withBasicAuth($this->username, $this->password)->post($url, $data);
  98. if ($response->successful()) {
  99. $json = json_decode($response->body(), true);
  100. foreach ($targetData as $dataRef) {
  101. $nameKey = "$dataRef/object-name";
  102. $valueKey = "$dataRef/present-value";
  103. $unitsKey = "$dataRef/units";
  104. $objectName = $json['values'][$nameKey]['value'] ?? '';
  105. $presentValue = $json['values'][$valueKey]['value'] ?? '';
  106. $units = $json['values'][$unitsKey]['value'] ?? '';
  107. $responseData[] = [
  108. 'displayName' => $objectName,
  109. 'present-value' => $presentValueMap[$presentValue] ?? $presentValue,
  110. 'units' => $units,
  111. ];
  112. }
  113. }
  114. return $responseData;
  115. }
  116. }