[FEAT] 新增溫控感測器離散事件接收處理機制與文件同步

1. [FEAT] 新增 App/Jobs/Machine/ProcessMachineEvent.php 用以非同步處理 machine/{serial_no}/event 事件,將收到的風扇狀態(fanon/fanoff)記錄在機台狀態日誌中。
2. [FEAT] 修改 ListenMqttQueue.php 支援 event 類型的 MQTT 事件分派路由。
3. [FEAT] 更新 config/api-docs.php 規格文件,將原本在 status 主題的風扇說明移去,並新增獨立的 event (機台硬體事件上報) 主題文件。
4. [FIX] 更新多語系資源檔,新增 fanon 與 fanoff 扁平鍵對譯並進行 ksort 排序與去逸出美化。
This commit is contained in:
sky121113 2026-06-02 14:19:48 +08:00
parent fba0dc6bf9
commit 9e3eb8944b
6 changed files with 84 additions and 1 deletions

View File

@ -9,6 +9,7 @@ use App\Jobs\Machine\ProcessHeartbeat;
use App\Jobs\Machine\ProcessMachineError;
use App\Jobs\Machine\ProcessTransaction;
use App\Jobs\Machine\ProcessStatus;
use App\Jobs\Machine\ProcessMachineEvent;
use App\Jobs\Transaction\ProcessInvoice;
use App\Jobs\Transaction\ProcessDispenseRecord;
use App\Jobs\Machine\ProcessCommandAck;
@ -97,6 +98,9 @@ class ListenMqttQueue extends Command
case 'status':
ProcessStatus::dispatch($serialNo, $payload);
break;
case 'event':
ProcessMachineEvent::dispatch($serialNo, $payload);
break;
case 'error':
ProcessMachineError::dispatch($serialNo, $payload);
break;

View File

@ -0,0 +1,59 @@
<?php
namespace App\Jobs\Machine;
use App\Models\Machine\Machine;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class ProcessMachineEvent implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $serialNo;
protected $payload;
/**
* Create a new job instance.
*/
public function __construct($serialNo, $payload)
{
$this->serialNo = $serialNo;
$this->payload = $payload;
}
/**
* Execute the job.
*/
public function handle(): void
{
$machine = Machine::withoutGlobalScopes()->where('serial_no', $this->serialNo)->first();
if (!$machine) {
Log::warning("ProcessMachineEvent: Machine not found [{$this->serialNo}]");
return;
}
$event = $this->payload['event'] ?? null;
if (!$event) {
Log::warning("ProcessMachineEvent: Missing event in payload", ['payload' => $this->payload]);
return;
}
// 寫入機台狀態日誌type 為 'status' 以便正確歸類顯示於「機台狀態」日誌中
$machine->logs()->create([
'company_id' => $machine->company_id,
'type' => 'status', // 忠實呈現於機台狀態中
'level' => 'info',
'message' => $event, // 例如 "fanon" 或 "fanoff"
'context' => $this->payload,
]);
Log::info("ProcessMachineEvent: Machine [{$machine->serial_no}] recorded event [{$event}] to status logs");
}
}

View File

@ -534,12 +534,26 @@ return [
'qos' => 0,
'description' => '用於機台連線與斷線的即時狀態同步。通常用於 MQTT 的遺囑訊息 (LWT) 設定,或由 Broker 連線事件觸發。',
'payload_parameters' => [
'status' => ['type' => 'string', 'description' => '連線狀態。接受值online, offline'],
'status' => ['type' => 'string', 'description' => '連線狀態。接受值online, offline, restarting'],
],
'payload_example' => [
'status' => 'online'
],
],
[
'name' => '機台硬體事件上報 (Event)',
'slug' => 'mqtt-event',
'action' => 'PUB',
'topic' => 'machine/{serial_no}/event',
'qos' => 1,
'description' => '用於機台上報各種獨立的硬體運行與物理事件。後台收到後會直接寫入機台狀態日誌中並進行多語系翻譯。',
'payload_parameters' => [
'event' => ['type' => 'string', 'description' => '事件識別碼。例如fanon (風扇開), fanoff (風扇關) 等。'],
],
'payload_example' => [
'event' => 'fanon'
],
],
[
'name' => '機台異常上報 (Error)',
'slug' => 'mqtt-error',

View File

@ -2276,6 +2276,8 @@
"enabled": "enabled",
"error": "error",
"failed": "failed",
"fanoff": "Fan turned off",
"fanon": "Fan turned on",
"files selected": "files selected",
"hours ago": "hours ago",
"image": "image",

View File

@ -2276,6 +2276,8 @@
"enabled": "有効",
"error": "異常",
"failed": "失敗",
"fanoff": "ファン停止",
"fanon": "ファン起動",
"files selected": "個のファイルを選択しました",
"hours ago": "時間前",
"image": "画像",

View File

@ -2276,6 +2276,8 @@
"enabled": "啟用",
"error": "異常",
"failed": "失敗",
"fanoff": "風扇關",
"fanon": "風扇開",
"files selected": "個檔案已選擇",
"hours ago": "小時前",
"image": "圖片",