在前面Home Assistant的File Notify Service用法一文中提到了怎麼將日誌寫進檔案中,如果要把內容直接放上lovelace裡的話,比較常見的是建立一個command line sensor去取得檔案的內容,並且依照需求做過濾。比如檔案內容是這樣
Home Assistant notifications (Log started: 2024-09-27T06:30:28.644724+00:00)
--------------------------------------------------------------------------------
2024/09/27 14:30:28 → 維護模式開啟。
2024/09/27 14:30:31 → 維護模式關閉。
2024/09/27 14:43:56 → 主缸水位在交界處。
2024/09/27 14:44:13 → 維護模式開啟。
2024/09/27 16:55:05 → 維護模式關閉。
2024/09/27 16:55:41 → 主缸水位在交界處。
2024/09/27 16:58:41 → 主缸水位正常。
我只想保留最新10筆日誌並放在lovelace哩,command line sensor可以這樣做
- sensor:
name: Aquarium_Log
command: "tail -n +3 /config/www/aquarium/aquarium.txt | tail -n 10"
它會去讀取/config/www/aquarium/aquarium.txt的檔案,從第3行開始讀取,並留下倒數10行的內容。展開sensor.aquarium_log的內容如下
透過markdown card就可以把它放在lovelace裡
到這裡其實看起來也不是什麼問題,但Home Assistant Sensor有字元數的限制,日誌的總字元數如果超過255,sensor會變成unknown。
找了好一陣子,發現有同樣問題的人也不少,多個解決方案中我覺得比較全面的方式是用內嵌網頁的方式。做法是建立一個html檔案,在html檔裡利用javascript讀取文字檔的內容,再透過iframe card放在lovelace裡。這裡會有二個檔案
- 原本的日誌檔,路徑與檔名為/local/aquarium/aquarium.txt,這裡的/local就是/config/www。
- 新建立的html檔,路徑與檔名為/local/aquarium/aquarium.html,透過javascript讀取日誌檔並轉成html。
aquarium.html的內容如下,先去除頭2行,再固定顯示倒數40行的內容。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { font-family: Arial, sans-serif; }
pre { white-space: pre-wrap; font-size: 14px; font-family: Arial, sans-serif; }
</style>
</head>
<body>
<pre id="logContent">Loading...</pre>
<script>
const cacheBuster = new Date().getTime();
fetch(`/local/aquarium/aquarium.txt?cb=${cacheBuster}`)
.then(response => {
if (!response.ok) {
throw new Error('Network error: ' + response.statusText);
}
return response.text();
})
.then(data => {
const lines = data.split('\n');
const trimmedLines = lines.slice(2);
const last40Lines = trimmedLines.slice(-40);
const result = last40Lines.join('\n');
document.getElementById('logContent').textContent = result;
})
.catch(error => {
document.getElementById('logContent').textContent = 'Logging error: ' + error.message;
});
</script>
</body>
</html>
將/local/aquarium/aquarium.html用iframe card嵌入lovelace裡