/.prettierrc Secret
Last active
December 12, 2024 20:38
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"overrides": [ | |
{ | |
"files": ["*.html", "**/*.js"], | |
"options": { | |
"semi": true, | |
"singleQuote": true, | |
"tabWidth": 4, | |
"printWidth": 200, | |
"trailingComma": "none" | |
} | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const mainLight = 'c5ab94d8-0569-43d1-81b0-3749771c07d5'; | |
const childLights = ['f974e477-38bd-4aee-a9cb-b2edc93e48c4', '6a785a37-564f-43ab-ac93-da56956d15ff']; | |
const hue = true; | |
const temp = true; | |
const main = function () { | |
const onoffcards = { | |
'7e05d282-ec27-4bdc-93c4-143475bc31a2': { | |
ownerUri: 'homey:device:AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', | |
id: 'homey:device:AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA:onoff_true', | |
type: 'trigger', | |
x: 0, | |
y: 40, | |
outputSuccess: ['70038a02-6b5f-4662-bed8-7cae5ef22ffe', '02fbae88-cc15-4549-9279-fcbbab2fee0f'] | |
}, | |
'0b05d456-4bd6-4979-94d2-04cb95b9d35b': { | |
ownerUri: 'homey:device:AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', | |
id: 'homey:device:AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA:onoff_false', | |
type: 'trigger', | |
x: 0, | |
y: 220, | |
outputSuccess: ['c8e96a0b-a2c2-4c9c-9146-cdb679ccef2e', '7620d6de-5ab2-4594-8df6-a6d0bfab7b76'] | |
}, | |
'70038a02-6b5f-4662-bed8-7cae5ef22ffe': { | |
ownerUri: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB', | |
id: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB:on', | |
type: 'action', | |
x: 480, | |
y: 0 | |
}, | |
'02fbae88-cc15-4549-9279-fcbbab2fee0f': { | |
ownerUri: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC', | |
id: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC:on', | |
type: 'action', | |
x: 480, | |
y: 80 | |
}, | |
'c8e96a0b-a2c2-4c9c-9146-cdb679ccef2e': { | |
ownerUri: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB', | |
id: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB:off', | |
type: 'action', | |
x: 480, | |
y: 180 | |
}, | |
'7620d6de-5ab2-4594-8df6-a6d0bfab7b76': { | |
ownerUri: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC', | |
id: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC:off', | |
type: 'action', | |
x: 480, | |
y: 260 | |
} | |
}; | |
const dimCards = { | |
'f70224ba-080c-42b5-bd12-57fca3a61238': { | |
ownerUri: 'homey:device:AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', | |
id: 'homey:device:AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA:dim_changed', | |
type: 'trigger', | |
x: 0, | |
y: 400, | |
outputSuccess: ['0fa741fa-6895-4166-8a46-a1fdeeb84183', '3cde5d66-09e6-42a5-837e-e314aae15c08'] | |
}, | |
'0fa741fa-6895-4166-8a46-a1fdeeb84183': { | |
ownerUri: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB', | |
id: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB:dim', | |
type: 'action', | |
x: 480, | |
y: 360, | |
args: { | |
dim: '[[trigger::f70224ba-080c-42b5-bd12-57fca3a61238::dim]]' | |
} | |
}, | |
'3cde5d66-09e6-42a5-837e-e314aae15c08': { | |
ownerUri: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC', | |
id: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC:dim', | |
type: 'action', | |
x: 480, | |
y: 440, | |
args: { | |
dim: '[[trigger::f70224ba-080c-42b5-bd12-57fca3a61238::dim]]' | |
} | |
} | |
}; | |
const tempCards = { | |
'1b5c9276-9984-42b5-a1b3-ee53289071a3': { | |
ownerUri: 'homey:app:com.trigger.lights', | |
id: 'homey:app:com.trigger.lights:trigger_DEVICE_TEMP', | |
type: 'trigger', | |
x: 0, | |
y: 560, | |
outputSuccess: ['017d67d3-1242-4ea6-ba3a-e7e690457365', '7d905d3b-4cf8-47b0-a45f-77d22fee177c'], | |
args: { | |
device: { | |
id: 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', | |
name: 'LIGHT' | |
} | |
} | |
}, | |
'017d67d3-1242-4ea6-ba3a-e7e690457365': { | |
ownerUri: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB', | |
id: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB:temperature', | |
type: 'action', | |
x: 480, | |
y: 540, | |
args: { | |
temperature: '[[trigger::1b5c9276-9984-42b5-a1b3-ee53289071a3::value]]' | |
} | |
}, | |
'7d905d3b-4cf8-47b0-a45f-77d22fee177c': { | |
ownerUri: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC', | |
id: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC:temperature', | |
type: 'action', | |
x: 480, | |
y: 620, | |
args: { | |
temperature: '[[trigger::1b5c9276-9984-42b5-a1b3-ee53289071a3::value]]' | |
} | |
} | |
}; | |
const hueCards = { | |
'13bd4ba5-c94d-4641-a2f7-6865238cfc3d': { | |
ownerUri: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB', | |
id: 'homey:device:BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB:hue', | |
type: 'action', | |
x: 480, | |
y: 720, | |
args: { | |
hue: '[[trigger::c063026c-33d6-4e54-8b2b-da5b1e275267::value]]' | |
} | |
}, | |
'f8bf00f5-2f8d-4965-9189-946e0088a1c2': { | |
ownerUri: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC', | |
id: 'homey:device:CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC:hue', | |
type: 'action', | |
x: 480, | |
y: 800, | |
args: { | |
hue: '[[trigger::c063026c-33d6-4e54-8b2b-da5b1e275267::value]]' | |
} | |
}, | |
'c063026c-33d6-4e54-8b2b-da5b1e275267': { | |
ownerUri: 'homey:app:com.trigger.lights', | |
id: 'homey:app:com.trigger.lights:trigger_DEVICE_HUE', | |
type: 'trigger', | |
x: 0, | |
y: 760, | |
outputSuccess: ['13bd4ba5-c94d-4641-a2f7-6865238cfc3d', 'f8bf00f5-2f8d-4965-9189-946e0088a1c2'], | |
args: { | |
device: { | |
id: 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', | |
name: 'LIGHT' | |
} | |
} | |
} | |
}; | |
let cards = { | |
...onoffcards, | |
...dimCards, | |
...(temp && tempCards), | |
...(hue && hueCards) | |
}; | |
let parsedCards = {}; | |
// Parse the cards to replace the IDs | |
Object.keys(cards).forEach((i) => { | |
let ownerUri = ''; | |
let id = ''; | |
if (cards[i].ownerUri.includes('AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA')) { | |
ownerUri = cards[i].ownerUri.replace('AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', mainLight); | |
id = cards[i].id.replace('AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', mainLight); | |
parsedCards[i] = cards[i]; | |
parsedCards[i].ownerUri = ownerUri; | |
parsedCards[i].id = id; | |
} | |
if (cards[i].ownerUri.includes('BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB')) { | |
ownerUri = cards[i].ownerUri.replace('BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB', childLights[0]); | |
id = cards[i].id.replace('BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB', childLights[0]); | |
parsedCards[i] = cards[i]; | |
parsedCards[i].ownerUri = ownerUri; | |
parsedCards[i].id = id; | |
} | |
if (cards[i].ownerUri.includes('CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC') && childLights.length > 1) { | |
ownerUri = cards[i].ownerUri.replace('CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC', childLights[1]); | |
id = cards[i].id.replace('CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC', childLights[1]); | |
parsedCards[i] = cards[i]; | |
parsedCards[i].ownerUri = ownerUri; | |
parsedCards[i].id = id; | |
} | |
if (cards[i].args && cards[i].args.device) { | |
parsedCards[i] = cards[i]; | |
parsedCards[i].args.device.id = parsedCards[i].args.device.id.replace('AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA', mainLight); | |
} | |
}); | |
return Homey.flow.createAdvancedFlow({ | |
advancedflow: { name: 'Group Flow', cards: parsedCards } | |
}); | |
}; | |
// Call the main function to execute the flow ID replacements | |
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// It's recommended to only use 1 id at a time. This will also fix your variables. | |
const oldIds = ['05165ac6-15b5-4415-972a-537840d383bb']; | |
const newIds = ['407bab3f-616c-4f7a-b15e-68b0e7f77825']; | |
// 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) => { | |
let cardsChanged = false; | |
let actions = null; | |
let conditions = null; | |
let trigger = null; | |
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)) { | |
trigger = f.trigger; | |
let replaceValue = ''; | |
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; | |
} | |
} | |
} | |
} | |
// Iterate through each action in the flow | |
f.actions.forEach(async (a, i) => { | |
let replaceValue = ''; | |
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'); | |
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; | |
} | |
} | |
} | |
}); | |
// Iterate through each condition in the flow | |
f.conditions.forEach(async (a, i) => { | |
let replaceValue = ''; | |
// 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'); | |
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 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 | |
const newCardData = { | |
id: f.id, | |
flow: { | |
id: f.id, | |
...(trigger && { trigger: trigger }), | |
...(actions && { actions: actions }), | |
...(conditions && { conditions: conditions }) | |
} | |
} | |
if (!softRun) { | |
console.log(`Updating flow "${f.name}" with new data...`, newCardData); | |
await Homey.flow.updateFlow(newCardData); | |
// If softRun is true, log the change that would be made | |
} else { | |
console.log(`Would update flow "${f.name}" with new data:`, newCardData); | |
} | |
} | |
}); | |
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 | |
const newCardData = { | |
id: af.id, | |
advancedflow: { cards: cards } | |
} | |
if (!softRun) { | |
console.log(`Updating advanced flow "${af.name}" with new cards...`, newCardData); | |
const response = await Homey.flow.updateAdvancedFlow(newCardData); | |
console.log(`Update response: ${JSON.stringify(response)}`); | |
} else { | |
console.log(`Would update advanced flow "${af.name}" with new cards:`, newCardData); | |
} | |
} | |
}); | |
}; | |
// Call the main function to execute the flow ID replacements | |
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// It's recommended to only use 1 id at a time. This will also fix your variables. | |
const deviceNameOld = 'VirtualSwitchABCD'; | |
const deviceNameNew = 'VirtualSwitchDCBA'; | |
// 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...'); | |
const devices = await Homey.devices.getDevices(); | |
const deviceNew = Object.values(devices).find((d) => deviceNameNew === d.name); | |
const deviceOld = Object.values(devices).find((d) => deviceNameOld === d.name); | |
const oldIds = []; | |
const newIds = []; | |
if (deviceNew) { | |
newIds.push(deviceNew.id); | |
} | |
if (deviceOld) { | |
oldIds.push(deviceOld.id); | |
} | |
console.log('Found Ids:', newIds, oldIds); | |
// Retrieve all of the existing flows | |
const flows = await Homey.flow.getFlows(); | |
// Iterate through each flow | |
Object.values(flows).forEach(async (f) => { | |
let cardsChanged = false; | |
let actions = null; | |
let conditions = null; | |
let trigger = null; | |
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)) { | |
trigger = f.trigger; | |
let replaceValue = ''; | |
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; | |
} | |
} | |
} | |
} | |
// Iterate through each action in the flow | |
f.actions.forEach(async (a, i) => { | |
let replaceValue = ''; | |
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'); | |
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; | |
} | |
} | |
} | |
}); | |
// Iterate through each condition in the flow | |
f.conditions.forEach(async (a, i) => { | |
let replaceValue = ''; | |
// 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'); | |
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 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 | |
const newCardData = { | |
id: f.id, | |
flow: { | |
id: f.id, | |
...(trigger && { trigger: trigger }), | |
...(actions && { actions: actions }), | |
...(conditions && { conditions: conditions }) | |
} | |
} | |
if (!softRun) { | |
console.log(`Updating flow "${f.name}" with new data...`, newCardData); | |
await Homey.flow.updateFlow(newCardData); | |
// If softRun is true, log the change that would be made | |
} else { | |
console.log(`Would update flow "${f.name}" with new data:`, newCardData); | |
} | |
} | |
}); | |
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 | |
const newCardData = { | |
id: af.id, | |
advancedflow: { cards: cards } | |
} | |
if (!softRun) { | |
console.log(`Updating advanced flow "${af.name}" with new cards...`, newCardData); | |
const response = await Homey.flow.updateAdvancedFlow(newCardData); | |
console.log(`Update response: ${JSON.stringify(response)}`); | |
} else { | |
console.log(`Would update advanced flow "${af.name}" with new cards:`, newCardData); | |
} | |
} | |
}); | |
}; | |
// Call the main function to execute the flow ID replacements | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment