1. 資料庫移轉:新增機台環境溫度、環境溫度上限設定,以及是否啟用環境溫度監測等欄位。 2. 後端核心:更新 Machine Model 與 MachineController,實作機台環境溫度設定的更新與歷史日誌 Ajax API。 3. MQTT 佇列:於 ListenMqttQueue 指令與 ProcessAmbientTemp Job 實作機台上報環境溫度的接收與寫入,並加入 Redis 快取防止重複日誌洗版。 4. 遠端指令:擴充 RemoteController 並於指令中心實作 'fanon'、'fanoff'、'fanauto' 與 'ambient_temp_limit' (環境溫度上限) 指令下發。 5. 前端頁面:於機台列表加入「環境溫度上限」微調計數器 UI,並整合 ApexCharts 折線圖展示溫度趨勢;更新遠端控制中心按鈕與歷史篩選器。 6. 多語系:同步更新並完美對齊 'zh_TW.json'、'en.json' 與 'ja.json',遵循字母 ksort 排序與斜線不逸出規範。
95 lines
3.0 KiB
PHP
95 lines
3.0 KiB
PHP
<?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;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class ProcessAmbientTemp implements ShouldQueue
|
|
{
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
protected $serialNo;
|
|
protected $payload;
|
|
|
|
/**
|
|
* Create a new job instance.
|
|
*/
|
|
public function __construct(string $serialNo, $payload)
|
|
{
|
|
$this->serialNo = $serialNo;
|
|
$this->payload = (array) $payload;
|
|
}
|
|
|
|
/**
|
|
* Execute the job.
|
|
*/
|
|
public function handle(): void
|
|
{
|
|
$machine = Machine::withoutGlobalScopes()->where('serial_no', $this->serialNo)->first();
|
|
|
|
if (!$machine) {
|
|
Log::warning("MQTT Ambient Temp: Machine not found", ['serial_no' => $this->serialNo]);
|
|
return;
|
|
}
|
|
|
|
// 環境溫度欄位更新
|
|
// 支持機台傳送 payload 為 {"temperature": 25} 或 {"ambient_temp": 25} 等結構
|
|
$temp = null;
|
|
if (isset($this->payload['temperature'])) {
|
|
$temp = (int) $this->payload['temperature'];
|
|
} elseif (isset($this->payload['ambient_temp'])) {
|
|
$temp = (int) $this->payload['ambient_temp'];
|
|
} elseif (isset($this->payload['raw_data'])) {
|
|
$temp = (int) $this->payload['raw_data'];
|
|
}
|
|
|
|
if ($temp === null) {
|
|
Log::warning("MQTT Ambient Temp: Missing temperature field in payload", [
|
|
'serial_no' => $this->serialNo,
|
|
'payload' => $this->payload
|
|
]);
|
|
return;
|
|
}
|
|
|
|
Log::debug("ProcessAmbientTemp: Ambient temperature reported for {$this->serialNo}: {$temp}");
|
|
|
|
$updateData = [
|
|
'ambient_temperature' => $temp,
|
|
];
|
|
|
|
// 讀取最後一次記錄日誌的溫度與時間,避免頻繁寫入相同的溫度日誌
|
|
$tempLogCacheKey = "machine:{$this->serialNo}:last_ambient_temp_log";
|
|
$lastLogEntry = Cache::get($tempLogCacheKey);
|
|
|
|
// 優先從快取取值,若無則從資料庫取
|
|
$oldTemp = isset($lastLogEntry['value']) ? (int)$lastLogEntry['value'] : $machine->ambient_temperature;
|
|
|
|
if ($temp !== (int)$oldTemp) {
|
|
Log::debug("ProcessAmbientTemp: Ambient temperature changed from {$oldTemp} to {$temp}. Triggering log.");
|
|
\App\Jobs\Machine\ProcessStateLog::dispatch(
|
|
$machine->id,
|
|
$machine->company_id,
|
|
"Ambient temperature reported: :temp°C",
|
|
'info',
|
|
['temp' => $temp],
|
|
'ambient_temp' // type 欄位
|
|
);
|
|
}
|
|
|
|
// 更新快取 (存活時間為 7 天)
|
|
Cache::put($tempLogCacheKey, [
|
|
'value' => $temp,
|
|
'at' => now()->toDateTimeString()
|
|
], 604800);
|
|
|
|
$machine->update($updateData);
|
|
}
|
|
}
|