[APP][Pro] AWTRIX Light - Connected Smart Clock for your Smart Home

I could not stand it that icons where not shown so I erased the device with the flasher. After that I installed the device again in Homey. Now icons are shown, so I guess something was messed up using the clock before with Home Assistant. Running latest test version by the way

Added some json to the action-card:

{"effect":"Plasma",
  "effectSettings":{
    "speed":3,
    "palette":"Rainbow",
    "blend":true
  }
}

Unfortunate this does not work. Is this because I did something wrong??

Use straight quotes, not the curly ones.

My example of an overlay:
Ulanzi

1 Like

App card does not work with this, i will look on it, and create new action card, where you can send whatever you want via JSON

1 Like

:+1:

Hi, my Awtrix is not showing de mqqt messages anymore since some time :frowning: anyone any tips? Installed it long time ago and cant even remember how i did it :smiley:


They are all not working anymore :frowning:

Trying to remove a custom app from Ulanzi with the following card is not successfull (app has not been deleted):
Ulanzi1.

The job will be done using this command:
Ulanzi2

Why can it not be done using the Awtrix app card?

Command used to create the app:
Ulanzi3

Becouse Homey prefix its app names… so it can delete only apps, it created…

If you create app via Flow, app name actually is: “homey:${name}” not the “${name}” itself… as Awtrix allow anyone with API access to send commands, i want to prevent over-writing apps from different sources. Im currently working on implementing autocomplete for apps name (homey ones only) and custom payload for adding more options to app (almost every option from API will be available)

1 Like

Awtrix after some update changed name and some stuff inside, i would recomend verify if it is still listening on that mqtt or have different mqtt setup (its name changed from awtrix_light to awtrix3).

Can be problem, but not sure, i do not use MQTT

1 Like

Can you please provider an example of using the RTTTL?

What am I doing wrong ?

EDIT: Not sure if this is the cause. I have noticed that on AWTRIX menus on the device. It says volume is N/A . The phone app says the volume is 24.

Is there some direct way to set overlay, without sending POST ?

nevermind
POST

Any tip, if you would like to get 2nd AWtrix displaying same info like the 1st one, except of manual adjustments of all flows ? :wink:

Thanks for idea @Bckp to re-use script [HOW-TO][Pro][Cloud] - Tool to FIX (advanced) flows after removing and re-adding devices and thanks @martijnpoppen for your support, I was able to modify it to do the replacement only in Flows with defined FlowID… let me share it in case someone would have similar challenge…

// It's recommended to only use 1 id at a time. This will also fix your variables.
const oldIds = ['oldId of device'];
const newIds = ['newId of device'];
const specificFlowIds = ['flow-id-1', 'flow-id-2', 'flow-id-3']; // Add the specific flow IDs here

// Set the softRun variable to true or false to determine whether changes should be logged or actually executed
const softRun = true; // true | false

// Open the console in your browser and the result will be shown there
// Howto open console: https://balsamiq.com/support/faqs/browserconsole/

const main = async function () {
    console.log('Starting main function...');

    // Retrieve all of the existing flows
    const flows = await Homey.flow.getFlows();

    // Iterate through each flow
    Object.values(flows).forEach(async (f) => {
        console.log(`Flow "${f.name}" with ID "${f.id}" is being checked.`);
        if (!specificFlowIds.includes(f.id)) {

            return;
        }

        console.log(`Checking flow "${f.name}"...`);

        // If the flow has a trigger with a URI or ID
        if (f.trigger && (f.trigger.uri || f.trigger.id)) {
            const trigger = f.trigger;

            let replaceValue = '';
            let cardsChanged = false;

            if (oldIds.length === 1) {
                replaceValue = oldIds[0];
            } else if (trigger.uri && trigger.uri.includes('homey:device:')) {
                replaceValue = trigger.uri.replace('homey:device:', '');
            } else if (trigger.id && trigger.id.includes('homey:device:')) {
                replaceValue = trigger.id.replace('homey:device:', '');
            }

            if (replaceValue.includes('|')) {
                replaceValue = replaceValue.split('|')[0];
            } else if (replaceValue.includes(':')) {
                replaceValue = replaceValue.split(':')[0];
            }

            console.log(`Checking IDs in flow "${f.name}": Replace value found - ${replaceValue}`);

            // If the flow contains the old device ID
            if (oldIds.includes(replaceValue)) {
                const replacer = new RegExp(replaceValue, 'g');
                const index = oldIds.findIndex((o) => o.includes(replaceValue));

                // Replace the old device ID with the corresponding new device ID in the trigger
                if (trigger.uri) {
                    const oldToken = trigger.uri;
                    trigger.uri = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== trigger.uri) {
                        console.log(`URI change detected. Old: ${oldToken}, New: ${trigger.uri}`);
                        cardsChanged = true;
                    }
                } else if (trigger.id) {
                    const oldToken = trigger.id;
                    trigger.id = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== trigger.id) {
                        console.log(`ID change detected. Old: ${oldToken}, New: ${trigger.id}`);
                        cardsChanged = true;
                    }
                }

                if (trigger.droptoken) {
                    const oldToken = trigger.droptoken;
                    trigger.droptoken = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== trigger.droptoken) {
                        console.log(`Droptoken change detected. Old: ${oldToken}, New: ${trigger.droptoken}`);
                        cardsChanged = true;
                    }
                }

                if (cardsChanged) {
                    console.log(`Preparing to update flow "${f.name}"...`);
                    if (!softRun) {
                        try {
                            const response = await Homey.flow.updateFlow({
                                id: f.id,
                                flow: { id: f.id, trigger: trigger }
                            });
                            console.log(`Update response: ${JSON.stringify(response)}`);
                        } catch (error) {
                            console.error(`Error updating flow "${f.name}":`, error);
                        }
                    } else {
                        console.log(`Would update flow "${f.name}" with new trigger:`, {
                            id: f.id,
                            flow: { id: f.id, trigger: trigger }
                        });
                    }
                }
            }
        }

        console.log(`Checking actions in flow "${f.name}"`);
        // Iterate through each action in the flow
        f.actions.forEach(async (a, i) => {
            let replaceValue = '';
            let cardsChanged = false;

            if (oldIds.length === 1) {
                replaceValue = oldIds[0];
            } else if (a.uri && a.uri.includes('homey:device:')) {
                replaceValue = a.uri.replace('homey:device:', '');
            } else if (a.id && a.id.includes('homey:device:')) {
                replaceValue = a.id.replace('homey:device:', '');
            }

            if (replaceValue.includes('|')) {
                replaceValue = replaceValue.split('|')[0];
            } else if (replaceValue.includes(':')) {
                replaceValue = replaceValue.split(':')[0];
            }

            if (oldIds.includes(replaceValue)) {
                const replacer = new RegExp(replaceValue, 'g');
                const actions = f.actions;
                const index = oldIds.findIndex((o) => o.includes(replaceValue));

                if (actions[i].uri) {
                    const oldToken = actions[i].uri;
                    actions[i].uri = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== actions[i].uri) {
                        console.log(`URI change detected in action. Old: ${oldToken}, New: ${actions[i].uri}`);
                        cardsChanged = true;
                    }
                } else if (actions[i].id) {
                    const oldToken = actions[i].id;
                    actions[i].id = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== actions[i].id) {
                        console.log(`ID change detected in action. Old: ${oldToken}, New: ${actions[i].id}`);
                        cardsChanged = true;
                    }
                }

                if (actions[i].args && actions[i].args.value && typeof actions[i].args.value === 'string') {
                    const oldToken = actions[i].args.value;
                    actions[i].args.value = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== actions[i].args.value) {
                        console.log(`Value change detected in action args. Old: ${oldToken}, New: ${actions[i].args.value}`);
                        cardsChanged = true;
                    }
                }

                if (cardsChanged) {
                    console.log(`Preparing to update actions in flow "${f.name}"...`);
                    if (!softRun) {
                        try {
                            const response = await Homey.flow.updateFlow({
                                id: f.id,
                                flow: { id: f.id, actions: actions }
                            });
                            console.log(`Update response: ${JSON.stringify(response)}`);
                        } catch (error) {
                            console.error(`Error updating actions in flow "${f.name}":`, error);
                        }
                    } else {
                        console.log(`Would update actions in flow "${f.name}" with:`, {
                            id: f.id,
                            flow: { id: f.id, actions: actions }
                        });
                    }
                }
            }
        });

        console.log(`Checking conditions in flow "${f.name}"`);
        // Iterate through each condition in the flow
        f.conditions.forEach(async (a, i) => {
            let replaceValue = '';
            let cardsChanged = false;

            if (oldIds.length === 1) {
                replaceValue = oldIds[0];
            } else if (a.uri && a.uri.includes('homey:device:')) {
                replaceValue = a.uri.replace('homey:device:', '');
            } else if (a.id && a.id.includes('homey:device:')) {
                replaceValue = a.id.replace('homey:device:', '');
            }

            if (replaceValue.includes('|')) {
                replaceValue = replaceValue.split('|')[0];
            } else if (replaceValue.includes(':')) {
                replaceValue = replaceValue.split(':')[0];
            }

            if (oldIds.includes(replaceValue)) {
                const replacer = new RegExp(replaceValue, 'g');
                const conditions = f.conditions;
                const index = oldIds.findIndex((o) => o.includes(replaceValue));

                if (conditions[i].uri) {
                    const oldToken = conditions[i].uri;
                    conditions[i].uri = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== conditions[i].uri) {
                        console.log(`URI change detected in condition. Old: ${oldToken}, New: ${conditions[i].uri}`);
                        cardsChanged = true;
                    }
                } else if (conditions[i].id) {
                    const oldToken = conditions[i].id;
                    conditions[i].id = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== conditions[i].id) {
                        console.log(`ID change detected in condition. Old: ${oldToken}, New: ${conditions[i].id}`);
                        cardsChanged = true;
                    }
                }

                if (cardsChanged) {
                    console.log(`Preparing to update conditions in flow "${f.name}"...`);
                    if (!softRun) {
                        try {
                            const response = await Homey.flow.updateFlow({
                                id: f.id,
                                flow: { id: f.id, conditions: conditions }
                            });
                            console.log(`Update response: ${JSON.stringify(response)}`);
                        } catch (error) {
                            console.error(`Error updating conditions in flow "${f.name}":`, error);
                        }
                    } else {
                        console.log(`Would update conditions in flow "${f.name}" with:`, {
                            id: f.id,
                            flow: { id: f.id, conditions: conditions }
                        });
                    }
                }
            }
        });
    });

 // Enhanced logging for advanced flows
// Enhanced logging for advanced flows
console.log('--------------------------------------');

// Retrieve all of the existing advanced flows
const advanced_flows = Object.values(await Homey.flow.getAdvancedFlows());
console.log(`Checking advanced flows. Total count: ${advanced_flows.length}`);

// Iterate through each advanced flow
advanced_flows.forEach(async (af) => {
    if (!specificFlowIds.includes(af.id)) {
        console.log(`Advanced flow "${af.name}" with ID "${af.id}" not in specific flow IDs list.`);
        return;
    }

    console.log(`Checking advanced flow "${af.name}" with ID "${af.id}"...`);

    const cards = af.cards;
    let cardsChanged = false;

    // Iterate through each card in the advanced flow
    for (const c in cards) {
        let replaceValue = null;

        console.log(`Checking card ID "${c}" in advanced flow "${af.name}"...`);

        if (oldIds.length === 1) {
            replaceValue = oldIds[0];
        } else if (cards[c].ownerUri && cards[c].ownerUri.includes('homey:device:')) {
            replaceValue = cards[c].ownerUri.replace('homey:device:', '');
        }

        if (replaceValue && replaceValue.includes('|')) {
            replaceValue = replaceValue.split('|')[0];
        } else if (replaceValue && replaceValue.includes(':')) {
            replaceValue = replaceValue.split(':')[0];
        }

        console.log(`Replace value: ${replaceValue}`);

        const replacer = new RegExp(replaceValue, 'g');
        const index = oldIds.findIndex((o) => o.includes(replaceValue));

        if (index === -1) {
            console.log(`No matching old ID found in card ID "${c}" of advanced flow "${af.name}".`);
            continue;
        }

        console.log(`Card ID "${c}" has replace value "${replaceValue}". Proceeding with replacement...`);

        if (cards[c].args && cards[c].droptoken) {
            const oldToken = cards[c].droptoken;
            cards[c].droptoken = oldToken.replace(replacer, newIds[index]);

            if (oldToken !== cards[c].droptoken) {
                console.log(`Droptoken change detected in advanced flow card. Old: ${oldToken}, New: ${cards[c].droptoken}`);
                cardsChanged = true;
            }
        }

        if (cards[c].args && cards[c].args.value && typeof cards[c].args.value === 'string') {
            const oldToken = cards[c].args.value;
            cards[c].args.value = oldToken.replace(replacer, newIds[index]);

            if (oldToken !== cards[c].args.value) {
                console.log(`Value change detected in advanced flow card args. Old: ${oldToken}, New: ${cards[c].args.value}`);
                cardsChanged = true;
            }
        }

        if (cards[c].args && cards[c].args.text && typeof cards[c].args.text === 'string') {
            const oldToken = cards[c].args.text;
            cards[c].args.text = oldToken.replace(replacer, newIds[index]);

            if (oldToken !== cards[c].args.text) {
                console.log(`Text change detected in advanced flow card args. Old: ${oldToken}, New: ${cards[c].args.text}`);
                cardsChanged = true;
            }
        }

        if (cards[c].args && cards[c].args.message && typeof cards[c].args.message === 'string') {
            const oldToken = cards[c].args.message;
            cards[c].args.message = oldToken.replace(replacer, newIds[index]);

            if (oldToken !== cards[c].args.message) {
                console.log(`Message change detected in advanced flow card args. Old: ${oldToken}, New: ${cards[c].args.message}`);
                cardsChanged = true;
            }
        }

        if (cards[c].ownerUri) {
            const oldToken = cards[c].ownerUri;
            cards[c].ownerUri = cards[c].ownerUri.replace(replacer, newIds[index]);

            if (oldToken !== cards[c].ownerUri) {
                console.log(`OwnerUri change detected in advanced flow card. Old: ${oldToken}, New: ${cards[c].ownerUri}`);
                cardsChanged = true;
            }
        }

        if (cards[c].id) {
            const oldToken = cards[c].id;
            cards[c].id = cards[c].id.replace(replacer, newIds[index]);

            if (oldToken !== cards[c].id) {
                console.log(`ID change detected in advanced flow card. Old: ${oldToken}, New: ${cards[c].id}`);
                cardsChanged = true;
            }
        }

        // Apply changes to nested properties within args
        if (cards[c].args) {
            for (const arg in cards[c].args) {
                if (typeof cards[c].args[arg] === 'string') {
                    const oldToken = cards[c].args[arg];
                    cards[c].args[arg] = oldToken.replace(replacer, newIds[index]);

                    if (oldToken !== cards[c].args[arg]) {
                        console.log(`Change detected in card args.${arg} of advanced flow card. Old: ${oldToken}, New: ${cards[c].args[arg]}`);
                        cardsChanged = true;
                    }
                } else if (typeof cards[c].args[arg] === 'object' && cards[c].args[arg] !== null) {
                    for (const subArg in cards[c].args[arg]) {
                        if (typeof cards[c].args[arg][subArg] === 'string') {
                            const oldToken = cards[c].args[arg][subArg];
                            cards[c].args[arg][subArg] = oldToken.replace(replacer, newIds[index]);

                            if (oldToken !== cards[c].args[arg][subArg]) {
                                console.log(`Change detected in card args.${arg}.${subArg} of advanced flow card. Old: ${oldToken}, New: ${cards[c].args[arg][subArg]}`);
                                cardsChanged = true;
                            }
                        }
                    }
                }
            }
        }
    }

    // If any cards in the advanced flow were changed
    if (cardsChanged) {
        console.log(`Preparing to update advanced flow "${af.name}" with new cards...`);
        if (!softRun) {
            try {
                const response = await Homey.flow.updateAdvancedFlow({
                    id: af.id,
                    advancedflow: { cards: cards }
                });
                console.log(`Update response for advanced flow "${af.name}": ${JSON.stringify(response)}`);
            } catch (error) {
                console.error(`Error updating advanced flow "${af.name}":`, error);
            }
        } else {
            console.log(`Would update advanced flow "${af.name}" with new cards:`, {
                id: af.id,
                advancedflow: { cards: cards }
            });
        }
    }
});


};

// Call the main function to execute the flow ID replacements
main();
1 Like