Hi Luigi,indeed you can use HomeyScript,
some examples:
// Update the variable, basic
oResult = await Homey.logic.updateVariable({
id: sID,
variable: { value: typedValue }
});
allVars = await Homey.logic.getVariables(); // all variables
iterate over allVars by VarID and update all vars by ID with updateVariable with typed(!) values.
an extended example to set and get variables and tags
/*
* ATTENTION ::::: start with bUpdateTags = false :::::
* -!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
* HomeyScript to save variables to tags and get values from tags
*
* Current date: 2025-09-13
*
* Author: Ruurd van der Noord
* Contributions: Help from Perplexity AI
*/
// Begin Arguments
// Default values if args[0] is not a string
const input = typeof args[0] === 'string' ? args[0] : 'bUpdateTags=false;bCheckTags=false;bDeleteTags=false';
// Parse the input and initialize FLAGS
const oFlags = Object.fromEntries(
input.split(';').map(arg => arg.split('=').map((bValue, iNum) => iNum === 1 ? isBool(bValue) : bValue))
);
// Assign final values as Constants
const bUpdateTags = oFlags['bUpdateTags'] || false;
const bDeleteTags = oFlags['bDeleteTags'] || false;
const bCheckTags = oFlags['bCheckTags'] || false;
// Determine action based on flags
if (bCheckTags) {
console.log("Checking tags...\n\n");
// Code to check tags
} else if (bUpdateTags) {
console.log("Updating tags...\n\n");
// Code to update tags
} else if (bDeleteTags) {
console.log("Deleting tags...\n\n");
// Code to delete tags
bUpdate = false; // Set bUpdate to false only when deleting
} else {
console.log("No TAG action specified...\n\n");
}
// End Arguments
let aError = []; // array to push ERRORS in
const oVarHomeyAll = Object.values(await Homey.logic.getVariables());
const iVarHomeyAllLen = Object.keys(oVarHomeyAll).length;
// Filter out CONSTS (with a second character is an underscore)
const aValidConsts = filterVariables(oVarHomeyAll, true);
const iValidConstsLen = aValidConsts.length;
// Filter out variables not a CONST (without a second character is an underscore)
const aValidVars = filterVariables(oVarHomeyAll, false);
const iValidVarsLen = aValidVars.length;
const s_NotFound = "!!!!!!"; // Placeholder for not found variables and values
const var_known =
[ // all Homey Variables
{ name: `Some name`, id: 'ID', type: `boolean`, _class: `Proprietary class`, _value: 'Some proprietary value', value: 'the TYPED value' }, // FLAG:b=OK:boolean
] // end var_known (201)
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
// END INITIATE
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
// BEGIN FUNCTIONS
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
function isBool(sValue) {
if (typeof sValue !== 'string') {
// Not a string or boolean - convert to string or handle error
sValue = String(sValue);
}
const sNormalized = sValue.trim().toLowerCase();
const aTruthyValues = ['true', 'yes', 'on', '1', '✓', '✔'];
const aFalsyValues = ['false', 'no', 'off', '0', '✗', '✘'];
if (aTruthyValues.includes(sNormalized)) return true;
if (aFalsyValues.includes(sNormalized)) return false;
// Unknown value: notify and treat as false for safety
sendPush("ZonneschermA-NEER3 SCRIPT ERROR 1");
return false;
}
// Function to filter variables based on whether they are Constants
function filterVariables(oVarHomeyAll, isConst) {
return Object.values(oVarHomeyAll).filter(oVar =>
oVar && typeof oVar === 'object' && 'name' in oVar && 'value' in oVar &&
(isConst ? oVar.name[1] === '_' : oVar.name[1] !== '_')
);
}
// Function to check Hungarian notation compliance
function checkHungarianNotation(oVariable) {
const cFirstChar = oVariable.name.charAt(0);
const sExpectedPrefix = (oVariable.type === 'number') ? 'i' :
(oVariable.type === 'string') ? 's' : 'b';
return cFirstChar === sExpectedPrefix;
}
async function getValidArray() {
try {
const validVariables1 = [];
if (oVarHomeyAll && typeof oVarHomeyAll === 'object') {
for (const key in oVarHomeyAll) {
const oVar = oVarHomeyAll[key];
if (oVar && typeof oVar === 'object' && 'name' in oVar && 'value' in oVar) {
validVariables1.push({ name: oVar.name, value: oVar.value, id: oVar.id });
} else {
aError.push(`Invalid variable structure at key ${key}: ${oVar}`);
console.error(`Invalid variable structure at key ${key}:`, oVar); // , oVar
}
}
} else {
aError.push("Error: oVarHomeyAll is not a valid object.");
console.error("Error: oVarHomeyAll is not a valid object.");
}
return validVariables1;
} catch (oError) {
aError.push(`An error occurred while fetching variables: ${oError}`);
console.error("An error occurred while fetching variables:", oError);
}
}
// Function to get variable value by name
function getVarValueByName(sName, oVariables) {
const oVariable = Object.values(oVariables).find(({ name }) => name === sName);
if (!oVariable) {
log('add: ' + sName);
aError.push(`Variable with name "${sName}" not found.`);
throw new Error(`Variable with name "${sName}" not found.`);
}
return oVariable.value;
}
// Helper function to format values based on their type
function formatValue(uValue) {
if (typeof uValue === 'number' || typeof uValue === 'boolean') {
return uValue;
} else if (typeof uValue === 'string') {
return uValue.length <= 20 ? `\`${uValue}\`` : '`>20`';
}
return '';
}
// Initialize output variable for logging
let sOutput = '\nconst aConstNames = // *CONST NAMES*\n[\n'; // in global scope ... Begin *CONST NAMES*
async function setAndGetTags(allConstants) {
const iTotalConstants = allConstants.length; // Total number of oConstants
let currentIndex = 0; // Index for tracking the current oConstant
allConstants.sort((a, b) => a.name.localeCompare(b.name)); // Sort oConstants alphabetically by name
try {
log(`let allCONST =\n[`); // Log the start of the oConstant list
// Iterate through each oConstant in the provided array
for (const oConstant of allConstants) {
currentIndex++; // Increment the index for each variable
// Validate oConstant properties
if (!oConstant || !oConstant.name || !oConstant.id || !oConstant.type) {
aError.push(`Invalid variable at index ${currentIndex}: ${oConstant}`);
console.error(`Invalid variable at index ${currentIndex}:`, oConstant); // Log error for invalid variable
continue; // Skip this iteration if the variable is invalid
}
// Set or delete tags based on the flags
if (bUpdateTags) {
await global.set(oConstant.name, oConstant.value); // Set the tag value
} else if (bDeleteTags) {
await global.set(oConstant.name, null); // Delete the tag value
}
const oKnownVariable = var_known.find(({ name }) => name === oConstant.name);
// log(`NAME... ${oKnownVariable.name}`);
//const oNewVar = oVarHomeyAll.find({ name: oConstant.name });
// Check if oKnownVariable is found in known variables
if (!oKnownVariable) {
aError.push(`No known variable found for: ${oConstant.name} - ${oConstant.id}`);
// console.error(`No known variable found for: ${oConstant.name}`); // Log error for unknown variable
}
// Check Hungarian notation validity for the current variable
const isValidNotation = checkHungarianNotation(oConstant);
const sFlagComment = `// FLAG:${oConstant.name.charAt(0)}=${isValidNotation ? 'OK' : 'NOT OK'}:${oConstant.type}`;
const sClassName = oKnownVariable ? oKnownVariable._class : s_NotFound;
const sObjectValue = oKnownVariable ? oKnownVariable.value : s_NotFound;
console.log(`{ name: \`${oConstant.name}\`, id: '${oConstant.id}', type: \`${oConstant.type}\`, _class: \`${sClassName}\`, _value: ${formatValue(sObjectValue)}, value: ${formatValue(oConstant.value)} }${(currentIndex === iTotalConstants) ? '' : ','} ${sFlagComment}\n`);
// Update output string for oConstants (adding *CONST NAMES*)
sOutput += `\`${oConstant.name}\`${(currentIndex === iTotalConstants) ? '' : ', '}`;
// Retrieve the tag value if checking tags is enabled
if (bCheckTags) {
const tagValue = await global.get(oConstant.name); // Get TAG value from global context
const expectedValue = getVarValueByName(oConstant.name, aValidConsts); // Get expected Value
if (typeof tagValue === 'undefined') {
console.log(`\t*** Tag: ${oConstant.name}, Value: undefined **`); // Log undefined tag values
} else if (expectedValue !== tagValue) {
aError.push(`ERROR: ${expectedValue} != ${tagValue} (${oConstant.name})\n`);
log(`ERROR: ${expectedValue} != ${tagValue} (${oConstant.name})\n`);
// Log discrepancies between expected and actual tag values
}
console.log(`${bUpdateTags ? '' : `\t`}\t** GET Tag: ${oConstant.name}, Value: ${tagValue} **`);
}
} // End of for loop
log(`]// end allCONST (${iTotalConstants})\n\n`); // Log end of oConstant list
} catch (oError) {
aError.push(`ERROR in setAndGetTags(): ${oError}`);
console.error(`ERROR in setAndGetTags():`, oError); // Log any errors that occur during execution
}
}
// Initialize output variable names for logging
let sVarNames = ''; // *VARALL NAMES* in global scope
async function allVariables() {
const validVariables = await getValidArray();
sVarNames = `const aVarNames = // *VARALL NAMES*\n[\n`;
validVariables.sort((a, b) => a.name.localeCompare(b.name));
let currentIndex = 0;
sOutput += `\n] // end aConstNames\n\nconst var_known =\n[ // all Homey Variables\n`; // END *CONST NAMES* ;;;;;;;;;; BEGIN var_known
try {
for (const variable of validVariables) {
currentIndex++;
const oKnownVariable = var_known.find(({ name }) => name === variable.name);
const sObjectValue = oKnownVariable ? oKnownVariable.value : s_NotFound;
const sClassName = oKnownVariable ? oKnownVariable._class : s_NotFound;
const isValidNotation = checkHungarianNotation(variable);
const sFlagComment = `// FLAG:${oKnownVariable ? oKnownVariable.name.charAt(0) : ''}=${isValidNotation ? 'OK' : 'NOT OK'}:${oKnownVariable ? oKnownVariable.type : ''}`;
sOutput += (`{ name: \`${variable.name}\`, id: '${variable.id}', type: \`${oKnownVariable?.type || ''}\`, _class: \`${sClassName}\`, _value: ${formatValue(sObjectValue)}, value: ${formatValue(variable.value)} }${(currentIndex === validVariables.length) ? '' : ', '} ${sFlagComment}\n`);
// Update output string for Constants (adding *VARALL NAMES*)
sVarNames += `${variable.name}\`${(currentIndex === validVariables.length) ? '' : ', '}`;
}
sVarNames += `\n] // end aVarNames\n`; // END *VARALL NAMES*
sOutput += `] // end var_known (${currentIndex})`;
return `${sOutput}\n`;
} catch (error) {
aError.push(`ERROR - allVariables: ${error}`);
console.error(`ERROR - allVariables: ${error}\n`);
}
}
await Homey.logic.updateVariable({
id: `e4036857-790c-4bbc-825f-301568f41505`, // s_ERROR
variable: {
value: `⍉`
}
});
log(`// Check variable s_ERROR
//-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!-!
`);
// Call the functions
await setAndGetTags(aValidConsts);
await allVariables();
log(sVarNames);
log(sOutput); // FROM aConstNames & adding *CONST NAMES* TO var_known
if (aError.length > 0)
await Homey.logic.updateVariable({
id: `e4036857-790c-4bbc-825f-301568f41505`, // s_ERROR
variable: {
value: aError.join('||')
}
});
return (iVarHomeyAllLen === iValidVarsLen + iValidConstsLen) && aError.length === 0;