glad you liked it⌠lazy as i am i actually took it a bit further⌠and combined it with your script(s)
Basically one can now do a search, if only one ID is found on each old and new search.
The script goes on and uses those idâs as replacements. if several are found it stops executing the rest and just outputs the result in API Playground. so one manually can copy/paste the correct ID avoiding mistakes
or if old and new id is filled it will go straight to doing the magic.
was thinking about adding a code in the end that deletes the âdeletemeâ device - since i rename the old device beforei run this, then manually delete it in the app. though if you are interested i can look into adding that too. hope its helpfull 
const finishedmsg = "finished update flow";
// you can either search for devices first or add the id's if they are familiar directly below.
const oldSearch = "deleteme";
const newSearch = "Master bedroom Night Lamp";
// It's recommended to only use 1 id at a time. This will also fix your variables.
let oldIds = [];
let newIds = [];
// Set the softRun variable to true or false to determine whether changes should be logged or actually executed
const softRun = false; // true | false
// Open the console in your browser and the result will be shown there
// Howto open console: https://balsamiq.com/support/faqs/browserconsole/
async function searchDevices() {
if (!oldIds.length || !newIds.length) {
try {
const devices = await Homey.devices.getDevices();
const allDevices = Object.values(devices);
let oldDevices = allDevices
.filter(device => device.name.toLowerCase().includes(oldSearch.toLowerCase()))
.map(device => ({ id: device.id, name: device.name }));
let newDevices = allDevices
.filter(device => device.name.toLowerCase().includes(newSearch.toLowerCase()))
.map(device => ({ id: device.id, name: device.name }));
if (oldDevices.length > 1 || newDevices.length > 1) {
return { oldDevices, newDevices };
}
if (oldDevices.length === 1 && newDevices.length === 1) {
oldIds = [oldDevices[0].id];
newIds = [newDevices[0].id];
}
} catch (error) {
console.error(error);
}
}
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(`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];
}
// 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(`Found old device ID in URI of trigger card in flow "${f.name}"`);
cardsChanged = true;
}
} else if (trigger.id) {
const oldToken = trigger.id;
trigger.id = oldToken.replace(replacer, newIds[index]);
if (oldToken !== trigger.id) {
console.log(`Found old device ID in ID of trigger card in flow "${f.name}"`);
cardsChanged = true;
}
}
// Replace the old device ID with the corresponding new device ID in the trigger droptoken
if (trigger.droptoken) {
const oldToken = trigger.droptoken;
trigger.droptoken = oldToken.replace(replacer, newIds[index]);
if (oldToken !== trigger.droptoken) {
console.log(`Found old device ID in droptoken of trigger card in flow "${f.name}"`);
cardsChanged = true;
}
}
// If softRun is false, update the flow with the new trigger
// If any cards in the advanced flow were changed
if (cardsChanged) {
// If softRun is false, update the advanced flow with the new cards
if (!softRun) {
console.log(`Updating flow "${f.name}" with new trigger...`);
await Homey.flow.updateFlow({
id: f.id,
flow: { id: f.id, trigger: trigger }
});
// If softRun is true, log the change that would be made
} else {
console.log(`Would update flow "${f.name}" with new trigger:`, {
id: f.id,
flow: { id: f.id, trigger: trigger }
});
}
}
}
}
// 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 the flow contains the old device ID
if (oldIds.includes(replaceValue)) {
const replacer = new RegExp(replaceValue, 'g');
const actions = f.actions;
const index = oldIds.findIndex((o) => o.includes(replaceValue));
// Replace the old device ID with the corresponding new device ID in the action
if (actions[i].uri) {
const oldToken = actions[i].uri;
actions[i].uri = oldToken.replace(replacer, newIds[index]);
if (oldToken !== actions[i].uri) {
console.log(`Found old device ID in URI of action card in flow "${f.name}"`);
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(`Found old device ID in ID of action card in flow "${f.name}"`);
cardsChanged = true;
}
}
// Replace the old device ID with the corresponding new device ID in the action droptoken
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(`Found old device ID in ID of action card in flow "${f.name}"`);
cardsChanged = true;
}
}
if (actions[i].args && actions[i].args.text && typeof actions[i].args.text === 'string') {
const oldToken = actions[i].args.text;
actions[i].args.text = oldToken.replace(replacer, newIds[index]);
if (oldToken !== actions[i].args.text) {
console.log(`Found old device ID in ID of action card in flow "${f.name}"`);
cardsChanged = true;
}
}
if (actions[i].args && actions[i].args.message && typeof actions[i].args.message === 'string') {
const oldToken = actions[i].args.message;
actions[i].args.message = oldToken.replace(replacer, newIds[index]);
if (oldToken !== actions[i].args.message) {
console.log(`Found old device ID in ID of action card in flow "${f.name}"`);
cardsChanged = true;
}
}
if (cardsChanged) {
// If softRun is false, update the flow with the new action
if (!softRun) {
console.log(`Updating flow "${f.name}" with new action...`);
await Homey.flow.updateFlow({
id: f.id,
flow: { id: f.id, actions: actions }
});
// If softRun is true, log the change that would be made
} else {
console.log(`Would update flow "${f.name}" with new action:`, {
id: f.id,
flow: { id: f.id, actions: actions }
});
}
}
}
});
// Iterate through each condition in the flow
f.conditions.forEach(async (a, i) => {
let replaceValue = '';
let cardsChanged = false;
// If the condition URI includes the device ID
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 the flow contains the old device ID
if (oldIds.includes(replaceValue)) {
const replacer = new RegExp(replaceValue, 'g');
const conditions = f.conditions;
const index = oldIds.findIndex((o) => o.includes(replaceValue));
// Replace the old device ID with the corresponding new device ID in the condition
if (conditions[i].uri) {
const oldToken = conditions[i].uri;
conditions[i].uri = oldToken.replace(replacer, newIds[index]);
if (oldToken !== conditions[i].uri) {
console.log(`Found old device ID in URI of condition card in flow "${f.name}"`);
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(`Found old device ID in ID of condition card in flow "${f.name}"`);
cardsChanged = true;
}
}
// Replace the old device ID with the corresponding new device ID in the condition droptoken
if (conditions[i].droptoken) {
const oldToken = conditions[i].droptoken;
conditions[i].droptoken = oldToken.replace(replacer, newIds[index]);
if (oldToken !== conditions[i].droptoken) {
console.log(`Found old device ID in Droptoken of condition card in flow "${f.name}"`);
cardsChanged = true;
}
}
if (cardsChanged) {
// If softRun is false, update the flow with the new condition
if (!softRun) {
console.log(`Updating flow "${f.name}" with new condition...`);
await Homey.flow.updateFlow({
id: f.id,
flow: { id: f.id, conditions: conditions }
});
// If softRun is true, log the change that would be made
} else {
console.log(`Would update flow "${f.name}" with new condition:`, {
id: f.id,
flow: { id: f.id, conditions: conditions }
});
}
}
}
});
});
console.log('--------------------------------------')
// Retrieve all of the existing advanced flows
const advanced_flows = Object.values(await Homey.flow.getAdvancedFlows());
// Iterate through each advanced flow
advanced_flows.forEach(async (af) => {
console.log(`Checking advanced flow "${af.name}"...`);
const cards = af.cards;
let cardsChanged = false;
// Iterate through each card in the advanced flow
for (const c in af.cards) {
let replaceValue = null;
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.includes('|')) {
replaceValue = replaceValue.split('|')[0];
} else if (replaceValue.includes(':')) {
replaceValue = replaceValue.split(':')[0];
}
const replacer = new RegExp(replaceValue, 'g');
const index = oldIds.findIndex((o) => o.includes(replaceValue));
if (cards[c].args && cards[c].droptoken) {
const oldToken = cards[c].droptoken;
cards[c].droptoken = cards[c].droptoken.replace(replacer, newIds[index]);
if (oldToken !== cards[c].droptoken) {
console.log(`Found old device ID in droptoken of card in advanced flow "${af.name}"`);
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 = cards[c].args.value.replace(replacer, newIds[index]);
if (oldToken !== cards[c].args.value) {
console.log(`Found old device ID in value of card in advanced flow "${af.name}"`);
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 = cards[c].args.text.replace(replacer, newIds[index]);
if (oldToken !== cards[c].args.text) {
console.log(`Found old device ID in test of card in advanced flow "${af.name}"`);
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 = cards[c].args.message.replace(replacer, newIds[index]);
if (oldToken !== cards[c].args.message) {
console.log(`Found old device ID in message of card in advanced flow "${af.name}"`);
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(`Found old device ID in ownerUri of card in advanced flow "${af.name}"`);
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(`Found old device ID in ownerUri of card in advanced flow "${af.name}"`);
cardsChanged = true;
}
}
}
// If any cards in the advanced flow were changed
if (cardsChanged) {
// If softRun is false, update the advanced flow with the new cards
if (!softRun) {
console.log(`Updating advanced flow "${af.name}" with new cards...`);
const response = await Homey.flow.updateAdvancedFlow({
id: af.id,
advancedflow: { cards: cards }
});
console.log(`Update response: ${JSON.stringify(response)}`);
} else {
console.log(`Would update advanced flow "${af.name}" with new cards:`, {
id: af.id,
advancedflow: { cards: cards }
});
}
}
});
console.log(finishedmsg);
};
// Call the main function to execute the flow ID replacements
main();
}
searchDevices();