很多人應該都有想要定時的功能但如果重開HA自動化可能會失效
個人之前都是用Script去弄但也很少在用定時功能
稍微研究了一下決定用input_datetime來做定時的設定
前置作業
- 建立input_datetime實體
input_datetime:
timer_start_time:
name: 冷氣定時紀錄
has_date: true
has_time: true
看你要設在哪邊config 還是packages都可以
我這邊主要是弄在冷氣的判斷所以我名稱用冷氣定時紀錄
隨你的使用自行更改
- 使用助手建立對應的定時按鈕
以我自己來說我建立的是 定時4 3 2 1小時 45 30 15分鐘 7個按鈕
當然名稱也可以依照你自己的定時目標去修改
開始設定
整體流程大致上如上圖
最上面一行流程說明
events state現在可以把一堆實體都加進來 就不用在畫面上一堆的events state了
把剛剛創建的按鈕都加進來就好
Function 設定計時結束時間
// 取得當前時間
const now = new Date();
// 根據 msg.topic 判斷需要增加的時間
let addHours = 0; // 預設增加的時間(小時)
let addMinutes = 0; // 預設增加的時間(分鐘)
switch (msg.topic) {
// 設定增加小時的量
case "input_button.leng_qi_ding_shi_1xiao_shi":
addHours = 1;
break;
case "input_button.leng_qi_ding_shi_2xiao_shi":
addHours = 2;
break;
case "input_button.leng_qi_ding_shi_3xiao_shi":
addHours = 3;
break;
case "input_button.leng_qi_ding_shi_4xiao_shi":
addHours = 4;
break;
//設定增加分鐘的量
case "input_button.leng_qi_ding_shi_15fen_zhong":
addMinutes = 15;
break;
case "input_button.leng_qi_ding_shi_30fen_zhong":
addMinutes = 30;
break;
case "input_button.leng_qi_ding_shi_45fen_zhong":
addMinutes = 45;
break;
default:
node.error("未識別的按鈕");
return null;
}
// 增加時間
now.setHours(now.getHours() + addHours);
now.setMinutes(now.getMinutes() + addMinutes);
// 格式化日期和時間為 YYYY-MM-DD 和 HH:MM:SS 格式
const pad = (num, len = 2) => num.toString().padStart(len, '0');
const formattedDate = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
const formattedTime = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
// 輸出的日期與時間
msg.payload = {
date: formattedDate, // 格式為 YYYY-MM-DD
time: formattedTime // 格式為 HH:MM:SS
};
return msg;
依照你自己的實體ID替換掉
case “input_button.leng_qi_ding_shi_1xiao_shi”:
addHours = 1;
break;
以冷氣定時1小時來說明
當前面enents state進來的msg.topic是 input_button.leng_qi_ding_shi_1xiao_shi (冷氣定時1小時)
則增加小時=1
如果你有很多依照你自己的設定去修改變量
最後設定定時結束時間
target就用剛剛創的input_datetime
最後面就接你要開啟什麼設備
第二行流程說明
使用inject 設定每隔多久啟動一次流程
要多久時間比對一次資料自己斟酌設定
Function 時間比對符合後停止流程
// 檢查流程是否已經執行過
const isExecuted = flow.get('timerExecuted') || false;
if (isExecuted) {
// 如果已經執行過,則返回不處理
return null;
}
// 取得 Home Assistant 狀態
const ha = global.get('homeassistant').homeAssistant;
const timerStartTime = ha.states["input_datetime.timer_start_time"].state;
// 檢查是否獲取到 timer_start_time 的值
if (!timerStartTime) {
node.error("未取得 timer_start_time 的值");
return null;
}
// 取得當前時間
const now = new Date();
// 解析 input_datetime 時間(假設時間格式為 YYYY-MM-DD HH:MM:SS)
const [date, time] = timerStartTime.split(" "); // 日期與時間分開
const timerDate = new Date(date + 'T' + time); // 將日期與時間轉換為 Date 物件
// 比較時間
if (timerDate < now) {
msg.payload = true; // 如果 timer_start_time 小於現在時間,輸出 true
flow.set('timerExecuted', true); // 設定流程已執行過
} else {
msg.payload = false; // 否則輸出 false
}
return msg;
const timerStartTime = ha.states[“input_datetime.timer_start_time”].state;
這行裡面的實體請改成你自己的
整體流程是
每隔多久(依照前一個inject設定)檢查input_datetime設定的時間跟目前時間
當目前時間小於input_datetime的時間後就往後丟一個false
而當目前時間大於 input_datetime的時間就往後丟一個true
並將timerExecuted 設為true
當timerExecuted為true 就不會比對時間直接停止該流程
Switch 直接判斷前面進來的是true 還是 false 如果為真就往後去執行關閉設備動作
第三行
當input_datetime資料變更時開啟流程
Function 重新啟動流程
// 重置流程執行狀態
flow.set('timerExecuted', false);
// 記錄日誌(可選)
node.status({ fill: "green", shape: "dot", text: "Reset isExecuted to false" });
return msg; // 確保訊息傳遞到後續節點(如果需要)
用途是當input_datetime變更後將timerExecuted 設為 false
並寫入第二行的function內重新啟動第二行的流程
整理設定流程大概是這樣
下面是將定時功能弄成media_player傳到HK使用
前置作業
- 使用SmartIR設定media_player
先前往 /homeassistant/custom_components/smartir/codes/media_player/
隨便找一個沒有的json編號建立一個json
以我這邊來說用的是1175.json
{
"manufacturer": "Logitech",
"supportedModels": [
"AC Timer"
],
"supportedController": "Broadlink",
"commandsEncoding": "Base64",
"commands": {
"sources": {
"無": "",
"1小時": "",
"2小時": "",
"3小時": "",
"4小時": "",
"15分鐘": "",
"30分鐘": "",
"45分鐘": ""
}
}
}
只要修改sources底下的內容就好
依照你自己的定時數量修改就可以
設定Media_player
smartir:
media_player:
- platform: smartir
name: 房間冷氣定時Source
unique_id: room_ac_timer
device_code: 1175
controller_data: remote.rm4c_pro
power_sensor: switch.maccha_zuo
name修改成你自己想要的
unique_id: 照你自己的需求修改如果要弄第二個千萬不要重複
device_code 看你剛剛弄的文件編號是多少
controller_data 改成你的黑豆id 實際上用不到
power_sensor 隨便找個不會關掉的開關就好
設定完後重開HA讓設定生效
新增一個source sensor
sensor:
- platform: template
sensors:
ac_timer_source:
friendly_name: "房間冷氣定時狀態"
value_template: "{{ state_attr('media_player.fang_jian_leng_qi_ding_shi_source', 'source') }}"
value_template 裡面的實體用剛剛新增的media_player id
設定好檢查沒問題就可以重開HA讓設定生效
NR 設定
整理流程如上圖所示
events state 使用剛剛建的sensor
Function 檢查來源定義執行實體
// 獲取 sensor.ac_timer_source 的值
const acTimerSource = msg.payload;
// 根據值判斷對應的 entity_id
let entityId = "";
switch (acTimerSource) {
case "1小時":
entityId = "input_button.leng_qi_ding_shi_1xiao_shi";
break;
case "2小時":
entityId = "input_button.leng_qi_ding_shi_2xiao_shi";
break;
case "3小時":
entityId = "input_button.leng_qi_ding_shi_3xiao_shi";
break;
case "4小時":
entityId = "input_button.leng_qi_ding_shi_4xiao_shi";
break;
case "15分鐘":
entityId = "input_button.leng_qi_ding_shi_15fen_zhong";
break;
case "30分鐘":
entityId = "input_button.leng_qi_ding_shi_30fen_zhong";
break;
case "45分鐘":
entityId = "input_button.leng_qi_ding_shi_45fen_zhong";
break;
default:
node.error("無法識別的 AC Timer Source: " + acTimerSource);
return null; // 無法識別的值時停止流程
}
// 建立正確格式的 payload
msg.payload = {
entity_id: entityId // 指定目標實體 ID
};
return msg;
這個函數主要的用途是
檢查前一個events state進來的source資料
去設定對應的entity_id
entity_id 還有 source請針對你的media_player 裡面的sources 內容去填寫
實體id 請用一開始創的定時按鈕
action 內容
這邊的action target請不要設定東西 會自動帶入前面的資料來決定要用什麼實體
以上為全部的設定流程
有問題在群內問我
至於建出來的media_player請自己到HomeKit Bridge去新增
HomeKit模式需要使用accessory 模式