Skip to content

lib-finTools 库参考(第 2 部分) ​

原文: https://finproducts.atlassian.net/wiki/spaces/JIDD3/pages/34793783691/FIN+5.3.1+lib-finTools+part+2 中文整理基于 FIN 5.3.1

导读: (data, split, sname, fname, ename, pname, en) = do

以下为 API 参考,保留英文以便对照源码;目录已列出(英文标题便于检索);概述已尽量中译。


目录(导读) ​

  • def
  • finFormStringSearchTransPrev(data, split, sname, fname, ename, pname, en)
  • finFormStringSearchTransStats()
  • finFormSyncToColl(pointList: null, ptType: null)
  • finFormTagDuplicate()
  • finFormTagSplitAndRename(id, selectedDicts)
  • finFormTempToReal(stage: null, data: null, delet: null)
  • finFormTempToRealStats(filter, type)
  • finFormTextArea(title, text, height: 250, width: 450)
  • finFormTextareaOk(title, text, height: null)
  • finFormUniqueEquipTypes(stage: null)
  • finFormUniqueTagsEasy(stage: null)
  • finFormUpdateConnectors(id, selectedDicts, fromDB: null, reopen: false)
  • finFormWriteLevels()
  • finGenerateSampleTagValue(id, targetTag, splitValue, renamePattern, commitResults: false)
  • finGetMinutesFromCur(cur, base)
  • finGetPointRecords(inp: null)
  • finGetUriFromRef(grid, tags: ["imageRef"], fileTagName: "file")
  • finGlobalControl(id, selectedDicts: null, fromFilter: false)
  • finGlobalControlActions(idList)
  • finGlobalControlCheckEnum(pointData)
  • finGlobalControlCommit(idList, action, value, units, pointKind, duration: null, forever: null)
  • finGlobalControlDurForm(idList, action, value, units, kind)
  • finGlobalControlFilterCheck(filterDict)
  • finGlobalControlFilterForm(idList: null, flt: null, err: null)
  • finGlobalControlFilterTable(filterThing)
  • finGlobalControlForm(listOfIds, filterOn)
  • finGraphicsBatchTags(data: null, selectedItems: [])
  • finGraphicsDeleteRecs(data: null, selectedItems: [])
  • finHardDelete(recs)
  • finHaystackHexReplaceForm(selectedDicts: null, stage: null)
  • finHisImport(recc, furi, fn: "rewrite", dictt: {ts:"ts", val:"val"}, dtype: "number")
  • finHisReadAddMeta(curGrid, point, curTimeSpan, timezone)
  • finHisReadBaseBuildCharts(grid, boolTable, enumTable, grouped, baselineTables, units, multiUnits, missingIds: null)
  • finHisReadBaseGetHis(interval, fold, interval2, fold2, point, baHis, timeZone, currentTimeSpan, baseLineTimeSpan)
  • finHisReadBaseGetTz(point)
  • finHisReadBaseline(ptList, curTS, baseTS: null, rollUps: null, chartOpts: null, noNames: false)
  • finHisReadBaselineCore(ptList, curTS, baseTS: null, rollUps: null, chartOpts: null, noNames: false, jobRec: null)
  • finHisReadBaselineRollup(chartSettingsDict, rollUpSettings, x)
  • finHisReadBaselineStrPoint(curPointHis, pointName, isBool: false)
  • finHisReadBaselineStrPointF(curPointHis, pointName, isBool: false)
  • finHisReadBaslineStatus(jobRef)
  • finHisReadComplexBa(history, pointRef)
  • finHisRewriteSpan(hisRecs, startTime, endTime, rewriteFunc: (value) => value, pTime: null)
  • finInvoke(rec, action, args: {})
  • finIsTagBlackList(tag)
  • finMacro(scope, pattern)
  • finMassEditTags(selectedDicts: null, stage: null, data: null)
  • finMatchPointsToCharts(ptList, optList, isRel: false)
  • finModBusMap(grid, files)
  • finMoveTag(filt1, filt2, tag1, deleteOrig: false)
  • finNavMetaCommit(newLevel, deleteLevel, parentLevel, isOptional: false)
  • finNavMetaDeleteFailForm(unDeletable)
  • finNavMetaGetLevels(keepEmpty: false)
  • finNavMetaWhoAmI(rec)
  • finPodFiles(name)
  • finPointActions(kind)
  • finPointNotTz()
  • finPointNumbersToEquip(id: null, stage: null, data: null)
  • finPostTrioFuncs(trioUri)
  • finPrecision(number, precision, useStr: false)
  • finProjectedCalc(recs, rangeFunc)
  • finReadAlarmTags(tags: [])
  • finReadAlarmTagsSearch(progStr)
  • finReadCloneEvents(id)
  • finRecordsSources(recordType)
  • finRefDis(ref)
  • finRemoveAnimationEditor(fileRef)
  • finRemoveUnits(numberToCheck)
  • finRenamePointsForm(selectedDicts: null, stage: null)
  • finRestorePod(pod)
  • finSampleHisReadBase(f: 0, fN2R: 0, nC: 0, nR: 0, nB: 0, p: 0, oC: 0, oR: 0, oB: 0)
  • finSaveEquipRecordsForm(id: false, selectedDicts: false)
  • finSaveFloorRecordsForm(id: false, selectedDicts: false)
  • finSavePointRecordsForm(id: false, selectedDicts: false)
  • finSaveRecords(filt, type, name1: null, name2: null)
  • finSaveRecordsForm()
  • finSaveRecordsSeparate(filter, useUnique)
  • finSaveSiteRecordsForm(id: false, selectedDicts: false)
  • finSavedCharts(id)
  • finSelectedConnectorTypes(selectedIds)
  • finSelectedPoints(selectedIds)
  • finSetImmediateSubOffTimeCommit(offTime, onTime, jobRef: null)
  • finShowEquipSummary(inp: null, pnts: null, sps: null)
  • finShowEquipSummaryRecur(inp, ind: 0, extra: null)
  • finSoftDelete(recs)
  • finStrGet(g, s: 0, e: null)
  • finStringSearchDicts(dictlist, dict1, dict2, col)
  • finStringSplitDicts(dictlist, col, splt, transform, newcol)
  • finSuperTagger(filter, column, matchList)
  • finSuperTaggerForm(id)
  • finSyncPoints(connIds, fromOrd, toOrd)
  • finSyncToColl(filter, isCollectOnInter, collectInterval, intervalUnits, isCOV, covInterval, basu: false)
  • finTagBlackList()
  • finTemplates()
  • finThemeUsed()
  • finToNumberList(s)
  • finToggleImmediateSubscriptions(action: "hide", filterStr: "", jobRec: null)
  • finTuningPolicyGetStats(policyList, byPolicy: false)
  • finTuningPolicyStatsForm(id: null, selectedDicts: null)
  • finUnique(g, colNames)
  • finUniqueConnectors(filter, connType)
  • finUniqueEquipTypes(filter, percentMatch, applyTags: false, tag: "navName")
  • finUniqueEquipTypes2(filter, percent, applyTags, tag: "navName")
  • finUpdateRecordsIgnoredTags()
  • finUpdateRecordsIgnoredTags2(obj)
  • finUploadSavedRecordsForm(stage: null, data: null, type: null)
  • finValidConnectors(connType)
  • finWriteBin(rec, tag, buf)
  • finWriteLevels(recs, conntype, wlevel, transfer)
  • finZincTagBatchEdit(recs, tagName, oldRow, newRow)
  • finZincTagBatchList(recs, tagName)
  • findPod(name)
  • findPointNames(equip, tag: "navName")
  • funcDefs()
  • getEventsData(id, catalog)
  • getHisTags()
  • …(其余标题见英文正文)

概述(中译) ​

finFormStringSearchTransPrev(数据, 分割, 姓, 名, 英文名, 父名, en)

轴突功能


API 正文(英文) ​

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(data, split, sname, fname, ename, pname, en) => do
  filt: data[0]
  col: data[1]
  list: []
  try do
    rec: finStringSearchDicts(readAll(parseFilter(filt)) ,{type: data[2]->val, value: data[3], char: data[4], disable: not en[0]}, {type1: data[5]->val, val1: data[6], type2: data[7]->val, val2: data[8], disable: not en[1]}, col).find(x=> x.has(col))
    list = list.add(col +": "+ rec.trap(col))

    if(sname != "") list = list.add("siteName:      "+ finStringSplitDicts([rec], col, split, eval("["+sname+"]"), "test")[0]->test)
    else if(rec.has("siteName")) list = list.add("siteName:     "+ rec->siteName)
    else list = list.add("siteName:     ")

    if(fname != "") list = list.add("floorName:     "+ finStringSplitDicts([rec], col, split, eval("["+fname+"]"), "test")[0]->test)
    else if(rec.has("floorName")) list = list.add("floorName:     "+ rec->floorName)
    else list = list.add("floorName:     ")

    if(ename != "") list = list.add("equipName:     "+ finStringSplitDicts([rec], col, split, eval("["+ename+"]"), "test")[0]->test)
    else if(rec.has("equipName")) list = list.add("equipName:     "+ rec->equipName)
    else list = list.add("equipName:     ")

    if(pname != "") list = list.add("pointName:     "+ finStringSplitDicts([rec], col, split, eval("["+pname+"]"), "test")[0]->test)
    else if(rec.has("pointName")) list = list.add("pointName:     "+ rec->pointName)
    else list = list.add("pointName:     ")
  end catch(e) list = [col+": None Found","siteName:      null","floorName:     null","equipName:     null","pointName:     null"]

  list
end


def ​

func:finFormStringSearchTransStats ​

finFormStringSearchTransStats() ​

Backend function for finFormStringSearchTrans


meta ​

deffunc:finFormStringSearchTransStats
finString✓
isfunc
liblib:finTools
namefinFormStringSearchTransStats

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  filt: read(finString and settings and primary)->filt.replace("and not changed","").trim
  col: read(finString and settings and primary)->col.trim
  text: toLocale("finStackExt::finFilter")+": "+ filt +"\n"
  text = text +toLocale("j2FinToolsExt::recordsPrompt")+": " + readCount(parseFilter(filt)) + "\n\n"

  if(readCount(siteName) > 0) sname: readAll(siteName).unique("siteName").size else sname: 0
  if(readCount(floorName) > 0) fname: readAll(floorName).unique("floorName").size else fname: 0
  if(readCount(equipName) > 0) ename: readAll(equipName).unique("equipName").size else ename: 0
  if(readCount(pointName) > 0) pname: readAll(pointName).unique("pointName").size else pname: 0

  text = text + toLocale("j2FinToolsExt::siteName") +":    \t"+ sname +" site(s)    \t"+ readCount(point and siteName) +" done   \t"+ readCount(point and not siteName) +" left\n"
  text = text + toLocale("j2FinToolsExt::floorName") +":   \t"+ fname +" floor(s)   \t"+ readCount(point and floorName) +" done   \t"+ readCount(point and not floorName) +" left\n"
  text = text + toLocale("j2FinToolsExt::equipName") +":   \t"+ ename +" equip(s)   \t"+ readCount(point and equipName) +" done   \t"+ readCount(point and not equipName) +" left\n"
  text = text + toLocale("j2FinToolsExt::pointName") +":   \t"+ pname +" point(s)   \t"+ readCount(point and pointName) +" done   \t"+ readCount(point and not siteName) +" left"

  lst: [
    {dis: toLocale("j2FinToolsExt::showItem").replace("{item}", "not siteName"), val: "not siteName"},
    {dis: toLocale("j2FinToolsExt::showItem").replace("{item}", "not floorName"), val: "not floorName"},
    {dis: toLocale("j2FinToolsExt::showItem").replace("{item}", "not equipName"), val: "not equipName"},
    {dis: toLocale("j2FinToolsExt::showItem").replace("{item}", "not pointName"), val: "not pointName"}
  ]

  body: [
    {name: "stats", editorType: "textarea", prompt:  toLocale("j2FinToolsExt::stats"), defVal: text, editable: false, height: 110},
    {name: "list", editorType: "list", dataProvider: lst.toAxonCode, listType: "checkbox", labelField: "dis", selectedValueTags: "val", height: 100},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
  ]

  { "dis": toLocale("j2FinToolsExt::stringParser"),
    "name": "finFormStringSearchTransStats",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "",
    "gotoAction": "finstack:folio:axonQuery=readAll(parseFilter([\""+filt+"\"].addAll(\$list).concat(\" and \"))).keepCols([\""+col+"\",\"id\",\"pointName\",\"equipName\",\"floorName\",\"siteName\"])",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finFormSyncToColl ​

finFormSyncToColl(pointList: null, ptType: null) ​

Axon function


meta ​

appFormOnfolio
deffunc:finFormSyncToColl
distoLocale("j2FinToolsExt::hisToCollected")
folderPathtoLocale("j2FinToolsExt::databaseCleanUp")
isfunc
liblib:finTools
namefinFormSyncToColl

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(pointList: null, ptType: null) => do
  instructions:"This form will use the filter below to find a list of records, and then allow you to change their history to collected. If a point filtered for doesn't have a his tag, it will be added and changed to collected."
  covInfo:"This will not affect boolean points as they are either COV or not."
  intervalTime:"How often history will be collected."
  intervalOn:"Check this box to enable collection interval."
  covOn: "Check this box to enable COV."

  units:[{typeUnit: "sec"}, {typeUnit: "min"}, {typeUnit: "hr"}]
  commitAct: "finSyncToColl(" + pointList.toRecList.map(r=> r->id).toAxonCode + ", \$collectEvery, \$collectInterval, \$intervalUnits, \$covCheckbox, 5)"

  intervalDef: true
  collectDef: 15
  unitsIndex: 1
  covDef: false
  covCollectDef: 5

  if(pointList != null and not pointList.isEmpty()) do
    intervalDef = pointList[0].has("hisCollectInterval")
    covDef = pointList[0].has("hisCollectCov")

    if(intervalDef) do
      collectDef = pointList[0]->hisCollectInterval
      unitsIndex = units.map(r => r->typeUnit).index(pointList[0]->hisCollectInterval.unit)
    end

    if(covDef and pointList[0]->kind == "Number") covCollectDef = pointList[0]->hisCollectCov
  end else if(pointList != null)
    intervalDef = false

  body: [
    {name: "collectEvery", editorType: "checkbox", label: toLocale("j2FinToolsExt::collectedOnTimedInterval") + ":", defVal: intervalDef, toolTip: intervalOn},
    {
      name: "intervalGrp",
      editorType: "group",
      prompt: toLocale("j2FinToolsExt::collectEvery") + ":",
      horizontal,
      children: [
        //{name: "intLablel", editorType: "label", text: "Collect every"},
        {name: "collectInterval", editorType: "numericstepper", defVal: collectDef, toolTip: intervalTime, width: 350},
        {name: "intervalUnits", editorType: "combobox", dataProvider: units.toAxonCode, labelField: "typeUnit", selectedValueTags: "typeUnit", defIndex: unitsIndex}
      ]
    },
    {name: "covCheckbox", editorType: "checkbox", label: toLocale("j2FinToolsExt::collectOnCov"), defVal: covDef, toolTip: covOn},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
  ]

  if(pointList != null and pointList[0]->kind == "Number") do
    body = body.add({name: "covInterval", editorType: "numericstepper", prompt: toLocale("j2FinToolsExt::onCovMoreThan") + ":", defVal: covCollectDef, toolTip: covInfo})
    commitAct = "finSyncToColl(" + pointList.toRecList.map(r=> r->id).toAxonCode + ", \$collectEvery, \$collectInterval, \$intervalUnits, \$covCheckbox, \$covInterval)"
  end else if(pointList == null) do
    body = body.insertAll(0, [
      {
        name: "filterPicker",
        editorType: "filter",
        toolTip: instructions,
        prompt:toLocale("j2FinToolsExt::hisCollectPointFilter"),
        encapsulate: true
      },

      {
        name: "collectSeprator",
        editorType: "separator",
        text: toLocale("j2FinToolsExt::collectionSettings")
      }
    ])

    body = body.add({name: "covInterval", editorType: "numericstepper", prompt: toLocale("j2FinToolsExt::onCovMoreThan")+":", defVal: covCollectDef, toolTip: covInfo})

    commitAct = "finSyncToColl(\$filterPicker, \$collectEvery, \$collectInterval, \$intervalUnits, \$covCheckbox, \$covInterval)"
  end

  {
    "dis": toLocale("j2FinToolsExt::hisToCollected"),
    "name": "finFormSyncToColl",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": commitAct,
    "gotoAction": "finstack:folio:axonQuery=readCount(\$filterPicker)",
    "helpDoc":"/wiki/display/FINStack/His+to+Collected",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finFormTagDuplicate ​

finFormTagDuplicate() ​

Axon function


meta ​

appFormOnfolio
deffunc:finFormTagDuplicate
distoLocale("j2FinToolsExt::duplicateTag")
folderPathtoLocale("finStackExt::advanced")+"/"+toLocale("j2FinToo...
isfunc
liblib:finTools
namefinFormTagDuplicate

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  body: [
    {name: "filter", editorType: "filter", prompt: toLocale("j2FinToolsExt::recordFilter")+":"},
    {name: "tag", editorType: "textinput", prompt: toLocale("j2FinToolsExt::tagToDuplicate")+":"},
    {name: "new", editorType: "textinput", prompt: toLocale("j2FinToolsExt::duplicatedTagName")+":"},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
  ]

  { "dis":toLocale("j2FinToolsExt::duplicateTag"),
    "name": "finFormTagDuplicate",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "readAll(parseFilter(\$filter)).each x=> if(x.has(\$tag)) x.diff({\$new: x.trap(\$tag)}).commit",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finFormTagSplitAndRename ​

finFormTagSplitAndRename(id, selectedDicts) ​

Axon function


meta ​

deffunc:finFormTagSplitAndRename
distoLocale("j2FinToolsExt::massRenameStringTags")
folderPathtoLocale("j2FinToolsExt::batchEditAndClone")
formOnpoint and not schedule
isfunc
liblib:finTools
namefinFormTagSplitAndRename
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id, selectedDicts) => do
  tagBlackList: ["actions", "bacnetCur", "curErr", "curStatus", "enum", "hisId", "hisStatus", "kind", "recipientRefs", "tz", "unit", "writeStatus", "navName"]
  selectedDicts = selectedDicts.map r => r->id
  filterDef: "id == " + id.toAxonCode
  loading: true

  if(selectedDicts.size > 1)
    filterDef = "id == @" + selectedDicts.concat(" or id==@")

  body: [
    {//filter
      name: "pointFilter",
      editorType: "filter",
      prompt: toLocale("finStackExt::finFilter")+":",
      defVal: filterDef
    },

    {//target tag
      name: "targetTag",
      editorType: "combobox",
      prompt: toLocale("finStackExt::tag")+":",
      dataProvider: "try [{name: \"navName\"}].toGrid.addRows(readAllTagNames(parseFilter(\$pointFilter)).findAll(v => v->kind == \"Str\" and not contains("+tagBlackList.toAxonCode+", v->name)).sort(\"name\")) catch [{name: \"Invalid Filter\"}]",
      labelField: "name",
      selectedValueTags: "name",
      encapsulate: false,
      defIndex: 0
    },

    {//splits
      name: "splitInput",
      editorType: "textinput",
      prompt: toLocale("j2FinToolsExt::splitVal")+":",
      defVal: "\" \"",
    },

    {//renames
      name: "patternInput",
      editorType: "textinput",
      prompt: toLocale("j2FinToolsExt::elementRenamed")+":",
      defVal: "1"
    },

    {//sample selctor
      name: "samplePoint",
      editorType: "combobox",
      prompt: toLocale("j2FinToolsExt::samplePoint")+":",
      dataProvider: "finFindTargetsForStrTagRename(\"\$targetTag\", \$pointFilter, \$splitInput)", //"if((\"\$targetTag\").isEmpty) readAll(parseFilter(\$pointFilter +\" and navName\")).map(r => r.set(\"dis\", r.dis)).sort(\"dis\") else try readAll(parseFilter(\$pointFilter +\" and \"+ \"\$targetTag\")).map(r => r.set(\"dis\", r.dis)).sort(\"dis\") catch []",
      labelField: "dis",
      selectedValueTags: "id",
      encapsulate: false,
      defIndex: 0
    },

    {//results
      name: "sampleResult",
      editorType: "list",
      listType: "checkbox",
      dataProvider: "try finGenerateSampleTagValue(parseRef(\"\$samplePoint\"[1..-1], false), \"\$targetTag\", \$splitInput, \$patternInput) catch []",
      labelField: "display",
      height: 50
    },

    {//apply now
      name: "applyNow",
      editorType: "checkbox",
      label: toLocale("j2FinToolsExt::applyNow")
    },

    {name:"cancelButton", editorType:"button", label:toLocale("finStackExt::cancel"), controlBar:true},
    {name:"commitButton", editorType:"button", label:toLocale("finStackExt::okay"), controlBar:true}
  ]

  loading = false

  try { "dis":toLocale("j2FinToolsExt::massRenameStringTags"),
    "name": "finFormTagSplitAndRename", //else "finFormTagSplitAndRename" + random(1..10000),
    "body":body.toJSON,
    "width": 450,
    "cancelButton": "\$cancelButton",
    "commitButton":"\$commitButton",
    "commitAction": "if(\$applyNow) finGenerateSampleTagValue(readAll(parseFilter(\$pointFilter)).colToList(\"id\"), \"\$targetTag\", \$splitInput, \$patternInput, true) else finFormDisplayTagRenames(\$pointFilter, \"\$targetTag\", \$splitInput, \$patternInput)",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
  catch ""
end


def ​

func:finFormTempToReal ​

finFormTempToReal(stage: null, data: null, delet: null) ​

Form to move prepared tempPoints into the project hierarchy


meta ​

deffunc:finFormTempToReal
distoLocale("j2FinToolsExt::importTempToProj")
finString✓
folderPathtoLocale("finStackExt::advanced")+"/"+toLocale("j2FinToo...
formOn(point or tempPoint) and not schedule
isfunc
liblib:finTools
namefinFormTempToReal

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(stage: null, data: null, delet: null) => do
  query:{ "dis": toLocale("j2FinToolsExt::importTempToProj"),
          "name": "finFormTempToReal",
          "cancelButton": "\$cancelButton",
          "commitButton": "\$applyButton",
          "commitAction": "",
          "finForm": marker() }
  runquer: true
  ////////////////////////////
  if(stage != 1) do //first form
    one: "[{msg: "+toLocale("j2FinToolsExt::totalPoints").toAxonCode+", data: try readCount(parseFilter(\$filter)) catch 0},"
    two: "{msg: "+toLocale("j2FinToolsExt::existingSite").toAxonCode+", data: finFormTempToRealStats(\$filter, \"es\")},"
    three: "{msg: "+toLocale("j2FinToolsExt::newSites").toAxonCode+", data: finFormTempToRealStats(\$filter, \"ns\")},"
    four: "{msg: "+toLocale("j2FinToolsExt::existingFloors").toAxonCode+", data: finFormTempToRealStats(\$filter, \"ef\")},"
    five: "{msg: "+toLocale("j2FinToolsExt::newFloors").toAxonCode+", data: finFormTempToRealStats(\$filter, \"nf\")},"
    six: "{msg: "+toLocale("j2FinToolsExt::existingEquips").toAxonCode+", data: finFormTempToRealStats(\$filter, \"ee\")},"
    seven: "{msg: "+toLocale("j2FinToolsExt::newEquips").toAxonCode+", data: finFormTempToRealStats(\$filter, \"ne\")}]"
    body: [
    {name: "filter", editorType: "filter", prompt: toLocale("j2FinToolsExt::searchRecords"), defVal: "tempPoint and changed"},
    {name: "table", editorType: "table", prompt: toLocale("j2FinToolsExt::stats"), dataProvider: one+two+three+four+five+six+seven},
    {name: "label", editorType: "separator", label: ""},
    {name: "delet", editorType: "checkbox", label: toLocale("j2FinToolsExt::deleteAllTempPoints"), defVal: false},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "applyButton", editorType: "button", label: toLocale("finStackExt::import"), controlBar: true}
    ]

    query = query.set("commitAction", "finFormTempToReal(1, \$filter, \$delet)")
  end
  else if(stage == 1) do
    if(delet) readAll(tempPoint and not changed).each x=> x.diff({trash}).commit

    recs: readAll(parseFilter(data)).findAll(x=> x.has("pointName") and x.has("equipName"))
    site: ""
    floor: ""
    equip: ""
    point: ""
    recs.each x=> do
      if(not x.has("siteName")) x = x.set("siteName", "finMockSite")
      if(not x.has("floorName")) x = x.set("floorName", "finMockFloor")
      point = x->pointName

      if(readCount(parseFilter("site and dis==\""+x->siteName+"\"")) == 0) site = diff(null,{dis: x->siteName, geoCountry: "US", geoState: "CA", site: marker(), tz: now().tz, test: marker()},{add}).commit->id
      else site = read(parseFilter("site and dis==\""+x->siteName+"\""))->id
      if(readCount(parseFilter("floor and dis==\""+x->floorName+"\" and siteRef==@"+site)) == 0) floor = diff(null,{dis: x->floorName, siteRef: site, floor: marker(), test: marker()},{add}).commit->id
      else floor = read(parseFilter("floor and dis==\""+x->floorName+"\" and siteRef==@"+site))->id
      if(readCount(parseFilter("equip and navName==\""+x->equipName+"\" and floorRef==@"+floor+" and siteRef==@"+site)) == 0) equip = diff(null,{disMacro: "\$siteRef \$navName", navName: x->equipName, floorRef: floor, siteRef: site, equip: marker(), test: marker()},{add}).commit->id
      else equip = read(parseFilter("equip and navName==\""+x->equipName+"\" and floorRef==@"+floor+" and siteRef==@"+site))->id

      x.diff({navName: point, equipRef: equip, floorRef: floor, siteRef: site, point: marker(), -tempPoint, -changed}).commit
    end
    runquer = false
  end

  if(runquer) query.set("body", body.toJSON).toGrid.addMeta({formExecute: marker()})
end


def ​

func:finFormTempToRealStats ​

finFormTempToRealStats(filter, type) ​

Axon function


meta ​

deffunc:finFormTempToRealStats
finString✓
isfunc
liblib:finTools
namefinFormTempToRealStats

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filter, type) => do
  counter: 0
  try work: readAll(parseFilter(filter)) catch work: null
  if(work == null) type = "nope"

  if(type == "es") do //existing site
    try work = work.colToList("siteName").unique.findAll(x=> x!=null) catch work = []
    work.each x=> if(readCount(parseFilter("site and dis==\""+x+"\"")) > 0) counter = counter + 1
  end
  else if(type == "ns") do //new site
    try work = work.colToList("siteName").unique.findAll(x=> x!=null) catch work = []
    work.each x=> if(readCount(parseFilter("site and dis==\""+x+"\"")) == 0) counter = counter + 1
  end
  else if(type == "ef") do //existing floor
    try work = work.colToList("floorName").unique.findAll(x=> x!=null) catch work = []
    work.each x=> if(readCount(parseFilter("floor and dis==\""+x+"\"")) > 0) counter = counter + 1
  end
  else if(type == "nf") do //new floor
    try work = work.colToList("floorName").unique.findAll(x=> x!=null) catch work = []
    work.each x=> if(readCount(parseFilter("floor and dis==\""+x+"\"")) == 0) counter = counter + 1
  end
  else if(type == "ee") do //existing equip
    try work = work.colToList("equipName").unique.findAll(x=> x!=null) catch work = []
    work.each x=> if(readCount(parseFilter("equip and navName==\""+x+"\"")) > 0) counter = counter + 1
  end
  else if(type == "ne") do //new equip
    try work = work.colToList("equipName").unique.findAll(x=> x!=null) catch work = []
    work.each x=> if(readCount(parseFilter("equip and navName==\""+x+"\"")) == 0) counter = counter + 1
  end

  counter
end


def ​

func:finFormTextArea ​

finFormTextArea(title, text, height: 250, width: 450) ​

Axon function


meta ​

deffunc:finFormTextArea
isfunc
liblib:finTools
namefinFormTextArea

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(title, text, height:250, width: 450) => do
  body: [
    {
      name:"textArea",
      editorType: "textarea",
      defVal: text,
      editable: false,
      height: height,
      //width: width
    },

    {
      name:"commitButton",
      editorType:"button",
      label:toLocale("finStackExt::okay"),
      controlBar:true
    }
  ]

  { "dis": title,
    "name":"simpleFormTextArea",
    "body":body.toJSON,
    "width": width,
    "commitButton":"\$commitButton",
    "commitAction": "",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finFormTextareaOk ​

finFormTextareaOk(title, text, height: null) ​

Axon function


meta ​

deffunc:finFormTextareaOk
isfunc
liblib:finTools
namefinFormTextareaOk

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(title, text, height: null) => do
  if(not height.isNumber) height = 100

  body: [
  {name: "text", editorType: "textarea", editable: false, defVal: text.toStr, height: height},
  {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::ok"), controlBar: true},
  ]

  {"dis": title.toStr,
  "name": "finFormTextareaOk",
  "body": body.toJSON,
  "cancelButton": "\$cancelButton",
  "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finFormUniqueEquipTypes ​

finFormUniqueEquipTypes(stage: null) ​

Axon function


meta ​

appFormOnfolio
deffunc:finFormUniqueEquipTypes
distoLocale("j2FinToolsExt::viewUniqueEquips")
folderPathtoLocale("finStackExt::advanced")
isfunc
liblib:finTools
namefinFormUniqueEquipTypes

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(stage: null) => do
  if(not stage.isList) do
    body: [
      {name: "filter", editorType: "filter", defVal: "equip", prompt: toLocale("finStackExt::finFilter")},
      {name: "percent", editorType: "numericstepper", minVal: 0, maxVal: 100, defVal: 80, prompt: toLocale("j2FinToolsExt::percentage")},
      {name: "tapply", editorType: "combobox", dataProvider: "[true, false]", labelField: "val", selectedValueTags: "val", defIndex: 1, prompt: toLocale("finStackExt::applyTags")},
      {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
      {name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    { "dis": toLocale("j2FinToolsExt::viewUniqueEquips"),
      "name": "finFormUniqueEquipTypes",
      "body": body.toJSON,
      "cancelButton": "\$cancelButton",
      "commitButton": "\$applyButton",
      "commitAction": "finFormUniqueEquipTypes([\$filter, \$percent, \$tapply])",
      "gotoAction": "finstack:folio:axonQuery=finUniqueEquipTypes(toStr(`\$filter`), \$percent, \$tapply).map r=> r.set(\"equipIds\", r->equipIds.split(\",\").map(g=> readById(g.split(\"@\")[1].parseRef)->navName +\" \"+g ).concat(\", \"))",
      "helpDoc": "/wiki/display/FINStack/View+Unique+Equips",
      "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end else do
    body: [
      {
        name: "results",
        editorType: "table",
        prompt: toLocale("finStackExt::reportsResults"),
        dataProvider: "finUniqueEquipTypes("+toAxonCode(stage[0])+", "+stage[1]+", "+stage[2]+").map r=> r.set(\"equipIds\", r->equipIds.split(\",\").map(g=> readById(g.split(\"@\")[1].parseRef)->navName +\" \"+g ).concat(\", \"))"},
      {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::ok"), controlBar: true}
    ]

    { "dis": toLocale("j2FinToolsExt::viewUniqueEquips"),
      "name": "finFormUniqueEquipTypes2",
      "body": body.toJSON,
      "cancelButton": "\$cancelButton",
      "helpDoc": "/wiki/display/FINStack/View+Unique+Equips",
      "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
end


def ​

func:finFormUniqueTagsEasy ​

finFormUniqueTagsEasy(stage: null) ​

Axon function


meta ​

appFormOnfolio
deffunc:finFormUniqueTagsEasy
distoLocale("j2FinToolsExt::findUniqueTags")
folderPathtoLocale("j2FinToolsExt::databaseCleanUp")
isfunc
liblib:finTools
namefinFormUniqueTagsEasy

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(stage:null) => do
  if(not stage.isList) do
    cmdstr: "finUniqueTags(\$cbox).map(x=> {count: try readCount(parseFilter(x->markers.replace(\",return\",\"\").replace(\",\",\" and \"))) catch x->count, name: try readCount(parseFilter(x->markers.replace(\",return\",\"\").replace(\",\",\" and \")))+\" - \"+x->markers catch toLocale(\"j2FinToolsExt::noValidMarkerTags\"), markers: x->markers}).sortr(\"count\")"
    cmdstr2: "split(read(navMeta)->equipPath,\"/\").remove(0).map(x=> {name: x.capitalize, val: x}).addAll([{name: toLocale(\"j2FinToolsExt::bacnetConnectors\"), val: \"bacnetConn\"},{name: toLocale(\"finStackExt::rightMenuSchedulesTitle\"), val: \"schedule\"},{name: toLocale(\"j2FinToolsExt::bLinePrograms\"), val: \"program\"},{name: toLocale(\"finStackExt::tunPolicies\"), val: \"conntuning\"}])"

    body: [
      {name: "cbox", editorType: "combobox", prompt: toLocale("j2FinToolsExt::navMetaElems")+":", dataProvider: cmdstr2, labelField: "name", selectedValueTags: "val", defIndex: 0},
      {name: "uniqueList", editorType: "list", prompt: toLocale("j2FinToolsExt::uniqueTags"), dataProvider: cmdstr, listType: "checkbox", resultType: "list", labelField: "name", selectedValueTags: "markers", height: 200},
      {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
      {name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    {
      "dis": toLocale("j2FinToolsExt::findUniqueTags"),
      "name": "finFormUniqueTagsEasy",
      "body": body.toJSON,
      "cancelButton": "\$cancelButton",
      "commitButton": "\$applyButton",
      "commitAction": "finFormUniqueTagsEasy([\$uniqueList])",
      "gotoAction": "finstack:folio:axonQuery=readAll(parseFilter(\$uniqueList.concat(\" or \").replace(\",\",\" and \")))",
      "helpDoc":"/wiki/display/FINStack/Find+Unique+Tags",
      "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end else do
    body: [
      {name: "results", editorType: "table", prompt: toLocale("finStackExt::reportsResults"), dataProvider: "readAll(parseFilter("+toAxonCode(stage[0])+".concat(\" or \").replace(\",\",\" and \")))"},
      {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::ok"), controlBar: true}
    ]

    {
      "dis": toLocale("j2FinToolsExt::findUniqueTags"),
      "name": "finFormUniqueTagsEasy2",
      "body": body.toJSON,
      "cancelButton": "\$cancelButton",
      "helpDoc":"/wiki/display/FINStack/Find+Unique+Tags",
      "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
end


def ​

func:finFormUpdateConnectors ​

finFormUpdateConnectors(id, selectedDicts, fromDB: null, reopen: false) ​

Axon function


meta ​

deffunc:finFormUpdateConnectors
distoLocale("j2FinToolsExt::updateConnectors")
folderPathtoLocale("finStackExt::advanced")
formOnregion or site or floor or equip or (point and not sched...
helpUpdate connectors
isfunc
liblib:finTools
namefinFormUpdateConnectors

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id, selectedDicts, fromDB: null, reopen: false) => do
  if(id != null) do
    selectedIds:  [id.toAxonCode]

    if(selectedDicts != null)
      selectedIds = selectedDicts.map(r => r->id.toAxonCode)
  end

  if (reopen == null) reopen = false

  action: ""
  existDataP: if(fromDB == null) "finExistingConnectors(" + selectedIds.toAxonCode() + ",\$connType)" else "finExistingConnectors(" + selectedIds.toAxonCode() + ","+fromDB->connType.toAxonCode+").findAll(v => v->id != \""+fromDB->conn.toAxonCode+"\")"

  body: [
    {
      name: "existingConnectors",
      editorType: "list",
      listType: "checkbox",
      prompt: (if(fromDB == null) toLocale("j2FinToolsExt::selectConnsOnPtsToUpdate") else toLocale("j2FinToolsExt::selectConnsToReplace").replace("{connType}", fromDB->connType).replace("{connDis}", fromDB->conn.readById.dis)) + ":",
      height: 150,
      dataProvider: existDataP,
      labelField: "dis",
      selectedValueTags: "id",
      toolTip: "This is all the connectors of a given type that currently exist in the selected points."
    },

    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "applyButton",  editorType: "button", label: toLocale("finStackExt::coreApply"),  controlBar: true}
  ]

  if(fromDB == null)
  do
    body = body.insert(0, {
      name: "connType",
      editorType: "combobox",
      prompt: toLocale("j2FinToolsExt::connectorTypes") + ":",
      //height: 100,
      dataProvider: "finSelectedConnectorTypes(" + selectedIds.toAxonCode() + ")",
      labelField: "type",
      selectedValueTags: "type",
      toolTip: "This is all the types of connector that currently exist in the selected points."
    }).add({
      name: "validConnectors",
      editorType: "combobox",
      prompt: toLocale("j2FinToolsExt::validConnsConfigured") + ":",
      //height: 150,
      dataProvider: "finValidConnectors(\$connType)",
      labelField: "dis",
      toolTip: "This is all the connectors of a given type that are present in the system."
    })

    if (reopen)
      body = body.insert(0, {name: "errMsg", editorType: "label", text: toLocale("j2FinToolsExt::selectExistingConnOnPoint")})

    action = "if (not isEmpty(\$existingConnectors)) finApplyUpdateConnectors(" + selectedIds.toAxonCode() + ",\$connType,\$existingConnectors,\$validConnectors) else finFormUpdateConnectors("+id.toAxonCode+", "+selectedDicts.toGrid.colToList("id").toAxonCode+".toRecList, null, true)"
  end
  else
    action = "finApplyUpdateConnectors(" + selectedIds.toAxonCode() + ", "+fromDB->connType.toAxonCode+", \$existingConnectors, "+fromDB->conn.readById.toAxonCode+")"

  { "dis": toLocale("j2FinToolsExt::updateConnectors"),
    "name": "updateConnectors"+random(0..1000),
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": action,
    "helpDoc":"/wiki/display/FINStack/Update+Connectors",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})

end


def ​

func:finFormWriteLevels ​

finFormWriteLevels() ​

Axon function


meta ​

appFormOnfolio
deffunc:finFormWriteLevels
distoLocale("j2FinToolsExt::changeWriteLevels")
folderPathtoLocale("j2FinToolsExt::databaseCleanUp")
isfunc
liblib:finTools
namefinFormWriteLevels

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  num: true
  cnames: finConnExts()
    .findAll(conn => readCount(parseFilter(conn->tag)) > 0)
    .colToList("name")

  comact: "finWriteLevels(\$filterPicker,\$radbut,\$numinput,\$chkbx)"

  body: [{
    name: "filterPicker",
    editorType: "filter",
    defVal: "(point and haystackWriteLevel) or (point and bacnetWriteLevel)",
    prompt: toLocale("j2FinToolsExt::recordFilter"),
    encapsulate: true
  }]

  if(cnames.size == 0) comact = "finWriteLevels(\$filterPicker,\"haystack\",\$numinput,\$chkbx)"
  else if(cnames.size == 1) comact = "finWriteLevels(\$filterPicker,\""+cnames[0]+"\",\$numinput,\$chkbx)"
  else cnames.each x=> do
    if(num) do
      body = body.add({name: "radbut", editorType: "radio", group: "g1", label: x.capitalize, selectedValue: x, defVal: true})
      num = false
    end
    else body = body.add({name: "radbut", editorType: "radio", group: "g1", label: x.capitalize, selectedValue: x})
  end

  body = body.addAll([
    {name: "numinput", editorType: "numericstepper", prompt:toLocale("j2FinToolsExt::connectorWriteLevel")+":", minVal: 1, maxVal: 16, defVal: 8},
    {name: "chkbx", editorType: "checkbox", label: toLocale("j2FinToolsExt::transferValue"), toolTip: "Invokes a write command at the new priority level and autos the old priority level"},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true
  }])

  {
    "dis": toLocale("j2FinToolsExt::changeWriteLevels"),
    "name": "finFormWriteLevels",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": comact,
    "helpDoc": "/wiki/display/FINStack/Change+Write+Levels",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finGenerateSampleTagValue ​

finGenerateSampleTagValue(id, targetTag, splitValue, renamePattern, commitResults: false) ​

Axon function


meta ​

deffunc:finGenerateSampleTagValue
isfunc
liblib:finTools
namefinGenerateSampleTagValue
overridable✓
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id, targetTag, splitValue, renamePattern, commitResults: false) => do
  pointRec: if(id.isList()) readByIds(id) else readById(id)
  targetVal: if(id.isList()) pointRec.findAll(v => v.has(targetTag)) else pointRec[targetTag]
  pattern: renamePattern.split(",")
  newValue: ""
  splitChar: ""
  //splitValue = splitValue.replace("\"", "")

  //for form list and commit
  if(id.isList()) do
    splitChar = splitValue.split("?")[0].replace("\"", "")
    if(splitValue.split("?") > 1) targetVal = eval(targetVal.toRecList.toAxonCode+".findAll(v => v->"+targetTag+".split("+splitChar.toAxonCode+").size " + splitValue.split("?")[1]+")")

    results: targetVal.map point => do
      tagVal: point[targetTag].split(splitChar)
      newValue = ""

      pattern.each x => do
        if(x.startsWith("\"") or x.startsWith("'") or x.parseInt(10, false) == null)
          newValue = newValue + x.replace("\"", "").replace("\\\"", "\"")
        else if(x.parseInt > 0)
          try newValue = newValue + tagVal[x.parseInt - 1] catch ""
        else
          try newValue = newValue + tagVal[x.parseInt] catch ""
      end

      if(commitResults) point.set(targetTag, newValue)
      else point.set("finFormDisplay", newValue + " ::: " + point[targetTag]).set(targetTag, newValue)
    end

    if(commitResults) results.each y => y.diff({}.set(targetTag, y[targetTag])).commit
    else return results
  end

  //for sample view
  else do
    if(splitValue.split("?")[0].replace("\"", "").size > 1)
      return [{display:toLocale("j2FinToolsExt::splitValErr")}]

    splitChar = splitValue.split("?")[0].replace("\"", "")

    /*if(splitValue.contains("?")) do
      targerVal = targetVal.split(splitChar).size
    end else*/
      targetVal = targetVal.split(splitChar)

    pattern.each x => do
      if(x.startsWith("\"") or x.startsWith("'") or x.parseInt(10, false) == null)
        newValue = newValue + x.replace("\"", "").replace("\\\"", "\"")
      else if(x.parseInt > 0)
        try newValue = newValue + targetVal[x.parseInt - 1] catch ""
      else
        try newValue = newValue + targetVal[x.parseInt] catch ""
    end

    return [{display: toLocale("j2FinToolsExt::original")+": " + pointRec[targetTag]}, {display: toLocale("j2FinToolsExt::afterRename")+": " + newValue}]
  end
end


def ​

func:finGetMinutesFromCur ​

finGetMinutesFromCur(cur, base) ​

Axon function


meta ​

baseChart✓
deffunc:finGetMinutesFromCur
isfunc
liblib:finTools
namefinGetMinutesFromCur
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(cur, base) => do
  numDays: 0
  minutes: 0

  curType: cur.debugType.toStr.replace("::", ",").split(",")[1]
  baseType: base.debugType.toStr.replace("::", ",").split(",")[1]

  if(curType == "FanSysFunc") cur = eval(cur.toStr)
  else if(curType != "Date") cur = cur.toStr.split(",")[0].parseDate

  if(baseType == "FanSysFunc") base = eval(base.toStr)
  else if(baseType != "Date") base = base.toStr.split(",")[0].parseDate

  numDays = cur - base
  numDays = numDays.toStr[0..-4].parseInt
  minutes = numDays * 24 * 60

  minutes = (minutes + "min").parseNumber
end


def ​

func:finGetPointRecords ​

finGetPointRecords(inp: null) ​

Get records from the PointRecords.zinc file in the finToolsExt pod to display in the batch record creator


meta ​

deffunc:finGetPointRecords
finUpdateRecords✓
isfunc
liblib:finTools
namefinGetPointRecords

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(inp: null) => do
  recs: ioReadZinc(`fan://j2FinToolsExt/assets/PointRecords.zinc`)
  levels: finNavMetaGetLevels().findAll(x=> x->name != inp).colToList("name").map(name=> name.replace("[","").replace("]","") )
  recs.finGridFilter(parseFilter("not "+ levels.concat(" and not ")))
end


def ​

func:finGetUriFromRef ​

finGetUriFromRef(grid, tags: ["imageRef"], fileTagName: "file") ​

Axon function


meta ​

constructfinGetUriFromRef(["imageRef"],"file")
deffunc:finGetUriFromRef
examplereadAll(site).finGetUriFromRef() readAll(site).finGetUri...
helpWill take a list of records, like readAll(site) and it w...
isfunc
liblib:finTools
namefinGetUriFromRef

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(grid, tags: ["imageRef"],fileTagName:"file") => do

    projectName: context()->projName
    result: grid.map(row =>
    do
      tags.each(tagName => do
          if (row.has(tagName))
            do
               row    = row.set(tagName.replace("Ref", "Uri"), ("/api/" + projectName + "/rec/" + row.get(tagName) + "/" + fileTagName).parseUri)
            end
        end)

        row
    end)

    result
end


def ​

func:finGlobalControl ​

finGlobalControl(id, selectedDicts: null, fromFilter: false) ​

This function opens a form that allows users to select points via a filter, or it takes in selected points, that will then allow the user to invoke command actions to all the selected points.

If a user selects one point, then the filter will be prefilled with the unique tags of that point. If no points are selected, then the filter will be empty.

If the user selects multiple points then no filter will be shown.


meta ​

appFormOnoldFolio, builder
deffunc:finGlobalControl
distoLocale("j2FinToolsExt::globalControl")
formOnpoint and not schedule
globalCont✓
isfunc
liblib:finTools
namefinGlobalControl

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id, selectedDicts:null, fromFilter:false) => do
  selectedIds: []
  pointType: null
  pointUnit: null
  matchingKind: true
  matchingUnit: true

  if(fromFilter == null or fromFilter == false)
    fromFilter = false
  /*from a "fresh" search*/
  else do
    selectedDicts = readAll(parseFilter(selectedDicts[0]->flt + " and writable")).toRecList
    id = selectedDicts[0]->id
  end

  if(id != null ) do
    if(readById(id).has("point")) do
      selectedIds = [id.toRec->id]
      pointType = readById(id)->kind
    else
      id = null
  end

  if(selectedDicts != null and id != null)
    selectedIds = selectedDicts.map(r => r.toRec->id)

  if(pointType == "Number")
    pointUnit = readById(id)["unit"]

  /*check if all points matchup*/
  selectedIds.toRecList.each point => do
    if(point->kind != pointType)
      matchingKind = false
    else if((pointUnit == null and point.has("unit")) or (pointUnit != null and (not point.has("unit") or point->unit != pointUnit)))
      matchingUnit = false
  end

  /*go to the proper form*/
  if(id == null and not fromFilter)
    finGlobalControlFilterForm(null)
  else if(selectedIds.size == 1 and not fromFilter) do
    finGlobalControlFilterForm(selectedIds)
  end else if(matchingKind and matchingUnit) do
    finGlobalControlForm(selectedIds, false)
  end else do
    if(matchingKind)
      finFormAlertOk(toLocale("finStackExt::regError"), toLocale("j2FinToolsExt::mismatchUnitTypeErr"))
    else
      finFormAlertOk(toLocale("finStackExt::regError"), toLocale("j2FinToolsExt::mismatchPointKindErr"))
  end
end


def ​

func:finGlobalControlActions ​

finGlobalControlActions(idList) ​

This function is part of "Global Control". It finds the actions available based of the first point passed. Actions are then returned for use in a comboBox.


meta ​

deffunc:finGlobalControlActions
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlActions

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(idList) => do
  actions: []
  durTime: false
  valPres: false

  /*find actions*/
  try do
  readById(idList[0]->id)->actions.split("\n").each act => do
      if(act.startsWith("\"")) do
        if(act.contains("duration")) durTime = true
        else durTime = false

        if(act.contains("val")) valPres = true
        else valPres = false
        act.split(",").each smallAct => do
          if(smallAct.startsWith("\"") and smallAct.endsWith("\"") and not smallAct.contains("\\\$"))
            actions = actions.add({name: smallAct.replace("\"", ""), dur: durTime, value: valPres})
        end
      end
    end
  end catch ""

  return actions
end


def ​

func:finGlobalControlCheckEnum ​

finGlobalControlCheckEnum(pointData) ​

This function is part of "Global Control". It finds the enums available based of the points passed. The enums are then returned for use in a comboBox. If all points do not have matching enums, then a single option is returned saying not all points have the same enums.


meta ​

deffunc:finGlobalControlCheckEnum
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlCheckEnum

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(pointData) => do
  curEnum: readById(pointData[0]->id)->enum
  matching: true
  enumList: [{dis: toLocale("j2FinToolsExt::noPointsSelected"), val: -1}]

  pointData.each x => do
    if(readById(x->id)->enum != curEnum)
      matching = false
  end

  if(matching) do
    enumList = []
    curEnum = curEnum.split(",")
    each(curEnum) (option, i) =>
      if(option != "") enumList = enumList.add({dis: option, val: i})
  end else
    enumList = [{dis: toLocale("j2FinToolsExt::notAllSelectedHaveSameEnums"), val: -1}]

  return enumList
end


def ​

func:finGlobalControlCommit ​

finGlobalControlCommit(idList, action, value, units, pointKind, duration: null, forever: null) ​

This function is part of "Global Control".

Commits all action to all points that have the action. Informs the user if any points were not commanded.


meta ​

deffunc:finGlobalControlCommit
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlCommit

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(idList, action, value, units, pointKind, duration:null, forever:null) => do
  success: true
  noGo:""
  dur: null

  if(forever == false)
    dur = parseNumber(duration->hours + (duration->min / 60) + (duration->sec / 3600) + "hr")
  if(pointKind == "Number" and value != null)
    value = parseNumber(value + units)

  idList.each point => do
    try invoke(point->id, action->name, {self:point->id,val:value,duration:dur})
    catch do
      success = false
      noGo = noGo + "\n -" + readById(point).dis
    end
  end

  if(success)
    if(action->value) finFormAlertOk(toLocale("j2FinToolsExt::complete"), toLocale("j2FinToolsExt::allPointsCommandedVal").replace("{value}", (value + units)).replace("{name}", action->name))
    else finFormAlertOk(toLocale("j2FinToolsExt::complete"), toLocale("j2FinToolsExt::allPointsCommanded").replace("{name}", action->name))
  else
    finFormAlertOk(toLocale("finStackExt::pointsStateWarning"), toLocale("j2FinToolsExt::notAllPointsHaveCommand").replace("{name}", action->name.toAxonCode) + " " + toLocale("j2FinToolsExt::followingPointsNotCommanded") + " " + noGo)
end


def ​

func:finGlobalControlDurForm ​

finGlobalControlDurForm(idList, action, value, units, kind) ​

This function is part of "Global Control".

If an action chosen requires a duration, this form will pop-up allowing the user to set the duration.


meta ​

deffunc:finGlobalControlDurForm
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlDurForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(idList, action, value, units, kind) => do
  body: [
    { name: "durationHours",
      prompt: toLocale("j2FinToolsExt::hoursCapital"),
      editorType:"numericstepper",
      minVal: 0,
      defVal: 1},

    { name: "durationMins",
      prompt: toLocale("j2FinToolsExt::minutesCapital"),
      editorType:"numericstepper",
      defVal: 0,
      minVal: 0,
      maxVal: 60},

    { name: "durationSecs",
      prompt: toLocale("finStackExt::secondsTime"),
      editorType:"numericstepper",
      defVal: 0,
      minVal: 0,
      maxVal: 60},

    { name: "forever",
      //prompt: "Forever",
      label: toLocale("finStackExt::forever"),
      editorType:"checkbox"},

    { name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true },
    { name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
  ]

  js: [
    "function checkJobStatus(jobHandle) {",
      "var promise;",
      "if (jobHandle === undefined) {",
        "promise = finstack.evalAll(['jobStatusAll().find(v => v->dis.startsWith(\"finGlobalControlCommit\") and v->started > "+now().toAxonCode+")']);",
      "} else {",
        "promise = finstack.evalAll(['jobStatusAll(\"'+jobHandle+'\")[0]']);",
      "}",
      "promise.then(function(event) {",
        "var jobStat = event.result[0].toObj(false, false, true);",
        "var isDone = jobStat['jobStatus'].startsWith('done');",
        "if (isDone) {",
          "window.top.app.HideLoader();",
        "} else {",
          //"var msg;",
          //"if (jobStat != null && jobStat != undefined) { msg = window.languageManager['loaderLoading'] + jobStat['progress'] + '%'; }",
          //"else { msg = window.languageManager['loaderLoading'] + '0%'; }",
          "window.top.app.HideLoader();",
          "window.top.app.ShowLoader(languageManager['commandingPoints']);",
          "setTimeout(function(){ checkJobStatus(jobStat['handle']); }, 2000);",
        "}",
      "});",
    "}",
    "window.top.app.ShowLoader(languageManager['commandingPoints']);",
    "checkJobStatus();"
  ]

  { "dis": toLocale("j2FinToolsExt::setActionDurarion"),
    "name": "finGlobalControlDurForm",
    "body": body.toJSON,
    "width": 250,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "jobRun(finGlobalControlCommit(" + idList.toAxonCode + ", " + action.toAxonCode + ", " + value.toAxonCode + ", " + units.toAxonCode + ", " + kind.toAxonCode + ", {hours: \$durationHours, min: \$durationMins, sec: \$durationSecs}, \$forever))",
    "completeAction": js.concat("\n"),
    "finForm": marker(),
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finGlobalControlFilterCheck ​

finGlobalControlFilterCheck(filterDict) ​

This function is part of "Global Control".

This form checks the filter to ensure all points are of the same kind and have the same units. If not, will return to the filter form with the filter used and informing the user of the error.


meta ​

deffunc:finGlobalControlFilterCheck
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlFilterCheck

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filterDict) => do
  tableData: filterDict[0]->tableR

  if(not tableData.isDict)
    tableData = tableData.find(v => v.has("aNumResults"))

  if (tableData->aNumResults == 0)
    finGlobalControlFilterForm(null, filterDict[0]->flt, toLocale("j2FinToolsExt::noMatchingWritablePointsFilter"))
  else if(tableData->cNumUnit == 1 and tableData->bNumKind == 1)
    finGlobalControl(null, filterDict, true)
  else if(tableData->bNumKind > 1)
    finGlobalControlFilterForm(null, filterDict[0]->flt, toLocale("j2FinToolsExt::mismatchPointKindErr"))
  else
    finGlobalControlFilterForm(null, filterDict[0]->flt, toLocale("j2FinToolsExt::mismatchUnitTypeErr"))
end


def ​

func:finGlobalControlFilterForm ​

finGlobalControlFilterForm(idList: null, flt: null, err: null) ​

This function is part of "Global Control".

Is a form that has a filter for the user to search for. Displays a table with the number of matching points, the number of different kinds, and the number of different units.

Also has checkboxes so the user can reduce the search to a certain point.


meta ​

deffunc:finGlobalControlFilterForm
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlFilterForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(idList:null, flt:null, err:null) => do
  filtIns: "Use this filter to search for points to command."
  tagList: []
  defa: "point and cmd"
  errMsg: false
  body: []

  if(idList == null and flt != null) do
    defa = flt
    body = body.add({name: "errLabel", editorType: "label", text: err})
  end else if(idList != null) do
    tagList = finUniqueTags(parseFilter("id==" + (if (idList[0].isRef) idList[0].toAxonCode else idList[0])))
    defa = tagList[0]->markers.split(",").concat(" and ")
  end

  body = body.addAll([
    { name: "filterPicker",
      editorType: "filter",
      toolTip: filtIns,
      defVal: defa,
      label:toLocale("finStackExt::pointFilter"), },

    { name: "table",
      editorType: "table",
      prompt: toLocale("j2FinToolsExt::filterResults"),
      height:150,
      editable: true,
      dataProvider: "finGlobalControlFilterTable(\$filterPicker)"},

    { name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true },
    { name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
  ])

  { "dis": toLocale("j2FinToolsExt::globalControl"),
    "name": "finGlobalControlFilterForm"+random(0..10000),
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "finGlobalControlFilterCheck([{flt: \$filterPicker, tableR: \$table}])",
    "helpDoc": "/wiki/display/FINStack/Global+Control",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finGlobalControlFilterTable ​

finGlobalControlFilterTable(filterThing) ​

This function is part of "Global Control".

For use with finGlobalControlFilterForm. Populates the table in that form.


meta ​

deffunc:finGlobalControlFilterTable
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlFilterTable

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filterThing) => do
  results: []
  tableRow: {}
  table:[]
  kinds: []
  units: []
  addErrMeta: false

  /*create the table to be displayed*/
  try do
    results = readAll(parseFilter(filterThing + " and writable"))

    results.each result => do
      if(not kinds.contains(result->kind)) kinds = kinds.add(result->kind)
      if(result.has("unit") and not units.contains(result->unit)) units = units.add(result->unit)
    end

    // add errors
    if (results.size == 0)
    do
      tableRow = {aErrorMessage: toLocale("j2FinToolsExt::noMatchingWritablePointsFilter")}
      table = table.add(tableRow)
      addErrMeta = true
    end

    if(kinds.size > 1) do
      tableRow = {aErrorMessage: toLocale("j2FinToolsExt::mismatchPointKindErr") + " " + toLocale("j2FinToolsExt::xPointKinds").replace("{number}", kinds.size.toStr)}
      table = table.add(tableRow)
      addErrMeta = true
    end

    if(units.size > 1) do
      tableRow = {aErrorMessage: toLocale("j2FinToolsExt::mismatchUnitTypeErr") + " " + toLocale("j2FinToolsExt::xPointUnits").replace("{number}", units.size.toStr)}
      table = table.add(tableRow)
      addErrMeta = true
    end

    // add valid results
    if(not tableRow.isEmpty())
      tableRow = {}

    tableRow = tableRow.set("aNumResults", results.size)
    tableRow = tableRow.set("bNumKind", kinds.size)
    tableRow = tableRow.set("cNumUnit", if(units.size == 0 and results.size > 0) 1 else units.size)

    table = table.add(tableRow)

    table = table.toGrid
    table = table.addColMeta("aNumResults", {dis: toLocale("j2FinToolsExt::numberOfResults")})
    table = table.addColMeta("bNumKind", {dis: toLocale("j2FinToolsExt::differentKinds")})
    table = table.addColMeta("cNumUnit", {dis: toLocale("j2FinToolsExt::differentUnits")})

    if (addErrMeta)
      table = table.addColMeta("aErrorMessage", {dis: toLocale("finStackExt::regError")})
  end
  catch ""

  return table
end


def ​

func:finGlobalControlForm ​

finGlobalControlForm(listOfIds, filterOn) ​

This function is part of "Global Control".

Main form. Shows a list of points that the user can choose from. Shows a combo box with the points actions, and finally a third field that is based off of point type. Third field will be what the new value will be. Enum = comboBox, String = input, Boolean = combobox, Number = numeric stepper.


meta ​

deffunc:finGlobalControlForm
globalCont✓
isfunc
liblib:finTools
namefinGlobalControlForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(listOfIds, filterOn) => do
  listInstr: "Check which point you would like to apply the command to. Only writable points show up."
  actionsIns: "Select which command you would like to apply to selected points."
  valInst: "Select the value you want to apply with the command."
  filtIns: "Use this filter to search for points to command."

  pointData: []
  actions: []
  notWrite: ""
  units: ""
  durTime: false
  valPres: false
  body:null
  tagList: []
  defa: ""
  valueFormObj: null
  pointKind: null

  listOfIds.each pointId => do
      if(readById(pointId).has("writable"))
        pointData = pointData.add({id: readById(pointId)->id, dis: readById(pointId).dis})
      else
        notWrite = notWrite + readById(pointId).dis + ", "
  end

  try units = readById(pointData[0]->id)->unit
  catch units = ""

  pointKind = if(readById(pointData[0]->id)->kind == "Str" and readById(pointData[0]->id).has("enum")) "Enum" else readById(pointData[0]->id)->kind

  h: if(pointData.size > 14) 325

  pointData = pointData.toGrid.sort("dis").toRecList

  body = {
    name: "pointsCommand",
    editorType: "list",
    prompt: toLocale("finStackExt::navMetaPoint") + ":",
    listType: "checkbox",
    defValTagName: "dis",
    toolTip: listInstr,
    //height: if(pointData.size > 14) 325,
    dataProvider: pointData.toAxonCode,//"readAll(forCombo)" ,
    labelField: "dis",
    selectedValueTags: "id"
  }

  if(pointData.size > 14)
    body = body.set("height", 325)

  body = [body]

  if(notWrite != "")
  do
    notWrite = notWrite[0..-3]
    body = body.add({name:"noWrite", editorType: "label", text: toLocale("j2FinToolsExt::followingHaveNoCommands") + notWrite})
  end

  /*find possible values based off of point kind*/
  if(pointKind == "Bool")
    valueFormObj = {
      name: "numberThing",
      prompt: toLocale("j2FinToolsExt::newValue") + ":",
      editorType:"combobox",
      toolTip: valInst,
      dataProvider: "if(\$actionsCombo->name.contains(\"Set Default\")) [{dis: \"" + toLocale("finStackExt::valTrue") + "\", val: true}, {dis: \"" + toLocale("finStackExt::valFalse") + "\", val: false}] else [{dis: \"" + toLocale("finStackMobileExt::coreNA") + "\", val: null}]",
      selectedValueTags: "val",
      labelField: "dis",
      defIndex: 0
    }
  else if(pointKind == "Number")
    valueFormObj = {
      name: "numberThing",
      prompt:  toLocale("j2FinToolsExt::newValue") +" ("+ units+"):",
      editorType:"numericstepper",
      toolTip: valInst
    }
  else if(pointKind == "Enum" )
    valueFormObj = {
      name: "numberThing",
      prompt: toLocale("j2FinToolsExt::newValue") + ":",
      editorType:"combobox",
      toolTip: valInst,
      dataProvider: "finGlobalControlCheckEnum(\$pointsCommand)",//.toAxonCode,
      selectedValueTags: "dis",
      labelField: "dis"
    }
  else if(pointKind == "Str")
    valueFormObj = {
      name: "numberThing",
      prompt: toLocale("j2FinToolsExt::newValue") + ":",
      editorType:"textinput",
      toolTip: valInst
    }

  /*add remaing form objects to body*/
  body = body.addAll([
    {
      name: "actionsCombo",
      editorType: "combobox",
      prompt: toLocale("finStackExt::jobMenuActions") + ":",
      toolTip: actionsIns,
      dataProvider: "finGlobalControlActions(\$pointsCommand)",
      labelField: "name",
      selectedValueTags:"name, value, dur"
    },

    valueFormObj,

    { name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true },
    { name: "applyButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
  ])

  js: [
    "function checkJobStatus(jobHandle) {",
      "var promise;",
      "if (jobHandle === undefined) {",
        "promise = finstack.evalAll(['jobStatusAll().find(v => v->dis.startsWith(\"finGlobalControlCommit\") and v->started > "+now().toAxonCode+")']);",
      "} else {",
        "promise = finstack.evalAll(['jobStatusAll(\"'+jobHandle+'\")[0]']);",
      "}",
      "promise.then(function(event) {",
        "var jobStat = event.result[0].toObj(false, false, true);",
        "var isDone = !jobStat || (jobStat.jobStatus && jobStat.jobStatus.startsWith('done'));",
        "if (isDone) {",
          "window.top.app.HideLoader();",
        "} else {",
          "window.top.app.HideLoader();",
          "window.top.app.ShowLoader(languageManager['commandingPoints']);",
          "setTimeout(function(){ checkJobStatus(jobStat['handle']); }, 2000);",
        "}",
      "});",
    "}",
    "window.top.app.ShowLoader(languageManager['commandingPoints']);",
    "checkJobStatus();"
  ]

  { "dis": toLocale("j2FinToolsExt::globalControl"),
    "name": "finGlobalControlForm",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "if(\$actionsCombo->dur) finGlobalControlDurForm(\$pointsCommand, \$actionsCombo, [null, \$numberThing][-1], " + units.toAxonCode + ", " + pointKind.toAxonCode + ") else jobRun(finGlobalControlCommit(\$pointsCommand, \$actionsCombo, [null, \$numberThing][-1], " + units.toAxonCode + ", " + pointKind.toAxonCode + "))",
    "completeAction": js.concat("\n"),
    "helpDoc": "/wiki/display/FINStack/Global+Control",
    "finForm": marker(),
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finGraphicsBatchTags ​

finGraphicsBatchTags(data: null, selectedItems: []) ​

Axon function


meta ​

appFormOnfolio
deffunc:finGraphicsBatchTags
distoLocale("j2FinToolsExt::batchTags")
folderPathtoLocale("j2FinToolsExt::graphicTools")
isfunc
liblib:finTools
namefinGraphicsBatchTags
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(data: null, selectedItems: []) => do
  if(data == null) do
    body: [
      {
        name: "files",
        editorType: "list",
        prompt: toLocale("finStackExt::rightMenuGraphicsTitle")+":",
        listType: "checkbox",
        height: 200,
        dataProvider: "readAll(fin5 and file).map(r => if(("+selectedItems.toAxonCode+").contains(r->id)) r.merge({selected}) else r).sort(\"dis\")",
        labelField: "dis",
        selectedValueTags: "id",
        defValTagName: "selected"
      },
      {name: "filter", editorType: "filter", prompt: toLocale("j2FinToolsExt::addTagsFilter")+":", defVal: ""},
      {name: "tags", editorType: "textinput", prompt: toLocale("finStackExt::notesOptionTags")+":", defVal: ""},
      {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
      {name: "commitButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    {"dis": toLocale("j2FinToolsExt::batchTags"),
    "name": "finGraphicsBatchTags",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",
    "commitAction": "finGraphicsBatchTags([\$files, \$tags, \$filter])",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
  ///////
  else do
    tmp: {}
    try dct: eval("{"+data[1]+"}") catch return finFormAlertOk(toLocale("finStackExt::regError"),toLocale("j2FinToolsExt::tagLineIncorrect") +": "+data[1])
    dct = dct.map(x=> if(x==marker()) "✓" else x)
    results: []
    cou: 0
    data[0].each x=> try do
      cou = 0
      tmp = readById(x).readFinFile
      tmp = tmp.map(y=> do
        if(toGrid([y]).finGridFilter(parseFilter(data[2])).size == 1) do
          cou = cou + 1
          y.merge(dct)
        end
        else y
      end)
      tmp.writeFinFile(x)
      results = results.add(readById(x).dis+":\n    "+toLocale("j2FinToolsExt::recWasModMulit").replace("{num}", cou.toStr)+"\n")
    end catch results = results.add(readById(x).dis+": "+toLocale("j2FinToolsExt::hadError")+" !!\n")

    x: finFormAlertOk(toLocale("j2FinToolsExt::results"),"")
    b: x[0]->body.ioReadJson.remove(0)
    b = b.add({name: "asdf", editorType: "textarea", defVal: results.concat("\n"), editable: false, height: 200})
    x.map(y=> y.set("body", b.toJSON))
  end
end


def ​

func:finGraphicsDeleteRecs ​

finGraphicsDeleteRecs(data: null, selectedItems: []) ​

Axon function


meta ​

appFormOnfolio
deffunc:finGraphicsDeleteRecs
distoLocale("j2FinToolsExt::deleteRecords")
folderPathtoLocale("j2FinToolsExt::graphicTools")
isfunc
liblib:finTools
namefinGraphicsDeleteRecs
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(data: null, selectedItems:[]) => do
  if(data == null) do
    body: [
    {name: "files", editorType: "list", prompt: toLocale("finStackExt::rightMenuGraphicsTitle")+":", listType: "checkbox", height: 200, defValTagName: "selected",
      dataProvider: "readAll(fin5 and file).map(r => if(("+selectedItems.toAxonCode+").contains(r->id)) r.merge({selected}) else r).sort(\"dis\")", labelField: "dis", selectedValueTags: "id"},
    {name: "filter", editorType: "filter", prompt: toLocale("j2FinToolsExt::recordFilter")+":", defVal: ""},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "commitButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    {"dis": toLocale("j2FinToolsExt::deleteRecords"),
    "name": "finGraphicsDeleteRecs",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",
    "commitAction": "finGraphicsDeleteRecs([\$files, \$filter])",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
  ///////
  else do
    tmp: {}
    results: []
    cou: 0
    data[0].each x=> try do
      tmp = readById(x).readFinFile
      cou = tmp.size
      tmp = tmp.findAll(y=> toGrid([y]).finGridFilter(parseFilter(data[1])).size == 0)
      cou = cou - tmp.size
      tmp.writeFinFile(x)
      results = results.add(readById(x).dis+":\n    "+toLocale("j2FinToolsExt::deletedNumRecords").replace("{num}", cou.toStr)+"\n")
    end catch results = results.add(readById(x).dis+": "+toLocale("j2FinToolsExt::hadError")+" !!\n")

    x: finFormAlertOk(toLocale("j2FinToolsExt::results"),"")
    b: x[0]->body.ioReadJson.remove(0)
    b = b.add({name: "asdf", editorType: "textarea", defVal: results.concat("\n"), editable: false, height: 200})
    x.map(y=> y.set("body", b.toJSON))
  end
end


def ​

func:finHardDelete ​

finHardDelete(recs) ​

A function to delete records permanently.

WARNING! Records can not be recovered.

e.g. read(foo).finHardDelete() //only one record readAll(point).finHardDelete() //multiple records


meta ​

deffunc:finHardDelete
isfunc
liblib:finTools
namefinHardDelete

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(recs) => do
  isRefs: recs.isRef or (recs.isList and not recs.isEmpty and recs.first.isRef)
  ids:    if (recs.isRef) [recs] else recs
  idsToDelete:  if (isRefs) finReadByIdsTrash(ids, false) else recs

  idsToDelete.toRecList.each x=> x.diff({},{remove}).commit
end


def ​

func:finHaystackHexReplaceForm ​

finHaystackHexReplaceForm(selectedDicts: null, stage: null) ​

Axon function


meta ​

deffunc:finHaystackHexReplaceForm
distoLocale("j2FinToolsExt::replaceHex")
folderPathtoLocale("finStackExt::rightMenuConnectors")+"/"+toLocal...
formOnhaystackConn
isfunc
liblib:finTools
namefinHaystackHexReplaceForm
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(selectedDicts: null, stage: null) => do
  if(stage != 1) do
    //plist: []
    //selectedDicts.each x=> do
    //  plist = plist.addAll(readAll(point and navName and haystackConnRef==x->id).findAll(y=> y->navName.contains("~")).colToList("id"))
    //end
    plist: readAll(navName and (point or equip)).findAll(y=> y->navName.contains("~")).colToList("id")

    hexes: []
    t: ""
    c: 0
    l: 0
    j: ""
    plist.each x=> do
      t = x.readById->navName
      c = 0
      l = size(t)
      (0..l - 1).eachWhile y=> do
        if(t[c..c] == "~") do
          c = c + 1
          j = t[c..c]
          if(parseInt(toStr(t[c+1 .. c+1]),16,false) != null) do
            c = c + 1
            j = j + t[c..c]
          end
          hexes = hexes.add(j)
        end
        c = c + 1
        if(c >= l) true
        else null
      end
    end
    hexes = hexes.unique

    body: [
    {name: "tbl", editorType: "table", prompt: toLocale("j2FinToolsExt::hexCharsWillBeReplaced")+":", dataProvider: hexes.map(x=> {h:x, c:toChar(parseInt(x,16))}).toAxonCode},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "commitButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    {"dis": toLocale("j2FinToolsExt::replaceHex"),
    "name": "finHaystackHexReplaceForm",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",
    "commitAction": "finHaystackHexReplaceForm("+toAxonCode(plist)+",1)",
    "helpDoc": "/wiki/spaces/FINStack/pages/148307998/Haystack+Hex+Replace",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end else do
    fixnames: (t) => do
      l: t.size
      n: ""
      c: 0
      j: ""
      (0..l - 1).eachWhile x=> do
        if(t[c..c] != "~") n = n + t[c..c]
        else do
          c = c + 1
          j = t[c..c]
          if(parseInt(t[c+1 .. c+1],16,false) != null) do
            c = c + 1
            j = j + t[c..c]
          end
          n = n + toChar(parseInt(j,16))
        end
        c = c + 1
        if(c >= l) true
        else null
      end
      n
    end
    selectedDicts.each x=> do
      x = x.readById
      x.diff({navName: fixnames(x->navName)}).commit
    end
  end
end


def ​

func:finHisImport ​

finHisImport(recc, furi, fn: "rewrite", dictt: {ts:"ts", val:"val"}, dtype: "number") ​

Function to import histories from a CSV file. Takes the point record to write to, the uri of the file, the "write" or "rewrite" parameter, and a dict specifying which column to get the timestamp from and which column to get the values to import.

finHisImport(record, <io/filename.csv>, "rewrite"/"write", {ts: "ts", val: "val"}, "number")


meta ​

deffunc:finHisImport
isfunc
liblib:finTools
namefinHisImport
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(recc, furi, fn:"rewrite", dictt:{ts: "ts", val: "val"}, dtype:"number") => do //imports history from a file to a point
  recc = recc.toRec
  file: []
  ioReadCsv(furi).each x=> file = file.add(x)
  tstp: dictt->ts
  vals: dictt->val

  pTime: ""

  gTime: g=> do //get time format
    a: g.toStr
    try do parseDateTime(a, "YYYY-MM-DD'T'hh:mm:ss.FFFz zzzz", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "YYYY-MM-DD'T'hh:mm:ss.FFFz zzzz" , now().tz, true).toTimeZone(now().tz); 0 end
    catch try do parseDateTime(a, "YYYY-MM-DD'T'hh:mm:ss.FFFz", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "YYYY-MM-DD'T'hh:mm:ss.FFFz" , now().tz, true).toTimeZone(now().tz); 1 end
    catch try do parseDateTime(a, "WWW MMM D hh:mm:ss zzz YYYY", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "WWW MMM D hh:mm:ss zzz YYYY" , now().tz, true).toTimeZone(now().tz); 1 end
    catch try do parseDateTime(a, "YYYY-MM-DD'T'hh:mm:ss", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "YYYY-MM-DD'T'hh:mm:ss" , now().tz, true).toTimeZone(now().tz); 2 end
    catch try do parseDateTime(a, "YYYY-MM-DD hh:mm:ss", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "YYYY-MM-DD hh:mm:ss" , now().tz, true).toTimeZone(now().tz); 3 end
    catch try do parseDateTime(a, "YYYY-MM-DD hh:mm", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "YYYY-MM-DD hh:mm" , now().tz, true).toTimeZone(now().tz); 4 end
    catch try do parseDateTime(a, "hh:mm:ss YYYY-MM-DD", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "hh:mm:ss YYYY-MM-DD" , now().tz, true).toTimeZone(now().tz); 5 end
    catch try do parseDateTime(a, "hh:mm YYYY-MM-DD", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "hh:mm YYYY-MM-DD" , now().tz, true).toTimeZone(now().tz); 6 end
    catch try do parseDateTime(a, "M/D/YYYY h:mm", now().tz, true); pTime = tim=> parseDateTime(tim.toStr, "M/D/YYYY h:mm" , now().tz, true).toTimeZone(now().tz); 7 end
    catch try do parseDateTime(a, "DD-MMM-YY h:mm:ss AA",now().tz,true); pTime = tim=> parseDateTime(tim.toStr, "DD-MMM-YY h:mm:ss AA",now().tz,true).toTimeZone(now().tz); 8 end
    catch try do parseDateTime(a, "DD/MM/YYYY hh:mm aa",now().tz,true); pTime = tim=> parseDateTime(tim.toStr, "DD/MM/YYYY hh:mm aa",now().tz,true).toTimeZone(now().tz); 9 end
    catch null
  end

  t: gTime(file[0].trap(tstp))

  k: (j,l:0)=> try j.toStr.parseNumber.finRemoveUnits catch l
  if(dtype == "bool") k = (j,l:false)=> try j.toStr.parseBool catch l

  if(t != null) do
    if(fn == "write") do //hisWrite function
      los: file.map(x=> {ts: x.trap(tstp).pTime(t), val: x.trap(vals).k})
      los.hisWrite(recc)
    end
    else if(fn == "rewrite") do //hisRewrite function
      tts: null
      num: null
      recc.hisRewrite((val,ts)=> do
        num = null
        tts = file.find((x,y)=> if(x.trap(tstp).pTime(t) == ts) do num=y; true end else false)
        if(num != null) file = file.remove(num)
        if(tts == null) [ts, val]
        else [ts, tts.trap(vals).k(val)] //if finds ts in file, rewrite old value
      end)
    end
  end else toLocale("j2FinToolsExt::invalidCsvTimeFormat")+ " "+ file[0].trap(tstp)
end


def ​

func:finHisReadAddMeta ​

finHisReadAddMeta(curGrid, point, curTimeSpan, timezone) ​

Axon function


meta ​

deffunc:finHisReadAddMeta
isfunc
liblib:finTools
namefinHisReadAddMeta

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(curGrid, point, curTimeSpan, timezone) => do
  curTimeSpan = curTimeSpan.toDateTimeSpan(timezone)
  return curGrid.addColMeta("val", point).addMeta({hisLimit: 10000, hisStart: curTimeSpan.start, hisEnd: curTimeSpan.end, view: "chart"}).renameCol("val", "v0")
end


def ​

func:finHisReadBaseBuildCharts ​

finHisReadBaseBuildCharts(grid, boolTable, enumTable, grouped, baselineTables, units, multiUnits, missingIds: null) ​

Axon function


meta ​

deffunc:finHisReadBaseBuildCharts
isfunc
liblib:finTools
namefinHisReadBaseBuildCharts

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(grid, boolTable, enumTable, grouped, baselineTables, units, multiUnits, missingIds:null) => do

  if(grid == null and boolTable == null and multiUnits.size == 0 and grouped.isEmpty)
    baselineTables
  else if(units.size > 1 or (units.size == 1 and boolTable != null) or multiUnits.size > 0 or grouped.size > 0) do
    if(grid != null) multiUnits = multiUnits.add(grid.chart)
    if(boolTable != null) multiUnits = multiUnits.add(boolTable.chart)
    if(enumTable != null) multiUnits = multiUnits.add(enumTable.chart)
    grouped.each x => multiUnits = multiUnits.add(x->charts.chart)

    multiUnits
  end else if(boolTable == null and enumTable == null) grid.chart.sort("ts")
  else if(boolTable != null) boolTable.chart
  else enumTable.chart
end


def ​

func:finHisReadBaseGetHis ​

finHisReadBaseGetHis(interval, fold, interval2, fold2, point, baHis, timeZone, currentTimeSpan, baseLineTimeSpan) ​

Axon function


meta ​

baSuExec✓
deffunc:finHisReadBaseGetHis
isfunc
liblib:finTools
namefinHisReadBaseGetHis
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(interval, fold, interval2, fold2, point, baHis, timeZone, currentTimeSpan, baseLineTimeSpan) => do
  newMeta: point

  isLocalHis: not baHis and point.has("his")
  isArchivedBaHis: not baHis and not point.has("bacnetHis")

  if (isLocalHis)
  do
    current: point.finHisRead(currentTimeSpan).hisClip()
    baseline: if(point->kind != "Str") point.finHisRead(baseLineTimeSpan).hisClip() else [].toGrid
  end
  else if (isArchivedBaHis)
  do
    current: try baReadArchiveHis(point->id, currentTimeSpan) catch [].toGrid.addMeta({hisRollupInterval:interval2,hisStart:currentTimeSpan,hisEnd:currentTimeSpan})
    baseline: if(point->kind != "Str") try baReadArchiveHis(point->id, baseLineTimeSpan).hisClip() catch [].toGrid.addMeta({hisRollupInterval:interval2,hisStart:baseLineTimeSpan,hisEnd:baseLineTimeSpan}) else []
  end
  else // ba point (system one)
  do
    current: point.baReadHis(currentTimeSpan.toDateTimeSpan(timeZone))
    baseline: if(point->kind != "Str") point.baReadHis(baseLineTimeSpan.toDateTimeSpan(timeZone)) else [].toGrid

    if(current.size > 0) current = current.map(r => r.set("ts", parseDateTime(r->ts.toTimeZone(timeZone).format("DD/MM/YYYY hh:mm:ss"), "DD/MM/YYYY hh:mm:ss", timeZone))).unique("ts").map(r => if(not r.has("v0")) r.set("v0",nan()) else r)
    if(baseline.size > 0) baseline = baseline.map(r => r.set("ts", parseDateTime(r->ts.toTimeZone(timeZone).format("DD/MM/YYYY hh:mm:ss"), "DD/MM/YYYY hh:mm:ss", timeZone))).unique("ts").map(r => if(not r.has("v0")) r.set("v0",nan()) else r) else []

    if(current.colNames.size > 2) current = finHisReadComplexBa(current, point->id)
    if(not baseline.isEmpty and baseline.colNames.size > 2) baseline = finHisReadComplexBa(baseline, point->id)
  end

  if(current.size > 0 and interval != null and point->kind != "Bool" and point->kind != "Str") do //if there are rollup settings
    current = current.hisRollup(fold, interval)
    baseline = baseline.hisRollup(fold, interval)

    if(interval2 != null) do //if interval2
      current = current.hisRollup(fold2, interval2)
      baseline = baseline.hisRollup(fold2, interval2)
    end //end interval2
  end

  if(point.has("shadowPointRef")) newMeta = readById(point->shadowPointRef)

  if(current.size == 0)
    current = current.addRow({
      ts: if(currentTimeSpan.isDateTime) currentTimeSpan.start else toDateTimeSpan(currentTimeSpan, timeZone).start,
      v0:nan()
    })

  if(baseline.size == 0)
    baseline = baseline.addRow({
      ts: if(baseLineTimeSpan.isDateTime) baseLineTimeSpan.start else toDateTimeSpan(baseLineTimeSpan, timeZone).start,
      v0:nan()
    })

  current = current.addColMeta("v0", newMeta)
  baseline = baseline.addColMeta("v0", newMeta)

  return [current, baseline]
end


def ​

func:finHisReadBaseGetTz ​

finHisReadBaseGetTz(point) ​

Axon function


meta ​

deffunc:finHisReadBaseGetTz
isfunc
liblib:finTools
namefinHisReadBaseGetTz

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(point) => do
  curSite: null

  if(point.has("siteRef")) do
    curSite = readById(point->siteRef)
    if(curSite.has("tz"))
      return curSite->tz
  end

  return now().tz
end


def ​

func:finHisReadBaseline ​

finHisReadBaseline(ptList, curTS, baseTS: null, rollUps: null, chartOpts: null, noNames: false) ​

Axon function


meta ​

baSuExec✓
baseChart✓
deffunc:finHisReadBaseline
isfunc
liblib:finTools
namefinHisReadBaseline
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(ptList, curTS, baseTS: null, rollUps: null, chartOpts:null, noNames: false) => do
  if(buildIsSiemens()) do
    saveJob: (job) => do
      diff(null, job, {add}).commit
    end

    temp: null
    currentTimeSpanStr: ""

    //re-assign vars
    if(baseTS.isDict) do
      temp = rollUps
      rollUps = baseTS
      baseTS = null
      if(temp.isList) chartOpts = temp
    end else if(baseTS.isList) do
      chartOpts = baseTS
      baseTS = null
    end else if(rollUps.isList) do
      chartOpts = rollUps
      rollUps = null
    end

    if(ptList.isDict or ptList.isRef) ptList = [ptList]

    if(ptList.isGrid)
      ptList = ptList.colToList("id").map(r => if(r == null) @null else r)
    else if(ptList.isList and ptList[0].isDict)
      ptList = ptList.map(r => if(r.has("id")) r->id else @null)

    if(not curTS.isDate) currentTimeSpanStr = curTS.toStr.replace(",", "..")
    else currentTimeSpanStr = curTS.toAxonCode

    if(currentTimeSpanStr.endsWith("month")) do
      endOfMonth: start(curTS).year.as("") + "-" + start(curTS).month.as("").format("00") + "-" + numDaysInMonth(start(curTS)).as("")
      currentTimeSpanStr = currentTimeSpanStr.replace("month", endOfMonth)
    end

    if(baseTS != null and not baseTS.isDate) baseTS = baseTS.toStr.replace(",", "..")
    else if(baseTS != null) baseTS = baseTS.toAxonCode

    if(chartOpts != null)
      chartOpts = chartOpts.toStr.replace("(val,acc) => null", "").split(",").map(r =>
        if(r.startsWith("curColor")) r.replace("#", "\"#") + "\""
        else if(r.startsWith("fold1") or r.endsWith(")") or r.startsWith("interval1")) r
        else if(not r.endsWith("}") and not r.endsWith("]")) r.replace(":", ":\"") + "\""
        else
        do
          splitVal: r.split(":")
          splitVal[0] + ":" + splitVal[1..-1].concat(":").toAxonCode.replace("]\"", "\"]").replace("}\"", "\"}")
        end
      ).concat(",") //.replace("(val,acc)", "") <--Moved to before split takes place, see FS5-382
    else chartOpts = "null"

    //echo(chartOpts)

    jobDict: {
      dis: "Chart Creation" + random(0..10000),
      job,
      jobExpr: "finHisReadBaselineCore(readByIds("+ptList.toAxonCode+", false), "+
        currentTimeSpanStr+", "+
        baseTS+", "+
        rollUps.toAxonCode+", "
        +chartOpts+", "
        +noNames.toAxonCode+
        ", jobCurRec())",
      jobSchedule: "at " + (now() + 0.5s).format("hh:mm:ss"),
      chartingJob
    }

    try jobRec: baSuExec(saveJob, curFunc(), [jobDict])
    catch jobRec: diff(null, jobDict, {add}).commit

    return [].toGrid.addMeta({query: "finHisReadBaslineStatus("+jobRec->id.toAxonCode+")", percent: 0})
  end else do
    //skip the job stuff if this is not for siemens
    finHisReadBaselineCore(ptList, curTS, baseTS, rollUps, chartOpts, noNames)
  end
end


def ​

func:finHisReadBaselineCore ​

finHisReadBaselineCore(ptList, curTS, baseTS: null, rollUps: null, chartOpts: null, noNames: false, jobRec: null) ​

takes the following parameters: [points], timeSpan, baseTimeSpan, {rollUpSettings}, [{chartSettings}]

points: REQUIRED - must be a grid or list of points. EX:'[point1, point2,...]' or readAll(filter)

timeSpan: REQUIRED - this will be the history length in terms of time. EX: today(), thisMonth(), date(YYYY, MM, DD), or YYYY-MM-DD

baseTimeSpan: OPTIONAL - this will be the history length in terms of time for a baseline, if not included there will be no baseline. EX: yesterday(), lastMonth(), date(YYYY, MM, DD), or YYYY-MM-DD

rollUpSettings: OPTIONAL - This must be a dict if included. If not included the history will not be rolled up. The following are needed:

interval1 -> REQUIRED, a rollUp interval EX: 1h, 1day
fold1 -> REQUIRED, a fold func EX: avg, sum
interval2 -> OPTIONAL, a second rollUp
fold2 -> OPTIONAL (REQUIRED if interval2 present), second fold func for second rollUp

chartSettings: OPTIONAL - This must be a list of dicts (can be list of one if desired). If this is not included, default chartSettings will be used (line, defaultColorScheme, all same group). If there are more points than settings, default settings will be applied to remaining points. A dict can contain the following:

curChatType -> REQUIRED, chart type EX: "line", "bar", "stackedBar", "scatter", "area", "runtime"
curColor -> OPTIONAL, color of main data; must be in hexadecimal. EX:"#FFFFFF"
chartGroup -> OPTIONAL, name of chart group. All charts with same group will appear on same chart. A string. EX: "a", "chart1"
baseChartType -> OPTIONAL, chart type for baseline data. See curChartType
baseColor -> OPTIONAL, color of baseline data. See curColor

meta ​

baSuExec✓
deffunc:finHisReadBaselineCore
isfunc
liblib:finTools
namefinHisReadBaselineCore

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(ptList, curTS, baseTS: null, rollUps: null, chartOpts:null, noNames: false, jobRec: null) => do
  temp: null
  chartGroup: ""
  fts: curFunc()
  relative: false

  //re-assign vars
  if(baseTS.isDict) do
    temp = rollUps
    rollUps = baseTS
    baseTS = null
    if(temp.isList) chartOpts = temp
  end else if(baseTS.isList) do
    chartOpts = baseTS
    baseTS = null
  end else if(rollUps.isList) do
    chartOpts = rollUps
    rollUps = null
  end

  if(chartOpts != null and chartOpts.toGrid.has("navName")) relative = true
  if(not ptList.isList and not ptList.isGrid) ptList = [ptList]
  if(ptList.size > 0 and ptList[0].isStr) ptList = ptList.map r => read(baUniqueId == r, false)
  if(not ptList.isGrid) ptList = ptList.toGrid

  //check for bad point ids
  dnes: ptList.finFindBadChartPts
  if(dnes == null) throw toLocale("j2FinToolsExt::allPointsDNE")

  ptList = ptList.findAll(v=> v.has("id")).map(r => finShadowPointToPoint(r->id))

  fixed:[]
  grid:null
  grouped:[]
  vNum:0
  baselineTables:[]
  multiUnits:[]
  boolTable:null
  enumTable:null
  units:[{unit:""}]
  unitPos:0
  curUnit:null
  fileLocation: ``
  curPercent: 1
  prcntStep: 0

  if(chartOpts != null) chartOpts = finMatchPointsToCharts(ptList,chartOpts, relative)

  if(ptList.has("unit") and (chartOpts==null or not relative)) do
    ptList=ptList.sort("unit")
    units=ptList.unique("unit").keepCols(["unit"]).map(row => if(row.has("unit")) row else {unit:""})
  end

  if(jobRec != null) do
    fileLocation = parseUri("io/hisChart_"+jobRec->dis.toTagName+".zinc")
    prcntStep = floor((99 / ptList.size) / 7)
  end

  each(ptList) (pt, x) => do //point loop
    if(pt.has("id")) do
      chartGroup=""
      periodValue:""
      detailView:null

      if(chartOpts!=null and x<chartOpts.size and chartOpts[x].has("periodValue")) periodValue=chartOpts[x]->periodValue //periodValue
      if(chartOpts!=null and x<chartOpts.size and chartOpts[x].has("detailView")) detailView=chartOpts[x]->detailView //detailView

      baHis:false
      tiz:finHisReadBaseGetTz(pt)

      if(pt.has("baHis")) baHis=true

      /*rollup settings*/
      fnd: finHisReadBaselineRollup(chartOpts,rollUps,x)
      fold: try fnd->fold catch null
      interval: try fnd->interval catch null
      fold2: try fnd->fold2 catch null
      interval2: try fnd->interval2 catch null

      if(jobRec != null) do
        curPercent = curPercent + prcntStep
        jobProgress(curPercent, "")
      end

  /*BASELINE*/
      if(baseTS != null) do

        if(jobRec != null) do
          curPercent = curPercent + prcntStep
          jobProgress(curPercent, "")
        end

        hists:finHisReadBaseGetHis(interval,fold,interval2,fold2,pt,baHis,tiz,curTS,baseTS)

        if(jobRec != null) do
          curPercent = curPercent + prcntStep
          jobProgress(curPercent, "")
        end

        current:hists[0]
        baseline:hists[1]
        baseColor:""
        baseType: if(pt->kind=="Number") "dashed" else "step"
        curColor:""
        curChartType: if(pt->kind=="Number") "line" else "step"

        offset:finGetMinutesFromCur(curTS,baseTS)

        if(baseline.size>0 and (baseline.size>0 or pt->kind=="Str")) do
          if(chartOpts!=null and x<chartOpts.size and chartOpts[x].has("curColor")) do //if there are chart settings and has color
            curColor=chartOpts[x]->curColor

            if(chartOpts[x].has("baseColor")) baseColor=chartOpts[x]->baseColor
          end //chartSettings-color

          if(chartOpts!=null and x<chartOpts.size and chartOpts[x].has("curChartType")) do //chart settings and curType
            curChartType=chartOpts[x]->curChartType
            if(chartOpts[x].has("baseChartType")) baseType=chartOpts[x]->baseChartType
            else baseType=curChartType
          end //chartSettings-curType

          if(jobRec != null) do
            curPercent = curPercent + prcntStep
            jobProgress(curPercent, "")
          end

          each(current) (stamp,i) => do //current grid
            if(stamp.has("v0") and baseline.size > i) fixed=fixed.add({ts:stamp->ts,v0:stamp->v0,v1: if(baseline.toRecList[i].has("v0")) baseline.toRecList[i]->v0 else null})
            else if(stamp.has("v0")) fixed=fixed.add({ts:stamp->ts,v0:stamp->v0})
            else if(baseline.size>i and baseline.toRecList[i].has("v0")) fixed=fixed.add({ts:baseline.toRecList[i]->ts,v0:0,v1:baseline.toRecList[i]->v0})
          end //current grid

          if(jobRec != null) do
            curPercent = curPercent + prcntStep
            jobProgress(curPercent, "")
          end

          if(fixed.size>0) do
            fixed=fixed.toGrid.sort("ts")
            fixed=fixed.addColMeta("v0", if(current.col("v0").meta->kind=="Str") current.col("v0").meta.set("chartKind","Bool") else current.col("v0").meta).addColMeta("v0",current.col("v0").meta.set("dis",pt.dis+": "+curTS.toStr.replace(","," to ")))
            fixed=fixed.addColMeta("v0",{chartType:curChartType,color:curColor,chartGroup:chartGroup,tsOffset:0})

            if(pt->kind != "Str") do
              fixed = fixed.addColMeta("v1", baseline.col("v0").meta.set("dis", pt.dis+" Baseline: "+baseTS.toStr.replace(",", " to ")))
              fixed = fixed.addColMeta("v1", {chartType: baseType, color: baseColor, chartGroup: chartGroup, tsOffset: offset, dashed})
              fixed = fixed.addMeta({dis: toLocale("j2FinToolsExt::recentVsBase"), hisStart: current.meta->hisStart, hisEnd: current.meta->hisEnd, hisLimit: 10000})
              try fixed = fixed.addMeta({hisInterval: current.meta->hisRollupInterval.toStr, hisIntervalUnit: current.meta->hisRollupInterval.unit}) catch ""
              fixed = fixed.addColMeta("ts", current.col("ts").meta)
            end else do
              fixed = fixed.addColMeta("v1", baseline.col("v0").meta.merge({chartKind: "Bool", chartType: baseType, color: baseColor, chartGroup:chartGroup, tsOffset:0 }))
              fixed = finHisReadBaselineStrPointF(fixed, pt.dis).addMeta({dis: toLocale("j2FinToolsExt::compareRecent")+":" + pt.dis, hisStart: current.meta->hisStart, hisEnd: current.meta->hisEnd, hisLimit: 10000})
              try fixed = fixed.addMeta({hisInterval: current.meta->hisRollupInterval.toStr, hisIntervalUnit: current.meta->hisRollupInterval.unit}) catch ""
              fixed = fixed.addColMeta("ts", current.col("ts").meta)
            end

            baselineTables = baselineTables.add(fixed.renameCol("v1", "v0base").chart)
            fixed = [] //reset temporary grid
          end //there is data
        end else baselineTables = baselineTables.add([{v0: null}].toGrid.addMeta({view: "chart"}).addColMeta("v0", pt))

        if(jobRec != null) do
          curPercent = curPercent + prcntStep
          jobProgress(curPercent, "")
        end
  /*NO BASELINE*/
      end else do
        try curUnit=pt->unit
        catch curUnit=""

        if(jobRec != null) do
          curPercent = curPercent + prcntStep
          jobProgress(curPercent, "")
        end

        current: []

        if(not baHis and pt.has("his"))
          current =pt.finHisRead(curTS).hisClip()
        else if(not baHis and not pt.has("bacnetHis"))
          current = try baReadArchiveHis(pt->id,curTS) catch [].toGrid.addMeta({hisRollupInterval:interval2,hisStart:curTS,hisEnd:curTS})
        else do
          current = pt.baReadHis(curTS.toDateTimeSpan(tiz))

          if(current.size>0) current=current.map(r => r.set("ts",parseDateTime(r->ts.toTimeZone(tiz).format("DD/MM/YYYY hh:mm:ss"),"DD/MM/YYYY hh:mm:ss",tiz))).unique("ts").map(r => if(not r.has("v0")) r.set("v0",nan()) else r)
          if(current.colNames.size>2) current=finHisReadComplexBa(current,pt->id)
        end

        if(jobRec != null) do
          curPercent = curPercent + prcntStep
          jobProgress(curPercent, "")
        end

        if(current.size>=0)
        do
          if(current.size==0) current=current.addRow({ts: if(curTS.isDateTime) curTS.start else toDateTimeSpan(curTS,tiz).start,v0:nan()}).addColMeta("v0",pt)
          if(pt.has("shadowPointRef")) current=current.addColMeta("v0",readById(pt->shadowPointRef))
          if(interval!=null and pt->kind!="Bool" and pt->kind!="Str") do //there are rollup settings
            current=current.hisRollup(fold,interval)

            //if there is interval2
            if(interval2!=null) current=current.hisRollup(fold2,interval2)
          end

          curColor:""
          curChartType: if(pt->kind=="Number") "line" else "step"

          if(chartOpts!=null and x<chartOpts.size and chartOpts[x].has("curColor")) curColor=chartOpts[x]->curColor //color
          if(chartOpts!=null and x<chartOpts.size and chartOpts[x].has("curChartType")) curChartType=chartOpts[x]->curChartType //curType
          if(chartOpts!=null and x<chartOpts.size and chartOpts[x].has("chartGroup")) chartGroup=chartOpts[x]->chartGroup //group

          if(jobRec != null) do
            curPercent = curPercent + prcntStep
            jobProgress(curPercent, "")
          end

          //LOOP in LOOP
          each(current) (stamp,i) => if(stamp.has("v0")) fixed=fixed.add({ts:stamp->ts,v0:stamp->v0})

          if(jobRec != null) do
            curPercent = curPercent + prcntStep
            jobProgress(curPercent, "")
          end

          if(fixed.size > 0) do
            fixed=fixed.toGrid
            fixed=fixed.addColMeta("v0", if(current.col("v0").meta->kind=="Str") current.col("v0").meta.set("chartKind","Bool") else current.col("v0").meta)
            fixed=fixed.addColMeta("v0",{chartType:curChartType,color:curColor,chartGroup:chartGroup,tsOffset:0})

            if(periodValue != null) do
              fixed=fixed.addColMeta("v0",{periodValue:periodValue})
            end

            if(detailView != null) do
              fixed=fixed.addMeta({detailView: detailView})
            end

            if(pt->kind != "Str") fixed=fixed.renameCol("v0","v"+x)

            if(jobRec != null) do
              curPercent = curPercent + floor(prcntStep / 2)
              jobProgress(curPercent, "")
            end

            if(chartGroup!="") grouped=grouped.finAddChartToGroup(chartGroup,fixed,x,pt,current)
            else if(x>0 and curUnit==units[unitPos]->unit and pt->kind!="Bool" and pt->kind!="Str" and grid!=null) grid=grid.join(fixed,"ts")//if not the first point
            else do //if not the first point, then if the first point
              if(curUnit!=units[unitPos]->unit and pt->kind!="Bool") do
                unitPos=unitPos+1
                if(grid!=null) multiUnits=multiUnits.add(grid.chart)
              end

              fixed=fixed.addMeta({dis:toLocale("j2FinToolsExt::recentData")+":"+pt.dis,hisStart:current.meta->hisStart,hisEnd:current.meta->hisEnd,hisLimit:10000})
              try fixed=fixed.addMeta({hisInterval:current.meta->hisRollupInterval.toStr, hisIntervalUnit: current.meta->hisRollupInterval.unit}) catch ""
              fixed=fixed.addColMeta("ts",current.col("ts").meta)

              if(pt->kind!="Bool" and pt->kind!="Str") grid=fixed
              else do
                if(pt->kind=="Bool") do
                  if(baHis) fixed=finHisReadBaselineStrPointF(fixed,pt.dis,true)
                  if(boolTable==null) boolTable=fixed
                  else boolTable=boolTable.join(fixed,"ts")
                end else if(pt->kind=="Str" and enumTable==null) do
                  fixed=finHisReadBaselineStrPointF(fixed, pt.dis).addMeta(fixed.meta)
                  fixed=fixed.addColMeta("ts", current.col("ts").meta)
                  multiUnits=multiUnits.add(fixed.chart)
                end//end strSTR
              end
            end//if the first point

            if(jobRec != null) do
              curPercent = curPercent + floor(prcntStep / 2)
              jobProgress(curPercent, "")
            end

            fixed=[]//reset temp grid
          end//there is data
        end else do
          multiUnits=multiUnits.add([{v0:null}].toGrid.addMeta({view:"chart"}).addColMeta("v0",pt).chart)

          if(jobRec != null) do
            curPercent = curPercent + prcntStep
            jobProgress(curPercent, "")
          end
        end
      end//no baseline
    end//not null

    if(jobRec != null) do
      curPercent = curPercent + prcntStep
      jobProgress(curPercent, "")
    end
  end//point loop

  writeFile: (chartToSave, fileLoc, flag) => do
  //possible that broken chart is trying to write timespan in hisStart instead of using both hisStart and hisEnd
    if(chartToSave.size>=1 and chartToSave[0].isGrid) chartToSave.map(r => do
      //a little hack to get around the edge case where the grid is empty and has the date span in just the hisStart tag
      t: r.meta
      if(t.has("hisStart") and t->hisStart.debugType == "proj::DateSpan") r = r.addMeta({hisStart: t->hisStart.start, hisEnd: t->hisStart.end})

      r.addMeta({invalidPoints: if(flag!= null and not flag.isEmpty) flag else removeMarker()}).ioWriteZinc("")
    end).ioWriteZinc(fileLoc)
    else chartToSave.toGrid.addMeta({invalidPoints: if(flag!=null and not flag.isEmpty) flag else removeMarker()}).ioWriteZinc(fileLoc)
  end

  all:finHisReadBaseBuildCharts(grid,boolTable,enumTable,grouped,baselineTables,units,multiUnits)

  if(jobRec != null) do
    try baSuExec(writeFile, curFunc(), [all, fileLocation, dnes])
    catch writeFile(all, fileLocation, dnes)
  end else do
    if(all.size>=1 and all[0].isGrid) all.map(r => r.addMeta({invalidPoints: if(dnes!= null and not dnes.isEmpty) dnes else removeMarker()}))
    else all.toGrid.addMeta({invalidPoints: if(dnes!=null and not dnes.isEmpty) dnes else removeMarker()}) //.ioWriteZinc(fileLocation)
  end
end


def ​

func:finHisReadBaselineRollup ​

finHisReadBaselineRollup(chartSettingsDict, rollUpSettings, x) ​

Axon function


meta ​

deffunc:finHisReadBaselineRollup
isfunc
liblib:finTools
namefinHisReadBaselineRollup

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(chartSettingsDict, rollUpSettings, x) => do
  interval: null
  interval2: null
  fold: null
  fold2: null

  if(chartSettingsDict != null and x < chartSettingsDict.size and (chartSettingsDict[x].has("interval1"))) do
    interval = chartSettingsDict[x]->interval1

    if(chartSettingsDict[x].has("fold1") and not chartSettingsDict[x]->fold1.isStr and chartSettingsDict[x]->fold1 != null)
      fold = chartSettingsDict[x]->fold1

    if(chartSettingsDict[x].has("interval2")) do
      interval1 = chartSettingsDict[x]->interval2
      if(chartSettingsDict[x].has("fold2") and not chartSettingsDict[x]->fold2.isStr and chartSettingsDict[x]->fold2 != null)
        fold2 = chartSettingsDict[x]->fold2
    end
  end else if(rollUpSettings != null) do
    interval = rollUpSettings->interval1
    if(rollUpSettings.has("fold1") and not rollUpSettings->fold1.isStr and rollUpSettings->fold1 != null)
      fold = rollUpSettings->fold1

    if(rollUpSettings.has("interval2")) do
      interval2 = rollUpSettings->interval2
      if(rollUpSettings.has("fold2") and not rollUpSettings->fold2.isStr and rollUpSettings->fold2 != null)
        fold2 = rollUpSettings->fold2
    end
  end

  if(fold == null and interval != null) fold = avg
  if(fold2 == null and interval2 != null) fold2 = avg

  return {fold: fold, interval: interval, fold2: fold2, interval2: interval2}
end


def ​

func:finHisReadBaselineStrPoint ​

finHisReadBaselineStrPoint(curPointHis, pointName, isBool: false) ​

Axon function


meta ​

deffunc:finHisReadBaselineStrPoint
isfunc
liblib:finTools
namefinHisReadBaselineStrPoint

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(curPointHis, pointName, isBool: false) => do
  values: []
  charts:[]
  tsList:[]
  enumVals:[]
  colName: curPointHis.colNames.find(v => v != "ts")    //find the data column
  isBaHis: curPointHis.col(colName).meta.has("baHis")   //determine if an "offline" point -- SIEMENS ONLY

  chartDict: {}
  mainHis: []
  colDict: {ts: null}

  //if a boolean point re-write values
  //to be true and false if 1 and 0 are used
  //then return the data
  if(isBool) do
    return curPointHis.map(r => if(r[colName] == 0) r.set(colName, false) else if(r[colName] == 1) r.set(colName, true) else r).reorderCols(["ts", colName])
  end

  if(not curPointHis.col("v0").meta.has("enum"))
    //if a string point find values in his
    enumVals = curPointHis.unique("v0").toRecList.map(r => r->v0) //.concat(",")
  else
    //an enum point, get the enum values
    enumVals = curPointHis.col("v0").meta->enum.split(",")

  each(enumVals) (x,i) => colDict = colDict.set("v"+i, false)

  //if the first value of history is not NaN
  if(curPointHis.first->v0 !=nan()) do
    curPointHis.each hist => do
      tempDis: if(isBaHis) enumVals[hist->v0 - 1] else hist->v0 //offline history returns the index of the enum, online returns the enum
      colIndex: enumVals.index(tempDis)

      mainHis = mainHis.add(colDict.set("v"+colIndex, true).set("ts", hist->ts))
    end

    mainHis = mainHis.toGrid

    each(enumVals) (colName, i) =>
      mainHis = mainHis.addColMeta("v"+i, curPointHis.col("v0").meta.set("dis", pointName + " " + colName).set("enum", enumVals.concat(",")))

    return mainHis
  end else
    return curPointHis
end


def ​

func:finHisReadBaselineStrPointF ​

finHisReadBaselineStrPointF(curPointHis, pointName, isBool: false) ​

Fantomized version of the finHisReadBaselineStrPoint function


meta ​

deffunc:finHisReadBaselineStrPointF
isfunc
liblib:finTools
namefinHisReadBaselineStrPointF

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finHisReadBaslineStatus ​

finHisReadBaslineStatus(jobRef) ​

Axon function


meta ​

baSuExec✓
deffunc:finHisReadBaslineStatus
isfunc
liblib:finTools
namefinHisReadBaslineStatus

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(jobRef) => do
//---BaSuExec funcs---
  cFunc: curFunc()

  deleteJob: (record) => do
    record.finHardDelete
  end

  readFile: (fileLoc) => do
    tempGrid: ioReadZinc(fileLoc)

    if(tempGrid[0].has("val"))
      tempGrid = tempGrid.toRecList.map(r => r->val.ioReadZinc())

    return tempGrid
  end

  fileDelete: (fileLoc) => do
    ioDelete(fileLoc)
  end
//---BaSuExec funcs---

  jobRec: readById(jobRef, false)
  jobList: readAll(chartingJob and jobLastTime)

  if(jobRec != null) do
    //clear old jobs and files if any
    jobList.findAll(v => v.has("jobLastStatus") and v->jobLastStatus.startsWith("done") and v->id != jobRec->id and (now() - v->jobLastTime > 4h)).each(x => do
      fileLocation: parseUri("io/hisChart_"+x->dis.toTagName+".zinc")

      try
        baSuExec(fileDelete, cFunc, [fileLocation])
      catch do
        try fileDelete(fileLocation)
        catch ""
      end

      try baSuExec(deleteJob, cFunc, [x])
      catch deleteJob(x)
    end)

    curJobStatus: jobStatusAll().find(v => v->dis == jobRec->dis)

    //determine status of job and what to return
    if(curJobStatus == null and not jobRec.has("jobLastRuntime"))
      return [].toGrid.addMeta({query: "finHisReadBaslineStatus("+jobRef.toAxonCode+")", percent: 1})
    else if(curJobStatus == null) do

      try baSuExec(deleteJob, cFunc, [jobRec])
      catch deleteJob(jobRec)

      return [].toGrid.addMeta({query: "", percent: 100})
    end else if(curJobStatus->progress < 100%)
      return [].toGrid.addMeta({query: "finHisReadBaslineStatus("+jobRef.toAxonCode+")", percent: curJobStatus->progress.as("")})
    else do
      data: []
      fileLocation: parseUri("io/hisChart_"+jobRec->dis.toTagName+".zinc")

      try data = baSuExec(readFile, cFunc, [fileLocation])
      catch do
        try data = readFile(fileLocation)
        catch ""
      end

      try
        baSuExec(fileDelete, cFunc, [fileLocation])
      catch do
        try fileDelete(fileLocation)
        catch ""
      end

      try baSuExec(deleteJob, cFunc, [jobRec])
      catch deleteJob(jobRec)

      return data
    end
  end else do
    //clear old jobs and files if any
    jobList.findAll(v => v.has("jobLastStatus") and v->jobLastStatus.startsWith("done") and (now() - v->jobLastTime > 4h)).each(x => do
      fileLocation: parseUri("io/hisChart_"+x->dis.toTagName+".zinc")

      try
        baSuExec(fileDelete, cFunc, [fileLocation])
      catch do
        try fileDelete(fileLocation)
        catch ""
      end

      try baSuExec(deleteJob, cFunc, [x])
      catch deleteJob(x) //.finHardDelete
    end)

    //return empty grid
    return [].toGrid.addMeta({query: "", percent: 100})
  end
end


def ​

func:finHisReadComplexBa ​

finHisReadComplexBa(history, pointRef) ​

Axon function


meta ​

deffunc:finHisReadComplexBa
isfunc
liblib:finTools
namefinHisReadComplexBa

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(history, pointRef) => do
  colToKeep: history.colNames.eachWhile x => do
    if(x != "ts" and history.col(x).meta->id == pointRef) x
  end

  history.keepCols(["ts", colToKeep]).renameCol(colToKeep, "v0")
end


def ​

func:finHisRewriteSpan ​

finHisRewriteSpan(hisRecs, startTime, endTime, rewriteFunc: (value) => value, pTime: null) ​

hisRewriteSpan(hisRecs, startTime, endTime, rewriteFunc: func, pTime: null) function returns "n histories rewritten" where n is histories modified

-hisRecs is the record or records to apply the transformation to -startTime is the dateTime to start editing -endTime is the dateTime to stop editing -rewriteFunc is the function that specifies what the transformation should be, nothing by default -pTime is a string that specifies how to parse startTime and endTime in the event that they are strings and not real dateTimes

examples:

//to add 10 to all values within startTime and endTime read(point).hisRewriteSpan(startTime, endTime, v=> v + 10)

//to use a string for startTime and endTime read(point).hisRewriteSpan("mm/dd/yyyy hh:mm am", "mm/dd/yyyy hh:mm pm", v=> v, "MM/DD/YYYY kk:mm aa") //see sys::DateTime.toLocale for parsing patterns

//to apply the transformation to multiple points readAll(point and his).hisRewriteSpan(startTime, endTime, v=> v + 10)


meta ​

constructread(point).finHisRewriteSpan("06/09/2015 05:45 am", "06...
deffunc:finHisRewriteSpan
isfunc
liblib:finTools
namefinHisRewriteSpan

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(hisRecs, startTime, endTime, rewriteFunc: value=> value, pTime: null) => do
  hisRecs = hisRecs.toRecList
  tss: []
  num: 0
  hisRecs.each hisRec=> do
    tss = []
    if(pTime == null) hisRec.hisRead(startTime .. endTime).each x=> tss = tss.add(x->ts)
    else hisRec.hisRead(parseDateTime(startTime, pTime)..parseDateTime(endTime, pTime)).hisClip.each x=> tss = tss.add(x->ts)
    hisRec.hisRewrite((val, ts)=> do
      if(tss.index(ts) != null) do
        num = num + 1
        [ts, rewriteFunc(val)]
      end
      else [ts, val]
    end)
  end

  toLocale("j2FinToolsExt::numHistoriesRewritten").replace("{num}", num.toStr)
end

//rewrites histories only within a certain range


def ​

func:finInvoke ​

finInvoke(rec, action, args: {}) ​

Axon function


meta ​

deffunc:finInvoke
isfunc
liblib:finTools
namefinInvoke

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(rec, action, args:{}) => do
  grid:     rec->actions.toStr.ioReadZinc
  row:      grid.find(r => r->dis == action)
  expr:     row->expr.toStr

  // parse + validate in one step; null means "not a simple name(...) call"
  m: reGroups(r"^\s*(\w+)\s*\((.*)\)\s*$", expr)
  if (m == null or row == null) return rec.invoke(action, args)

  funcName: m[1]
  inside:   m[2].trim
  params:   if (inside == "") [] else inside.split(",").map(p => p.trim)

  hasMissing: params.any(param => param.startsWith("\$") and param[1..-1] != "self" and args.missing(param[1..-1]))

  if (not hasMissing)
    rec.invoke(action, args)
  else do
    argList: params.map(param => do
               if (param.startsWith("\$")) do
                 name: param[1..-1]
                 if (name == "self") rec->id else args[name]
               end
               else eval(param)
             end)
    call(funcName, argList)
  end
end


def ​

func:finIsTagBlackList ​

finIsTagBlackList(tag) ​

Return whether the given tag is a member of the tag blacklist (see finTagBlackList())


meta ​

deffunc:finIsTagBlackList
isfunc
liblib:finTools
namefinIsTagBlackList

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(tag) => do
  // TODO help doc
  finTagBlackList().map(r => reFind(r->regex, tag)).any(v => v != null)
end


def ​

func:finMacro ​

finMacro(scope, pattern) ​

Process macro pattern with given scope of variable name/value pairs. The pattern is a Unicode string with embedded expressions:

$tag: resolve tag name from scope, variable name ends with first non-tag, see Etc.isTagName ${tag}: resolve tag name from scope $pod::key: localization key

Any variables which cannot be resolved in the scope are returned as-is (such $name) in the result string.

If a tag resolves to Ref, then we use Ref.dis for string. Example:

readAll(site).finMacro("\\\$dis : \\\$id")

meta ​

constructreadAll(site).finMacro("$dis blabla $id")
deffunc:finMacro
isfunc
liblib:finTools
namefinMacro

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finMassEditTags ​

finMassEditTags(selectedDicts: null, stage: null, data: null) ​

Axon function


meta ​

deffunc:finMassEditTags
distoLocale("j2FinToolsExt::massEditTags")
folderPathtoLocale("j2FinToolsExt::batchEditAndClone")
formOnsite or floor or equip or (point and not schedule) or ba...
isfunc
liblib:finTools
namefinMassEditTags

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(selectedDicts: null, stage: null, data: null) => do
  if(stage == null) do
    filt: if (selectedDicts.contains("clone")) "cloneRef==@"+selectedDicts.map(x=> x->id).concat(" or cloneRef==@") else "id==@"+selectedDicts.map(x=> x->id).concat(" or id==@")

    body: [
    {name: "filt", editorType: "filter", prompt: toLocale("finStackExt::finFilter")+":", defVal: filt},
    {name: "tag", editorType: "combobox", prompt: toLocale("j2FinToolsExt::sharedTags")+":", labelField: "val", selectedValueTags: "val", defIndex: 0,
      dataProvider: "try if(readCount(parseFilter(\$filt))>0) readAll(parseFilter(\$filt)).toRecList.map(x=> x.names.concat(\" \")).concat(\" \")"+
      ".split(\" \").unique.findAll(x=> index([\"id\",\"mod\",\"return\"],x)==null and readCount(parseFilter(\"(\"+\$filt+\") and \"+x))"+
      "==readCount(parseFilter(\$filt))).sort((x,y)=> if(x==\"navName\") -1 else 0) else [\"No Match\"] catch [\"Processing Error\"]"
    },
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "commitButton", editorType: "button", label: toLocale("finStackExt::next"), controlBar: true}
    ]

    {"dis": toLocale("j2FinToolsExt::massEditTags"),
    "name": "finMassEditTags",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",
    "commitAction": "finMassEditTags(readAll(parseFilter(\$filt)),1,\$tag)",
    "helpDoc": "/wiki/spaces/FINStack/pages/85458970/Mass+Edit+Tags",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
  //////////////////////
  else if(stage == 1) do
    body: [
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "commitButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    comAct: "finMassEditTags([ "
    tmp: {}
    g: ""
    c: 0
    n: 0
    selectedDicts.sort((x,y)=> x.dis <=> y.dis).each x=> do
      g = x[data]

      if(g.isStr or (g == null and data == "description")) tmp = {editorType: if(g != null and g.size>60) "textarea" else "textinput", defVal: g, t: "str"}
      else if(g.isNumber) do tmp = {editorType: "numericstepper", defVal: g, t: "num"}; n = n + 1 end
      else if(g.isRef) tmp = {editorType: "textinput", defVal: "@"+g, t: "ref"}
      else if(g.isBool) tmp = {editorType: "combobox", labelField: "a", selectedValueTags: "b",
        dataProvider: "[{a:\"True\",b:true},{a:\"False\",b:false}]", defIndex: if(g) 0 else 1, t: "bool"}
      else if(g.isDateTime) tmp = {editorType: "textinput", defVal: g, t: "datm"}
      else if(g.isTime) tmp = {editorType: "textinput", defVal: g, t: "time"}
      else if(g.isUri) tmp = {editorType: "textinput", defVal: g, t: "uri"}
      else if(g.isDate) tmp = {editorType: "textinput", defVal: g, t: "date"}
      else tmp = {editorType: "label", text: toLocale("j2FinToolsExt::sharedTags").replace("{varType}", (if(g==marker()) toLocale("finStackExt::folioQueryMarkers") else toLocale("finStackExt::dataType"))), t: "unk"}

      if(tmp->t != "unk") comAct = comAct + "{i: @"+x->id+", v: \$"+c+"rec, t: \""+tmp->t+"\"},"
      body = body.add(tmp.remove("t").merge({name: c+"rec", prompt: x.dis}))
      c = c + 1
    end

    if(n == selectedDicts.size) do
      body = body.addAll([
      {name: "la", editorType: "label", text: ""},
      {name: "ib", editorType: "numericstepper", defVal: 0, prompt: toLocale("j2FinToolsExt::incrementBy")+":"},
      {name: "sn", editorType: "numericstepper", defVal: 0, prompt:  toLocale("j2FinToolsExt::startingNumber")+":"}
      ])
      comAct = comAct[0..-2] + "],2,[\""+data+"\", \$ib, \$sn])"
    end else comAct = comAct[0..-2] + "],2,[\""+data+"\"])"

    {"dis": toLocale("j2FinToolsExt::massEditTags"),
    "name": "finMassEditTags1",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",
    "commitAction": comAct,
    "helpDoc": "/wiki/spaces/FINStack/pages/85458970/Mass+Edit+Tags",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
  //////////////////////
  else if(stage == 2) do
    c: 0
    v: ""
    t: data.size > 1
    r: {}
    if(t) c = data[2]
    selectedDicts.each x=> do
      r = readById(x->i)
      if(t) do
        v = c
        c = c + data[1]
      end else do
        if(x->t == "num") try v = x->v.toStr.parseNumber * eval("1"+r.trap(data[0]).unit) catch v = x->v.toStr.parseNumber
        else if(x->t == "ref") v = x->v.replace("@","").parseRef
        else if(x->t == "bool") v = x->v.toStr.parseBool
        else if(x->t == "datm") v = x->v.parseDateTime
        else if(x->t == "time") v = x->v.parseTime
        else if(x->t == "uri") v = x->v.parseUri
        else if(x->t == "date") v = x->v.parseDate
        else v = x->v.toStr
      end
      r.diff({}.set(data[0], v)).commit
    end
  end
end


def ​

func:finMatchPointsToCharts ​

finMatchPointsToCharts(ptList, optList, isRel: false) ​

Axon function


meta ​

deffunc:finMatchPointsToCharts
isfunc
liblib:finTools
namefinMatchPointsToCharts
noDoc✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(ptList, optList, isRel: false) => do
  if(isRel) do
    optList = optList.map(x => do
      if(ptList.find(v => v.has("navName") and x.has("navName") and v->navName == x->navName) == null) x = x.set("order", -1)
      else do
        orderNum: ptList.eachWhile((y, j) => if(y->navName == x->navName) return j)
        x = x.set("order", orderNum)
      end
      x
    end).findAll(v=> v->order != -1).sort((a,b) => a->order<=>b->order)
  end else do
    optList = optList.map((row,i) => if(i<ptList.size and ptList[i].has("unit")) row.set("unit",ptList[i]->unit) else row)
    if(optList.toGrid.has("unit")) optList = optList.toGrid.sort("unit").toRecList
  end

  optList
end


def ​

func:finModBusMap ​

finModBusMap(grid, files) ​

Axon function


meta ​

deffunc:finModBusMap
isfunc
liblib:finTools
namefinModBusMap
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(grid,files)=> do

  //check the kind of grid: 1:finstack modbus 2:contemp. controls csv format
  if(grid.size <=0) throw "grid empty."
  rec:grid.get(0)
  format:if(rec.has("uri") and rec.has("modbusRegMapUri") and rec.has("site") and rec.has("floor")) true else false
  if(files != null and files.size > 0) do
    files.each()(id)=>do
      copyModbusFile(id,"/db/modbus/")
    end
  end
  if(format) do

    grid.each() (rec)=> do
      tags :if(rec.get("addTags") != null) rec.get("addTags") else ""
      tagArr :{}
      if(tags != "") do
        tagItems : tags.split(",")
        tagItems.each(it=> do
          if(it.index(":")>=0) do
            kv: it.split(":")
            tagArr = tagArr.set(kv.get(0),kv.get(1))
          end
          else
            tagArr = tagArr.set(it,marker())

        end)
      end

      importModbus(rec.get("uri"),rec.get("modbusRegMapUri"),rec.get("dis"),rec.get("modbusSlave"),rec.get("site"),rec.get("floor"),rec.get("tenant"),tagArr,rec.get("folderPath"))
    end
  end

end


def ​

func:finMoveTag ​

finMoveTag(filt1, filt2, tag1, deleteOrig: false) ​

Backend for finCopyTagForm

Usage: finMoveTag(filt1, filt2, tag1, deleteOrig: false)

Copies tag value to other records.

Filt1 is filter to copy from. Filt2 is filter to copy to. Tag1 is tag whose value to clone. DeleteOrig is flag to remove original tag being cloned.


meta ​

deffunc:finMoveTag
isfunc
liblib:finTools
namefinMoveTag

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filt1,filt2,tag1,deleteOrig:false) => do
  readAll(parseFilter(filt1)).each rec => do
    tag: rec.trap(tag1)
    parent: finNavMetaWhoAmI(rec)
    nextFilter: if(parent != null) filt2 + " and " + parent + "Ref == " + rec->id.toAxonCode else filt2

    if(deleteOrig) rec.diff({}.set(tag1, removeMarker())).commit

    readAll(parseFilter(nextFilter)).each x=> do
      x.diff({}.set(tag1, tag)).commit
    end
  end
end


def ​

func:finNavMetaCommit ​

finNavMetaCommit(newLevel, deleteLevel, parentLevel, isOptional: false) ​

Axon function


meta ​

deffunc:finNavMetaCommit
isfunc
liblib:finTools
namefinNavMetaCommit

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(newLevel, deleteLevel, parentLevel, isOptional: false) => do
  // add new level
  if(deleteLevel == false) do
    // required level
    if (not isOptional and not newLevel.startsWith("["))
    do
      if(parentLevel == "") //if new level has no parent
        finNavMeta(newLevel)
      else
        finNavMeta(newLevel, parentLevel) //if newLevel will have a parent
    end

    // optional
    else
    do
      // parent is: root, optional, or final node
      if (parentLevel == "" or parentLevel.startsWith("[") or read(navMeta)->equipPath.split("/")[-1] == parentLevel)
        return finFormNavMeta({level: newLevel, parent: parentLevel, optional: true})
      else
      do
        if (not newLevel.startsWith("["))
          newLevel = "["+newLevel+"]"

        finNavMeta(newLevel, parentLevel)
      end
    end
  end

  //delete level
  else
  do
    if (read(navMeta)->equipPath.split("/").find(v => v == newLevel or v == "["+newLevel+"]").startsWith("[") and not newLevel.startsWith("["))
      newLevel = "["+newLevel+"]"

    if(not(newLevel == "point" or newLevel == "site" or newLevel == "equip"))
      finNavMeta("-" + newLevel)
    else
      finFormAlertOk(toLocale("finStackExt::regError"), toLocale("j2FinToolsExt::cannotDeleteNavLevel").replace("{navLevel}", newLevel))
  end //end delete level

end //end function


def ​

func:finNavMetaDeleteFailForm ​

finNavMetaDeleteFailForm(unDeletable) ​

Axon function


meta ​

deffunc:finNavMetaDeleteFailForm
isfunc
liblib:finTools
namefinNavMetaDeleteFailForm
obsolete✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(unDeletable) => do

  body: [
    {name: "cantDelete", editorType: "label", text: toLocale("j2FinToolsExt::cannotDeleteNavLevel").replace("{navLevel}", unDeletable)},
    {name: "applyButton", editorType: "button", label: toLocale("finStackExt::ok"), controlBar: true}
  ]

  {
    "dis": toLocale("finStackExt::regError"),
    "name": "finNavMetaDeleteFailForm",
    "body": body.toJSON,
    "commitButton": "\$applyButton",
    "commitAction": "",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finNavMetaGetLevels ​

finNavMetaGetLevels(keepEmpty: false) ​

Axon function


meta ​

deffunc:finNavMetaGetLevels
isfunc
liblib:finTools
namefinNavMetaGetLevels

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(keepEmpty: false) => do

  navList: split(read(navMeta)->equipPath, "/")
  if(keepEmpty == false) do
    navList = navList.remove(0)
  end

  //navDict:{}
  listOfNavDicts: []

  navList.each x => do
    listOfNavDicts = listOfNavDicts.add({name: x})
    //echo(listOfNavDicts)
    end

  return listOfNavDicts.toGrid()
end


def ​

func:finNavMetaWhoAmI ​

finNavMetaWhoAmI(rec) ​

This function takes a Record, and it will return what the record is based on navMeta. Meaning, if it's a site,it will return site, if the record isn't something that is in navMeta that it will return null


meta ​

constructread(point).finNavMetaWhoAmI()
deffunc:finNavMetaWhoAmI
helpUse this function to check if the record is something in...
isfunc
liblib:finTools
namefinNavMetaWhoAmI

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(rec) => do

 navMetaList:read(navMeta).get("equipPath").split("/").remove(0).map() row => row.replace("[","").replace("]","")

 recType: navMetaList.find(metaItem => rec.has(metaItem))

end


def ​

func:finPodFiles ​

finPodFiles(name) ​


meta ​

deffunc:finPodFiles
isfunc
liblib:finTools
namefinPodFiles

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finPointActions ​

finPointActions(kind) ​

Axon function


meta ​

deffunc:finPointActions
isfunc
liblib:finTools
namefinPointActions

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(kind) => do
  if (kind == "Number")
    [{dis: toLocale("j2FinToolsExt::emergencySet"),      expr:"pointEmergencyOverride(\$self, \$val)",    hvac_finCat:9},
     {dis: toLocale("finStackExt::emergencyAuto"), expr:"pointEmergencyAuto(\$self)",               hvac_finCat:9},
     {dis: toLocale("j2FinToolsExt::manualSet"),         expr:"pointOverride(\$self, \$val, \$duration)", hvac_finCat:6},
     {dis: toLocale("finStackExt::manualAuto"),    expr:"pointAuto(\$self)",                        hvac_finCat:6},
     {dis: toLocale("j2FinToolsExt::setDefault"),        expr:"pointSetDef(\$self, \$val)",               hvac_finCat:3},
     {dis: toLocale("j2FinToolsExt::setNull"),           expr:"pointSetDef(\$self, null)",                hvac_finCat:3}].toGrid

  else if (kind == "Bool")
    [{dis: toLocale("j2FinToolsExt::emergencyActive"),   expr:"pointEmergencyOverride(\$self, true)",     hvac_finCat:9},
     {dis: toLocale("j2FinToolsExt::emergencyInactive"), expr:"pointEmergencyOverride(\$self, false)",    hvac_finCat:9},
     {dis: toLocale("finStackExt::emergencyAuto"), expr:"pointEmergencyAuto(\$self)",               hvac_finCat:9},
     {dis: toLocale("j2FinToolsExt::manualOn"),          expr:"pointOverride(\$self, true, \$duration)",  hvac_finCat:6},
     {dis: toLocale("j2FinToolsExt::manualOff"),         expr:"pointOverride(\$self, false, \$duration)", hvac_finCat:6},
     {dis: toLocale("finStackExt::manualAuto"),    expr:"pointAuto(\$self)",                        hvac_finCat:6},
     {dis: toLocale("j2FinToolsExt::setDefault"),        expr:"pointSetDef(\$self, \$val)",               hvac_finCat:3}].toGrid

  else if (kind == "Enum")
    [{dis: toLocale("j2FinToolsExt::emergencySet"),      expr:"pointEmergencyOverride(\$self, \$val)",    hvac_finCat:9},
     {dis: toLocale("finStackExt::emergencyAuto"), expr:"pointEmergencyAuto(\$self)",               hvac_finCat:9},
     {dis: toLocale("j2FinToolsExt::manualSet"),         expr:"pointOverride(\$self, \$val, \$duration)", hvac_finCat:6},
     {dis: toLocale("finStackExt::manualAuto"),    expr:"pointAuto(\$self)",                        hvac_finCat:6},
     {dis: toLocale("j2FinToolsExt::setDefault"),        expr:"pointSetDef(\$self, \$val)",               hvac_finCat:3},
     {dis: toLocale("j2FinToolsExt::setNull"),           expr:"pointSetDef(\$self, null)",                hvac_finCat:3}].toGrid

  else if (kind == "Str")
    [{dis: toLocale("j2FinToolsExt::emergencySet"),      expr:"pointEmergencyOverride(\$self, \$val)",    hvac_finCat:9},
     {dis: toLocale("finStackExt::emergencyAuto"), expr:"pointEmergencyAuto(\$self)",               hvac_finCat:9},
     {dis: toLocale("j2FinToolsExt::manualSet"),         expr:"pointOverride(\$self, \$val, \$duration)", hvac_finCat:6},
     {dis: toLocale("finStackExt::manualAuto"),    expr:"pointAuto(\$self)",                        hvac_finCat:6},
     {dis: toLocale("j2FinToolsExt::setDefault"),        expr:"pointSetDef(\$self, \$val)",               hvac_finCat:3},
     {dis: toLocale("j2FinToolsExt::setNull"),           expr:"pointSetDef(\$self, null)",                hvac_finCat:3}].toGrid

end


def ​

func:finPointNotTz ​

finPointNotTz() ​

Axon function


meta ​

deffunc:finPointNotTz
isfunc
liblib:finTools
namefinPointNotTz

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  readAll(site).each x=> do
    try finRewriteHisTz(x->id,x->tz) catch ""
  end
end


def ​

func:finPointNumbersToEquip ​

finPointNumbersToEquip(id: null, stage: null, data: null) ​

Axon function


meta ​

deffunc:finPointNumbersToEquip
distoLocale("j2FinToolsExt::pointNumbersToEquip")
formOnpoint and not schedule
isfunc
liblib:finTools
namefinPointNumbersToEquip
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id: null, stage: null, data: null) => do
  if(stage == null) do
    id = id.toRec

    body: [
    {name: "filt", editorType: "filter", prompt: toLocale("finStackExt::finFilter")+":", defVal: "point and equipRef==@"+id->equipRef}, //filter
    {name: "pref", editorType: "textinput", prompt: toLocale("j2FinToolsExt::equipPrefix")+":", defVal: "VAV-"}, //equip prefix
    {name: "site", editorType: "textinput", prompt: toLocale("j2FinToolsExt::siteDis")+":", defVal: id->siteRef->dis}, //siteref
    {name: "flor", editorType: "textinput", prompt: toLocale("j2FinToolsExt::floorDis")+":", defVal: id->floorRef->dis}, //floorref
    {name: "prev", editorType: "list", prompt: toLocale("finStackExt::preview"), dataProvider: "[\$pref+\"1\"]", labelField: "val", height: 25}, //preview
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "commitButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    {"dis": toLocale("j2FinToolsExt::pointNumbersToEquip"),
    "name": "finPointNumbersToEquip",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",                //  0       1       2       3
    "commitAction": "finPointNumbersToEquip(null, 0, [\$filt, \$pref, \$site, \$flor])",
    "helpDoc": "/wiki/spaces/FINStack/pages/87359490/Point+Numbers+to+Equip",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
  //////////////////////
  else if(stage == 0) do
    s: (try read(site and dis==data[2]) catch {})
    f: (try read(floor and dis==data[3] and siteRef->dis==data[2]) catch {})
    e: []
    te: 0
    p: readAll(parseFilter(data[0]))
    p.each x=> e = e.add(x->navName.split("_")[-1])
    e = e.unique
    if(not f.isEmpty and not s.isEmpty) e.each x=> do
      te = te + readCount(equip and floorRef==f->id and navName==data[1]+x)
    end

    text: toLocale("j2FinToolsExt::youAreAboutTo")+"\n"

    if (not s.isEmpty)
      text = text + toLocale("j2FinToolsExt::useExistingItem").replace("{item}", toLocale("j2FinToolsExt::site")).replace("{num}", "1") + "\n"
    else
      text = text + toLocale("j2FinToolsExt::createNewItem").replace("{item}", toLocale("j2FinToolsExt::site")).replace("{num}", "1") + "\n"

    if (not f.isEmpty)
      text = text + toLocale("j2FinToolsExt::useExistingItem").replace("{item}", toLocale("j2FinToolsExt::floor")).replace("{num}", "1") + "\n"
    else
      text = text + toLocale("j2FinToolsExt::createNewItem").replace("{item}", toLocale("j2FinToolsExt::floor")).replace("{num}", "1") + "\n"

    //text = text + (if(not s.isEmpty)"use "else"create ") + " 1 "+ (if(not s.isEmpty)" existing"else" new") +" site\n"
    //text = text + (if(not f.isEmpty)"use "else"create ") + " 1 "+ (if(not f.isEmpty)" existing"else" new") +" floor\n"
    text = text + toLocale("j2FinToolsExt::useExistingItem").replace("{item}", toLocale("finStackExt::navMetaEquip")).replace("{num}", te.toStr)+"\n" //"use " + te + " existing equips\n"
    text = text + toLocale("j2FinToolsExt::createNewItem").replace("{item}", toLocale("finStackExt::navMetaEquip")).replace("{num}", (e.size - te).toStr)+"\n" //"create " + (e.size - te) + " new equips\n"
    text = text + toLocale("j2FinToolsExt::moveExistingItem").replace("{item}", toLocale("finStackExt::navMetaPoint")).replace("{num}", p.size.toStr)+"\n" //"move " + p.size + " existing points\n"

    body: [
    {name: "pref", editorType: "textarea", prompt:  toLocale("finStackExt::preview"), defVal: text, editable: false},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "commitButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    {"dis": toLocale("j2FinToolsExt::pointNumbersToEquip"),
    "name": "finPointNumbersToEquip1",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",
    "commitAction": "finPointNumbersToEquip(null, 1, "+data.toAxonCode+")",
    "helpDoc": "/wiki/spaces/FINStack/pages/87359490/Point+Numbers+to+Equip",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
  //////////////////////
  else if(stage == 1) do
    try site: read(site and dis==data[2]) catch
      site: diff(null, {geoCountry:"US",geoState:"AL",site:marker(),dis:data[2],tz:"New_York"}, {add}).commit
    try floor: read(floor and dis==data[3] and siteRef==site->id) catch
      floor: diff(null, {floor:marker(),tz:"New_York",dis:data[3],siteRef:site->id}, {add}).commit
    tmp: ""
    equ: {}

    readAll(parseFilter(data[0])).each x=> do
      tmp = x->navName.split("_")[-1]
      try equ = read(equip and floorRef==floor->id and navName==data[1]+tmp) catch
        equ = diff(null, {floorRef:floor->id,equip:marker(),navName:data[1]+tmp,disMacro:"\$siteRef \$navName",tz:"New_York",siteRef:site->id}, {add}).commit
      x.diff({siteRef:site->id, floorRef:floor->id, equipRef:equ->id}).commit
    end

  end
end


def ​

func:finPostTrioFuncs ​

finPostTrioFuncs(trioUri) ​

Axon function


meta ​

deffunc:finPostTrioFuncs
isfunc
liblib:finTools
namefinPostTrioFuncs

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(trioUri) => do

    //------------------------------------------------
    // post a function

    postFunc: (rec) => do

        existing: read(func and name == rec->name, false)

        // insert new function
        if (existing == null) do

            commit(diff(null, rec, {add}))
            success = success.add({name: rec->name, insert})

        // update existing function
        end else do
            commit(diff(existing, rec))
            success = success.add({name: rec->name, update})
        end
    end

    //------------------------------------------------

    // main

    trioFuncs: ioReadTrio(trioUri)

    // make sure every function's src is syntactically valid
    failure: []
    trioFuncs.each rec => do
        try
            eval(rec->src)
        catch (ex)
            failure = failure.add({
                name: rec->name,
                syntaxError,
                exception: replace(ex.toStr, "\\n", "\n")})
    end
    if (failure.size > 0)
        return failure

    // post all the functions
    success: []
    trioFuncs.each rec => postFunc(rec)
    return success

end


def ​

func:finPrecision ​

finPrecision(number, precision, useStr: false) ​

Usage: finPrecision(number, precision, useStr: false) Returns a number with the specified precision. Supports numbers less than 100 trillion. Supports up to 12 decimal places.

Warning: function does not round up to new precision. Precision will be made an integer no greater than 10 or less than 0. The bigger the number and precision, the less accuracy will result. Setting the useStr parameter to true will return the result as a string, which may be more accurate in some cases.

e.g. finPrecision(7.2323, 2) //precision 2 7.23

finPrecision(2.352952, 3) //precision 3 2.352

finPrecision(2.32, 5) //precision 5 2.32000


meta ​

deffunc:finPrecision
isfunc
liblib:finTools
namefinPrecision
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(number, precision, useStr: false) => do
  if(abs(number) > 99999999999999) throw toLocale("j2FinToolsExt::numberTooLargeForCalc")
  if(number == floor(number))
  do
    if (number >= 0) number = number + 0.00000000001
    else number = number - 0.00000000001
  end
  number = number.toStr

  precision = floor(precision)
  if(precision > 10) precision = 10
  else if(precision < 0) precision = 0

  if(number.contains("E")) do
    number = number.split("E")
    powr: number[1].parseNumber.finRemoveUnits
    if(powr > -10) do
      number = split(number[0]+"0000000000",".")
      if(powr >= 0) number = number.set(1, number[1][0..powr-1] +"."+ number[1][powr..-1])
      else number = number.set(0, ("0000000000"+number[0])[0..powr-1] +"."+ ("0000000000"+number[0])[powr..-1])
      number = number.concat("").split(".")
      number = number.set(1, number[1][0..precision])
      if(precision == 0) number = number.set(1,"")
      number =  number.concat(".")[0..-2]
    end else number = "0"
  end
  else if(number != "NaN") do
    rmvUnit: (strnum) => do
      asdf: []
      (0..strnum.size-1).eachWhile x=> do
        if(strnum[x].isDigit(10)) do asdf = asdf.add(strnum[x..x]); null end
        else true
      end
      asdf.concat("")
    end

    number = number.split(".")

    if(precision > 0) do
      if (number.size > 1)
      do
        number = number.set(1, number[1].rmvUnit)
        number = number.set(1, (number[1]+"0000000000")[0..precision])
        number = number.concat(".")[0..-2]
      end
      else
      do
        number = number[0].rmvUnit + "."
        (1..precision).each x => number = number + "0"
      end
    end
    else number = number[0].rmvUnit
  end

  if(useStr) number
  else number.parseNumber
end


def ​

func:finProjectedCalc ​

finProjectedCalc(recs, rangeFunc) ​

Used for projecting the use of something like an electric meter's kWh. This will only work for values that are a measure of something or not compiled values. Acceptable input values are today, thisWeek, thisMonth, or thisYear.

Use: readAll(point).finProjectedCalc(today) read(id==@xxxxxxxx-xxxxxxxx).finProjectedCalc(thisWeek)

Function will return a grid with columns for the point id, the current use, the estimated remaining projection, the estimated total projection, a message.

Function reads the history of the point based on the span input, adds up all the current values, divides by the number of read intervals to find average read number, then sees how many history collects are left and multiplies average by that.


meta ​

deffunc:finProjectedCalc
isfunc
liblib:finTools
namefinProjectedCalc

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(recs, rangeFunc) => do //read(stuff).finProjectedCalc(thisWeek)
  //can use today, thisWeek, thisMonth, thisYear
  rfunc: toStr(rangeFunc)[0..-3]
  things: recs.toRecList
  lists: []
  trend: [].toGrid
  proj: 0
  tot: 0
  curuse: 0
  intv: 0min
  msg: ""
  intvs: 0
  intvsLeft: 0
  intvsTotal: 0

  toIntvs: (rfunca, intva)=> do
    toHours: {today: 24, thisWeek: 168, thisMonth: 730.8, thisYear: 8760}
    unitsperhour: {min: 60, h: 1, sec: 3600}
    hours: toHours.trap(rfunca)
    parts: unitsperhour.trap(intva.unit)
    intva = parseInt(toStr(intva)[0..-intva.unit.size-1])
    //24h * 60min / 15min
    //parseInt(toStr(15min)[0..-unit(15min).size-1])
    hours * parts / intva
  end

  if(rfunc=="today" or rfunc=="thisWeek" or rfunc=="thisMonth" or rfunc=="thisYear") do
    things.each thing => do
      try do
        trend = thing.hisRead(rangeFunc).hisClip
        intv = thing->hisCollectInterval
        proj = 0
        tot = 0
        curuse = 0
        intvs = 0
        intvsLeft = 0
        intvsTotal = 0
        msg = null

        if (trend.size > 0) do //if has history
          trend.each x=> curuse = curuse + x->v0
          intvs = trend.size
          intvsTotal = rfunc.toIntvs(intv)
          intvsLeft = intvsTotal - intvs
          proj = (curuse / intvs) * intvsLeft
          tot = proj + curuse
        end
        else msg = toLocale("j2FinToolsExt::noHistoryFound")

        lists = lists.add({id: thing->id, curUse: curuse, estProject: proj, estTotal: tot, msg: msg})
      end catch null
    end
  end
  else throw toLocale("j2FinToolsExt::spanFunctionNotValid").replace("{name}", rfunc)

  lists.toGrid
end
//read(id==@1a169f42-97348ed4).finProjectedCalc(today)


def ​

func:finReadAlarmTags ​

finReadAlarmTags(tags: []) ​

Axon function


meta ​

deffunc:finReadAlarmTags
isfunc
liblib:finTools
namefinReadAlarmTags
topics✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(tags: []) => do
  programStrs: readAll(program).findAll(v => v->program.contains("t=\"alarm\"")).keepCols(["program"])
  //tags: []
  curPos:0
  temp: []

  if(not tags.isEmpty)
    tags = tags.map r => {dis: r}

  programStrs.each x => do
    curPos = x->program.index("t=\"tag\"")
    temp = temp.addAll(finReadAlarmTagsSearch(x->program[curPos..-1]))
  end

  temp = temp.map(row => row.replace("t=\"tag\" name=\"", "")[0..-2])

  temp.each x => do
    if(tags.find(v => v->dis == x) == null and x != "cost" and x != "alarmText" and x != "priority" and x != "instructions")
      tags = tags.add({dis: x})
  end

  tags
end


def ​

func:finReadAlarmTagsSearch ​

finReadAlarmTagsSearch(progStr) ​

Axon function


meta ​

deffunc:finReadAlarmTagsSearch
isfunc
liblib:finTools
namefinReadAlarmTagsSearch

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(progStr) => do
  curList:[]
  curPos: progStr.index("t=\"tag\"")
  temp: null

  if(curPos != null) do
    temp = reFind(r"t=\x22tag\x22 name=\x22[a-zA-Z_0-9]+\x22", progStr)
    curList = curList.add(temp)
    curPos = progStr.index(temp) + temp.size
    return curList.addAll(finReadAlarmTagsSearch(progStr[curPos..-1]))
  end else
    return []
end


def ​

func:finReadCloneEvents ​

finReadCloneEvents(id) ​

Axon function


meta ​

deffunc:finReadCloneEvents
isfunc
liblib:finTools
namefinReadCloneEvents

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id) => do
  readById(id)->scheduleGrid.findAll r =>
      (not r.has("weekly")) and (not r.has("defaultEvent"))
end


def ​

func:finRecordsSources ​

finRecordsSources(recordType) ​


meta ​

deffunc:finRecordsSources
isfunc
liblib:finTools
namefinRecordsSources

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finRefDis ​

finRefDis(ref) ​

Get the dis of a ref


meta ​

deffunc:finRefDis
isfunc
liblib:finTools
namefinRefDis

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finRemoveAnimationEditor ​

finRemoveAnimationEditor(fileRef) ​

Axon function


meta ​

baSuExec✓
deffunc:finRemoveAnimationEditor
isfunc
liblib:finTools
namefinRemoveAnimationEditor

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(fileRef) => do
  readTheFile: (myfile) => do
    return myfile.set("mod", now()).readFinFile
  end

  writeTheFile: (myFile, myFileId) => do
    myFile.writeFinFile(myFileId)
  end

  anime: readById(fileRef, false)
  graphics: readAll(fin5)
  funcStuff: curFunc()

  fileMeta: null
  newHtmlMeta: null

  if(fileRef != null) do
    graphics.each(gfile => do
      fileContents: null
      foundAnimationEditors: []

      try fileContents = baSuExec(readTheFile, funcStuff, [gfile])
      catch fileContents = gfile.set("mod", now()).readFinFile

      foundAnimationEditors = fileContents.findAll(v => v.has("elementTagName") and v.has("description") and (v->elementTagName.split(".")[0] + "." + v->description).toTagName == anime->dis.replace(".json", "").toTagName).colToList("id")

      if(foundAnimationEditors.size > 0) do
        //fileContents = fileContents.findAll(v => not v.has("elementTagName") or not v.has("description") or (v->elementTagName.split(".")[0] + "." + v->description).toTagName != anime->dis.replace(".json", "").toTagName)
        fileContents = fileContents.findAll(v => not v.has("id") or not foundAnimationEditors.contains(v->id))

        //remove left over html from meta
        fileMeta = fileContents.meta
        newHtmlMeta = fileMeta->finView

        foundAnimationEditors.each x => do
          newHtmlMeta = newHtmlMeta.replace(reFind("<canvas[^>]*id=\""+x+"\"[^>]*></canvas>", newHtmlMeta), "")
        end

        fileMeta = fileMeta.set("finView", newHtmlMeta)
        fileContents = fileContents.addMeta(fileMeta)

        try baSuExec(writeTheFile, funcStuff, [fileContents, file->id])
        catch fileContents.writeFinFile(gfile->id)
      end

    end)
  end

  wrappedDiffRemove(fileRef)
end


def ​

func:finRemoveUnits ​

finRemoveUnits(numberToCheck) ​

removeUnits(number) Removes' the unit from a number passed in. Will return an int or a float


meta ​

deffunc:finRemoveUnits
isfunc
liblib:finTools
namefinRemoveUnits

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(numberToCheck) => do
  unt: numberToCheck.unit

  if(unt != null) do
    charsToRemove: -(unt.size+1)
    numStr: toStr(numberToCheck)[0..charsToRemove]
    decimalStr: 0

    try do
      decimalStr = numStr.split(".")[0] + "." + numStr.split(".")[1]//[0..1]
      decimalStr = parseFloat(decimalStr)
    catch
      return parseInt(numStr.split(".")[0]) //return parseFloat(numStr)*/

    return decimalStr
  end else
    return numberToCheck
end


def ​

func:finRenamePointsForm ​

finRenamePointsForm(selectedDicts: null, stage: null) ​

Form to change navNames of points if they match the filter


meta ​

deffunc:finRenamePointsForm
distoLocale("j2FinToolsExt::renamePoints")
formOnpoint and not schedule
isfunc
liblib:finTools
namefinRenamePointsForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(selectedDicts: null, stage: null) => do
  if(stage != 2) do
    if(selectedDicts == null) dval: "point"
    else dval: "id==@"+selectedDicts.toRecIdList.concat(" or id==@")

    try nname: read(parseFilter(dval) and navName)->navName
    catch nname: ""

    body: [
      {name: "filt", editorType: "filter", prompt: toLocale("finStackExt::pointFilter")+":", defVal: dval},
      {name: "nav", editorType: "textinput", prompt: toLocale("j2FinToolsExt::newNavName")+":", defVal: nname},
      {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
      {name: "commitButton", editorType: "button", label: toLocale("finStackExt::coreApply"), controlBar: true}
    ]

    {
      "dis": toLocale("j2FinToolsExt::renamePoints"),
      "name": "finRenamePointsForm",
      "body": body.toJSON,
      "cancelButton": "\$cancelButton",
      "commitButton": "\$commitButton",
      "commitAction": "finRenamePointsForm({filt: \$filt, nav: \$nav, id:"+selectedDicts.map(r=> r->id).toAxonCode+"}, 2)",
      "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
  else if(stage == 2) do
    try cnt: readCount(parseFilter(selectedDicts->filt))
    catch cnt: 0

    equipId: selectedDicts->id[0].readById->equipRef
    body: [
      {
        name: "label",
        editorType: "label",
        prompt: toLocale("finStackExt::warning").upper,
        text: toLocale("j2FinToolsExt::xPointsWillBeRenamed").replace("{number}", cnt.toStr).replace("{name}", selectedDicts->nav)
      },

      {name: "label", editorType: "label", text: toLocale("j2FinToolsExt::continuePrompt")},
      {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::no"), controlBar: true},
      {name: "commitButton", editorType: "button", label: toLocale("finStackExt::yes"), controlBar: true}
    ]

    {
      "dis": toLocale("j2FinToolsExt::renamePoints"),
      "name": "finRenamePointsConfirmationForm",
      "body": body.toJSON,
      "cancelButton": "\$cancelButton",
      "commitButton": "\$commitButton",
      "commitAction": "readAll("+selectedDicts->filt+").each x=> x.diff({navName: "+ selectedDicts->nav.toAxonCode +"}).commit",
      "refreshTrees": marker(),
      "completeAction": "window.app.RefreshBuilderTreeNodeForId('"+equipId.toAxonCode+"')",
      "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
end


def ​

func:finRestorePod ​

finRestorePod(pod) ​


meta ​

constructfinRestorePod("fooExt")
deffunc:finRestorePod
isfunc
liblib:finTools
namefinRestorePod

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finSampleHisReadBase ​

finSampleHisReadBase(f: 0, fN2R: 0, nC: 0, nR: 0, nB: 0, p: 0, oC: 0, oR: 0, oB: 0) ​

Axon function


meta ​

chart✓
constructfinSampleHisReadBase(1,0,0,0,0,0,0,0,0)
deffunc:finSampleHisReadBase
isfunc
liblib:finTools
namefinSampleHisReadBase

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(f:0, fN2R:0, nC:0, nR:0, nB:0, p:0, oC:0, oR:0, oB:0) => do
  data: readAll(sensor and power)[0..1]
  charts: []

  if(f == 0 and fN2R == 0 and nC == 0 and nR == 0 and nB == 0 and p == 0 and oC == 0 and oR == 0 and oB == 0) do
    f = 1
    fN2R = 1
    nC = 1
    nR = 1
    nB = 1
    p = 1
    oC = 1
    oR = 1
    oB = 1
  end

  /*----param 1, has all possible params----*/
  if(f == 1 or f == true) do
    full: finHisReadBaseline(data, thisMonth(), lastMonth(), {interval1: 1hr, fold1: max, interval2:1day, fold2: avg}, [{curChartType: "line", curColor: "#CC00CC", chartGroup: "a", baseChartType:"line", baseColor: "#000000"}, {curChartType: "line", curColor: "#009933", chartGroup: "a", baseChartType:"line", baseColor: "#E68A2E"}])
    charts = charts.add(heading("full: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), lastMonth(), {interval1: 1hr, fold1: max, interval2:1day, fold2: avg}, [{curChartType: \"line\", curColor: \"#CC00CC\", chartGroup: \"a\", baseChartType:\"line\", baseColor: \"#000000\"}, {curChartType: \"line\", curColor: \"#009933\", chartGroup: \"a\", baseChartType:\"line\", baseColor: \"#E68A2E\"}])"))
    charts = charts.addAll(full)
  end

  /*----param 2, doesn't have second rollup----*/
  if(fN2R == 1 or fN2R == true) do
    fullNo2Roll: finHisReadBaseline(data, thisMonth(), lastMonth(), {interval1: 1day, fold1: max}, [{curChartType: "line", curColor: "#CC00CC", chartGroup: "a", baseChartType:"line", baseColor: "#000000"}, {curChartType: "line", curColor: "#009933", chartGroup: "a", baseChartType:"line", baseColor: "#E68A2E"}])
    charts = charts.add(heading("fullNo2Roll: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), lastMonth(), {interval1: 1hr, fold1: max}, [{curChartType: \"line\", curColor: \"#CC00CC\", chartGroup: \"a\", baseChartType:\"line\", baseColor: \"#000000\"}, {curChartType: \"line\", curColor: \"#009933\", chartGroup: \"a\", baseChartType:\"line\", baseColor: \"#E68A2E\"}])"))
    charts = charts.addAll(fullNo2Roll)
  end

  /*----param 3, doesn't have chartSettingsDict----*/
  if(nC == 1 or nC == true) do
    noChart: finHisReadBaseline(data, thisMonth(), lastMonth(), {interval1: 1day, fold1: max})
    charts = charts.add(heading("noChart: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), lastMonth(), {interval1: 1hr, fold1: max})"))
    charts = charts.addAll(noChart)
  end

  /*----param 4, doesn't have any rollups----*/
  if(nR == 1 or nR == true) do
    noRoll: finHisReadBaseline(data, thisMonth(), lastMonth(), [{curChartType: "line", curColor: "#CC00CC", chartGroup: "a", baseChartType:"line", baseColor: "#000000"}, {curChartType: "line", curColor: "#009933", chartGroup: "a", baseChartType:"line", baseColor: "#E68A2E"}])
    charts = charts.add(heading("noRoll: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), lastMonth(), [{curChartType: \"line\", curColor: \"#CC00CC\", chartGroup: \"a\", baseChartType:\"line\", baseColor: \"#000000\"}, {curChartType: \"line\", curColor: \"#009933\", chartGroup: \"a\", baseChartType:\"line\", baseColor: \"#E68A2E\"}])"))
    charts = charts.addAll(noRoll)
  end

  /*----param 5, doesn't have a baseline----*/
  if(nB == 1 or nB == true) do
    noBase: finHisReadBaseline(data, today(), {interval1: 1h, fold1: max}, [{curChartType: "area", curColor: "#CC00CC", chartGroup: "a"}, {curChartType: "area", curColor: "#009933", chartGroup: "a"}])
    charts = charts.add(heading("noBase: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), {interval1: 1hr, fold1: max}, [{curChartType: \"area\", curColor: \"#CC00CC\", chartGroup: \"a\"}, {curChartType: \"area\", curColor: \"#009933\", chartGroup: \"a\"}])"))
    charts = charts.add(noBase)
  end

  /*----param 6, only has required params: points and timeSpan-----*/
  if(p == 1 or p == true) do
    plain: finHisReadBaseline(data, thisMonth())
    charts = charts.add(heading("plain: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth())"))
    charts = charts.add(plain)
  end

  /*----param 7, only has chartSetingsDict; no baseline or rollups----*/
  if(oC == 1 or oC == true) do
    onlyChart: finHisReadBaseline(data, thisMonth(), [{curChartType: "line", curColor: "#CC00CC", chartGroup: "a"}, {curChartType: "line", curColor: "#009933", chartGroup: "a"}])
    charts = charts.add(heading("onlyChart: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), [{curChartType: \"line\", curColor: \"#CC00CC\", chartGroup: \"a\"}, {curChartType: \"line\", curColor: \"#009933\", chartGroup: \"a\"}])"))
    charts = charts.add(onlyChart)
  end

  /*----param 8, only has rollup; no baseline or chartSettingsDict----*/
  if(oR == 1 or oR == true) do
    onlyRoll: finHisReadBaseline(data, thisMonth(), {interval1: 1day, fold1: max})
    charts = charts.add(heading("onlyRoll: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), {interval1: 1hr, fold1: max})"))
    charts = charts.add(onlyRoll)
  end

  /*----param 9, only has baseline, no rollup or chartSettingsDict----*/
  if(oB == 1 or oB == true) do
    onlyBase: finHisReadBaseline(data, thisMonth(), lastMonth())
    charts = charts.add(heading("onlyBase: readAll(sensor and power)[0..1].finHisReadBaseline(thisMonth(), lastMonth())"))
    charts = charts.addAll(onlyBase)
  end

  charts
end


def ​

func:finSaveEquipRecordsForm ​

finSaveEquipRecordsForm(id: false, selectedDicts: false) ​

Axon function


meta ​

batchRecords✓
deffunc:finSaveEquipRecordsForm
distoLocale("j2FinToolsExt::saveEquipRecords")
folderPathtoLocale("j2FinToolsExt::createBatchRecords")
helpDoc/wiki/display/FINStack/Create+Batch+Records
isfunc
liblib:finTools
namefinSaveEquipRecordsForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id: false, selectedDicts: false) => do
  selectedIds: []
  filtstr: ""
  if(not isBool(selectedDicts)) do
    selectedIds = selectedDicts.map(r => "@" + r->id)
    selectedIds.each x=> filtstr = filtstr+"id=="+x+" or "
    filtstr = filtstr[0 .. -5]
  end

  body: [
  {name: "list", editorType: "list", prompt: toLocale("j2FinToolsExt::equipsToSave"), listType: "radio", dataProvider: filtstr, labelField: "dis"},
  {name: "fname", editorType: "textinput", prompt:toLocale("j2FinToolsExt::createNewFile"), defVal: ""},
  {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
  {name: "applyButton", editorType: "button", label: toLocale("finStackExt::save"), controlBar: true}
  ]

  comAct: "finSaveRecords("+filtstr.toAxonCode()+",\"Equip\",\$fname"
  if(ioDir(`io/equipLibraries/`).size > 0) do
    body = body.insert(2,{name: "efiles", editorType: "combobox", prompt: toLocale("finStackExt::omMenuUseExisting"),
      dataProvider: "ioDir(`io/equipLibraries/`)", labelField: "name", selectedValueTags: "uri", defIndex: 0})
    comAct = comAct + ",\$efiles"
  end
  comAct = comAct + ")"

  { "dis": toLocale("j2FinToolsExt::saveEquipRecords"),
    "name": "finSaveEquipRecordsForm",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": comAct,
    "helpDoc": "/wiki/display/FINStack/Create+Batch+Records",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finSaveFloorRecordsForm ​

finSaveFloorRecordsForm(id: false, selectedDicts: false) ​

Axon function


meta ​

batchRecords✓
deffunc:finSaveFloorRecordsForm
distoLocale("j2FinToolsExt::saveFloorRecords")
folderPathtoLocale("j2FinToolsExt::createBatchRecords")
helpDoc/wiki/display/FINStack/Create+Batch+Records
isfunc
liblib:finTools
namefinSaveFloorRecordsForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id: false, selectedDicts: false) => do
selectedIds: []
filtstr: ""
if(not isBool(selectedDicts)) do
  selectedIds = selectedDicts.map(r => "@" + r->id)
  selectedIds.each x=> filtstr = filtstr+"id=="+x+" or "
  filtstr = filtstr[0 .. -5]
end

body: [
  {name: "list", editorType: "list", prompt: toLocale("j2FinToolsExt::floorsToSave")+":", listType: "radio", dataProvider: filtstr, labelField: "dis"},
  {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
  {name: "applyButton", editorType: "button", label: toLocale("finStackExt::save"), controlBar: true}
  ]

  { "dis": toLocale("j2FinToolsExt::saveFloorRecords"),
    "name": "finSaveFloorRecordsForm",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "finSaveRecords("+filtstr.toAxonCode()+",\"Floor\")",
    "helpDoc": "/wiki/display/FINStack/Create+Batch+Records",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finSavePointRecordsForm ​

finSavePointRecordsForm(id: false, selectedDicts: false) ​

Axon function


meta ​

batchRecords✓
deffunc:finSavePointRecordsForm
distoLocale("j2FinToolsExt::savePointRecords")
folderPathtoLocale("j2FinToolsExt::createBatchRecords")
formOnpoint and not schedule
helpDoc/wiki/display/FINStack/Create+Batch+Records
isfunc
liblib:finTools
namefinSavePointRecordsForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id: false, selectedDicts: false) => do
  selectedIds: []
  filtstr: ""
  if(not isBool(selectedDicts)) do
    selectedIds = selectedDicts.map(r => "@" + r->id)
    selectedIds.each x=> filtstr = filtstr+"id=="+x+" or "
    filtstr = filtstr[0 .. -5]
  end

  body: [
    {name: "list", editorType: "list", prompt: toLocale("j2FinToolsExt::pointsToSave") + ":", listType: "checkbox", dataProvider: "readAll(" + filtstr + ")", labelField: "dis"},
    {name: "fname", editorType: "textinput", prompt: toLocale("j2FinToolsExt::createNewFile") + ":", defVal: ""},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "applyButton", editorType: "button", label: toLocale("finStackExt::save"), controlBar: true}
  ]

  comAct: "finSaveRecords("+filtstr.toAxonCode()+",\"Point\",\$fname"
  if(ioDir(`io/pointLibraries/`).size > 0) do
    body = body.insert(2,{name: "efiles", editorType: "combobox", prompt: toLocale("finStackExt::omMenuUseExisting"),
      dataProvider: "ioDir(`io/pointLibraries/`)", labelField: "name", selectedValueTags: "uri", defIndex: 0})
    comAct = comAct + ",\$efiles"
  end
  comAct = comAct + ")"

  { "dis": toLocale("j2FinToolsExt::savePointRecords"),
    "name": "finSavePointRecordsForm",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": comAct,
    "helpDoc": "/wiki/display/FINStack/Create+Batch+Records",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finSaveRecords ​

finSaveRecords(filt, type, name1: null, name2: null) ​

Axon function


meta ​

batchRecords✓
deffunc:finSaveRecords
isfunc
liblib:finTools
namefinSaveRecords

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filt, type, name1: null, name2: null) => do
  results: readAll(parseFilter(filt)).sort("navName")
  navs: read(navMeta)->equipPath.split("/").remove(0).map(r=> r.capitalize)

  if(name1 != null and name1.trim != "") do
    name: "io/"+type.lower+"Libraries/"+name1
    if(not name1.endsWith(".zinc")) name = name + ".zinc"
  end
  else if(name2 != null) name: name2.toStr
  else name: "io/"+type.lower+"Libraries/"+type+"Records.zinc"

  try do //append
    dat: []
    ioReadZinc(name.parseUri).sort("navName").each x=> dat = dat.add(x) //check that exists
    rez: {}
    rmvs: []
    temp: []
    results.each result=> do
      if(type == "Point") rez = result.remove("curVal").remove("curStatus").remove("mod")
      else rez = result.remove("mod")
      (0 .. dat.size-1).each y=>
        if((dat[y].has("id") and dat[y]->id == rez->id) or (dat[y].has("navName") and dat[y]->navName == rez->navName) or dat[y].dis == rez.dis)
          rmvs = rmvs.add(y)
      temp = temp.add(rez) //append to zinc
    end
    if(rmvs.size > 0) (rmvs.size-1 .. 0).each x=> dat = dat.remove(rmvs[x])
    dat = dat.addAll(temp)
    dat.toGrid.sort("navName").ioWriteZinc(name.parseUri)
  end
  catch do //make new zinc if previous not exist
    result: []
    results.each x=> do
      if(type == "Point") result = result.add(x.remove("curVal").remove("curStatus").remove("mod"))
      else if(navs.index(type) != null) result = result.add(x.remove("mod"))
    end
    result.toGrid.sort("navName").ioWriteZinc(name.parseUri)
  end
end


def ​

func:finSaveRecordsForm ​

finSaveRecordsForm() ​

Axon function


meta ​

appFormOnfolio
batchRecords✓
deffunc:finSaveRecordsForm
distoLocale("j2FinToolsExt::saveRecords")
folderPathtoLocale("j2FinToolsExt::createBatchRecords")
helpDoc/wiki/display/FINStack/Create+Batch+Records
isfunc
liblib:finTools
namefinSaveRecordsForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
body: [
  {name: "filt", editorType: "filter", prompt:  toLocale("j2FinToolsExt::recordsToSave")+":"},
  {name: "chkbx", editorType: "checkbox", label: toLocale("j2FinToolsExt::useUniqueNavName")},
  {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
  {name: "applyButton", editorType: "button", label: toLocale("finStackExt::save"), controlBar: true}
  ]

  { "dis": toLocale("j2FinToolsExt::saveRecords"),
    "name": "finSaveRecordsForm",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "finSaveRecordsSeparate(\$filt,\$chkbx)",
    "helpDoc": "/wiki/display/FINStack/Create+Batch+Records",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finSaveRecordsSeparate ​

finSaveRecordsSeparate(filter, useUnique) ​

Axon function


meta ​

batchRecords✓
deffunc:finSaveRecordsSeparate
isfunc
liblib:finTools
namefinSaveRecordsSeparate

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filter,useUnique) => do
  navs: read(navMeta)->equipPath.split("/").remove(0)

  //return nav type that something is, null if not
  type: (rec) => do
    val: null
    navs.each nav=> do
      try do
        read(parseFilter("id=="+rec+" and "+nav))
        val = nav
      end catch ""
    end
    return val
  end

  //create list of recs
  recs: []
  if(useUnique) try results: readAll(parseFilter(filter)).unique("navName") catch results: readAll(parseFilter(filter)).unique("dis")
  else results: readAll(parseFilter(filter))
  results.each r=> recs = recs.add(r->id)

  //create dict of lists w/ keys being navs
  navDict: {}
  navs.each r=> navDict = navDict.set(r,"\"\"")

  //populate lists based on type
  t: ""
  recs.each x=> do
    t = type(x)
    if(t != null) navDict = navDict.set(t, navDict.get(t)+" or id=="+x)
  end

  //throw to save function
  navDict.each((x,y)=> if(x != "\"\"") finSaveRecords(x,y.capitalize))
end


def ​

func:finSaveSiteRecordsForm ​

finSaveSiteRecordsForm(id: false, selectedDicts: false) ​

Axon function


meta ​

batchRecords✓
deffunc:finSaveSiteRecordsForm
distoLocale("j2FinToolsExt::saveSiteRecords")
folderPathtoLocale("j2FinToolsExt::createBatchRecords")
helpDoc/wiki/display/FINStack/Create+Batch+Records
isfunc
liblib:finTools
namefinSaveSiteRecordsForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id: false, selectedDicts: false) => do
selectedIds: []
filtstr: ""
if(not isBool(selectedDicts)) do
  selectedIds = selectedDicts.map(r => "@" + r->id)
  selectedIds.each x=> filtstr = filtstr+"id=="+x+" or "
  filtstr = filtstr[0 .. -5]
end

body: [
  {name: "list", editorType: "list", prompt:  toLocale("j2FinToolsExt::sitesToSave") + ":", listType: "radio", dataProvider: filtstr, labelField: "dis"},
  {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
  {name: "applyButton", editorType: "button", label: toLocale("finStackExt::save"), controlBar: true}
  ]

  { "dis": toLocale("j2FinToolsExt::saveSiteRecords"),
    "name": "finSaveSiteRecordsForm",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$applyButton",
    "commitAction": "finSaveRecords("+filtstr.toAxonCode()+",\"Site\")",
    "helpDoc": "/wiki/display/FINStack/Create+Batch+Records",
    "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finSavedCharts ​

finSavedCharts(id) ​

finSavedCharts(Rec id) Finds all the saved charts related to the record that is passed in. Finds functions with savedChart tag and uses queryString tag for custom chart function.


meta ​

chartOnDownload✓
chartTest✓
deffunc:finSavedCharts
isfunc
liblib:finTools
namefinSavedCharts

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id) => do
  if (id == null) return [].toGrid
  tempElementOn: (id, onTag) => do
    id = id.toRec
    recs: []
    readAll(id).colNames.findAll(x=> x.endsWith(onTag+"On")).each x=> do
      readAll(parseFilter(x)).each y=> recs = recs.add(y)
    end
    funcs().colNames.findAll(x=> x.endsWith(onTag+"On")).each x=> do
      funcs(parseFilter(x)).each y=> recs = recs.add(y)
    end
    id = [id].toGrid
    recs.findAll(x=> try id.finGridFilter(parseFilter(x->chartOn)).size > 0 catch false)
  end

  try do
    currentId:id.toRecId()
    recs: readById(currentId).tempElementOn("chart")
  end catch recs: [].toGrid

  scer: []
  tmp: {}
  type: id.toRec.finNavMetaWhoAmI
  if(type == null) type = "id"

  recs.each x=> do
    if(x.has("func")) do
      tmp = {chartOn: x->chartOn, chartOnDownload, chartTest, finSavedChart, dis: x.dis, mod: now()}
      if(x.has("queryString")) tmp = tmp.merge({queryString: x->queryString, savedChart: x->queryString})
      else tmp = tmp.merge({queryString: x->name+"(\$targetRef)", savedChart: x->name+"(\$targetRef)"})
    end
    else tmp = x.set("finSavedChart",marker())
    if(x.has("id")) tmp = tmp.set("id",x->id)
    if(x.has("excludes")) tmp = tmp.set("excludes", x->excludes)
    scer = scer.add(tmp)
  end
  funcs(finSavedChart and name and not chartOn).each x=> do
    tmp = {chartOn: type, chartOnDownload, chartTest, finSavedChart, dis: x.dis, mod: now()}
    if(x.has("queryString")) tmp = tmp.merge({queryString: x->queryString, savedChart: x->queryString})
    else tmp = tmp.merge({queryString: x->name+"(\$targetRef)", savedChart: x->name+"(\$targetRef)"})
    if(x.has("excludes")) tmp = tmp.set("excludes", x->excludes)
    scer = scer.add(tmp)
  end

  scer.toGrid
end


def ​

func:finSelectedConnectorTypes ​

finSelectedConnectorTypes(selectedIds) ​

Axon function


meta ​

deffunc:finSelectedConnectorTypes
isfunc
liblib:finTools
namefinSelectedConnectorTypes

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(selectedIds) => do

  recList : finSelectedPoints(selectedIds)

  connMap: {}
  recList.each rec => do
    rec.each((v,k) => do
      if (endsWith(k, "ConnRef")) do
        type: k[0..-8]
        connMap = connMap.set(type, type)
      end
    end)
  end

  connList: []
  connMap.each((v,k) => connList = connList.add({"type": v}))

  if (connList.size == 0)
    connList = connList.add({type: toLocale("j2FinToolsExt::noConnectorsFound")})

  return connList.toGrid()
end


def ​

func:finSelectedPoints ​

finSelectedPoints(selectedIds) ​

Axon function


meta ​

deffunc:finSelectedPoints
isfunc
liblib:finTools
namefinSelectedPoints

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(selectedIds) => do
  result: []

  selectedIds.each id =>
  do
    dict: read(parseFilter("id == " + id))

    filter: ""
    if      (dict.has("equip"))  filter = "point and equipRef == @"  + dict.get("id")
    else if (dict.has("floor"))  filter = "point and floorRef == @"  + dict.get("id")
    else if (dict.has("site"))   filter = "point and siteRef == @"   + dict.get("id")
    else if (dict.has("region")) filter = "point and regionRef == @" + dict.get("id")
    else                         filter = "id == @" + dict.get("id")

    if (filter != "")
    do
      grid: readAll(parseFilter(filter))
      grid.each r => result = result.add(r)
    end

  end

  return result
end


def ​

func:finSetImmediateSubOffTimeCommit ​

finSetImmediateSubOffTimeCommit(offTime, onTime, jobRef: null) ​

Axon function


meta ​

alarmEmailToggle✓
deffunc:finSetImmediateSubOffTimeCommit
isfunc
liblib:finTools
namefinSetImmediateSubOffTimeCommit

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(offTime, onTime, jobRef:null) => do
  // only su or admin
  if (not finGetCurrentUser().has("isAdmin"))
    return finFormAlertOk("Warning", "Setting the topic email silence period for all users requires Admin permission.")

  fullHour: ["hh:mm", "h:mm"]
  halfHour: ["kk:mm AA", "kk:mmAA", "k:mm AA", "k:mmAA"]

  offOk: reMatches(r"[0-2]?\d:[0-5]\d\s?([aApP][mM])?", offTime)
  onOk: reMatches(r"[0-2]?\d:[0-5]\d\s?([aApP][mM])?", onTime)

  offEnd: reFind(r"[aApP][mM]", offTime)
  onEnd: reFind(r"[aApP][mM]", onTime)

  formattedOff: if(offOk) do
    if(offEnd !=  null) halfHour.eachWhile(v => parseTime(offTime, v, false))
    else fullHour.eachWhile(v => parseTime(offTime, v, false))
  end else null

  formattedOn: if(onOk) do
    if(onEnd != null) halfHour.eachWhile(v => parseTime(onTime, v, false))
    else fullHour.eachWhile(v => parseTime(onTime, v, false))
  end else null

  // re-open form if times provided cannot be formatted
  if(formattedOff == null or formattedOn == null)
    return finFormSetImmediateSubscriptionOffTime({on: onTime, off: offTime})

  // update all users
  finSetTopicEmailSilenceTime(userReadAll(topicsEmailImmediate).colToList("id"), formattedOff, formattedOn)

  // delete deprecated job if it exists
  if(jobRef != null)
    readById(jobRef).diff({}, {remove}).commit
end


def ​

func:finShowEquipSummary ​

finShowEquipSummary(inp: null, pnts: null, sps: null) ​

Axon function


meta ​

deffunc:finShowEquipSummary
isfunc
liblib:finTools
namefinShowEquipSummary
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(inp: null, pnts: null, sps: null) => do
  if(inp == null) do
    finShowEquipSummaryRecur(readAll(site).toRecList.map(x=> x.merge({a})).map(x=> x.remove("a")))
  end else if(inp.isStr) do
    if(not pnts.isStr) pnts = "vipPoint"
    if(not sps.isStr) sps = "vipSp"
    finShowEquipSummaryRecur(readAll(parseFilter("("+inp+") and equip")).toRecList, 0, {pnts: pnts, sps: sps})
  end else do
    finShowEquipSummaryRecur(readById(inp).toRecList)
  end
end


def ​

func:finShowEquipSummaryRecur ​

finShowEquipSummaryRecur(inp, ind: 0, extra: null) ​

Axon function


meta ​

deffunc:finShowEquipSummaryRecur
isfunc
liblib:finTools
namefinShowEquipSummaryRecur
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(inp, ind: 0, extra: null) => do
  tmp: []

  genColor: (vv,lv,hv)=> do
    c: [[8, 41, 229],[57, 83, 229],[255, 255, 255],[229, 90, 89],[229, 5, 0]]
    z: (vv - ((hv + lv) / 2)) / ((hv - lv) / 4)
    if(z == 2) z = 1.999
    i: floor(z + 2)
    c1: c[i]
    c2: c[i+1]
    z = z - floor(z)
    r: toHex(z * (c2[0] - c1[0]) + c1[0])
    if(r.size == 1) r = "0" + r
    g: toHex(z * (c2[1] - c1[1]) + c1[1])
    if(g.size == 1) g = "0" + g
    b: toHex(z * (c2[2] - c1[2]) + c1[2])
    if(b.size == 1) b = "0" + b
    "#"+r+g+b
  end

  if(inp.size > 0) (0..inp.size - 1).each x=> do
    tmp = finNavChildren("equip", inp[x]->id).findAll(y=> not y.has("point")).finNavRollup.toRecList.map(y=> y.merge({"a"})).map(y=> y.remove("a"))
    if(tmp.size > 0) inp = inp.set(x, inp[x].set("subItems", finShowEquipSummaryRecur(tmp, ind+1, extra)))
    else if(extra.isDict) do
      g: [{numAlarms:0, numManual:0, numUnackAlarms:0}]
      if(inp[x].has("equipRef")) g = finNavChildren("equip",inp[x]->equipRef).find(y=> y->id == inp[x]->id).toGrid.finNavRollup
      else if(inp[x].has("floorRef")) g = finNavChildren("equip",inp[x]->floorRef).find(y=> y->id == inp[x]->id).toGrid.finNavRollup
      g = g[0]
      //inp = inp.set(x, inp[x].merge({numAlarms:g->numAlarms, numManual:g->numManual, numUnackAlarms:g->numUnackAlarms}))
      inp = inp.map((y,z)=> do
        if(z == x) inp[x].merge({numAlarms:g->numAlarms, numManual:g->numManual, numUnackAlarms:g->numUnackAlarms})
        else inp[z]
      end)
    end
  end

  vpfilt: "vipPoint"
  vsfilt: "vipSp"
  if(extra.isDict) do
    vpfilt = extra->pnts
    vsfilt = extra->sps
  end

  inp.map(y=> do
    if(y.has("equip") and readCount(parseFilter(vpfilt) and equipRef==y->id) > 0 and readCount(parseFilter(vsfilt) and equipRef==y->id) > 0) do
      pt: read(parseFilter(vpfilt) and equipRef==y->id)
      sp: read(parseFilter(vsfilt) and equipRef==y->id)
      v: pt->curVal - sp->curVal
      if(sp.has("vipLowOffset")) l: sp->vipLowOffset
      else l: -5
      if(sp.has("vipHighOffset")) h: sp->vipHighOffset
      else h: 5
      if(v < l) v = l
      if(v > h) v = h
      y = y.merge({vipPoint: pt, vipSp: sp, color: genColor(v,l,h)})
    end
    y.merge({indent: ind})
  end)
end


def ​

func:finSoftDelete ​

finSoftDelete(recs) ​

A function to send records to the trash. Records can be recovered in the folio trash.

e.g. read(foo).finSoftDelete() //only one record readAll(point).finSoftDelete() //multiple records


meta ​

deffunc:finSoftDelete
isfunc
liblib:finTools
namefinSoftDelete

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(recs) => do
  recs.toRecList.each x=> x.diff({trash}).commit
end


def ​

func:finStrGet ​

finStrGet(g, s: 0, e: null) ​

function: finStrGet(string, start, end)

This function gets a substring starting from start and ending at end of a string.

It acts just like the get() function, only it adapts to values that are out of the range of the string.

e.g.: "asdf".finStrGet(0) -> "a" "asdf".finStrGet(8) -> "f" "asdf".finStrGet(-1) -> "f" "asdf".finStrGet(-20) -> "a"


meta ​

deffunc:finStrGet
isfunc
liblib:finTools
namefinStrGet

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(g,s:0,e:null) => do
  if(e == null) e = s

  if(s >= g.size) s = g.size - 1
  else if(s < -1 * g.size) s = -1 * g.size
  if(e >= g.size) e = g.size - 1
  else if(e < -1 * g.size) e = -1 * g.size

  if(g.size == 0) ""
  else g[s..e]
end


def ​

func:finStringSearchDicts ​

finStringSearchDicts(dictlist, dict1, dict2, col) ​

Function to search through a list of dicts and return only those that meet the defined criteria.

Usage: finStringSearchDicts(dictlist, dict1, dict2, col)

dictlist: List of dicts to search through dict1:

Used for counting occurences in specified column
char field can be comma separated for different characters
Types:
    hasMoreThan is >
    hasLessThan is <
    hasEqualTo is ==
    notMoreThan is <=
    notLessThan is >=
    notEqualTo is !=
disable can be omitted, if true then it will not be used to filter out the dicts

dict2:

Used to check if column contains a string
Can be comma separated for multiple strings
The possible types are contains, notContains, startsWith, notStartsWith, endsWith, notEndsWith

col: Which column to search in disable can be omitted, if true then it will not be used to filter out the dicts

Examples:

finStringSearchDicts([{one: "hello.world.today"},{one: "hello.world"}], {type: "notMoreThan", value: 2, char: "."}, {contains: "ot, ay"}, "one")
finStringSearchDicts(listOfRecs,{value:3,type:"hasMore",char:".,the,???"},{contains:"?,!",notContains:"fat.jason,???"},"colName")
readAll(point).finStringSearchDicts({type: "notMoreThan", value: 2, char: "-"}, {contains: "1,2"}, "navName")

meta ​

deffunc:finStringSearchDicts
finString✓
isfunc
liblib:finTools
namefinStringSearchDicts

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

//search through dictlist and return only those that meet specifications
(dictlist, dict1, dict2, col) => do
  //dictlist: list of stuff to search through
  //dict1: {type: "hasMoreThan", value: 3, char: "."} //counting
  //dict2: {type1: "contains", str1: "jason,34", type2: "notContains", str2: "?,!,foo"} //string
  //col: which col to search in
  dictlist = dictlist.toRecList
  endlist: []
  tmp: ""
  func1: ""
  func2: ""
  func3: ""

  count: (string, char)=> do //find number of occurences
    cnt: 0
    thi: char.size() - 1
    if(string.size >= char.size) (0 .. string.size - 1 - thi).each x=> if(string[x .. x + thi] == char) cnt = cnt + 1
    cnt
  end

  /*
  type1: contains, val1: "", type2: notContains, val2: ""
  type1: startsWith, val1: "", type2: notStartsWith, val2: ""
  type1: endsWith, val1: "", type2: notEndsWith, val2: ""
  */

  if(not dict2.has("type1") or dict2->val1.trim == "") dict2 = dict2.set("type1", "contains").set("val1", "")
  if(not dict2.has("type2") or dict2->val2.trim == "") dict2 = dict2.set("type2", "contains").set("val2", "")

  if(dict1.has("disable") and dict1->disable == true) dict1 = {type: "hasMoreThan", value: 0, char: ""}
  if(dict2.has("disable") and dict2->disable == true) dict2 = {type1: "contains", val1: "", type2: "contains", val2: ""}

  if(dict2->type1 == "contains") func2 = (x,y)=> x.contains(y)
  else if(dict2->type1 == "notContains") func2 = (x,y)=> not x.contains(y)
  else if(dict2->type1 == "startsWith") func2 = (x,y)=> x.startsWith(y)
  else if(dict2->type1 == "notStartsWith") func2 = (x,y)=> not x.startsWith(y)
  else if(dict2->type1 == "endsWith") func2 = (x,y)=> x.endsWith(y)
  else if(dict2->type1 == "notEndsWith") func2 = (x,y)=> not x.endsWith(y)
  else throw dict2->type1 + " is not a valid option"

  if(dict2->type2 == "contains") func3 = (x,y)=> x.contains(y)
  else if(dict2->type2 == "notContains") func3 = (x,y)=> not x.contains(y)
  else if(dict2->type2 == "startsWith") func3 = (x,y)=> x.startsWith(y)
  else if(dict2->type2 == "notStartsWith") func3 = (x,y)=> not x.startsWith(y)
  else if(dict2->type2 == "endsWith") func3 = (x,y)=> x.endsWith(y)
  else if(dict2->type2 == "notEndsWith") func3 = (x,y)=> not x.endsWith(y)
  else throw dict2->type2 + " is not a valid option"

  //make the function be correct
  if(dict1->type == "hasMoreThan") func1 = eval("x=> if(x > "+dict1->value+") true else false")
  else if(dict1->type == "hasLessThan") func1 = eval("x=> if(x < "+dict1->value+") true else false")
  else if(dict1->type == "hasEqualTo") func1 = eval("x=> if(x == "+dict1->value+") true else false")
  else if(dict1->type == "notMoreThan") func1 = eval("x=> if(x <= "+dict1->value+") true else false")
  else if(dict1->type == "notLessThan") func1 = eval("x=> if(x >= "+dict1->value+") true else false")
  else if(dict1->type == "notEqualTo") func1 = eval("x=> if(x != "+dict1->value+") true else false")
  else throw dict1->type + " is not a valid option"

  dictlist.each dict=> do
    if(dict.has(col)) do
      tmp = dict.trap(col)
      if(dict1->char.split(",").map(g=> tmp.count(g).func1).find(g=> g) == true and dict2->val1.split(",").map(g=> tmp.func2(g.trim)).find(g=> g) != null and dict2->val2.split(",").map(g=> tmp.func3(g.trim)).find(g=> g) != null)
        endlist = endlist.add(dict)
    end
  end

  endlist
end

//finStringSearchDicts(listOfRecs,{value:3,type:"hasMoreThan",char:".,the,???"},{contains:"?,!",notContains:"fat.jason,???"},"colName")

//finStringSearchDicts([{one: "hello.world.today"},{one: "hello.world"}], {type: "notMoreThan", value: 2, char: "."}, {contains: "ot, ay"}, "one")


def ​

func:finStringSplitDicts ​

finStringSplitDicts(dictlist, col, splt, transform, newcol) ​

Function to go through a list of dicts and split the specified column by the split character and put it together in a flexible way.

Usage: finStringSplitDicts(dictlist, col, splt, transform, newcol)

dictlist: List of dicts to iterate through col: Which column to look through splt: Character(s) to split by transform: List of how to reconstruct string newcol: Name of column to put transformed string in

Examples:

finStringSplitDicts([{one: "hello.world.today", two: "cake"}], "one", ".", ["({{one}}) hello ", 2, " today {{two}}"], "hi")

Takes [{one: "hello.world.today", two: "cake"}] list, gets column named "one", splits that by ".", rearranges as "(hello.world.today) hello world today cake".

Can use {{colName}} to input a column into the string, calling {{two}} inputs column "two" into string, "cake".
Can also use {{colRef->prop}} to input the property of a ref column into the string.

meta ​

deffunc:finStringSplitDicts
finString✓
isfunc
liblib:finTools
namefinStringSplitDicts

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

//search through dictlist and transform column value
(dictlist, col, splt, transform, newcol) => do
  dictlist = dictlist.toRecList
  endlist: []
  tmp: ""
  text: ""
  exec: true

  findGroups: s=> do
    grps: []
    (1 .. ceil(s.split("{").size / 2)).eachWhile x=> do
      t: reFind(r"\{\{[^\}]+\}\}", s)
      if(t == null) true
      else do
        grps = grps.add(t)
        s = s.replace(t, "")
        null
      end
    end
    grps
  end

  dictlist.each dict=> do
    if(dict.has(col)) do
      text: ""
      tmp = dict.trap(col).replace(splt, toChar(8)).split(toChar(8)).map(g=> g.trim)

      transform.each g=> do
        if(g.isNumber and g <= tmp.size) text = text + tmp[g - 1]
        else if(not g.isNumber) text = text + g
      end

      text.findGroups.each g=> do
        h: g[2..-3].trim
        if(dict.has(h)) text = text.replace(g, dict.trap(h).toStr)
        else if(h.contains("->")) do
          h = h.replace("->",toChar(8)).split(toChar(8))
          if(dict.has(h[0]) and dict.trap(h[0]).isRef) do
            d: dict.trap(h[0]).readById(false)
            if(d != null and d.has(h[1])) text = text.replace(g, d.trap(h[1]).toStr)
          end
        end
      end

      endlist = endlist.add(dict.set(newcol, text.trim))
    end
  end

  endlist
end

//transform variables numbered from 1 not 0

//finStringSplitDicts(dictlist, "dis", ".", ["foo", 2, "jason {{colName}}"], "newCol")
//dis: "RTU.Cooler.1"
//newCol: "fooCoolerjason"

//if index doesn't exist, replace with ""

//finStringSplitDicts([{one: "hello.world.today", two: "cake"}], "one", ".", ["({{one}}) hello ", 2, " today {{two}}"], "hi")


def ​

func:finSuperTagger ​

finSuperTagger(filter, column, matchList) ​

finSuperTagger


meta ​

constructfinSuperTagger(filter, column, matchList)
deffunc:finSuperTagger
isfunc
liblib:finTools
namefinSuperTagger

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finSuperTaggerForm ​

finSuperTaggerForm(id) ​

Axon function


meta ​

deffunc:finSuperTaggerForm
distoLocale("j2FinToolsExt::superTagger")
folderPathtoLocale("finStackExt::advanced")
formOnsuperTagger
helpThis is an advanced form that lets you use regex express...
hideMobile✓
isfunc
liblib:finTools
namefinSuperTaggerForm

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id) => do
    rec: id.toRec()
    body:
    [
        {
            name: "filterText",
            editorType: "textinput",
            prompt:toLocale("finStackExt::finFilter") },
        {
            name: "columnText",
            editorType: "textinput",
            prompt:toLocale("j2FinToolsExt::columnToMatch") },
        {
            name: "pastedData",
            editorType: "table",
            prompt: toLocale("j2FinToolsExt::pasteExcelTagger"),
            height:150 },
        {
            name: "cancelButton",
            editorType: "button",
            label: toLocale("finStackExt::cancel"),
            controlBar: true },
        {
            name: "applyButton",
            editorType: "button",
            label: toLocale("finStackExt::coreApply"),
            controlBar: true }
    ]

    {
        "dis": toLocale("j2FinToolsExt::superTagger"),
        "name": "create a note",
        "body": body.toJSON,
        "cancelButton": "\$cancelButton",
        "commitButton": "\$applyButton",
        "commitAction": "finSuperTagger(\$filterText,\$columnText,\$pastedData)",
        "gotoAction": "finstack:folio:axonQuery=readCount(\$filterText)",
        "helpDoc":"/wiki/display/FINStack/Super+Tagger",
        "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})

end


def ​

func:finSyncPoints ​

finSyncPoints(connIds, fromOrd, toOrd) ​

ToDo: Move this to migration script


meta ​

deffunc:finSyncPoints
isfunc
liblib:finTools
namefinSyncPoints

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finSyncToColl ​

finSyncToColl(filter, isCollectOnInter, collectInterval, intervalUnits, isCOV, covInterval, basu: false) ​

Axon function


meta ​

baSuExec✓
deffunc:finSyncToColl
isfunc
liblib:finTools
namefinSyncToColl

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filter, isCollectOnInter, collectInterval, intervalUnits, isCOV, covInterval, basu:false) => do
  pointList: null

  if(filter.isList()) pointList = readByIds(filter)
  else pointList = readAll(parseFilter(filter))

  auxPointCount:pointList.finGridFilter(aux).size

  if((licStatus()->usage + auxPointCount) > licStatus()->points)
    return finFormAlertOk(toLocale("finStackExt::regError"),toLocale("j2FinToolsExt::histToCollectPointLimitError").replace("{pointFilterSize}", auxPointCount.toStr))

  //do not allow less than 15 seconds
  if(intervalUnits == "sec" and collectInterval < 15)
    collectInterval = 15

  //set up various data that will be used
  timeInterval: parseNumber(collectInterval + intervalUnits)

  //apply changes to collection
  pointList.each currentPoint => do
    if(isCollectOnInter or isCOV) do //if either interval or cov is selected
      if(isCollectOnInter and isCOV == false) //hisCollectInterval only
        currentPoint.diff({-aux, -haystackHis, hisCollectInterval: timeInterval, -hisCollectCov, his}).commit
      else if(isCollectOnInter and isCOV and (currentPoint->kind != "Bool" and currentPoint->kind != "Str")) //both, not bool
        currentPoint.diff({-aux, -haystackHis, hisCollectInterval: timeInterval, hisCollectCov: covInterval, his}).commit
      else if(isCollectOnInter and isCOV and (currentPoint->kind == "Bool" or currentPoint->kind == "Str")) //both, bool
        currentPoint.diff({-aux, -haystackHis, hisCollectInterval: timeInterval, hisCollectCov, his}).commit
      else if(isCOV and (currentPoint->kind != "Bool" and currentPoint->kind != "Str")) //cov only, not bool
        currentPoint.diff({-aux, -haystackHis, -hisCollectInterval, hisCollectCov: covInterval, his}).commit
      else if(isCOV and (currentPoint->kind == "Bool" or currentPoint->kind == "Str")) //cov only, bool
        currentPoint.diff({-aux, -haystackHis, -hisCollectInterval, hisCollectCov, his}).commit
    end
  end //end loop
end


def ​

func:finTagBlackList ​

finTagBlackList() ​

Return a grid of all those tags which should not be removed by the user.


meta ​

deffunc:finTagBlackList
isfunc
liblib:finTools
namefinTagBlackList

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  // TODO help doc, dis

  [
    {regex: r"^id$",    dis: "\"id\""    },
    {regex: r"^mod$",   dis: "\"mod\""   },
    {regex: r"^site$",  dis: "\"site\""  },
    {regex: r"^equip$", dis: "\"equip\"" },
    {regex: r"^point$", dis: "\"point\"" },

    {regex: r"^cur*",      dis: toLocale("j2FinToolsExt::startsWithStr").replace("{tagName}", "cur")},
    {regex: r"^his*",      dis: toLocale("j2FinToolsExt::startsWithStr").replace("{tagName}", "his")},

    {regex: r"^*Cur$",     dis: toLocale("j2FinToolsExt::endsWithStr").replace("{tagName}", "Cur")},
    {regex: r"^*His$",     dis: toLocale("j2FinToolsExt::endsWithStr").replace("{tagName}", "His")},
    {regex: r"^*ConnRef$", dis: toLocale("j2FinToolsExt::endsWithStr").replace("{tagName}", "ConnRef")},
    {regex: r"^*Write$",   dis: toLocale("j2FinToolsExt::endsWithStr").replace("{tagName}", "Write")},
    {regex: r"^connRef$",  dis: "\"connRef\""},
    {regex: r"^write(?!.*?(?:Def|\d)).*$", dis: toLocale("j2FinToolsExt::startsWithButDoesNotEnd").replace("{tagName}", "write").replace("{tagName2}", "Def")}
  ]

end


def ​

func:finTemplates ​

finTemplates() ​

Returns records with templateOn from pods and the database


meta ​

deffunc:finTemplates
isfunc
liblib:finTools
namefinTemplates

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  temp: finBacnetTemplates().toGrid.finGridFilter(templateOn)
  locl: readAll(templateOn)
  if(locl.size > 0) temp = temp.addRows(locl)
  temp
end


def ​

func:finThemeUsed ​

finThemeUsed() ​

This function will return the theme that the user is using. It is used in FIN Builder to have themes inside of FIN BUilder Custom Graphics


meta ​

constructfinThemeUsed()
deffunc:finThemeUsed
isfunc
liblib:finTools
namefinThemeUsed

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  ///// This function will return the theme used based on the user. If the user is a su then it defaults to the black theme. If the user
  ///// doesn't have a finThemeRef defined then it will return the black theme.

  user: finGetCurrentUser()
  currentUserName: user->username
  currentProject: context()->projName
  userTheme:  try user->finThemeRef->dis catch null
  myLogoId: try read(myLogo)->id catch null

  darkTheme:
  {
  windowBG:"2B2B2B",
  textBG:"212121",
  textBGStroke:"linear-gradient(to bottom, #212121 0%, #212121 93%, #4f4f4f 97%, #4f4f4f 100%)",
  accentColor:"linear-gradient(to bottom, #00ABFE 0%, #0A579A 100%)",
  windowHeader:"linear-gradient(to bottom, #2B2B2B 0%, #1C1C1C 100%)",
  textTitle:"ffffff",
  textValue:"29ABE1",
  texture:100,
  shadow:50,
  highlight:"4F4F4F",
  shadow2:"000000",
  accentColorStroke:"linear-gradient(to bottom, #96DEFF 0%, #00ABFE 1%, #0A579A 100%)",
  windowHeaderStroke:"linear-gradient(to bottom, #4F4F4F 0%, #2B2B2B 1%, #1C1C1C 100%)",
  buttonMouseOver:"linear-gradient(to bottom, #69CFFF 0%, #0D75D1 100%)",
  buttonDown:"linear-gradient(to bottom, #04213B 0%, #0A579A 100%)",
  logo: ("/api/" + currentProject + "/rec/" + myLogoId + "/file").parseUri
  }

  lightOrangeTheme:
  {
  windowBG:"E0E0E0",
  textBG:"F0F0F0",
  textBGStroke:"linear-gradient(to bottom, #F0F0F0 0%, #F0F0F0 93%, #ffffff 97%, #ffffff 100%)",
  accentColor:"linear-gradient(to bottom, #FFC954 0%, #F08E1F 100%)",
  windowHeader:"linear-gradient(to bottom, #E0E0E0 0%, #999999 100%)",
  textTitle:"333333",
  textValue:"FFC954",
  texture:14,
  shadow:30,
  highlight:"FFFFFF",
  shadow2:"CCCCCC",
  accentColorStroke:"linear-gradient(to bottom, #FFF2D6 0%, #FFC954 1%, #F08E1F 100%)",
  windowHeaderStroke:"linear-gradient(to bottom, #FFFFFF 0%, #E0E0E0 1%, #999999 100%)",
  buttonMouseOver:"linear-gradient(to bottom, #FFE09C 0%, #F0A54F 100%)",
  buttonDown:"linear-gradient(to bottom, #8A4004 0%, #F08E1F 100%)",
  logo: ("/api/" + currentProject + "/rec/" + myLogoId + "/file").parseUri
  }

  siemensTheme:
  {
  windowBG:"E0E0E0",
  textBG:"C0C0C0",
  textBGStroke:"linear-gradient(to bottom, #C0C0C0 0%, #C0C0C0 93%, #ffffff 97%, #ffffff 100%)",
  accentColor:"linear-gradient(to bottom, #1AC2C4 0%, #019999 100%)",
  windowHeader:"linear-gradient(to bottom, #cccccc 0%, #b6b6b6 100%)",
  textTitle:"333333",
  textValue:"333333",
  texture:14,
  shadow:30,
  highlight:"FFFFFF",
  shadow2:"c0c0c0",
  accentColorStroke:"linear-gradient(to bottom, #7BDFE0 0%, #1AC2C4 1%, #019999 100%)",
  windowHeaderStroke:"linear-gradient(to bottom, #FFFFFF 0%, #cccccc 1%, #b6b6b6 100%)",
  buttonMouseOver:"linear-gradient(to bottom, #47DBDE 0%, #0BB5B8 100%)",
  buttonDown:"linear-gradient(to bottom, #015354 0%, #019999 100%)",
  logo: ("/api/" + currentProject + "/rec/" + myLogoId + "/file").parseUri
  }

  lightBlueTheme:
  {
  windowBG:"E0E0E0",
  textBG:"C0C0C0",
  textBGStroke:"linear-gradient(to bottom, #C0C0C0 0%, #C0C0C0 93%, #ffffff 97%, #ffffff 100%)",
  accentColor:"linear-gradient(to bottom, #00ABFE 0%, #0A579A 100%)",
  windowHeader:"linear-gradient(to bottom, #cccccc 0%, #b6b6b6 100%)",
  textTitle:"333333",
  textValue:"29ABE1",
  texture:14,
  shadow:30,
  highlight:"FFFFFF",
  shadow2:"c0c0c0",
  accentColorStroke:"linear-gradient(to bottom, #96DEFF 0%, #00ABFE 1%, #0A579A 100%)",
  windowHeaderStroke:"linear-gradient(to bottom, #FFFFFF 0%, #cccccc 1%, #b6b6b6 100%)",
  buttonMouseOver:"linear-gradient(to bottom, #69CFFF 0%, #0D75D1 100%)",
  buttonDown:"linear-gradient(to bottom, #04213B 0%, #0A579A 100%)",
  logo: ("/api/" + currentProject + "/rec/" + myLogoId + "/file").parseUri
  }

  if ((currentUserName== "su") or (user == null))

    lightBlueTheme

  else if (userTheme == "Light Blue Theme")

    lightBlueTheme

  else if (userTheme == "Light Orange Theme")
    lightOrangeTheme

  else if (userTheme == "Siemens Theme")
    siemensTheme

  else if (userTheme == "Dark Theme")
    darkTheme

  else

    lightBlueTheme

end


def ​

func:finToNumberList ​

finToNumberList(s) ​

Function to import a string and output values 3-5 will output 3,4,5 starting-ending 4,5 will output 4,5 number1,number2... 2.2.2 will output 2 4 starting.quantity,increment

Input: 1) 12-14,19,5.10.5 2) VAV-[1-12] fooBag 3) VAV-[1,2,3,18-28,29,30] 4) VAV-[5.10.5]

Output: 1) 12,13,14,19,5,10,15,20,25,30,35,40,45,50 2) VAV-1 fooBag,VAV-2 fooBag,VAV-3 fooBag,...,VAV-11 fooBag,VAV-12 fooBag 3) VAV-1,VAV-2,VAV-3,VAV-18,VAV-19,...,VAV-27,VAV-28,VAV-29,VAV-30 4) VAV-5,VAV-10,VAV-15,VAV-20,VAV-25,VAV-30,VAV-35,VAV-40,VAV-45,VAV-50


meta ​

deffunc:finToNumberList
isfunc
liblib:finTools
namefinToNumberList

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(s) => do
  genList: gL_s=> do
    gL_o: []
    gL_g: ""
    gL_s.replace(" ","").split(",").each gL_x=> try do
      if(gL_x.contains("-")) do
        gL_g = gL_x.split("-")
        (gL_g[0].parseInt .. gL_g[1].parseInt).each gL_y=> gL_o = gL_o.add(gL_y)
      end
      else if(gL_x.contains(".")) do
        gL_g = gL_x.split(".").map(gL_y=> gL_y.parseInt)
        if(gL_g.size < 3) gL_g = gL_g.add(1)
        (1..gL_g[1]).each gL_y=> do
          gL_o = gL_o.add(gL_g[0])
          gL_g = gL_g.set(0,gL_g[0]+gL_g[2])
        end
      end
      else gL_o = gL_o.add(gL_x.parseInt)
    end catch null
    gL_o
  end

  split: (s_s, s_d)=> do
    s_o: []
    s_t: ""
    (0 .. s_s.size - 1).each s_x=> do
      if(s_s[s_x..s_x] == s_d) do
        s_o = s_o.add(s_t)
        s_t = ""
      end else s_t = s_t + s_s[s_x..s_x]
    end
    s_o.add(s_t)
  end

  if(s.contains("[") and s.contains("]")) do
    pr: s.split("[")[0]
    su: s.split("]")[1]
    tmp: genList(s.split("[")[1].split("]")[0]).map(x=> pr+x+su)
  end else tmp: genList(s)

  if(tmp.size == 0) s
  else tmp
end


def ​

func:finToggleImmediateSubscriptions ​

finToggleImmediateSubscriptions(action: "hide", filterStr: "", jobRec: null) ​

Axon function


meta ​

alarmEmailToggle✓
deffunc:finToggleImmediateSubscriptions
deprecated✓
isfunc
liblib:finTools
namefinToggleImmediateSubscriptions

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(action: "hide", filterStr: "", jobRec: null) => do
  users: null

  if(jobRec != null) do
    if(action == "show") readById(jobRec->id).diff({jobSchedule: "at " + jobRec->offTime.format("hh:mm:ss"), showing: false}, {force}).commit
    else readById(jobRec->id).diff({jobSchedule: "at " + jobRec->onTime.format("hh:mm:ss"), showing: true}, {force}).commit
  end

  if(action == "hide") do
    if(filterStr == "") filterStr = "topicsEmailImmediate"
    else filterStr = "topicsEmailImmediate and (" + filterStr + ")"

    users = userReadAll(parseFilter(filterStr))
    users.each user => finToggleUserSubscriptions(user->id, true)

    return toLocale("j2FinToolsExt::numSubsHidden").replace("{num}", users.size.toStr)
  end else if(action == "show") do
    if(filterStr == "") filterStr = "hiddenTopicsEmailImmediate"
    else filterStr = "hiddenTopicsEmailImmediate and (" + filterStr + ")"

    users = userReadAll(parseFilter(filterStr))
    users.each user => finToggleUserSubscriptions(user->id, false)

    return toLocale("j2FinToolsExt::numSubsShown").replace("{num}", users.size.toStr)
  end else
    throw toLocale("j2FinToolsExt::incorrectActionParam")
end


def ​

func:finTuningPolicyGetStats ​

finTuningPolicyGetStats(policyList, byPolicy: false) ​

Axon function


meta ​

deffunc:finTuningPolicyGetStats
isfunc
liblib:finTools
namefinTuningPolicyGetStats
polyStats✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(policyList, byPolicy:false) => do
  stats: []
  //conns: null
  totalConns: 0
  directPts: 0
  pointsUnderConns: 0
  policyDict: {}

  if(byPolicy) do
    each(policyList) (policy, i) => do
      conns: readAll(connTuningRef == policy->id).findAll(v => not v.has("point"))
      totalConns = conns.size
      directPts = readAll(connTuningRef == policy->id and point).size

      pointsUnderConns = 0
      conns.each x => do
        connType: readAllTagNames(id==x->id).find(v => v->name.endsWith("Conn"))->name
        pointsUnderConns = pointsUnderConns + readAll(parseFilter("point and " + connType + "Ref == " + x->id.toAxonCode + " and not connTuningRef")).size
      end

      policyDict = {name: policy.dis, connectorsUsed: totalConns, pointsUnderConnectors: pointsUnderConns, directPoints: directPts, totalPoints: directPts + pointsUnderConns}
      if(policy.has("pollTime")) policyDict = policyDict.set("pollTime", policy->pollTime)
      if(policy.has("writeMaxTime")) policyDict = policyDict.set("writeMaxTime", policy->writeMaxTime)
      if(policy.has("writeMinTime")) policyDict = policyDict.set("writeMinTime", policy->writeMinTime)
      if(policy.has("writeSchedule")) policyDict = policyDict.set("writeSchedule", marker())

      stats = stats.add(policyDict)
    end

    stats = stats.toGrid
    stats = stats.reorderCols(stats.colNames.moveTo("connectorsUsed", -1).moveTo("pointsUnderConnectors", -1).moveTo("directPoints", -1).moveTo("totalPoints", -1))
  end else do
    each(policyList) (connector, i) => do
      connType: readAllTagNames(id==connector->id).find(v => v->name.endsWith("Conn"))->name
      mainPolicy: {dis: "null"}
      pointWithTunes: null
      pointTunes: "["

      if(readById(connector).has("connTuningRef"))
        mainPolicy = readById(connector->connTuningRef)

      if(mainPolicy->dis == "null")
        pointWithTunes = readAll(parseFilter("point and " + connType + "Ref == " + connector->id.toAxonCode + " and connTuningRef"))
      else
        pointWithTunes = readAll(parseFilter("point and " + connType + "Ref == " + connector->id.toAxonCode + " and connTuningRef != " + mainPolicy->id.toAxonCode))

      if(not pointWithTunes.isEmpty())
        pointWithTunes = pointWithTunes.unique("connTuningRef")

      pointsUnderConns = readAll(parseFilter("point and " + connType + "Ref == " + connector->id.toAxonCode + " and not connTuningRef")).size
      directPts = readAll(parseFilter("point and " + connType + "Ref == " + connector->id.toAxonCode + " and connTuningRef")).size

      pointWithTunes.each tune => pointTunes = pointTunes + readById(tune->connTuningRef).dis + ", "
      if(pointTunes != "[") pointTunes = pointTunes[0..-3] + "]"

      policyDict = {connector: connector->dis, name: mainPolicy->dis, pointsUnderConnector: pointsUnderConns, directPoints: directPts, totalPoints: directPts + pointsUnderConns, connectorPolicy}
      if(pointTunes != "[") policyDict = policyDict.set("directPointPolicies", pointTunes)
      if(mainPolicy.has("pollTime")) policyDict = policyDict.set("pollTime", mainPolicy->pollTime)
      if(mainPolicy.has("writeMaxTime")) policyDict = policyDict.set("writeMaxTime", mainPolicy->writeMaxTime)
      if(mainPolicy.has("writeMinTime")) policyDict = policyDict.set("writeMinTime", mainPolicy->writeMinTime)
      if(mainPolicy.has("writeSchedule")) policyDict = policyDict.set("writeSchedule", marker())

      stats = stats.add(policyDict)
      pointWithTunes.each point => do
        policy: readById(point->connTuningRef)
        points: readAll(parseFilter("point and " + connType + "Ref == " + connector->id.toAxonCode + " and connTuningRef == " + policy->id.toAxonCode)).size

        policyDict = {connector: connector->dis, name: policy->dis, pointPolicy, totalPoints: points}
        if(policy.has("pollTime")) policyDict = policyDict.set("pollTime", policy->pollTime)
        if(policy.has("writeMaxTime")) policyDict = policyDict.set("writeMaxTime", policy->writeMaxTime)
        if(policy.has("writeMinTime")) policyDict = policyDict.set("writeMinTime", policy->writeMinTime)
        if(policy.has("writeSchedule")) policyDict = policyDict.set("writeSchedule", marker())
        stats = stats.add(policyDict)
      end
    end

    stats = stats.toGrid
    stats = stats.reorderCols(stats.colNames.moveTo("name", 0).moveTo("connector", 0).moveTo("pointsUnderConnector", -1).moveTo("directPoints", -1).moveTo("totalPoints", -1))
  end

  stats
end


def ​

func:finTuningPolicyStatsForm ​

finTuningPolicyStatsForm(id: null, selectedDicts: null) ​

Axon function


meta ​

appFormOnbuilder, folio
deffunc:finTuningPolicyStatsForm
distoLocale("j2FinToolsExt::tuningPolicyStats")
folderPathtoLocale("finStackExt::rightMenuConnectors")+"/"+toLocal...
formOnconnTuningRef
helpShow all tuning policy stats or tuning policies associat...
isfunc
liblib:finTools
namefinTuningPolicyStatsForm
polyStats✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id: null, selectedDicts: null) => do
  policies: readAll(connTuning)
  totalConns: 0
  conns: null
  pointsUnderConns: 0
  directPts: 0
  stats: []
  policyDict: {}
  selectedIds: null
  header: toLocale("j2FinToolsExt::finTuningPolicyHeader")

  if(id != null) do
    selectedIds = [id.toRec->id]
    policies = []
    connType: ""
    header = toLocale("j2FinToolsExt::tuningPolicyStatsByConn")

    if(selectedDicts != null)
      selectedIds = selectedDicts.map(r => r.toRec->id)

    policies = policies.map(row => readById(row))
    stats = finTuningPolicyGetStats(selectedIds, false)
  end else
    stats = finTuningPolicyGetStats(policies, true)

  body: [ { name: "stats",
             editorType: "textarea",
             editable: false,
             height: 300,
             defVal: stats.ioWriteTrio("") + "\n"
             },

           {name: "applyButton", editorType: "button", label: toLocale("finStackExt::okay"), controlBar: true}]

  { "dis": header,
  "name": "tuningPolicyStats",
  "body": body.toJSON,
  "cancelButton": "",
  "commitButton": "\$applyButton",
  "commitAction": "",
  "helpDoc": "/wiki/display/FINStack/Tuning+Policy+Stats",
  "finForm": marker()
  }.toGrid.addMeta({formExecute: marker()})
  end


def ​

func:finUnique ​

finUnique(g, colNames) ​


meta ​

deffunc:finUnique
isfunc
liblib:finTools
namefinUnique

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finUniqueConnectors ​

finUniqueConnectors(filter, connType) ​

Find all the unique connectors of the given type, among the recs which match the given filter


meta ​

deffunc:finUniqueConnectors
isfunc
liblib:finTools
namefinUniqueConnectors

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finUniqueEquipTypes ​

finUniqueEquipTypes(filter, percentMatch, applyTags: false, tag: "navName") ​

Find the uniqe types for the equips


meta ​

deffunc:finUniqueEquipTypes
isfunc
liblib:finTools
namefinUniqueEquipTypes

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finUniqueEquipTypes2 ​

finUniqueEquipTypes2(filter, percent, applyTags, tag: "navName") ​

Axon function


meta ​

deffunc:finUniqueEquipTypes2
isfunc
liblib:finTools
namefinUniqueEquipTypes2

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(filter, percent, applyTags, tag:"navName")=> do
  typeMap:{}
  result :[]

  try do
    readAll(parseFilter(filter)).each( equip=> do
      pointNames : findPointNames(equip,tag)

      key : pointNames.toStr
      type : typeMap.get(key)
      if (type == null) do
        type = {"pointNames":pointNames,"similarity":[],"equips":[]}
      end

      type = type.set("equips",type.get("equips").add(equip))
      typeMap = typeMap.set(key,type)
    end)

    tsize:0
    typeMap.each((v,k)=> tsize = tsize+1)

    if(tsize >= 1000)
      throw toLocale("j2FinToolsExt::tooManyEquipTypes")

    // save types to array
    types : []
    n : 0
    typeMap.each ((type,key)=> do

      // init similarity
      tsize.times(i=>  type = type.set("similarity",type.get("similarity").add(0)) )
      types = types.add(type)

      // update tags with type
      if (applyTags) do
        changes :{"equipType":parseNumber(n.toStr)}
        diffs : []
        type.get("equips").each (equip=> do
          diffs = diffs.add(diff(equip, changes))
        end)
        diffs.commit
      end

      n = n+1
    end)

    // compute the similarities
    // NOTE: this is O(n**2)!!!!
    (tsize).times(i=> do
      a : types.get(i)
      a = a.set("similarity",a.get("similarity").set(i,1))
      j: i + 1
      (tsize - j).times( ij=> do

        b: types.get(j)
        sml : jaccardIndex(a,b)
        a = a.set("similarity",a.get("similarity").set(j,sml))
        b = b.set("similarity",b.get("similarity").set(i, sml))

        types = types.set(j, b)
        j = j+1
      end)
      types = types.set(i, a)
    end)

    // return grid

    types.each ((type,i)=> do
      eqsize: 0
      type.get("equips").each((v,k)=>eqsize = eqsize +1)
      pnsize: 0
      type.get("pointNames").each((v,k)=>pnsize = pnsize +1)

      dict : {}
      dict = dict.set("id",        parseRef("type"+padZero(i,3), false))
      dict = dict.set("numEquips", parseNumber(eqsize.toStr))
      dict = dict.set("numPoints", parseNumber(pnsize.toStr))
      dict = dict.set("equipIds",  listOfEquipIds(type))

      dict = addSimilarTypes(type,dict, i, percent, types)

      result = result.add(dict.toRec)
    end)

    meta : {"filter":filter,"percentMatch":percent}
    result = result.toGrid().addMeta(toRec(meta))
    //result = result.map(x=> do
    //  try x.set("navNames", x->equipIds.split(",").map(x=> read(parseFilter("id=="+x))->navName).concat(","))
    //  catch x
    //end)
    //result = result.reorderCols(result.colNames.moveTo("navNames", result.colNames.index("equipIds")+1))
  end
  catch(er) do
    logInfo("finTools","finUniqueEquipTypes2",er)
    result = toGrid([])
  end

  result
end


def ​

func:finUpdateRecordsIgnoredTags ​

finUpdateRecordsIgnoredTags() ​

Axon function


meta ​

deffunc:finUpdateRecordsIgnoredTags
isfunc
liblib:finTools
namefinUpdateRecordsIgnoredTags
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

()=> do
  ["roomRef","regionRef","siteRef","floorRef","equipRef","equipName","floorName","siteName","pointName","basName",
  "kind","mod","id","curStatus","curErr","curTracksWrite","curCalibration","cur","curVal",
  "hisErr","hisEnd","hisStart","writeErr","write1","write2","write3","write4","write5","write6",
  "write7","write8","write9","write10","write11","write12","write13","write14","write15","write16","write17","writeVal","writeLevel","writeStatus",
  "imageRef","hisCollectCov", "hisCollectInterval","hisInterpolate", "hisInterval","hisEndVal","hisTsPrecision", "hisYear", "hisSize","hisWrite","hisRead",
  "runTime", "runStarts","kind","tz","is", "haystackHis", "hisStatus","hisId","hisCur",
  "bacnetCur","haystackCur","bacnetConnRef","haystackConnRef","bacnetHis",
  "subequipPrefix","stdNavName","libraryIndex","libraryName"  ]
end


def ​

func:finUpdateRecordsIgnoredTags2 ​

finUpdateRecordsIgnoredTags2(obj) ​

Axon function


meta ​

deffunc:finUpdateRecordsIgnoredTags2
isfunc
liblib:finTools
namefinUpdateRecordsIgnoredTags2
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(obj)=> do
  if(not obj.has("hisCollectInterval") and not obj.has("hisCollectCov"))
    return finUpdateRecordsIgnoredTags()
  else
   return ["hisId","roomRef","regionRef","siteRef","floorRef","equipRef","equipName","floorName","siteName","pointName","basName",
  "kind","mod","id","writeStatus","curStatus","curErr","curTracksWrite","curCalibration","cur","curVal",
  "writeErr","write1","write2","write3","write4","write5","write6",
  "write7","write8","write9","write10","write11","write12","write13","write14","write15","write16","write17","writeVal","writeLevel","writeStatus",
  "imageRef", "runTime", "runStarts","writeVal","kind","tz","is",
  "bacnetCur","haystackCur","bacnetConnRef","haystackConnRef","haystackHis", "bacnetHis","hisStatus","hisErr", "hisSize", "hisStart", "hisEnd", "hisEndVal",
  "subequipPrefix","stdNavName","libraryIndex","libraryName"  ]
end


def ​

func:finUploadSavedRecordsForm ​

finUploadSavedRecordsForm(stage: null, data: null, type: null) ​

Axon function


meta ​

appFormOnfolio
batchRecords✓
deffunc:finUploadSavedRecordsForm
distoLocale("j2FinToolsExt::uploadSavedRecs")
folderPathtoLocale("j2FinToolsExt::createBatchRecords")
formOnsite or floor or equip or (point and not schedule)
isfunc
liblib:finTools
namefinUploadSavedRecordsForm
overridable✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(stage: null, data: null, type: null) => do
  if(stage != 1) do
    body: [
    {name: "file", editorType: "file", prompt: toLocale("j2FinToolsExt::zincRecordFile")+":", fileTypes: ["zinc"]},
    {name: "type", editorType: "radio", label: toLocale("j2FinToolsExt::pointLib")+":", group: "group1", selectedValue: "point", defVal: true},
    {name: "type", editorType: "radio", label: toLocale("j2FinToolsExt::equipLib")+":", group: "group1", selectedValue: "equip"},
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::cancel"), controlBar: true},
    {name: "commitButton", editorType: "button", label: toLocale("finStackExt::upload"), controlBar: true}
    ]

    {"dis": toLocale("j2FinToolsExt::uploadSavedRecs"),
    "name": "finUploadSavedRecords",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "commitButton": "\$commitButton",
    "commitAction": "finUploadSavedRecordsForm(1,[\$file],\$type)",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end else do
    body: [
    {name: "cancelButton", editorType: "button", label: toLocale("finStackExt::ok"), controlBar: true}
    ]

    if(type == null) do
      type = "point"
      body = body.insert(0,{name: "label", editorType: "label", text: toLocale("j2FinToolsExt::typeNotFoundDefaultToPt")})
    end

    if(data != null and data.size > 0 and data[0].toStr.trim != "") do
      try do
        file: data[0].toStr.parseRef.readById
        name: file->dis
        if(not name.endsWith(".zinc")) name = name + ".zinc"
        ioReadStr(ioBin(file,"file")).ioWriteStr(parseUri("io/"+type+"Libraries/"+name))
        file.finHardDelete
        body = body.insert(0,{name: "label", editorType: "label", text: toLocale("j2FinToolsExt::fileNameUploadedSuccess").replace("{name}", file->dis)})
      end catch body = body.insert(0,{name: "label", editorType: "label", text: toLocale("j2FinToolsExt::fileInjectionError")})
    end
    else body = body.insert(0,{name: "label", editorType: "label", text: toLocale("j2FinToolsExt::fileUploadError")})

    {"dis": toLocale("j2FinToolsExt::uploadSavedRecs"),
    "name": "finUploadSavedRecords",
    "body": body.toJSON,
    "cancelButton": "\$cancelButton",
    "finForm": marker()
    }.toGrid.addMeta({formExecute: marker()})
  end
end


def ​

func:finValidConnectors ​

finValidConnectors(connType) ​

Axon function


meta ​

deffunc:finValidConnectors
isfunc
liblib:finTools
namefinValidConnectors

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(connType) => do
  try
  do
    readAll(parseFilter(connType + "Conn")).sort("dis")
  end
  catch(er)
  do
    //echo("error parsefilter:"+connType)
    [{dis: toLocale("j2FinToolsExt::noValidConnTypeFound").replace("{connType}", (if (connType != toLocale("j2FinToolsExt::noConnectorsFound")) " " + connType + " " else " "))}].toGrid
  end
end


def ​

func:finWriteBin ​

finWriteBin(rec, tag, buf) ​


meta ​

deffunc:finWriteBin
isfunc
liblib:finTools
namefinWriteBin

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finWriteLevels ​

finWriteLevels(recs, conntype, wlevel, transfer) ​

Axon function


meta ​

deffunc:finWriteLevels
isfunc
liblib:finTools
namefinWriteLevels

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(recs, conntype, wlevel, transfer) => do
  recs = readAll(parseFilter(recs+" and "+conntype+"ConnRef")).toRecList()

  recs.each r => do
    if(transfer) do
      num: r.trap(conntype+"WriteLevel")
      val: r.pointWriteArray.find(x=> x->level == num)
      if(val.has("val")) do
        val = val->val
        r.pointWrite(val, wlevel, "CWL")
        r.pointWrite(null, num, "CWL")
      end
    end
    r.diff({}.set(conntype+"WriteLevel",wlevel)).commit //change connector level
  end
end


def ​

func:finZincTagBatchEdit ​

finZincTagBatchEdit(recs, tagName, oldRow, newRow) ​

Given a list of recs and a tag name such as "schedule" which stores an Zinc encoded grid, apply a change to the row identified by the given tags. If oldRow is null, then add to end. If newRow is null, then remove the row.


meta ​

deffunc:finZincTagBatchEdit
isfunc
liblib:finTools
namefinZincTagBatchEdit

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:finZincTagBatchList ​

finZincTagBatchList(recs, tagName) ​

Given a list of recs and a tag name such as "schedule" which stores an Zinc encoded grid return a list of the unique dicts rows in the zinc tag values. We automatically add a usedBy column with a comma separated list of Refs which contain the dict.


meta ​

deffunc:finZincTagBatchList
isfunc
liblib:finTools
namefinZincTagBatchList

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:findPod ​

findPod(name) ​


meta ​

deffunc:findPod
isfunc
liblib:finTools
namefindPod

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:findPointNames ​

findPointNames(equip, tag: "navName") ​

Axon function


meta ​

deffunc:findPointNames
isfunc
liblib:finTools
namefindPointNames
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(equip, tag:"navName")=>do
  list : []
  readAll(parseFilter("point and equipRef == " + equip->id)).each (point=>do
    navName : point.get(tag)
    list = list.add(navName)
  end)
  list = list.sort ((a, b)=> a<=>b)

  pointNames :{}
  list.each (elem=> do
    if(not pointNames.has(elem))
      pointNames = pointNames.set(elem,elem)
  end)
  return pointNames
end


def ​

func:funcDefs ​

funcDefs() ​


meta ​

deffunc:funcDefs
isfunc
liblib:finTools
namefuncDefs

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:getEventsData ​

getEventsData(id, catalog) ​

Axon function


meta ​

deffunc:getEventsData
isfunc
liblib:finTools
namegetEventsData
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id,catalog)=> do
  rec :id.toRec
  if(catalog == "") do
    readById(id)->scheduleGrid.findAll(r=>not r.has("weekly") and not r.has("defaultEvent")).map(r=>r.set("label",r.dis))
  end
  else if(catalog == "weekly") do
    [
      {dis:"mon",label:toLocale("finStackExt::dRuleMon")},
      {dis:"tue",label:toLocale("finStackExt::dRuleTue")},
      {dis:"wed",label:toLocale("finStackExt::dRuleWed")},
      {dis:"thu",label:toLocale("finStackExt::dRuleThu")},
      {dis:"fri",label:toLocale("finStackExt::dRuleFri")},
      {dis:"sat",label:toLocale("finStackExt::dRuleSat")},
      {dis:"sun",label:toLocale("finStackExt::dRuleSun")}
    ]
  end
  else if(catalog == "whole") do
    allEvents: [
      {dis:"mon",label:toLocale("finStackExt::dRuleMon")},
      {dis:"tue",label:toLocale("finStackExt::dRuleTue")},
      {dis:"wed",label:toLocale("finStackExt::dRuleWed")},
      {dis:"thu",label:toLocale("finStackExt::dRuleThu")},
      {dis:"fri",label:toLocale("finStackExt::dRuleFri")},
      {dis:"sat",label:toLocale("finStackExt::dRuleSat")},
      {dis:"sun",label:toLocale("finStackExt::dRuleSun")}
    ].map(item=> item.set("selected",true))

    readById(id)->scheduleGrid
      .findAll(r=>not r.has("weekly") and not r.has("defaultEvent"))
      .map(r=>r.set("label",r.dis).set("selected",true)).each(r=> allEvents = allEvents.add(r))

    return allEvents
  end
end


def ​

func:getHisTags ​

getHisTags() ​

Axon function


meta ​

deffunc:getHisTags
isfunc
liblib:finTools
namegetHisTags
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

()=> do
  [
    "his","hisCur","hisWrite","hisRead","hisErr","hisEnd","hisStart","hisCollectCov", "hisCollectInterval","hisInterpolate",
    "hisInterval","hisEndVal","hisTsPrecision", "hisYear", "hisSize","hisStatus","bacnetHis","haystackHis"
  ]
end


def ​

func:getPodVersion ​

getPodVersion(pod) ​


meta ​

deffunc:getPodVersion
isfunc
liblib:finTools
namegetPodVersion

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:hideRef ​

hideRef(obj) ​

Axon function


meta ​

deffunc:hideRef
isfunc
liblib:finTools
namehideRef
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(obj)=>do
  obj->kind=="Ref" or obj->kind == "Marker"
end


def ​

func:ignoredConnTags ​

ignoredConnTags(rec) ​

Axon function


meta ​

deffunc:ignoredConnTags
isfunc
liblib:finTools
nameignoredConnTags
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(rec)=> do
  props:[]
  ignored:["Cur","Read","His","Write","ConnRef"]
  rec.each((v,prop)=> do
    if(prop.index("ConnRef") != null) do
      deviceName: prop.replace("ConnRef","")
      ignored.each(skip=> do
        if(props.index(deviceName + skip) == null)
          props = props.add(deviceName + skip)
      end)
    end
  end)

  return props
end


def ​

func:importModbus ​

importModbus(uri, regMapUri, conDis, slave, siteName, floorName, tenantName, tagObj, folderPath) ​


meta ​

deffunc:importModbus
isfunc
liblib:finTools
nameimportModbus

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:ioCopyFile ​

ioCopyFile(fromPath, toPath) ​


meta ​

deffunc:ioCopyFile
isfunc
liblib:finTools
nameioCopyFile

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:ioCreateDir ​

ioCreateDir(toPath) ​


meta ​

deffunc:ioCreateDir
isfunc
liblib:finTools
nameioCreateDir

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:ioExists ​

ioExists(path) ​


meta ​

deffunc:ioExists
isfunc
liblib:finTools
nameioExists

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:ioReadFileStr ​

ioReadFileStr(path) ​


meta ​

deffunc:ioReadFileStr
isfunc
liblib:finTools
nameioReadFileStr

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:ioUnzipPod ​

ioUnzipPod(pod, toPath) ​


meta ​

deffunc:ioUnzipPod
isfunc
liblib:finTools
nameioUnzipPod

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:ioWriteFile ​

ioWriteFile(handle, toPath) ​


meta ​

deffunc:ioWriteFile
isfunc
liblib:finTools
nameioWriteFile

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:jaccardIndex ​

jaccardIndex(this, that) ​

Axon function


meta ​

deffunc:jaccardIndex
isfunc
liblib:finTools
namejaccardIndex
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(this, that)=> do
  intersection : this.get("pointNames").findAll (s=> that.get("pointNames").has(s))
  union : {}
  this.get("pointNames").each((v,k) => union = union.set(k,v))
  that.get("pointNames").each (k=> do
    if (not union.has(k))
      union = union.set(k,k);
  end)
  tsize:0
  union.each((v,k)=>do
    tsize = tsize + 1
  end)
  if (tsize == 0) return 1

  isize:0
  intersection.each((v,k)=>do
    isize = isize + 1
  end)
  return isize / tsize
end


def ​

func:kioskImageImport ​

kioskImageImport() ​


meta ​

deffunc:kioskImageImport
isfunc
liblib:finTools
namekioskImageImport

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:listFile ​

listFile(root) ​


meta ​

deffunc:listFile
isfunc
liblib:finTools
namelistFile

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:listOfEquipIds ​

listOfEquipIds(type) ​

Axon function


meta ​

deffunc:listOfEquipIds
isfunc
liblib:finTools
namelistOfEquipIds
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(type)=> do
  sb :""
  type.get("equips").each ((equip,i)=>do
    if (i > 0) sb = sb+(",")
    sb = sb+ "@" + equip->id.toStr
  end)
  return sb
end


def ​

func:loadPodGraphic ​

loadPodGraphic(path) ​


meta ​

deffunc:loadPodGraphic
isfunc
liblib:finTools
nameloadPodGraphic

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:markerOnly ​

markerOnly(obj) ​

Axon function


meta ​

deffunc:markerOnly
isfunc
liblib:finTools
namemarkerOnly
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(obj)=>do
  obj->kind != "Marker"
end


def ​

func:navDuplicate2 ​

This function calls navDuplicate using the parameters to duplicates records and then adjusts the names.


meta ​

constructnavDuplicate2("equip", read(equip)->id, {count: 2, noChi...
deffunc:navDuplicate2
isfunc
liblib:finTools
namenavDuplicate2
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(type,id,opts)=> do
  orgRec:id.toRec
  disTag:""
  if(orgRec.has("navName"))
    disTag = "navName"
  else do
    if(orgRec.dis == null and orgRec.has("dis")) do
      orgRec.set(dis,"")
      disTag = "dis"
    end
  end
  recName :orgRec.get(disTag)

  grid:navDuplicate(type,id,opts)
  //echo("distag= "+disTag)
  if(disTag != "" and grid != null and grid.size > 0)
  grid.each() (row)=> do
    rec:readById(row->id)
    newName:rec.get(disTag)
    recNumStr :reFind(r"(\d)+$",recName)
    if(recNumStr == null) recNumStr = ""

    newNumStr :reFind(r"(\d)+$",newName)
    if(newNumStr == null) newNumStr == ""

    if(recNumStr.size > newNumStr.size) do
        idx:index(newName,newNumStr)
        newStrPart: newName[0..idx-1]
        newNumStr = newNumStr.padl(recNumStr.size,"0")
        newName = newStrPart + newNumStr
        //echo("newName = "+newNumStr)
        changes :{}.set(disTag,newName)
        //echo("changes: "+changes.toStr)
        commit(diff(rec,changes))
    end
  end
  return grid
end


def ​

func:padZero ​

padZero(number, width) ​

Axon function


meta ​

deffunc:padZero
isfunc
liblib:finTools
namepadZero
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(number,width)=> do
  sb :""
  sb =sb + number.toStr
  if(sb.size >= width) return sb

  (width-sb.size).times( i=> sb = "0" + sb )
  return sb
end


def ​

func:publishPod ​

publishPod(pod, user, pwd, sandbox) ​

Axon function


meta ​

deffunc:publishPod
isfunc
liblib:finTools
namepublishPod
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(pod,user, pwd, sandbox)=> do
  echo("user " + user)
  finPublishTemplatePackage(pod,user,pwd,sandbox)
  finFormAlertOk("Success", "Pod published")
end


def ​

func:readFileTrio ​

readFileTrio(path) ​


meta ​

deffunc:readFileTrio
isfunc
liblib:finTools
namereadFileTrio

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:readFinToolsCsv ​

readFinToolsCsv(uri) ​

Read a csv from the pod


meta ​

deffunc:readFinToolsCsv
isfunc
liblib:finTools
namereadFinToolsCsv

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:runJob ​

runJob(exp) ​


meta ​

deffunc:runJob
isfunc
liblib:finTools
namerunJob

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function


def ​

func:sampleAddTags ​

sampleAddTags(colName, filter) ​

Axon function


meta ​

deffunc:sampleAddTags
isfunc
liblib:finTools
namesampleAddTags
private✓

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(colName,filter)=>do
  copyTableData:[{addTags:"air,flow,sensor"}.set(colName,"(abc).*").set("help","regex startwith abc"),
                 {addTags:"chilled,water,valve"}.set(colName,".*(abc)").set("help","regex endwith abc"),
                 {addTags:"chilled,water,valve"}.set(colName,".*(abc)+.*").set("help","regex contains abc")]
  try do
    stuff: readAll(parseFilter(filter)).unique(colName).map(x=> x.set("addTags", x.findAll((b,a)=> x.has(a) and x.trap(a) == marker()).names.concat(",") ))
    stuff = stuff.map(x=> do
      if(x.has("hisCollectInterval")) x = x.set("addTags", x->addTags+",hisCollectInterval:"+x->hisCollectInterval.toAxonCode)
      if(x.has("hisCollectCov")) x = x.set("addTags", x->addTags+",hisCollectCov:"+x->hisCollectCov.toAxonCode)
      x
    end)
    stuff.keepCols([colName,"addTags"]).findAll(r=>r.get(colName) != null and r.get(colName) != "").addRows(copyTableData).reorderCols([colName,"addTags","help"])
  end
  catch(er)
    []

end


def ​

func:wrappedDiffRemove ​

wrappedDiffRemove(id) ​

Axon function


meta ​

baSuExec✓
deffunc:wrappedDiffRemove
isfunc
liblib:finTools
namewrappedDiffRemove

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id) => do
  diffRemove: (p)=> do
    //used in animation editor delete form
 diff(readById(p),null,{remove}).commit
  end

  try baSuExec(diffRemove,curFunc(),[id])
  catch diffRemove(id)
end


def ​

func:wrappedIoReadJson ​

wrappedIoReadJson(path) ​

Axon function


meta ​

baSuExec✓
deffunc:wrappedIoReadJson
isfunc
liblib:finTools
namewrappedIoReadJson

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(path) => do
  readJson: (p)=> do
    ioReadJson(p)
  end

  try baSuExec(readJson,curFunc(),[path])
  catch readJson(path)
end


def ​

func:wrappedIoReadStr ​

wrappedIoReadStr(path) ​

Axon function


meta ​

baSuExec✓
deffunc:wrappedIoReadStr
isfunc
liblib:finTools
namewrappedIoReadStr

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(path) => do
  readStr: (p)=> do
    ioReadStr(p)
  end

  try baSuExec(readStr,curFunc(),[path])
  catch readStr(path)
end