找回密码
 立即注册
查看: 234|回复: 4

[流程系列] 自动关闭电视

[复制链接]

4

主题

11

回帖

81

积分

注册会员

积分
81
金钱
66
HASS币
0
发表于 3 天前 | 显示全部楼层 |阅读模式
已实现的功能:电视机持续播放XX分钟后,强制关闭,并且必需等待XX分钟后,才能继续开启。

1、自定义电视机持续播放的时间(设置trigger节点对应的时间间隔)
2、自定义电视机休息的时间(设置trigger节点对应的时间间隔)
3、休息时间未达到,强制开机,5秒后强制关机(5秒可在第一个节点中自行设置,建议最短不要小于3秒)
4、未使用global变量,而是使用的flow变量,重新部署后会全部初始化(可自行改为global变量,即使重新部署也会持续状态。)

未实现的功能:未超过持续播放时间,中途关闭后,下次继续打开,不能继续上次的计时

流程图如下:
1288457f-95fb-4a16-85b2-9627e187a3a7.png

完整Json如下:
[
    {
        "id": "e72a13ae9e87116b",
        "type": "tab",
        "label": "Auto Check TV",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "f1bcc932a71348f3",
        "type": "server",
        "name": "Home Assistant",
        "version": 5,
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": true,
        "heartbeatInterval": 30,
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": ": ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "default",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": true
    },
    {
        "id": "4aaff77571386409",
        "type": "api-call-service",
        "z": "e72a13ae9e87116b",
        "name": "Turn off - TV",
        "server": "f1bcc932a71348f3",
        "version": 7,
        "debugenabled": false,
        "action": "media_player.turn_off",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "media_player.sony_xr_55x91j"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "blockInputOverrides": true,
        "domain": "media_player",
        "service": "turn_off",
        "x": 610,
        "y": 200,
        "wires": [
            []
        ]
    },
    {
        "id": "049a206b6a3aad13",
        "type": "function",
        "z": "e72a13ae9e87116b",
        "name": "Check",
        "func": "\nif( flow.get("isForceOff") === undefined){\n    flow.set("isForceOff",false);\n//    node.warn("检测: 强制关闭电视已经置为'否'");\n}\n\nif(flow.get("isForceOff")==false){\n    msg.payload = true;\n//    node.warn("检测: 允许开启电视");\n} else {\n    msg.payload = false;\n//    node.warn("检测: 不允许开启电视");\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 270,
        "y": 160,
        "wires": [
            [
                "e667612bfbc34390"
            ]
        ]
    },
    {
        "id": "e667612bfbc34390",
        "type": "switch",
        "z": "e72a13ae9e87116b",
        "name": "Payload",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "true"
            },
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 400,
        "y": 120,
        "wires": [
            [
                "90575e4f1dedc685"
            ],
            [
                "4aaff77571386409"
            ]
        ]
    },
    {
        "id": "d2d8cc09d4170b43",
        "type": "function",
        "z": "e72a13ae9e87116b",
        "name": "Reset",
        "func": "\nif(flow.get("isForceOff")){\n    flow.set("isForceOff",false);\n    node.warn("重置: 强制关闭电视已经置为'否'");\n}",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 910,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "33bae3b5f5f91286",
        "type": "function",
        "z": "e72a13ae9e87116b",
        "name": "Retest",
        "func": "if( flow.get("isForceOff") === undefined){\n    flow.set("isForceOff",true);\n}\n\nif(flow.get("isForceOff")==false){\n    msg.payload = true;\n//    node.warn("复验: 允许再次开启电视");\n} else {\n    msg.payload = false;\n//    node.warn("复验: 暂不允许开启电视,需再次等待20分钟");\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 270,
        "y": 240,
        "wires": [
            [
                "3c4b231196671ca1"
            ]
        ]
    },
    {
        "id": "15cab9ddbb157d92",
        "type": "function",
        "z": "e72a13ae9e87116b",
        "name": "Set",
        "func": "\nif(flow.get("isForceOff")==false){\n    flow.set("isForceOff",true);\n    msg.payload = false;\n    node.warn("设置: 强制关闭电视已经置为'是'");\n}\n\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 930,
        "y": 120,
        "wires": [
            [
                "1e80f6515b60622f"
            ]
        ]
    },
    {
        "id": "3c4b231196671ca1",
        "type": "switch",
        "z": "e72a13ae9e87116b",
        "name": "Payload",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 400,
        "y": 280,
        "wires": [
            [
                "3df548d33c309f45",
                "6d72c3758c3f7756"
            ]
        ]
    },
    {
        "id": "e804949e5d09f2dc",
        "type": "switch",
        "z": "e72a13ae9e87116b",
        "name": "Payload",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 760,
        "y": 280,
        "wires": [
            [
                "d2d8cc09d4170b43"
            ]
        ]
    },
    {
        "id": "1044ded30ce37fa3",
        "type": "switch",
        "z": "e72a13ae9e87116b",
        "name": "Payload",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "true"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 760,
        "y": 120,
        "wires": [
            [
                "15cab9ddbb157d92"
            ]
        ]
    },
    {
        "id": "6db3aa6920ddf0d0",
        "type": "poll-state",
        "z": "e72a13ae9e87116b",
        "name": "TV State",
        "server": "f1bcc932a71348f3",
        "version": 3,
        "exposeAsEntityConfig": "",
        "updateInterval": "5",
        "updateIntervalType": "num",
        "updateIntervalUnits": "seconds",
        "outputInitially": false,
        "outputOnChanged": false,
        "entityId": "media_player.sony_xr_55x91j",
        "stateType": "str",
        "ifState": "on",
        "ifStateType": "str",
        "ifStateOperator": "is",
        "outputs": 2,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "entity"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 80,
        "y": 120,
        "wires": [
            [
                "049a206b6a3aad13"
            ],
            [
                "33bae3b5f5f91286"
            ]
        ]
    },
    {
        "id": "1e80f6515b60622f",
        "type": "api-call-service",
        "z": "e72a13ae9e87116b",
        "name": "Turn off - TV",
        "server": "f1bcc932a71348f3",
        "version": 7,
        "debugenabled": false,
        "action": "media_player.turn_off",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "media_player.sony_xr_55x91j"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "blockInputOverrides": true,
        "domain": "media_player",
        "service": "turn_off",
        "x": 890,
        "y": 180,
        "wires": [
            []
        ]
    },
    {
        "id": "3df548d33c309f45",
        "type": "api-call-service",
        "z": "e72a13ae9e87116b",
        "name": "Turn off - TV",
        "server": "f1bcc932a71348f3",
        "version": 7,
        "debugenabled": false,
        "action": "media_player.turn_off",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "media_player.sony_xr_55x91j"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "blockInputOverrides": true,
        "domain": "media_player",
        "service": "turn_off",
        "x": 610,
        "y": 340,
        "wires": [
            []
        ]
    },
    {
        "id": "90575e4f1dedc685",
        "type": "trigger",
        "z": "e72a13ae9e87116b",
        "name": "Wait 45 Min",
        "op1": "",
        "op2": "",
        "op1type": "nul",
        "op2type": "payl",
        "duration": "45",
        "extend": false,
        "overrideDelay": false,
        "units": "min",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 590,
        "y": 120,
        "wires": [
            [
                "1044ded30ce37fa3"
            ]
        ]
    },
    {
        "id": "6d72c3758c3f7756",
        "type": "trigger",
        "z": "e72a13ae9e87116b",
        "name": "Wait 20 Min",
        "op1": "",
        "op2": "",
        "op1type": "nul",
        "op2type": "payl",
        "duration": "20",
        "extend": false,
        "overrideDelay": false,
        "units": "min",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 590,
        "y": 280,
        "wires": [
            [
                "e804949e5d09f2dc"
            ]
        ]
    }
]
希望有大神能帮忙完善,感谢。











回复

使用道具 举报

3

主题

103

回帖

718

积分

高级会员

积分
718
金钱
612
HASS币
0
发表于 3 天前 | 显示全部楼层
本帖最后由 home_assistant 于 2025-5-28 16:52 编辑

我写一个Demo应该符合你的逻辑,请参考。

[{"id":"1a2b3c4d5e6f7g8h","type":"tab","label":"倒计时测试模板","disabled":false,"info":""},{"id":"manual_off","type":"inject","z":"1a2b3c4d5e6f7g8h","name":"手动关机","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":120,"y":80,"wires":[["manual_off_func"]]},{"id":"manual_off_func","type":"function","z":"1a2b3c4d5e6f7g8h","name":"手动关机保存剩余时间","func":"// 当前时间\nconst now = Date.now();\n// 获取倒计时结束时间\nconst endTime = flow.get('countdownEndTime') || 0;\n\nif(endTime > now){\n    const remaining = endTime - now;\n    flow.set('countdownRemaining', remaining);\n    node.status({fill:'yellow',shape:'ring',text:`手动关机,剩余 ${remaining/1000}s`});\n    node.warn(`手动关机,保存剩余时间 ${remaining} 毫秒`);\n}else{\n    flow.set('countdownRemaining', 0);\n    node.status({fill:'grey',shape:'dot',text:'无剩余时间'});\n}\nflow.set('countdownEndTime', 0);\nreturn null;","outputs":0,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":80,"wires":[]},{"id":"tv_on","type":"inject","z":"1a2b3c4d5e6f7g8h","name":"电视开机","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":120,"y":140,"wires":[["tv_on_func"]]},{"id":"tv_on_func","type":"function","z":"1a2b3c4d5e6f7g8h","name":"开机恢复倒计时","func":"const now = Date.now();\nlet remaining = flow.get('countdownRemaining') || 0;\nif(remaining > 0){\n    flow.set('countdownEndTime', now + remaining);\n    flow.set('countdownRemaining', 0);\n    node.status({fill:'green',shape:'dot',text:`开机,继续倒计时剩余 ${(remaining/1000).toFixed(1)}s`});\n    node.warn(`开机,继续倒计时剩余 ${remaining} 毫秒`);\n}else{\n    const defaultTime = 60 * 1000;\n    flow.set('countdownEndTime', now + defaultTime);\n    node.warn('开机,启动60秒新倒计时');\n}\nreturn null;","outputs":0,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":140,"wires":[]},{"id":"countdown_check_inject","type":"inject","z":"1a2b3c4d5e6f7g8h","name":"定时检测(1秒)","props":[],"repeat":"1","crontab":"","once":true,"onceDelay":"1","topic":"","x":130,"y":200,"wires":[["countdown_check_func"]]},{"id":"countdown_check_func","type":"function","z":"1a2b3c4d5e6f7g8h","name":"倒计时检测","func":"const now = Date.now();\nconst endTime = flow.get('countdownEndTime') || 0;\n\nif(endTime !== 0 && now >= endTime){\n    flow.set('countdownEndTime', 0);\n    flow.set('countdownRemaining', 0);\n    node.status({fill:'red',shape:'dot',text:'倒计时结束,自动关机'});\n    node.warn('倒计时结束,自动关闭电视');\n    return {payload: '自动关机'};\n}else if(endTime !== 0){\n    const left = ((endTime - now)/1000).toFixed(1);\n    node.status({fill:'blue',shape:'dot',text:`倒计时剩余 ${left}s`});\n    return {payload: `倒计时剩余 ${left} 秒`};\n}\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":200,"wires":[["0decc9c6affb810c"]]},{"id":"0decc9c6affb810c","type":"debug","z":"1a2b3c4d5e6f7g8h","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":540,"y":200,"wires":[]}]
Test.png
回复

使用道具 举报

3

主题

103

回帖

718

积分

高级会员

积分
718
金钱
612
HASS币
0
发表于 3 天前 | 显示全部楼层
本帖最后由 home_assistant 于 2025-5-28 16:55 编辑

卡了!!!只保留上一帖子。
回复

使用道具 举报

0

主题

159

回帖

1467

积分

金牌会员

积分
1467
金钱
1308
HASS币
0
发表于 3 天前 | 显示全部楼层
感谢,正好需要限制下
回复

使用道具 举报

14

主题

193

回帖

1438

积分

论坛技术达人

积分
1438
金钱
1231
HASS币
0
发表于 3 天前 | 显示全部楼层
哈哈哈 这要是我小时候 我就一直按开机
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )

GMT+8, 2025-5-31 08:19 , Processed in 0.120655 second(s), 24 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表