外观
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
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finFormStringSearchTransStats
finFormStringSearchTransStats()
Backend function for finFormStringSearchTrans
meta
| def | func:finFormStringSearchTransStats |
| finString | ✓ |
| is | func |
| lib | lib:finTools |
| name | finFormStringSearchTransStats |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finFormSyncToColl
finFormSyncToColl(pointList: null, ptType: null)
Axon function
meta
| appFormOn | folio |
| def | func:finFormSyncToColl |
| dis | toLocale("j2FinToolsExt::hisToCollected") |
| folderPath | toLocale("j2FinToolsExt::databaseCleanUp") |
| is | func |
| lib | lib:finTools |
| name | finFormSyncToColl |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finFormTagDuplicate
finFormTagDuplicate()
Axon function
meta
| appFormOn | folio |
| def | func:finFormTagDuplicate |
| dis | toLocale("j2FinToolsExt::duplicateTag") |
| folderPath | toLocale("finStackExt::advanced")+"/"+toLocale("j2FinToo... |
| is | func |
| lib | lib:finTools |
| name | finFormTagDuplicate |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finFormTagSplitAndRename
finFormTagSplitAndRename(id, selectedDicts)
Axon function
meta
| def | func:finFormTagSplitAndRename |
| dis | toLocale("j2FinToolsExt::massRenameStringTags") |
| folderPath | toLocale("j2FinToolsExt::batchEditAndClone") |
| formOn | point and not schedule |
| is | func |
| lib | lib:finTools |
| name | finFormTagSplitAndRename |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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 ""
enddef
func:finFormTempToReal
finFormTempToReal(stage: null, data: null, delet: null)
Form to move prepared tempPoints into the project hierarchy
meta
| def | func:finFormTempToReal |
| dis | toLocale("j2FinToolsExt::importTempToProj") |
| finString | ✓ |
| folderPath | toLocale("finStackExt::advanced")+"/"+toLocale("j2FinToo... |
| formOn | (point or tempPoint) and not schedule |
| is | func |
| lib | lib:finTools |
| name | finFormTempToReal |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finFormTempToRealStats
finFormTempToRealStats(filter, type)
Axon function
meta
| def | func:finFormTempToRealStats |
| finString | ✓ |
| is | func |
| lib | lib:finTools |
| name | finFormTempToRealStats |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finFormTextArea
finFormTextArea(title, text, height: 250, width: 450)
Axon function
meta
| def | func:finFormTextArea |
| is | func |
| lib | lib:finTools |
| name | finFormTextArea |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finFormTextareaOk
finFormTextareaOk(title, text, height: null)
Axon function
meta
| def | func:finFormTextareaOk |
| is | func |
| lib | lib:finTools |
| name | finFormTextareaOk |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finFormUniqueEquipTypes
finFormUniqueEquipTypes(stage: null)
Axon function
meta
| appFormOn | folio |
| def | func:finFormUniqueEquipTypes |
| dis | toLocale("j2FinToolsExt::viewUniqueEquips") |
| folderPath | toLocale("finStackExt::advanced") |
| is | func |
| lib | lib:finTools |
| name | finFormUniqueEquipTypes |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finFormUniqueTagsEasy
finFormUniqueTagsEasy(stage: null)
Axon function
meta
| appFormOn | folio |
| def | func:finFormUniqueTagsEasy |
| dis | toLocale("j2FinToolsExt::findUniqueTags") |
| folderPath | toLocale("j2FinToolsExt::databaseCleanUp") |
| is | func |
| lib | lib:finTools |
| name | finFormUniqueTagsEasy |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finFormUpdateConnectors
finFormUpdateConnectors(id, selectedDicts, fromDB: null, reopen: false)
Axon function
meta
| def | func:finFormUpdateConnectors |
| dis | toLocale("j2FinToolsExt::updateConnectors") |
| folderPath | toLocale("finStackExt::advanced") |
| formOn | region or site or floor or equip or (point and not sched... |
| help | Update connectors |
| is | func |
| lib | lib:finTools |
| name | finFormUpdateConnectors |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finFormWriteLevels
finFormWriteLevels()
Axon function
meta
| appFormOn | folio |
| def | func:finFormWriteLevels |
| dis | toLocale("j2FinToolsExt::changeWriteLevels") |
| folderPath | toLocale("j2FinToolsExt::databaseCleanUp") |
| is | func |
| lib | lib:finTools |
| name | finFormWriteLevels |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finGenerateSampleTagValue
finGenerateSampleTagValue(id, targetTag, splitValue, renamePattern, commitResults: false)
Axon function
meta
| def | func:finGenerateSampleTagValue |
| is | func |
| lib | lib:finTools |
| name | finGenerateSampleTagValue |
| overridable | ✓ |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finGetMinutesFromCur
finGetMinutesFromCur(cur, base)
Axon function
meta
| baseChart | ✓ |
| def | func:finGetMinutesFromCur |
| is | func |
| lib | lib:finTools |
| name | finGetMinutesFromCur |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finGetPointRecords
finGetPointRecords(inp: null)
Get records from the PointRecords.zinc file in the finToolsExt pod to display in the batch record creator
meta
| def | func:finGetPointRecords |
| finUpdateRecords | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGetPointRecords |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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 ")))
enddef
func:finGetUriFromRef
finGetUriFromRef(grid, tags: ["imageRef"], fileTagName: "file")
Axon function
meta
| construct | finGetUriFromRef(["imageRef"],"file") |
| def | func:finGetUriFromRef |
| example | readAll(site).finGetUriFromRef() readAll(site).finGetUri... |
| help | Will take a list of records, like readAll(site) and it w... |
| is | func |
| lib | lib:finTools |
| name | finGetUriFromRef |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| appFormOn | oldFolio, builder |
| def | func:finGlobalControl |
| dis | toLocale("j2FinToolsExt::globalControl") |
| formOn | point and not schedule |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControl |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finGlobalControlActions |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlActions |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finGlobalControlCheckEnum |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlCheckEnum |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finGlobalControlCommit |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlCommit |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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)
enddef
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
| def | func:finGlobalControlDurForm |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlDurForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
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
| def | func:finGlobalControlFilterCheck |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlFilterCheck |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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"))
enddef
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
| def | func:finGlobalControlFilterForm |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlFilterForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finGlobalControlFilterTable
finGlobalControlFilterTable(filterThing)
This function is part of "Global Control".
For use with finGlobalControlFilterForm. Populates the table in that form.
meta
| def | func:finGlobalControlFilterTable |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlFilterTable |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finGlobalControlForm |
| globalCont | ✓ |
| is | func |
| lib | lib:finTools |
| name | finGlobalControlForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finGraphicsBatchTags
finGraphicsBatchTags(data: null, selectedItems: [])
Axon function
meta
| appFormOn | folio |
| def | func:finGraphicsBatchTags |
| dis | toLocale("j2FinToolsExt::batchTags") |
| folderPath | toLocale("j2FinToolsExt::graphicTools") |
| is | func |
| lib | lib:finTools |
| name | finGraphicsBatchTags |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finGraphicsDeleteRecs
finGraphicsDeleteRecs(data: null, selectedItems: [])
Axon function
meta
| appFormOn | folio |
| def | func:finGraphicsDeleteRecs |
| dis | toLocale("j2FinToolsExt::deleteRecords") |
| folderPath | toLocale("j2FinToolsExt::graphicTools") |
| is | func |
| lib | lib:finTools |
| name | finGraphicsDeleteRecs |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finHardDelete |
| is | func |
| lib | lib:finTools |
| name | finHardDelete |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finHaystackHexReplaceForm
finHaystackHexReplaceForm(selectedDicts: null, stage: null)
Axon function
meta
| def | func:finHaystackHexReplaceForm |
| dis | toLocale("j2FinToolsExt::replaceHex") |
| folderPath | toLocale("finStackExt::rightMenuConnectors")+"/"+toLocal... |
| formOn | haystackConn |
| is | func |
| lib | lib:finTools |
| name | finHaystackHexReplaceForm |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finHisImport |
| is | func |
| lib | lib:finTools |
| name | finHisImport |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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)
enddef
func:finHisReadAddMeta
finHisReadAddMeta(curGrid, point, curTimeSpan, timezone)
Axon function
meta
| def | func:finHisReadAddMeta |
| is | func |
| lib | lib:finTools |
| name | finHisReadAddMeta |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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")
enddef
func:finHisReadBaseBuildCharts
finHisReadBaseBuildCharts(grid, boolTable, enumTable, grouped, baselineTables, units, multiUnits, missingIds: null)
Axon function
meta
| def | func:finHisReadBaseBuildCharts |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaseBuildCharts |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finHisReadBaseGetHis
finHisReadBaseGetHis(interval, fold, interval2, fold2, point, baHis, timeZone, currentTimeSpan, baseLineTimeSpan)
Axon function
meta
| baSuExec | ✓ |
| def | func:finHisReadBaseGetHis |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaseGetHis |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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]
enddef
func:finHisReadBaseGetTz
finHisReadBaseGetTz(point)
Axon function
meta
| def | func:finHisReadBaseGetTz |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaseGetTz |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finHisReadBaseline
finHisReadBaseline(ptList, curTS, baseTS: null, rollUps: null, chartOpts: null, noNames: false)
Axon function
meta
| baSuExec | ✓ |
| baseChart | ✓ |
| def | func:finHisReadBaseline |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaseline |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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 rollUpchartSettings: 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 curColormeta
| baSuExec | ✓ |
| def | func:finHisReadBaselineCore |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaselineCore |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finHisReadBaselineRollup
finHisReadBaselineRollup(chartSettingsDict, rollUpSettings, x)
Axon function
meta
| def | func:finHisReadBaselineRollup |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaselineRollup |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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}
enddef
func:finHisReadBaselineStrPoint
finHisReadBaselineStrPoint(curPointHis, pointName, isBool: false)
Axon function
meta
| def | func:finHisReadBaselineStrPoint |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaselineStrPoint |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finHisReadBaselineStrPointF
finHisReadBaselineStrPointF(curPointHis, pointName, isBool: false)
Fantomized version of the finHisReadBaselineStrPoint function
meta
| def | func:finHisReadBaselineStrPointF |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaselineStrPointF |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finHisReadBaslineStatus
finHisReadBaslineStatus(jobRef)
Axon function
meta
| baSuExec | ✓ |
| def | func:finHisReadBaslineStatus |
| is | func |
| lib | lib:finTools |
| name | finHisReadBaslineStatus |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finHisReadComplexBa
finHisReadComplexBa(history, pointRef)
Axon function
meta
| def | func:finHisReadComplexBa |
| is | func |
| lib | lib:finTools |
| name | finHisReadComplexBa |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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")
enddef
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
| construct | read(point).finHisRewriteSpan("06/09/2015 05:45 am", "06... |
| def | func:finHisRewriteSpan |
| is | func |
| lib | lib:finTools |
| name | finHisRewriteSpan |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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 rangedef
func:finInvoke
finInvoke(rec, action, args: {})
Axon function
meta
| def | func:finInvoke |
| is | func |
| lib | lib:finTools |
| name | finInvoke |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finIsTagBlackList
finIsTagBlackList(tag)
Return whether the given tag is a member of the tag blacklist (see finTagBlackList())
meta
| def | func:finIsTagBlackList |
| is | func |
| lib | lib:finTools |
| name | finIsTagBlackList |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(tag) => do
// TODO help doc
finTagBlackList().map(r => reFind(r->regex, tag)).any(v => v != null)
enddef
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
| construct | readAll(site).finMacro("$dis blabla $id") |
| def | func:finMacro |
| is | func |
| lib | lib:finTools |
| name | finMacro |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finMassEditTags
finMassEditTags(selectedDicts: null, stage: null, data: null)
Axon function
meta
| def | func:finMassEditTags |
| dis | toLocale("j2FinToolsExt::massEditTags") |
| folderPath | toLocale("j2FinToolsExt::batchEditAndClone") |
| formOn | site or floor or equip or (point and not schedule) or ba... |
| is | func |
| lib | lib:finTools |
| name | finMassEditTags |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finMatchPointsToCharts
finMatchPointsToCharts(ptList, optList, isRel: false)
Axon function
meta
| def | func:finMatchPointsToCharts |
| is | func |
| lib | lib:finTools |
| name | finMatchPointsToCharts |
| noDoc | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finModBusMap
finModBusMap(grid, files)
Axon function
meta
| def | func:finModBusMap |
| is | func |
| lib | lib:finTools |
| name | finModBusMap |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finMoveTag |
| is | func |
| lib | lib:finTools |
| name | finMoveTag |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finNavMetaCommit
finNavMetaCommit(newLevel, deleteLevel, parentLevel, isOptional: false)
Axon function
meta
| def | func:finNavMetaCommit |
| is | func |
| lib | lib:finTools |
| name | finNavMetaCommit |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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 functiondef
func:finNavMetaDeleteFailForm
finNavMetaDeleteFailForm(unDeletable)
Axon function
meta
| def | func:finNavMetaDeleteFailForm |
| is | func |
| lib | lib:finTools |
| name | finNavMetaDeleteFailForm |
| obsolete | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finNavMetaGetLevels
finNavMetaGetLevels(keepEmpty: false)
Axon function
meta
| def | func:finNavMetaGetLevels |
| is | func |
| lib | lib:finTools |
| name | finNavMetaGetLevels |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()
enddef
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
| construct | read(point).finNavMetaWhoAmI() |
| def | func:finNavMetaWhoAmI |
| help | Use this function to check if the record is something in... |
| is | func |
| lib | lib:finTools |
| name | finNavMetaWhoAmI |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(rec) => do
navMetaList:read(navMeta).get("equipPath").split("/").remove(0).map() row => row.replace("[","").replace("]","")
recType: navMetaList.find(metaItem => rec.has(metaItem))
enddef
func:finPodFiles
finPodFiles(name)
meta
| def | func:finPodFiles |
| is | func |
| lib | lib:finTools |
| name | finPodFiles |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finPointActions
finPointActions(kind)
Axon function
meta
| def | func:finPointActions |
| is | func |
| lib | lib:finTools |
| name | finPointActions |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finPointNotTz
finPointNotTz()
Axon function
meta
| def | func:finPointNotTz |
| is | func |
| lib | lib:finTools |
| name | finPointNotTz |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
() => do
readAll(site).each x=> do
try finRewriteHisTz(x->id,x->tz) catch ""
end
enddef
func:finPointNumbersToEquip
finPointNumbersToEquip(id: null, stage: null, data: null)
Axon function
meta
| def | func:finPointNumbersToEquip |
| dis | toLocale("j2FinToolsExt::pointNumbersToEquip") |
| formOn | point and not schedule |
| is | func |
| lib | lib:finTools |
| name | finPointNumbersToEquip |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finPostTrioFuncs
finPostTrioFuncs(trioUri)
Axon function
meta
| def | func:finPostTrioFuncs |
| is | func |
| lib | lib:finTools |
| name | finPostTrioFuncs |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finPrecision |
| is | func |
| lib | lib:finTools |
| name | finPrecision |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finProjectedCalc |
| is | func |
| lib | lib:finTools |
| name | finProjectedCalc |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
| def | func:finReadAlarmTags |
| is | func |
| lib | lib:finTools |
| name | finReadAlarmTags |
| topics | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finReadAlarmTagsSearch
finReadAlarmTagsSearch(progStr)
Axon function
meta
| def | func:finReadAlarmTagsSearch |
| is | func |
| lib | lib:finTools |
| name | finReadAlarmTagsSearch |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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 []
enddef
func:finReadCloneEvents
finReadCloneEvents(id)
Axon function
meta
| def | func:finReadCloneEvents |
| is | func |
| lib | lib:finTools |
| name | finReadCloneEvents |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(id) => do
readById(id)->scheduleGrid.findAll r =>
(not r.has("weekly")) and (not r.has("defaultEvent"))
enddef
func:finRecordsSources
finRecordsSources(recordType)
meta
| def | func:finRecordsSources |
| is | func |
| lib | lib:finTools |
| name | finRecordsSources |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finRefDis
finRefDis(ref)
Get the dis of a ref
meta
| def | func:finRefDis |
| is | func |
| lib | lib:finTools |
| name | finRefDis |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finRemoveAnimationEditor
finRemoveAnimationEditor(fileRef)
Axon function
meta
| baSuExec | ✓ |
| def | func:finRemoveAnimationEditor |
| is | func |
| lib | lib:finTools |
| name | finRemoveAnimationEditor |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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)
enddef
func:finRemoveUnits
finRemoveUnits(numberToCheck)
removeUnits(number) Removes' the unit from a number passed in. Will return an int or a float
meta
| def | func:finRemoveUnits |
| is | func |
| lib | lib:finTools |
| name | finRemoveUnits |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finRenamePointsForm
finRenamePointsForm(selectedDicts: null, stage: null)
Form to change navNames of points if they match the filter
meta
| def | func:finRenamePointsForm |
| dis | toLocale("j2FinToolsExt::renamePoints") |
| formOn | point and not schedule |
| is | func |
| lib | lib:finTools |
| name | finRenamePointsForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finRestorePod
finRestorePod(pod)
meta
| construct | finRestorePod("fooExt") |
| def | func:finRestorePod |
| is | func |
| lib | lib:finTools |
| name | finRestorePod |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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 | ✓ |
| construct | finSampleHisReadBase(1,0,0,0,0,0,0,0,0) |
| def | func:finSampleHisReadBase |
| is | func |
| lib | lib:finTools |
| name | finSampleHisReadBase |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finSaveEquipRecordsForm
finSaveEquipRecordsForm(id: false, selectedDicts: false)
Axon function
meta
| batchRecords | ✓ |
| def | func:finSaveEquipRecordsForm |
| dis | toLocale("j2FinToolsExt::saveEquipRecords") |
| folderPath | toLocale("j2FinToolsExt::createBatchRecords") |
| helpDoc | /wiki/display/FINStack/Create+Batch+Records |
| is | func |
| lib | lib:finTools |
| name | finSaveEquipRecordsForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finSaveFloorRecordsForm
finSaveFloorRecordsForm(id: false, selectedDicts: false)
Axon function
meta
| batchRecords | ✓ |
| def | func:finSaveFloorRecordsForm |
| dis | toLocale("j2FinToolsExt::saveFloorRecords") |
| folderPath | toLocale("j2FinToolsExt::createBatchRecords") |
| helpDoc | /wiki/display/FINStack/Create+Batch+Records |
| is | func |
| lib | lib:finTools |
| name | finSaveFloorRecordsForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finSavePointRecordsForm
finSavePointRecordsForm(id: false, selectedDicts: false)
Axon function
meta
| batchRecords | ✓ |
| def | func:finSavePointRecordsForm |
| dis | toLocale("j2FinToolsExt::savePointRecords") |
| folderPath | toLocale("j2FinToolsExt::createBatchRecords") |
| formOn | point and not schedule |
| helpDoc | /wiki/display/FINStack/Create+Batch+Records |
| is | func |
| lib | lib:finTools |
| name | finSavePointRecordsForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finSaveRecords
finSaveRecords(filt, type, name1: null, name2: null)
Axon function
meta
| batchRecords | ✓ |
| def | func:finSaveRecords |
| is | func |
| lib | lib:finTools |
| name | finSaveRecords |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finSaveRecordsForm
finSaveRecordsForm()
Axon function
meta
| appFormOn | folio |
| batchRecords | ✓ |
| def | func:finSaveRecordsForm |
| dis | toLocale("j2FinToolsExt::saveRecords") |
| folderPath | toLocale("j2FinToolsExt::createBatchRecords") |
| helpDoc | /wiki/display/FINStack/Create+Batch+Records |
| is | func |
| lib | lib:finTools |
| name | finSaveRecordsForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finSaveRecordsSeparate
finSaveRecordsSeparate(filter, useUnique)
Axon function
meta
| batchRecords | ✓ |
| def | func:finSaveRecordsSeparate |
| is | func |
| lib | lib:finTools |
| name | finSaveRecordsSeparate |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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))
enddef
func:finSaveSiteRecordsForm
finSaveSiteRecordsForm(id: false, selectedDicts: false)
Axon function
meta
| batchRecords | ✓ |
| def | func:finSaveSiteRecordsForm |
| dis | toLocale("j2FinToolsExt::saveSiteRecords") |
| folderPath | toLocale("j2FinToolsExt::createBatchRecords") |
| helpDoc | /wiki/display/FINStack/Create+Batch+Records |
| is | func |
| lib | lib:finTools |
| name | finSaveSiteRecordsForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
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 | ✓ |
| def | func:finSavedCharts |
| is | func |
| lib | lib:finTools |
| name | finSavedCharts |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finSelectedConnectorTypes
finSelectedConnectorTypes(selectedIds)
Axon function
meta
| def | func:finSelectedConnectorTypes |
| is | func |
| lib | lib:finTools |
| name | finSelectedConnectorTypes |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()
enddef
func:finSelectedPoints
finSelectedPoints(selectedIds)
Axon function
meta
| def | func:finSelectedPoints |
| is | func |
| lib | lib:finTools |
| name | finSelectedPoints |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finSetImmediateSubOffTimeCommit
finSetImmediateSubOffTimeCommit(offTime, onTime, jobRef: null)
Axon function
meta
| alarmEmailToggle | ✓ |
| def | func:finSetImmediateSubOffTimeCommit |
| is | func |
| lib | lib:finTools |
| name | finSetImmediateSubOffTimeCommit |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finShowEquipSummary
finShowEquipSummary(inp: null, pnts: null, sps: null)
Axon function
meta
| def | func:finShowEquipSummary |
| is | func |
| lib | lib:finTools |
| name | finShowEquipSummary |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finShowEquipSummaryRecur
finShowEquipSummaryRecur(inp, ind: 0, extra: null)
Axon function
meta
| def | func:finShowEquipSummaryRecur |
| is | func |
| lib | lib:finTools |
| name | finShowEquipSummaryRecur |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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)
enddef
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
| def | func:finSoftDelete |
| is | func |
| lib | lib:finTools |
| name | finSoftDelete |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(recs) => do
recs.toRecList.each x=> x.diff({trash}).commit
enddef
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
| def | func:finStrGet |
| is | func |
| lib | lib:finTools |
| name | finStrGet |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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]
enddef
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 dictsdict2:
Used to check if column contains a string
Can be comma separated for multiple strings
The possible types are contains, notContains, startsWith, notStartsWith, endsWith, notEndsWithcol: 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
| def | func:finStringSearchDicts |
| finString | ✓ |
| is | func |
| lib | lib:finTools |
| name | finStringSearchDicts |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
| def | func:finStringSplitDicts |
| finString | ✓ |
| is | func |
| lib | lib:finTools |
| name | finStringSplitDicts |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
| construct | finSuperTagger(filter, column, matchList) |
| def | func:finSuperTagger |
| is | func |
| lib | lib:finTools |
| name | finSuperTagger |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finSuperTaggerForm
finSuperTaggerForm(id)
Axon function
meta
| def | func:finSuperTaggerForm |
| dis | toLocale("j2FinToolsExt::superTagger") |
| folderPath | toLocale("finStackExt::advanced") |
| formOn | superTagger |
| help | This is an advanced form that lets you use regex express... |
| hideMobile | ✓ |
| is | func |
| lib | lib:finTools |
| name | finSuperTaggerForm |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finSyncPoints
finSyncPoints(connIds, fromOrd, toOrd)
ToDo: Move this to migration script
meta
| def | func:finSyncPoints |
| is | func |
| lib | lib:finTools |
| name | finSyncPoints |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finSyncToColl
finSyncToColl(filter, isCollectOnInter, collectInterval, intervalUnits, isCOV, covInterval, basu: false)
Axon function
meta
| baSuExec | ✓ |
| def | func:finSyncToColl |
| is | func |
| lib | lib:finTools |
| name | finSyncToColl |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finTagBlackList
finTagBlackList()
Return a grid of all those tags which should not be removed by the user.
meta
| def | func:finTagBlackList |
| is | func |
| lib | lib:finTools |
| name | finTagBlackList |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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")}
]
enddef
func:finTemplates
finTemplates()
Returns records with templateOn from pods and the database
meta
| def | func:finTemplates |
| is | func |
| lib | lib:finTools |
| name | finTemplates |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
() => do
temp: finBacnetTemplates().toGrid.finGridFilter(templateOn)
locl: readAll(templateOn)
if(locl.size > 0) temp = temp.addRows(locl)
temp
enddef
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
| construct | finThemeUsed() |
| def | func:finThemeUsed |
| is | func |
| lib | lib:finTools |
| name | finThemeUsed |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finToNumberList |
| is | func |
| lib | lib:finTools |
| name | finToNumberList |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finToggleImmediateSubscriptions
finToggleImmediateSubscriptions(action: "hide", filterStr: "", jobRec: null)
Axon function
meta
| alarmEmailToggle | ✓ |
| def | func:finToggleImmediateSubscriptions |
| deprecated | ✓ |
| is | func |
| lib | lib:finTools |
| name | finToggleImmediateSubscriptions |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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")
enddef
func:finTuningPolicyGetStats
finTuningPolicyGetStats(policyList, byPolicy: false)
Axon function
meta
| def | func:finTuningPolicyGetStats |
| is | func |
| lib | lib:finTools |
| name | finTuningPolicyGetStats |
| polyStats | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finTuningPolicyStatsForm
finTuningPolicyStatsForm(id: null, selectedDicts: null)
Axon function
meta
| appFormOn | builder, folio |
| def | func:finTuningPolicyStatsForm |
| dis | toLocale("j2FinToolsExt::tuningPolicyStats") |
| folderPath | toLocale("finStackExt::rightMenuConnectors")+"/"+toLocal... |
| formOn | connTuningRef |
| help | Show all tuning policy stats or tuning policies associat... |
| is | func |
| lib | lib:finTools |
| name | finTuningPolicyStatsForm |
| polyStats | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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()})
enddef
func:finUnique
finUnique(g, colNames)
meta
| def | func:finUnique |
| is | func |
| lib | lib:finTools |
| name | finUnique |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
| def | func:finUniqueConnectors |
| is | func |
| lib | lib:finTools |
| name | finUniqueConnectors |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finUniqueEquipTypes
finUniqueEquipTypes(filter, percentMatch, applyTags: false, tag: "navName")
Find the uniqe types for the equips
meta
| def | func:finUniqueEquipTypes |
| is | func |
| lib | lib:finTools |
| name | finUniqueEquipTypes |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finUniqueEquipTypes2
finUniqueEquipTypes2(filter, percent, applyTags, tag: "navName")
Axon function
meta
| def | func:finUniqueEquipTypes2 |
| is | func |
| lib | lib:finTools |
| name | finUniqueEquipTypes2 |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finUpdateRecordsIgnoredTags
finUpdateRecordsIgnoredTags()
Axon function
meta
| def | func:finUpdateRecordsIgnoredTags |
| is | func |
| lib | lib:finTools |
| name | finUpdateRecordsIgnoredTags |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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" ]
enddef
func:finUpdateRecordsIgnoredTags2
finUpdateRecordsIgnoredTags2(obj)
Axon function
meta
| def | func:finUpdateRecordsIgnoredTags2 |
| is | func |
| lib | lib:finTools |
| name | finUpdateRecordsIgnoredTags2 |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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" ]
enddef
func:finUploadSavedRecordsForm
finUploadSavedRecordsForm(stage: null, data: null, type: null)
Axon function
meta
| appFormOn | folio |
| batchRecords | ✓ |
| def | func:finUploadSavedRecordsForm |
| dis | toLocale("j2FinToolsExt::uploadSavedRecs") |
| folderPath | toLocale("j2FinToolsExt::createBatchRecords") |
| formOn | site or floor or equip or (point and not schedule) |
| is | func |
| lib | lib:finTools |
| name | finUploadSavedRecordsForm |
| overridable | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finValidConnectors
finValidConnectors(connType)
Axon function
meta
| def | func:finValidConnectors |
| is | func |
| lib | lib:finTools |
| name | finValidConnectors |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:finWriteBin
finWriteBin(rec, tag, buf)
meta
| def | func:finWriteBin |
| is | func |
| lib | lib:finTools |
| name | finWriteBin |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:finWriteLevels
finWriteLevels(recs, conntype, wlevel, transfer)
Axon function
meta
| def | func:finWriteLevels |
| is | func |
| lib | lib:finTools |
| name | finWriteLevels |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
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
| def | func:finZincTagBatchEdit |
| is | func |
| lib | lib:finTools |
| name | finZincTagBatchEdit |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
| def | func:finZincTagBatchList |
| is | func |
| lib | lib:finTools |
| name | finZincTagBatchList |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:findPod
findPod(name)
meta
| def | func:findPod |
| is | func |
| lib | lib:finTools |
| name | findPod |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:findPointNames
findPointNames(equip, tag: "navName")
Axon function
meta
| def | func:findPointNames |
| is | func |
| lib | lib:finTools |
| name | findPointNames |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:funcDefs
funcDefs()
meta
| def | func:funcDefs |
| is | func |
| lib | lib:finTools |
| name | funcDefs |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:getEventsData
getEventsData(id, catalog)
Axon function
meta
| def | func:getEventsData |
| is | func |
| lib | lib:finTools |
| name | getEventsData |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:getHisTags
getHisTags()
Axon function
meta
| def | func:getHisTags |
| is | func |
| lib | lib:finTools |
| name | getHisTags |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
()=> do
[
"his","hisCur","hisWrite","hisRead","hisErr","hisEnd","hisStart","hisCollectCov", "hisCollectInterval","hisInterpolate",
"hisInterval","hisEndVal","hisTsPrecision", "hisYear", "hisSize","hisStatus","bacnetHis","haystackHis"
]
enddef
func:getPodVersion
getPodVersion(pod)
meta
| def | func:getPodVersion |
| is | func |
| lib | lib:finTools |
| name | getPodVersion |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:hideRef
hideRef(obj)
Axon function
meta
| def | func:hideRef |
| is | func |
| lib | lib:finTools |
| name | hideRef |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(obj)=>do
obj->kind=="Ref" or obj->kind == "Marker"
enddef
func:ignoredConnTags
ignoredConnTags(rec)
Axon function
meta
| def | func:ignoredConnTags |
| is | func |
| lib | lib:finTools |
| name | ignoredConnTags |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:importModbus
importModbus(uri, regMapUri, conDis, slave, siteName, floorName, tenantName, tagObj, folderPath)
meta
| def | func:importModbus |
| is | func |
| lib | lib:finTools |
| name | importModbus |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:ioCopyFile
ioCopyFile(fromPath, toPath)
meta
| def | func:ioCopyFile |
| is | func |
| lib | lib:finTools |
| name | ioCopyFile |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:ioCreateDir
ioCreateDir(toPath)
meta
| def | func:ioCreateDir |
| is | func |
| lib | lib:finTools |
| name | ioCreateDir |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:ioExists
ioExists(path)
meta
| def | func:ioExists |
| is | func |
| lib | lib:finTools |
| name | ioExists |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:ioReadFileStr
ioReadFileStr(path)
meta
| def | func:ioReadFileStr |
| is | func |
| lib | lib:finTools |
| name | ioReadFileStr |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:ioUnzipPod
ioUnzipPod(pod, toPath)
meta
| def | func:ioUnzipPod |
| is | func |
| lib | lib:finTools |
| name | ioUnzipPod |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:ioWriteFile
ioWriteFile(handle, toPath)
meta
| def | func:ioWriteFile |
| is | func |
| lib | lib:finTools |
| name | ioWriteFile |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:jaccardIndex
jaccardIndex(this, that)
Axon function
meta
| def | func:jaccardIndex |
| is | func |
| lib | lib:finTools |
| name | jaccardIndex |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:kioskImageImport
kioskImageImport()
meta
| def | func:kioskImageImport |
| is | func |
| lib | lib:finTools |
| name | kioskImageImport |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:listFile
listFile(root)
meta
| def | func:listFile |
| is | func |
| lib | lib:finTools |
| name | listFile |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:listOfEquipIds
listOfEquipIds(type)
Axon function
meta
| def | func:listOfEquipIds |
| is | func |
| lib | lib:finTools |
| name | listOfEquipIds |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:loadPodGraphic
loadPodGraphic(path)
meta
| def | func:loadPodGraphic |
| is | func |
| lib | lib:finTools |
| name | loadPodGraphic |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:markerOnly
markerOnly(obj)
Axon function
meta
| def | func:markerOnly |
| is | func |
| lib | lib:finTools |
| name | markerOnly |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(obj)=>do
obj->kind != "Marker"
enddef
func:navDuplicate2
navDuplicate2(type, id, opts)
This function calls navDuplicate using the parameters to duplicates records and then adjusts the names.
meta
| construct | navDuplicate2("equip", read(equip)->id, {count: 2, noChi... |
| def | func:navDuplicate2 |
| is | func |
| lib | lib:finTools |
| name | navDuplicate2 |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:padZero
padZero(number, width)
Axon function
meta
| def | func:padZero |
| is | func |
| lib | lib:finTools |
| name | padZero |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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
enddef
func:publishPod
publishPod(pod, user, pwd, sandbox)
Axon function
meta
| def | func:publishPod |
| is | func |
| lib | lib:finTools |
| name | publishPod |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(pod,user, pwd, sandbox)=> do
echo("user " + user)
finPublishTemplatePackage(pod,user,pwd,sandbox)
finFormAlertOk("Success", "Pod published")
enddef
func:readFileTrio
readFileTrio(path)
meta
| def | func:readFileTrio |
| is | func |
| lib | lib:finTools |
| name | readFileTrio |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:readFinToolsCsv
readFinToolsCsv(uri)
Read a csv from the pod
meta
| def | func:readFinToolsCsv |
| is | func |
| lib | lib:finTools |
| name | readFinToolsCsv |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:runJob
runJob(exp)
meta
| def | func:runJob |
| is | func |
| lib | lib:finTools |
| name | runJob |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
def
func:sampleAddTags
sampleAddTags(colName, filter)
Axon function
meta
| def | func:sampleAddTags |
| is | func |
| lib | lib:finTools |
| name | sampleAddTags |
| private | ✓ |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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)
[]
enddef
func:wrappedDiffRemove
wrappedDiffRemove(id)
Axon function
meta
| baSuExec | ✓ |
| def | func:wrappedDiffRemove |
| is | func |
| lib | lib:finTools |
| name | wrappedDiffRemove |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon 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)
enddef
func:wrappedIoReadJson
wrappedIoReadJson(path)
Axon function
meta
| baSuExec | ✓ |
| def | func:wrappedIoReadJson |
| is | func |
| lib | lib:finTools |
| name | wrappedIoReadJson |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(path) => do
readJson: (p)=> do
ioReadJson(p)
end
try baSuExec(readJson,curFunc(),[path])
catch readJson(path)
enddef
func:wrappedIoReadStr
wrappedIoReadStr(path)
Axon function
meta
| baSuExec | ✓ |
| def | func:wrappedIoReadStr |
| is | func |
| lib | lib:finTools |
| name | wrappedIoReadStr |
supertypes
| feature | Feature namespace of definitions formatted as feature:name |
| func | Axon function |
src
(path) => do
readStr: (p)=> do
ioReadStr(p)
end
try baSuExec(readStr,curFunc(),[path])
catch readStr(path)
end