Script to add/remove SimpleSysLog cards to/from flows doesn't remove cards

Issue #10 resolved
Peter Dee created an issue

Hi Arie,

While thinking I clutter the forum topic a bit, I think it’s better to report here.

The script to add/remove SimpleSysLog cards to/from flows, I can’t get cards to be removed from selected flows.

The returned error, and the console output are in the screenshots.

The exact script I used:

(these two ways did not make a difference in the result, and which one is the right one to use? :

a: “const deleteActionCards = true; !createActionCards; // = true,

b: “const deleteActionCards = !createActionCards; // = true,

)

const version = '1.0.1';

let flowNames = ['Check Timeline msgs number','Scene Sleep_Away AF', 'Scene Sleep_Away_2 AF']; // Use this line for selected flows
//let flowNames; // Use this line for all flows

const excludeBrokenFlows = true;
const automaterLocation = 'BottomLeft'; //TopLeft, LeftTop, BottomLeft
const automaterOffsetY = 60;
const automaterOffsetX = 0;
const automaterAutoMoveCards = true;
const errorSeverity = 3, triggerSeverity = 6, conditionSeverity = 6, actionSeverity = 6, facility = 16;
// Emergency=0 Alert=1 Critical=2 Error=3 Warning=4 Notice=5 Informational=6 Debug=7

const positionErrorCards = { y: -1.5, x: 0.25 }; //Number of blocks relative from the card to which it is appended.
const createErrorCards = false; // = true, automaticly create logging card for each error in the selected (or all) flows.
const deleteErrorCards = true; !createErrorCards; // = true, delete all automaticly created logging card from the selected (or all) flows.

const positionTriggerCards = { y: -1.5, x: 0.25 }; //Number of blocks relative from the card to which it is appended.
const createTriggerCards = false; // = true, automaticly create logging card for each error in the selected (or all) flows.
const deleteTriggerCards = true; !createTriggerCards; // = true, delete all automaticly created logging card from the selected (or all) flows.

const positionConditionCards = { y: -1.5, x: 0.25 }; //Number of blocks relative from the card to which it is appended.
const createConditionCards = false; // = true, automaticly create logging card for each error in the selected (or all) flows.
const deleteConditionCards = true; !createConditionCards; // = true, delete all automaticly created logging card from the selected (or all) flows.

const positionActionCards = { y: -2.0, x: 0.6 }; //Number of blocks relative from the card to which it is appended.
const createActionCards = false; // = true, automaticly create logging card for each error in the selected (or all) flows.
const deleteActionCards = true; !createActionCards; // = true, delete all automaticly created logging card from the selected (or all) flows.



/* Automatic const, leave it be */
const createAutomaterCard = 'homey:app:nl.nielsdeklerk.log:Automater'; // Zet to null for no card (required as of now)
const automaterUri = createAutomaterCard.substring(0, createAutomaterCard.lastIndexOf(':'));
const automaterId = createAutomaterCard.substring(createAutomaterCard.lastIndexOf(':') + 1);
const automaterMoveCardsY = _.max([positionTriggerCards.y, positionErrorCards.y]) * 20 * -1;
const automaterTopMargin = 160;

console.log(automaterMoveCardsY);


async function run() {
  let APIv3 = Number.parseInt((await Homey.system.getInfo()).homeyVersion.split('.')) >= 10;

  let afs = await Homey.flow.getAdvancedFlows();
  afs = _.toArray(afs);

  if (excludeBrokenFlows) afs = _.filter(afs, x => !x.broken);

  if (flowNames) afs = _.filter(afs, x => flowNames.indexOf(x.name) > -1);

  console.log(afs[1]);

  for (let i = 0; i < afs.length; i++) {
    let af = afs[i];
    let logCard;
    let automaterCard = _.find(af.cards, x => checkId(x, automaterUri, automaterId));
    let automaterArgs = {
      af, position: { location: automaterLocation, offsetY: automaterOffsetY, offsetX: automaterOffsetX, autoMoveCards: automaterAutoMoveCards },
      errorSeverity, triggerSeverity, conditionSeverity, actionSeverity, facility, createErrorCards, createTriggerCards, createConditionCards, createActionCards
    };
    if (automaterCard)
      automaterCard.args.id = af.id;
    if (automaterCard && automaterCard.args.update) {
      automaterArgs.card = automaterCard;
      updateAutomaterCard(automaterArgs);
    }
    if (!automaterCard) {
      automaterCard = getNewAutomaterCard(automaterArgs);
      automaterArgs.card = automaterCard;
      af.cards[uuid()] = automaterCard;
    }
    for (const cardKey in af.cards) {
      if (Object.hasOwnProperty.call(af.cards, cardKey)) {
        //const af.cards[cardKey] = af.cards[cardKey];
        if (checkId(af.cards[cardKey], automaterUri, automaterId)) continue;
        if (!af.cards[cardKey].id) continue;

        if (automaterCard.args.errorCards===false) {

          if (checkId(af.cards[cardKey], 'homey:app:nl.nielsdeklerk.log', 'Automater_log') && af.cards[cardKey].args.auto_created == true) {
            delete af.cards[cardKey];
            //continue;
          }
          if (af.cards[cardKey].outputError) af.cards[cardKey].outputError = _.filter(af.cards[cardKey].outputError, x => af.cards[x]);
          //continue;
        }
        if (automaterCard.args.errorCards===true && !checkId(af.cards[cardKey], 'homey:app:nl.nielsdeklerk.log') && af.cards[cardKey].type != 'trigger' && (!af.cards[cardKey].outputError || !af.cards[cardKey].outputError.length || !(logCard = _.find(af.cards[cardKey].outputError, x => af.cards[x] && af.cards[x].id && checkId(af.cards[x], 'homey:app:nl.nielsdeklerk.log'))))) {
          let uid = uuid();
          let newCard = getNewCard({ card: af.cards[cardKey], cardKey, af, position: positionErrorCards, automaterCard, type: 'error', severity: errorSeverity });
          if (!af.cards[cardKey].outputError) af.cards[cardKey].outputError = [];
          af.cards[cardKey].outputError.push(uid);
          let l = {};
          l[uid] = newCard;
          af.cards = _.merge(l, af.cards);
        }
        if (!checkId(af.cards[cardKey], 'homey:app:nl.nielsdeklerk.log') && af.cards[cardKey].type === 'trigger') {

          if ((!af.cards[cardKey].outputSuccess || !af.cards[cardKey].outputSuccess.length || !(logCard = _.find(af.cards[cardKey].outputSuccess, x => af.cards[x] && af.cards[x].id && checkId(af.cards[x], 'homey:app:nl.nielsdeklerk.log')))) && automaterCard.args.triggerCards===true) {
            let uid = uuid();
            let newCard = getNewCard({ card: af.cards[cardKey], cardKey, af, position: positionTriggerCards, automaterCard, type: 'trigger', severity: triggerSeverity });
            if (!af.cards[cardKey].outputSuccess) af.cards[cardKey].outputSuccess = [];
            af.cards[cardKey].outputSuccess.push(uid);
            let l = {};
            l[uid] = newCard;
            af.cards = _.merge(l, af.cards);
          } else if (logCard && automaterCard.args.updateCards===true) updateLogCard({ card: logCard, af, automaterCard, severity: automaterCard.args.triggerSeverity, facility: automaterCard.args.facility });
        }
        if (!checkId(af.cards[cardKey], 'homey:app:nl.nielsdeklerk.log') && af.cards[cardKey].type === 'condition') {
          let errorCard = _.find(af.cards[cardKey].outputError, x => af.cards[x] && af.cards[x].id && checkId(af.cards[x], 'homey:app:nl.nielsdeklerk.log'));
          if (errorCard) errorCard = af.cards[errorCard];

          if ((!af.cards[cardKey].outputTrue || !af.cards[cardKey].outputTrue.length || !(logCard = _.find(af.cards[cardKey].outputTrue, x => af.cards[x] && af.cards[x].id && checkId(af.cards[x], 'homey:app:nl.nielsdeklerk.log')))) && automaterCard.args.conditionCards===true) {
            let uid = uuid();
            let newCard = getNewCard({ card: af.cards[cardKey], cardKey, af, position: positionConditionCards, automaterCard, type: 'condition', value: true, id: errorCard.args.id, severity: conditionSeverity });

            if (!af.cards[cardKey].outputTrue) af.cards[cardKey].outputTrue = [];
            af.cards[cardKey].outputTrue.push(uid);
            let l = {};
            l[uid] = newCard;
            af.cards = _.merge(l, af.cards);
          } else if (logCard && automaterCard.args.updateCards===true) updateLogCard({ card: logCard, af, automaterCard, severity: automaterCard.args.conditionSeverity, facility: automaterCard.args.facility });

          logCard = undefined;
          if ((!af.cards[cardKey].outputFalse || !af.cards[cardKey].outputFalse.length || !(logCard = _.find(af.cards[cardKey].outputFalse, x => af.cards[x] && af.cards[x].id && checkId(af.cards[x], 'homey:app:nl.nielsdeklerk.log')))) && automaterCard.args.conditionCards===true) {
            let uid = uuid();
            let newCard = getNewCard({ card: af.cards[cardKey], cardKey, af, position: positionConditionCards, automaterCard, type: 'condition', value: false, id: errorCard.args.id, severity: conditionSeverity });
            if (!af.cards[cardKey].outputFalse) af.cards[cardKey].outputFalse = [];
            af.cards[cardKey].outputFalse.push(uid);
            let l = {};
            l[uid] = newCard;
            af.cards = _.merge(l, af.cards);
          } else if (logCard && automaterCard.args.updateCards===true) updateLogCard({ card: logCard, af, automaterCard, severity: automaterCard.args.conditionSeverity, facility: automaterCard.args.facility });

        }
        if (!checkId(af.cards[cardKey], 'homey:app:nl.nielsdeklerk.log') && af.cards[cardKey].type === 'action') {
          if ((!af.cards[cardKey].outputSuccess || !af.cards[cardKey].outputSuccess.length || !(logCard = _.find(af.cards[cardKey].outputSuccess, x => af.cards[x] && af.cards[x].id && checkId(af.cards[x], 'homey:app:nl.nielsdeklerk.log')))) && automaterCard.args.actionCards===true) {
            let errorCard = _.find(af.cards[cardKey].outputError, x => af.cards[x] && af.cards[x].id && checkId(af.cards[x], 'homey:app:nl.nielsdeklerk.log'));
            if (errorCard) errorCard = af.cards[errorCard];
            let uid = uuid();
            let newCard = getNewCard({ card: af.cards[cardKey], cardKey, af, position: positionActionCards, automaterCard, type: 'action', id: errorCard.args.id, severity: actionSeverity });
            if (!af.cards[cardKey].outputSuccess) af.cards[cardKey].outputSuccess = [];
            af.cards[cardKey].outputSuccess.push(uid);
            let l = {};
            l[uid] = newCard;
            af.cards = _.merge(l, af.cards);
          } else if (logCard && automaterCard.args.updateCards===true) updateLogCard({ card: logCard, af, automaterCard, severity: automaterCard.args.actionSeverity, facility: automaterCard.args.facility }); 
        }
      }
    }

    try {
      let id = af.id;
      af = {
        //id: af.id,
        name: af.name,
        cards: af.cards
      };
      //console.log(JSON.stringify(af));
      afs[i] = af;
      await Homey.flow.updateAdvancedFlow({ id, advancedflow: af });
    } catch (ex) {
      console.log(ex);
    }

  }
  return afs;
  //log(JSON.stringify(afs));



  function uuid() {
    var d = new Date().getTime();
    var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0;
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      var r = Math.random() * 16;
      if (d > 0) {
        r = (d + r) % 16 | 0;
        d = Math.floor(d / 16);
      } else {
        r = (d2 + r) % 16 | 0;
        d2 = Math.floor(d2 / 16);
      }
      return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
  }

  function checkId(card, uri, id) {
    return id ?
      (APIv3 ? card.id == uri + ':' + id : card.ownerUri == uri && card.id == id)
      :
      (APIv3 ? card.id.startsWith(uri + ':') : card.ownerUri == uri)
      ;
  }

  function getNewCard({ card, cardKey, af, position: { x, y }, automaterCard, type, value, id, severity }) {
    let r = {};

    if (APIv3) {
      r.ownerUri = "homey:app:nl.nielsdeklerk.log";
      r.id = 'homey:app:nl.nielsdeklerk.log:Automater_log';
    } else {
      r.ownerUri = "homey:app:nl.nielsdeklerk.log";
      r.id = "Automater_log";
    }

    if (!id) automaterCard.args[card.type + 'Index']++;
    id = id ? id : (card.type.substring(0, 1).toUpperCase() + automaterCard.args[card.type + 'Index']);
    let log = id;
    switch (type) {
      case "error": log += ": [[" + (APIv3 ? 'card' : card.type) + "::" + cardKey + "::error]]"; break;
      case "trigger": log += ': Triggered'; break;
      case "condition": log += ': ' + value; break;
      case "action": log += ': Executed'; break;
    }
    r.args = {
      id,
      log,
      group: af.name,
      severity: severity || "6",
      facility: automaterCard.args.facility || '16',
      auto_created: true
    };


    r.type = "action";
    x = card.x + (20 * x);
    r.x = x > 0 ? x : 0;
    y = card.y + (20 * y);
    r.y = y > 0 ? y : 0;

    return r;
  }

  function getNewAutomaterCard({ af, errorSeverity, triggerSeverity, conditionSeverity, actionSeverity, facility, position: { location, offsetX, offsetY, autoMoveCards }, createErrorCards, createTriggerCards, createConditionCards, createActionCards }) {
    let r = {};
    const uri = createAutomaterCard.substring(0, createAutomaterCard.lastIndexOf(':'));
    const id = createAutomaterCard.substring(createAutomaterCard.lastIndexOf(':') + 1);

    if (APIv3) {
      r.ownerUri = uri;
      r.id = uri + ':' + id;
    } else {
      r.ownerUri = uri;
      r.id = id;
    }
    r.args = {
      //id:af.id,
      group: af.name,
      triggerIndex: 0,
      conditionIndex: 0,
      actionIndex: 0,
      update: true,
      updateCards: true,
      errorCards: createErrorCards,
      triggerCards: createTriggerCards,
      conditionCards: createConditionCards,
      actionCards: createActionCards,
      //autoMoveCards,
      // errorSeverity:3,
      // conditionSeverity:6,
      // actionSeverity:6,
      // facility: "16",
      auto_created: true
    };

    r.type = "action";
    let x = 0, y = 0;
    switch (location) {
      case "LeftTop":
        x = 0 + (offsetX > 0 ? (offsetX) : 0);
        y = 0 + (offsetY > 0 ? (offsetY) : 0);
        _.each(af.cards, x => { x.x += 400; x.y += automaterMoveCardsY });
        break;
      case "TopLeft":
        x = 0 + (offsetX > 0 ? (offsetX) : 0);
        y = 0 + (offsetY > 0 ? (offsetY) : 0);
        _.each(af.cards, x => x.y += automaterTopMargin + automaterMoveCardsY);
        break;
      case "BottomLeft":
        x = 0 + offsetX > 0 ? (offsetX || 0) : 0;
        let max = _.maxBy(_.toArray(af.cards), x => x.y);
        max = max ? max.y + automaterTopMargin + automaterMoveCardsY : 0;
        y = max + (offsetY > 0 ? (offsetY) : 0);
        _.each(af.cards, x => { x.y += automaterMoveCardsY });
        break;
    }
    r.x = x > 0 ? x : 0;
    r.y = y > 0 ? y : 0;

    r.args.errorSeverity = errorSeverity ? errorSeverity.toString() : '';
    r.args.conditionSeverity = conditionSeverity ? conditionSeverity.toString() : '';
    r.args.actionSeverity = actionSeverity ? actionSeverity.toString() : '';
    r.args.triggerSeverity = triggerSeverity ? triggerSeverity.toString() : '';
    r.args.facility = facility ? facility.toString() : '';

    updateAutomaterCard({ card: r, af, errorSeverity, triggerSeverity, conditionSeverity, actionSeverity, facility })
    // x= card.x + (20 * x);
    // r.x= x>0?x:0;
    // y = card.y + (20 * y);
    // r.y= y>0?y:0;
    return r;
  }

  function updateAutomaterCard({ card, af, errorSeverity, triggerSeverity, conditionSeverity, actionSeverity, facility, createErrorCards, createTriggerCards, createConditionCards, createActionCards }) {
    card.args.id = af.id;
    card.args.group = af.name;

    card.args.errorCards = createErrorCards;
    card.args.triggerCards = createTriggerCards;
    card.args.conditionCards = createConditionCards;
    card.args.actionCards = createActionCards;

    card.args.errorSeverity = errorSeverity ? errorSeverity.toString() : '';
    card.args.conditionSeverity = conditionSeverity ? conditionSeverity.toString() : '';
    card.args.actionSeverity = actionSeverity ? actionSeverity.toString() : '';
    card.args.triggerSeverity = triggerSeverity ? triggerSeverity.toString() : '';
    card.args.facility = facility ? facility.toString() : '';

  }

  function updateLogCard({ card, af, severity, facility, automaterCard }) {
    af.cards[card].args.group = automaterCard.args.group;
    af.cards[card].args.severity = severity ? severity.toString() : '';
    af.cards[card].args.facility = facility ? facility.toString() : '';
  }

}
run();

Thanks in advance and no hurries,

Peter

.

Comments (5)

  1. Log in to comment