#1163 Xeto equipment points validation

Charles Goodman Mon 9 Jun

Could someone please direct me to the documentation for setting up an equipment xeto spec that would validate the points as well.

Our goal/expectation is to create a xeto equipment spec that would allow specFits() to confirm that the equipment has the required points and those points are also valid instances of their respective point spec.

simple example:

//temporary sensor point spec
TempSensor : Point {
    pointTempTag
}

//temporary ahu equip spec
TempAhu : Ahu {
        ahuTempTag
    points : {TempSensor
    }
}

for background we are running testing our xeto specs within a local instance of haxall while using haystackConn to pull in some of our recs from the production skyspark instance. When running below, it correctly identifies the missing "ahuTempTag" but does not identify the missing required point.

readById(@haystackConn).haystackReadAll(equip and ahu).fitsExplain(TempAhu)

Brian Frank Mon 9 Jun

Look over the existing guideline 36 VAVs here and some of the equip templates here

Also there are several videos on YouTube linked to here

Charles Goodman Tue 10 Jun

Thank you Brian for the references, I reviewed these again and attempted to follow along with the deep dive video working through which functions still work with the latest version of haxall that I freshly downloaded, 3.1.11.

I was missing the sys::Query argument which I have corrected. However, it is still not functioning as expected. As I droppped back to test the axon query() and queryAll() functions that were demonstrated in the video I ran into multiple errors. I have looked at the Skyfoundary and Haxall docs and tried to use both functions in local instance of Haxall and our skyspark instance with the same results.

Below is my attempt to reproduce the results you achieved in your video and then also trying the syntax seen in the documentation. You assistance would be greatly appreciated.

Axon shell v3.1.11 ('?' for help, 'quit' to quit)
axon> load(`https://project-haystack.org/example/download/charlie.zinc`)
LOAD: loading 'https://project-haystack.org/example/download/charlie.zinc' {} ...
LOAD: loaded 624 recs
axon> read(temp and point)
// @c-0150 "Charlie Floor-4 VAV_21 space_temp"
{cur, mod: 2025-06-10T12:39:54.25Z UTC, tz: "Detroit", air, point, dis: "Charlie Floor-4 VAV_21 space_temp", his, zone, equipRef: @c-0145 "Charlie Floor-4 VAV_21", id: @c-0150 "Charlie Floor-4 VAV_21 space_temp", temp, kind: "Number", siteRef: @c-0000 "Charlie", unit: "┬░F", sensor}
axon> using("*")
using ashrae.g36
using doc.xeto
using ph.equips
using ph.points
using ph.resources
using ph.attrs
using ph.points.elec
using acme
using doc.xeto.tools
using ph
using axon
using sys.comp
axon> read(temp and point)
// @c-0150 "Charlie Floor-4 VAV_21 space_temp"
{cur, mod: 2025-06-10T12:39:54.25Z UTC, tz: "Detroit", air, point, dis: "Charlie Floor-4 VAV_21 space_temp", his, zone, equipRef: @c-0145 "Charlie Floor-4 VAV_21", id: @c-0150 "Charlie Floor-4 VAV_21 space_temp", temp, kind: "Number", siteRef: @c-0000 "Charlie", unit: "┬░F", sensor}
axon> read(temp and point).query(Point.equips)
ERROR: sys::UnknownSlotErr: Point.equips
sys::UnknownSlotErr: Point.equips
  axon::StaticCall.eval (Call.fan:158)
  axon::Fn.callLazy (Fn.fan:84)
  fan.sys.List.map (List.java:870)
  axon::Fn.callLazy (Fn.fan:84)
  axon::DotCall.eval (Call.fan:112)
  axon::AxonContext.evalExpr (AxonContext.fan:104)
  axon::AxonContext.eval (AxonContext.fan:97)
  axon::AxonContext.eval (AxonContext.fan)
  axonsh::ShellContext.run (ShellContext.fan:80)
  axonsh::ShellContext.runInteractive (ShellContext.fan:51)
  axonsh::Main.main (Main.fan:29)
  jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
  java.lang.reflect.Method.invoke (Method.java:580)
  fan.sys.Method.invoke (Method.java:573)
  fan.sys.Method$MethodFunc.callOn (Method.java:244)
  fan.sys.Method.callOn (Method.java:139)
  fanx.tools.Fan.callMain (Fan.java:185)
  fanx.tools.Fan.executeType (Fan.java:147)
  fanx.tools.Fan.execute (Fan.java:41)
  fanx.tools.Fan.run (Fan.java:308)
  fanx.tools.Fan.main (Fan.java:346)
axon> read(temp and point).query(spec("ph::Point.equips"))
ERROR: Func failed: query(Obj subject,Spec spec,Bool checked); args: (NotNullMapDict,XetoSpec)
  haystack::UnknownRecErr: @c-0150 ph::Point.equips
haystack::UnknownRecErr: @c-0150 ph::Point.equips
  hxXeto::XetoFuncs.query (XetoFuncs.fan:712)
  hxXeto::XetoFuncs.query (XetoFuncs.fan)
  jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
  java.lang.reflect.Method.invoke (Method.java:580)
  fan.sys.Method.invoke (Method.java:573)
  fan.sys.Method$MethodFunc.callList (Method.java:212)
  fan.sys.Method.callList (Method.java:138)
  axon::FantomFn.doCall (FantomFn.fan:125)
  axon::AxonContext.callInNewFrame (AxonContext.fan:202)
  axon::AxonContext.callInNewFrame (AxonContext.fan)
  axon::FantomFn.callx (FantomFn.fan:113)
  axon::Fn.callLazy (Fn.fan:84)
  axon::DotCall.eval (Call.fan:112)
  axon::AxonContext.evalExpr (AxonContext.fan:104)
  axon::AxonContext.eval (AxonContext.fan:97)
  axon::AxonContext.eval (AxonContext.fan)
  axonsh::ShellContext.run (ShellContext.fan:80)
  axonsh::ShellContext.runInteractive (ShellContext.fan:51)
  axonsh::Main.main (Main.fan:29)
  jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
  java.lang.reflect.Method.invoke (Method.java:580)
  fan.sys.Method.invoke (Method.java:573)
  fan.sys.Method$MethodFunc.callOn (Method.java:244)
  fan.sys.Method.callOn (Method.java:139)
  fanx.tools.Fan.callMain (Fan.java:185)
  4 More...
axon>

Brian Frank Tue 10 Jun

We had to change that API because it was causing problems. So you cannot use dot in a spec literal. Instead look it up like this:

equip.queryAll(spec("ph::Equip.points"))

Charles Goodman Tue 10 Jun

I saw that option in some of the docs and tried it with the same setup pulling in the charlie example project

axon> load(`https://project-haystack.org/example/download/charlie.zinc`)

then ran the following to read the first point and attempt to pull the point's equip

axon> read(temp and point).query(spec("ph::Point.equips"))

this gave me the following error

ERROR: Func failed: query(Obj subject,Spec spec,Bool checked); args: (NotNullMapDict,XetoSpec) haystack::UnknownRecErr: @c-0150 ph::Point.equips haystack::UnknownRecErr: @c-0150 ph::Point.equips hxXeto::XetoFuncs.query (XetoFuncs.fan:712) hxXeto::XetoFuncs.query (XetoFuncs.fan) jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103) java.lang.reflect.Method.invoke (Method.java:580) fan.sys.Method.invoke (Method.java:573) fan.sys.Method$MethodFunc.callList (Method.java:212) fan.sys.Method.callList (Method.java:138) axon::FantomFn.doCall (FantomFn.fan:125) axon::AxonContext.callInNewFrame (AxonContext.fan:202) axon::AxonContext.callInNewFrame (AxonContext.fan) axon::FantomFn.callx (FantomFn.fan:113) axon::Fn.callLazy (Fn.fan:84) axon::DotCall.eval (Call.fan:112) axon::AxonContext.evalExpr (AxonContext.fan:104) axon::AxonContext.eval (AxonContext.fan:97) axon::AxonContext.eval (AxonContext.fan) axonsh::ShellContext.run (ShellContext.fan:80) axonsh::ShellContext.runInteractive (ShellContext.fan:51) axonsh::Main.main (Main.fan:29) jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103) java.lang.reflect.Method.invoke (Method.java:580) fan.sys.Method.invoke (Method.java:573) fan.sys.Method$MethodFunc.callOn (Method.java:244) fan.sys.Method.callOn (Method.java:139) fanx.tools.Fan.callMain (Fan.java:185) 4 More...

when I use the queryAll() instead of query i get the following error

axon> read(vav).queryAll(spec("ph::Equip.points"))   
    empty  
    -----

However, we know that the vav equip in that sample project does have points and the query should find them. I have also tried this with my custom specs as well and I got the same result.

Brian Frank Wed 11 Jun

I don't think any of those examples have been updated to use specs yet

Charles Goodman Wed 11 Jun

I am attempting to following along with your xeto deep dive video you referenced where you loaded the charlie example project and explained the ability to query related recs either from the equipment to return its points or from the point to return the equipment using queryAll(Equip.points)

I am unable to duplicate this even with the updated syntax using

queryAll(spec("ph::Equip.points"))

link to the time stamp in the referenced video showing the use of the queryAll function on the charlie project.

https://youtu.be/UvxWmU72wvs?t=2467

If this is no longer supported, is there any updated references? Apologies if I am missing something, but this is a awesome feature that we are hoping to employ.

Charles Goodman Wed 11 Jun

UPDATE: I pulled haxall 3.1.10 and the queryAll works as expected on charlie project

however, I can't get the same results using haxall 3.1.11, even with the updated syntax to use queryAll(spec("ph::Equip.points")) as this returns null

haxall 3.1.10

axon> read(vav)
// @c-0153 "Charlie Floor-4 VAV_22"
{mod: 2025-06-12T00:09:05.499Z UTC, siteRef: @c-0000 "Charlie", custom: {equipGroup: "VAVs"}, vav, dis: "Charlie Floor-4 VAV_22", equip, id: @c-0153 "Charlie Floor-4 VAV_22"}
axon> read(vav).queryAll(Equip.points)
id                                              air  cmd  cooling  cur
----------------------------------------------  ---  ---  -------  ---
@c-0154 "Charlie Floor-4 VAV_22 dpr_pos"        Γ£ô                  Γ£ô
@c-0155 "Charlie Floor-4 VAV_22 eff_cl_stpt"    Γ£ô         Γ£ô        Γ£ô
@c-0156 "Charlie Floor-4 VAV_22 eff_ht_stpt"    Γ£ô                  Γ£ô
@c-0157 "Charlie Floor-4 VAV_22 flow_input"     Γ£ô                  Γ£ô
@c-0158 "Charlie Floor-4 VAV_22 hw_valve"                          Γ£ô
@c-0159 "Charlie Floor-4 VAV_22 occ_cl_stpt"    Γ£ô         Γ£ô        Γ£ô
@c-0160 "Charlie Floor-4 VAV_22 unocc_ht_stpt"  Γ£ô                  Γ£ô
@c-015a "Charlie Floor-4 VAV_22 occ_ht_stpt"    Γ£ô                  Γ£ô
@c-015b "Charlie Floor-4 VAV_22 occ_status"          Γ£ô             Γ£ô
@c-015c "Charlie Floor-4 VAV_22 occ_switch"                        Γ£ô
@c-015d "Charlie Floor-4 VAV_22 sa_temp"        Γ£ô                  Γ£ô
@c-015e "Charlie Floor-4 VAV_22 space_temp"     Γ£ô                  Γ£ô
@c-015f "Charlie Floor-4 VAV_22 unocc_cl_stpt"  Γ£ô         Γ£ô        Γ£ô
axon>

haxall 3.1.11

axon> read(vav).queryAll(spec("ph::Equip.points"))
empty
-----

Brian Frank Yesterday

Like I said that database doesn't have the spec tag. You have to add at least the basic specs for Site, Equip, and Point for it to fit things with the latest validation code. You can see the problems using a query like this:

readById(@c-0153).toPoints.fitsExplain(spec("ph::Point"))

Run these queries to add basic spec tags:

readAll(site).map(r=>diff(r, {spec:@ph::Site}).commit)
readAll(equip).map(r=>diff(r, {spec:@ph::Equip}).commit)
readAll(point).map(r=>diff(r, {spec:@ph::Point}).commit)

Charles Goodman Yesterday

thank you sir! That is what we were missing. I didn't see that in the documentation and we hadn't gotten that far with implementing the xeto spec to have the specs added to the recs.

would it be possible to update the documentation for query and queryAll to include this requirement, that the "Subject must be a record id or dict in the database." AND must have a spec loaded.

Login or Signup to reply.