『分享』透過input_datetime 在NR中建立定時服務

很多人應該都有想要定時的功能但如果重開HA自動化可能會失效
個人之前都是用Script去弄但也很少在用定時功能
稍微研究了一下決定用input_datetime來做定時的設定

前置作業

  1. 建立input_datetime實體
input_datetime:
  timer_start_time:
    name: 冷氣定時紀錄
    has_date: true
    has_time: true

看你要設在哪邊config 還是packages都可以
我這邊主要是弄在冷氣的判斷所以我名稱用冷氣定時紀錄
隨你的使用自行更改

  1. 使用助手建立對應的定時按鈕

    以我自己來說我建立的是 定時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使用


前置作業

  1. 使用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 模式


1個讚