Here's my ver. 0.02 code, adding some buttons to the UI to execute without leaving the page, or exit without execution. I also added code to prevent a rule being acted upon in both the TRUE and FALSE sections (duplicate rules get set to TRUE).
Some code lines have been commented out where I was trying to create a "Select All" control, but I have not been able to get it to work yet (ChatGPT has not been able to suggest a fix yet either).
import hubitat.helper.RMUtils
import groovy.transform.Field
@Field static final String vRM_Version = "5.0"
definition(
name: "Rule Machine Private Boolean Manager v. 0.02",
namespace: "Groovy Example",
author: "John Land, with an assist from ChatGPT",
description: "Set Private Boolean for selected Rule Machine rules",
category: "Convenience",
iconUrl: "",
iconX2Url: "",
singleInstance: true
)
preferences {
page(name: "mainPage")
}
def mainPage() {
dynamicPage(name: "mainPage", title: "", install: true, uninstall: true) {
def vRuleList = RMUtils.getRuleList(vRM_Version)
def vAllRuleIDs = vRuleList*.key
if (!vRuleList) {
section("No Rules Found") {
paragraph "No Rule Machine 5.0 rules were found."
}
return
}
// ===== PB TRUE Section =====
section("") {
// input(name: "vSelectAllTrue", type: "bool", title: "Select All for PB TRUE?", defaultValue: false, submitOnChange: true)
//
// // Auto-select/deselect only on change
// if (settings.vSelectAllTrue && (!settings.vTruePB_Rules || settings.vTruePB_Rules.size() != vAllRuleIDs.size())) {
// app.updateSetting("vTruePB_Rules", [type: "enum", value: vAllRuleIDs])
// } else if (!settings.vSelectAllTrue && settings.vTruePB_Rules?.size()) {
// app.updateSetting("vTruePB_Rules", [type: "enum", value: []])
// }
input(name: "vTruePB_Rules", type: "enum", title: "Set PB to TRUE for these Rules", multiple: true, required: false, options: vRuleList)
}
// ===== PB FALSE Section =====
section("") {
// input(name: "vSelectAllFalse", type: "bool", title: "Select All for PB FALSE?", defaultValue: false, submitOnChange: true)
//
// if (settings.vSelectAllFalse && (!settings.vFalsePB_Rules || settings.vFalsePB_Rules.size() != vAllRuleIDs.size())) {
// app.updateSetting("vFalsePB_Rules", [type: "enum", value: vAllRuleIDs])
// } else if (!settings.vSelectAllFalse && settings.vFalsePB_Rules?.size()) {
// app.updateSetting("vFalsePB_Rules", [type: "enum", value: []])
// }
input(name: "vFalsePB_Rules", type: "enum", title: "Set PB to FALSE for these Rules", multiple: true, required: false, options: vRuleList)
}
section("") {
input(name: "vEnableInfoLogging", type: "bool", title: "Enable information logging?", defaultValue: true)
}
section("") {
input(name: "vEnableDebugLogging", type: "bool", title: "Enable debug logging?", defaultValue: false)
}
section("") {
input(name: "vRunNow", type: "button", title: "Set Private Booleans Now")
}
section("") {
input(name: "vExitNow", type: "button", title: "Exit without doing anything")
}
if (state.vExitPressed) {
section("") {
state.clear()
paragraph "Exit button was pressed, so actions were taken. Press DONE to exit page."
}
}
}
}
def installed() {
logDebug "App installed with settings: ${settings}"
initialize()
}
def updated() {
logDebug "App updated with settings: ${settings}"
unsubscribe()
initialize()
}
def logInfo(msg) {
if (settings.vEnableInfoLogging) {
log.info msg
}
}
def logDebug(msg) {
if (settings.vEnableDebugLogging) {
log.debug msg
}
}
def initialize() {
// Set Private Booleans
appButtonHandler()
setPrivateBooleans()
}
def appButtonHandler(btn) {
switch (btn) {
case "vRunNow":
setPrivateBooleans()
break
case "vExitNow":
logInfo "User exited without action."
// Optional cleanup
state.clear()
state.vExitPressed = true
return // Exit early; don’t render the rest of the page
break
}
}
def setPrivateBooleans() {
log.info "Now setting Private Booleans for selected Rules ..."
// If a Rule is selected to be set TRUE, remove that Rule from the list of Rules to be set FALSE
def vTruePB_RulesList = vTruePB_Rules ?: []
def vFalsePB_RulesList = vFalsePB_Rules?.findAll { !(it in vTruePB_Rules) } ?: []
// Set PB TRUE for 1st set of selected rules
vTruePB_RulesList?.each { vRuleID ->
logInfo "Setting Private Boolean to TRUE for rule: ${vRuleID}"
RMUtils.sendAction([vRuleID], "setRuleBooleanTrue", app.label, vRM_Version)
}
// Set PB FALSE for 2nd set of selected rules
vFalsePB_RulesList?.each { vRuleID ->
logInfo "Setting Private Boolean to FALSE for rule: ${vRuleID}"
RMUtils.sendAction([vRuleID], "setRuleBooleanFalse", app.label, vRM_Version)
}
log.info "Setting Private Booleans for selected Rules completed"
}