@butlr/butlr-mcp-server 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cache/topology-cache.d.ts +6 -6
- package/dist/cache/topology-cache.js +6 -6
- package/dist/clients/queries/topology.d.ts +14 -0
- package/dist/clients/queries/topology.d.ts.map +1 -1
- package/dist/clients/queries/topology.js +48 -0
- package/dist/clients/queries/topology.js.map +1 -1
- package/dist/clients/reporting-client.d.ts +6 -0
- package/dist/clients/reporting-client.d.ts.map +1 -1
- package/dist/clients/reporting-client.js.map +1 -1
- package/dist/clients/types.d.ts +1 -1
- package/dist/clients/types.d.ts.map +1 -1
- package/dist/tools/butlr-list-topology.d.ts.map +1 -1
- package/dist/tools/butlr-list-topology.js +7 -53
- package/dist/tools/butlr-list-topology.js.map +1 -1
- package/dist/tools/butlr-search-assets.d.ts +1 -0
- package/dist/tools/butlr-search-assets.d.ts.map +1 -1
- package/dist/tools/butlr-search-assets.js +59 -15
- package/dist/tools/butlr-search-assets.js.map +1 -1
- package/dist/tools/butlr-traffic-flow.d.ts.map +1 -1
- package/dist/tools/butlr-traffic-flow.js +147 -54
- package/dist/tools/butlr-traffic-flow.js.map +1 -1
- package/dist/types/responses.d.ts +1 -1
- package/dist/types/responses.d.ts.map +1 -1
- package/dist/utils/asset-flattener.d.ts.map +1 -1
- package/dist/utils/asset-flattener.js +15 -3
- package/dist/utils/asset-flattener.js.map +1 -1
- package/dist/utils/graphql-helpers.d.ts +26 -1
- package/dist/utils/graphql-helpers.d.ts.map +1 -1
- package/dist/utils/graphql-helpers.js +30 -5
- package/dist/utils/graphql-helpers.js.map +1 -1
- package/dist/utils/occupancy-helpers.d.ts +72 -3
- package/dist/utils/occupancy-helpers.d.ts.map +1 -1
- package/dist/utils/occupancy-helpers.js +129 -18
- package/dist/utils/occupancy-helpers.js.map +1 -1
- package/dist/utils/topology-merge.d.ts +24 -0
- package/dist/utils/topology-merge.d.ts.map +1 -0
- package/dist/utils/topology-merge.js +57 -0
- package/dist/utils/topology-merge.js.map +1 -0
- package/llms.txt +1 -1
- package/package.json +1 -1
|
@@ -78,12 +78,18 @@ export function flattenTopology(sites) {
|
|
|
78
78
|
building_name: building.name,
|
|
79
79
|
floor_id: floor.id,
|
|
80
80
|
floor_name: floor.name,
|
|
81
|
-
room_id: zone.roomID,
|
|
81
|
+
room_id: zone.room_id || zone.roomID,
|
|
82
|
+
room_name: (floor.rooms || []).find((r) => r.id === (zone.room_id || zone.roomID))
|
|
83
|
+
?.name,
|
|
82
84
|
customID: zone.customID,
|
|
83
85
|
capacity: zone.capacity,
|
|
84
86
|
coordinates: zone.coordinates,
|
|
85
87
|
});
|
|
86
88
|
}
|
|
89
|
+
// Room names for device breadcrumbs. `buildAssetPath` renders a
|
|
90
|
+
// `room_name` segment for sensors, hives and zones, and the flat
|
|
91
|
+
// device lists carry only `room_id`.
|
|
92
|
+
const roomNamesById = new Map((floor.rooms || []).map((r) => [r.id, r.name]));
|
|
87
93
|
// Add sensors
|
|
88
94
|
for (const sensor of floor.sensors || []) {
|
|
89
95
|
flattened.push({
|
|
@@ -96,7 +102,12 @@ export function flattenTopology(sites) {
|
|
|
96
102
|
building_name: building.name,
|
|
97
103
|
floor_id: floor.id,
|
|
98
104
|
floor_name: floor.name,
|
|
99
|
-
|
|
105
|
+
// snake_case first: GET_ALL_SENSORS selects `room_id`, and the
|
|
106
|
+
// camelCase resolver is buggy for NULL values. Reading only
|
|
107
|
+
// `roomID` here dropped the room segment from every flattened
|
|
108
|
+
// sensor's breadcrumb path.
|
|
109
|
+
room_id: sensor.room_id || sensor.roomID,
|
|
110
|
+
room_name: roomNamesById.get(sensor.room_id || sensor.roomID || ""),
|
|
100
111
|
mac_address: sensor.mac_address,
|
|
101
112
|
mode: sensor.mode,
|
|
102
113
|
model: sensor.model,
|
|
@@ -116,7 +127,8 @@ export function flattenTopology(sites) {
|
|
|
116
127
|
building_name: building.name,
|
|
117
128
|
floor_id: floor.id,
|
|
118
129
|
floor_name: floor.name,
|
|
119
|
-
room_id: hive.roomID,
|
|
130
|
+
room_id: hive.room_id || hive.roomID,
|
|
131
|
+
room_name: roomNamesById.get(hive.room_id || hive.roomID || ""),
|
|
120
132
|
serialNumber: hive.serialNumber,
|
|
121
133
|
is_online: hive.isOnline || hive.is_online,
|
|
122
134
|
hiveVersion: hive.hiveVersion,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset-flattener.js","sourceRoot":"","sources":["../../src/utils/asset-flattener.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"asset-flattener.js","sourceRoot":"","sources":["../../src/utils/asset-flattener.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,9 +29,34 @@ export declare function rethrowIfGraphQLError(error: unknown): void;
|
|
|
29
29
|
export declare function throwIfGraphQLErrors(result: {
|
|
30
30
|
error?: unknown;
|
|
31
31
|
}): void;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a sensor is a KNOWN test device: a mirror/virtual sensor
|
|
34
|
+
* (mi-rr-or*) or a fake test sensor (fa-ke*).
|
|
35
|
+
*
|
|
36
|
+
* Use this when refusing a caller's explicit request for one named sensor.
|
|
37
|
+
* Refusing costs the caller their query, so it needs positive evidence, and
|
|
38
|
+
* the MAC prefixes are the only positive evidence available. A blank or
|
|
39
|
+
* missing `mac_address` is unknown provenance, not proof: a provisioned but
|
|
40
|
+
* not yet MAC bound sensor is a real device with real reporting rows, and
|
|
41
|
+
* sensors are addressed by `id` everywhere, so a blank MAC never makes a row
|
|
42
|
+
* unqueryable.
|
|
43
|
+
*
|
|
44
|
+
* `isProductionSensor` below is the stricter counterpart for FILTERING
|
|
45
|
+
* aggregate lists, where the trade runs the other way.
|
|
46
|
+
*/
|
|
47
|
+
export declare function isKnownTestSensor(sensor: Sensor): boolean;
|
|
32
48
|
/**
|
|
33
49
|
* Check if a sensor is a production device (not a test/placeholder).
|
|
34
|
-
* Filters out mirror/virtual sensors (mi-rr-or*)
|
|
50
|
+
* Filters out mirror/virtual sensors (mi-rr-or*), fake test sensors (fa-ke*),
|
|
51
|
+
* and MAC-less placeholder rows.
|
|
52
|
+
*
|
|
53
|
+
* Stricter than `isKnownTestSensor` on purpose. This is the filter for
|
|
54
|
+
* aggregate views (topology listings, hardware health, occupancy sensor
|
|
55
|
+
* counts), where a MAC-less placeholder row inflates every headline number it
|
|
56
|
+
* lands in, and `butlr_hardware_snapshot` reports those rows under
|
|
57
|
+
* `test_devices_excluded.sensors.placeholder`. Excluding an unknown row from a
|
|
58
|
+
* total is cheap; refusing a caller's explicit query for it is not, which is
|
|
59
|
+
* why the single-sensor path uses `isKnownTestSensor` instead.
|
|
35
60
|
*/
|
|
36
61
|
export declare function isProductionSensor(sensor: Sensor): boolean;
|
|
37
62
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/graphql-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAGxD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAK1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CActE;AAED
|
|
1
|
+
{"version":3,"file":"graphql-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/graphql-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAGxD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAK1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CActE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAMpD"}
|
|
@@ -46,15 +46,40 @@ export function throwIfGraphQLErrors(result) {
|
|
|
46
46
|
// Surface other ErrorLike shapes (e.g. ServerError) for the outer catch.
|
|
47
47
|
throw result.error;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if a sensor is a KNOWN test device: a mirror/virtual sensor
|
|
51
|
+
* (mi-rr-or*) or a fake test sensor (fa-ke*).
|
|
52
|
+
*
|
|
53
|
+
* Use this when refusing a caller's explicit request for one named sensor.
|
|
54
|
+
* Refusing costs the caller their query, so it needs positive evidence, and
|
|
55
|
+
* the MAC prefixes are the only positive evidence available. A blank or
|
|
56
|
+
* missing `mac_address` is unknown provenance, not proof: a provisioned but
|
|
57
|
+
* not yet MAC bound sensor is a real device with real reporting rows, and
|
|
58
|
+
* sensors are addressed by `id` everywhere, so a blank MAC never makes a row
|
|
59
|
+
* unqueryable.
|
|
60
|
+
*
|
|
61
|
+
* `isProductionSensor` below is the stricter counterpart for FILTERING
|
|
62
|
+
* aggregate lists, where the trade runs the other way.
|
|
63
|
+
*/
|
|
64
|
+
export function isKnownTestSensor(sensor) {
|
|
65
|
+
const mac = sensor.mac_address?.trim() ?? "";
|
|
66
|
+
return mac.startsWith("mi-rr-or") || mac.startsWith("fa-ke");
|
|
67
|
+
}
|
|
49
68
|
/**
|
|
50
69
|
* Check if a sensor is a production device (not a test/placeholder).
|
|
51
|
-
* Filters out mirror/virtual sensors (mi-rr-or*)
|
|
70
|
+
* Filters out mirror/virtual sensors (mi-rr-or*), fake test sensors (fa-ke*),
|
|
71
|
+
* and MAC-less placeholder rows.
|
|
72
|
+
*
|
|
73
|
+
* Stricter than `isKnownTestSensor` on purpose. This is the filter for
|
|
74
|
+
* aggregate views (topology listings, hardware health, occupancy sensor
|
|
75
|
+
* counts), where a MAC-less placeholder row inflates every headline number it
|
|
76
|
+
* lands in, and `butlr_hardware_snapshot` reports those rows under
|
|
77
|
+
* `test_devices_excluded.sensors.placeholder`. Excluding an unknown row from a
|
|
78
|
+
* total is cheap; refusing a caller's explicit query for it is not, which is
|
|
79
|
+
* why the single-sensor path uses `isKnownTestSensor` instead.
|
|
52
80
|
*/
|
|
53
81
|
export function isProductionSensor(sensor) {
|
|
54
|
-
return
|
|
55
|
-
sensor.mac_address.trim() !== "" &&
|
|
56
|
-
!sensor.mac_address.startsWith("mi-rr-or") &&
|
|
57
|
-
!sensor.mac_address.startsWith("fa-ke"));
|
|
82
|
+
return !!sensor.mac_address && sensor.mac_address.trim() !== "" && !isKnownTestSensor(sensor);
|
|
58
83
|
}
|
|
59
84
|
/**
|
|
60
85
|
* Check if a hive is a production device (not a test/placeholder).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql-helpers.js","sourceRoot":"","sources":["../../src/utils/graphql-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEhF;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,eAAe,IAAI,KAAK,IAAI,cAAc,IAAI,KAAK,CAAC,EAAE,CAAC;QAChG,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAoD,CAAC,CAAC;QAC7F,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA2B;IAC9D,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO;IAE1B,IAAI,qBAAqB,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,qBAAqB,CAAC;YACpB,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7C,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,UAAU,EAAE,CAAC,CAAC,UAAU;aACzB,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,MAAM,MAAM,CAAC,KAAK,CAAC;AACrB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"graphql-helpers.js","sourceRoot":"","sources":["../../src/utils/graphql-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEhF;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,eAAe,IAAI,KAAK,IAAI,cAAc,IAAI,KAAK,CAAC,EAAE,CAAC;QAChG,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAoD,CAAC,CAAC;QAC7F,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA2B;IAC9D,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO;IAE1B,IAAI,qBAAqB,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,qBAAqB,CAAC;YACpB,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7C,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,UAAU,EAAE,CAAC,CAAC,UAAU;aACzB,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,MAAM,MAAM,CAAC,KAAK,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC7C,OAAO,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAChG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAU;IACzC,OAAO,CACL,CAAC,CAAC,IAAI,CAAC,YAAY;QACnB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;QAC/B,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CACpD,CAAC;AACJ,CAAC"}
|
|
@@ -5,18 +5,52 @@
|
|
|
5
5
|
* Both tools share: topology fetching, sensor filtering, asset resolution,
|
|
6
6
|
* measurement selection, and recommendation logic.
|
|
7
7
|
*/
|
|
8
|
-
import type { Sensor, Site, Floor, Building } from "../clients/types.js";
|
|
8
|
+
import type { Sensor, Site, Floor, Building, Room } from "../clients/types.js";
|
|
9
9
|
import type { TimezoneMetadata } from "./timezone-helpers.js";
|
|
10
10
|
import type { MeasurementRecommendation, BaseMeasurementData } from "../types/responses.js";
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* The spatial hierarchy on its own, flattened for lookup.
|
|
13
|
+
*
|
|
14
|
+
* Split out from TopologyContext because a caller that resolves ONE known
|
|
15
|
+
* sensor needs the hierarchy but not the org's whole sensor inventory.
|
|
13
16
|
*/
|
|
14
|
-
export interface
|
|
17
|
+
export interface TopologyOnly {
|
|
15
18
|
sites: Site[];
|
|
16
19
|
buildings: Building[];
|
|
17
20
|
floors: Floor[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Topology and sensor data fetched in parallel for occupancy tools.
|
|
24
|
+
*/
|
|
25
|
+
export interface TopologyContext extends TopologyOnly {
|
|
18
26
|
productionSensors: Sensor[];
|
|
19
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Fetch and flatten the spatial hierarchy (sites, buildings, floors).
|
|
30
|
+
*/
|
|
31
|
+
export declare function fetchTopology(): Promise<TopologyOnly>;
|
|
32
|
+
/**
|
|
33
|
+
* Fetch the org's full sensor inventory, test/mirror devices removed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function fetchProductionSensors(): Promise<Sensor[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Fetch specific sensors by ID.
|
|
38
|
+
*
|
|
39
|
+
* Unlike fetchProductionSensors this does NOT filter test devices: the caller
|
|
40
|
+
* asked for these exact IDs, so a mirror device has to come back so the caller
|
|
41
|
+
* can say so, rather than silently becoming "not found".
|
|
42
|
+
*/
|
|
43
|
+
export declare function fetchSensorsByIds(ids: string[]): Promise<Sensor[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Fetch the sensors bound to specific rooms via `sensors(room_ids:)`.
|
|
46
|
+
*
|
|
47
|
+
* Like fetchSensorsByIds this does NOT filter test devices: the caller scoped
|
|
48
|
+
* the query to rooms it already knows about, and the row set has to be
|
|
49
|
+
* complete so the caller can apply whatever gate fits its use (e.g.
|
|
50
|
+
* isKnownTestSensor for a refusal gate that must not drop MAC-less
|
|
51
|
+
* placeholder rows).
|
|
52
|
+
*/
|
|
53
|
+
export declare function fetchSensorsByRoomIds(roomIds: string[]): Promise<Sensor[]>;
|
|
20
54
|
/**
|
|
21
55
|
* Fetch topology and production sensors in a single parallel call.
|
|
22
56
|
* Shared by both current-occupancy and timeseries tools.
|
|
@@ -39,6 +73,41 @@ export interface AssetContext {
|
|
|
39
73
|
* Resolve full context for an asset ID: type validation, name, timezone, sensor partitioning.
|
|
40
74
|
*/
|
|
41
75
|
export declare function resolveAssetContext(assetId: string, ctx: TopologyContext): AssetContext;
|
|
76
|
+
/**
|
|
77
|
+
* Resolved context for a single sensor: display name, timezone, and the
|
|
78
|
+
* breadcrumb path to it.
|
|
79
|
+
*
|
|
80
|
+
* Lives next to resolveAssetContext so there is ONE definition of how a
|
|
81
|
+
* sensor's timezone and path are derived. Sensors are not an asset type
|
|
82
|
+
* resolveAssetContext handles (it partitions an enclosing space's sensors by
|
|
83
|
+
* mode, which is not meaningful for a single device), but they resolve
|
|
84
|
+
* against the same topology by the same rules, and a second copy of those
|
|
85
|
+
* rules in a tool is how the two drifted apart before.
|
|
86
|
+
*/
|
|
87
|
+
export interface SensorContext {
|
|
88
|
+
name: string;
|
|
89
|
+
timezone: string;
|
|
90
|
+
tzMetadata: TimezoneMetadata;
|
|
91
|
+
timezoneFallback: boolean;
|
|
92
|
+
path: string;
|
|
93
|
+
room?: Room;
|
|
94
|
+
floor?: Floor;
|
|
95
|
+
building?: Building;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Resolve a single sensor's display name, timezone and breadcrumb path.
|
|
99
|
+
*
|
|
100
|
+
* Room first, floor second, for BOTH timezone and path. The room's own floor
|
|
101
|
+
* is authoritative: `sensor.floor_id` can be unset while `room_id` still
|
|
102
|
+
* resolves, and it can disagree with the room's actual floor. Keying the path
|
|
103
|
+
* off `floor_id` (while keying the timezone off `room_id`) drops every path
|
|
104
|
+
* segment in the first case and names the wrong floor in the second.
|
|
105
|
+
*
|
|
106
|
+
* Only snake_case linkage fields are read. Both queries that feed this
|
|
107
|
+
* (GET_ALL_SENSORS, GET_SENSORS_BY_IDS) select `floor_id`/`room_id` and not
|
|
108
|
+
* the camelCase resolvers, which are buggy for NULL values.
|
|
109
|
+
*/
|
|
110
|
+
export declare function resolveSensorContext(sensor: Sensor, ctx: TopologyOnly): SensorContext;
|
|
42
111
|
/**
|
|
43
112
|
* Get the measurement name for presence data based on asset type.
|
|
44
113
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"occupancy-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/occupancy-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"occupancy-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/occupancy-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,30 +6,22 @@
|
|
|
6
6
|
* measurement selection, and recommendation logic.
|
|
7
7
|
*/
|
|
8
8
|
import { apolloClient } from "../clients/graphql-client.js";
|
|
9
|
-
import { GET_ALL_SENSORS, GET_FULL_TOPOLOGY } from "../clients/queries/topology.js";
|
|
9
|
+
import { GET_ALL_SENSORS, GET_FULL_TOPOLOGY, GET_SENSORS_BY_IDS, GET_SENSORS_BY_ROOM_IDS, } from "../clients/queries/topology.js";
|
|
10
10
|
import { detectAssetType } from "./asset-helpers.js";
|
|
11
11
|
import { isProductionSensor, throwIfGraphQLErrors } from "./graphql-helpers.js";
|
|
12
12
|
import { getTimezoneForAsset, buildTimezoneMetadata } from "./timezone-helpers.js";
|
|
13
13
|
import { rethrowIfGraphQLError } from "./graphql-helpers.js";
|
|
14
14
|
/**
|
|
15
|
-
* Fetch
|
|
16
|
-
* Shared by both current-occupancy and timeseries tools.
|
|
15
|
+
* Fetch and flatten the spatial hierarchy (sites, buildings, floors).
|
|
17
16
|
*/
|
|
18
|
-
export async function
|
|
19
|
-
let topoResult
|
|
17
|
+
export async function fetchTopology() {
|
|
18
|
+
let topoResult;
|
|
20
19
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}),
|
|
26
|
-
apolloClient.query({
|
|
27
|
-
query: GET_ALL_SENSORS,
|
|
28
|
-
fetchPolicy: "network-only",
|
|
29
|
-
}),
|
|
30
|
-
]);
|
|
20
|
+
topoResult = await apolloClient.query({
|
|
21
|
+
query: GET_FULL_TOPOLOGY,
|
|
22
|
+
fetchPolicy: "network-only",
|
|
23
|
+
});
|
|
31
24
|
throwIfGraphQLErrors(topoResult);
|
|
32
|
-
throwIfGraphQLErrors(sensorsResult);
|
|
33
25
|
}
|
|
34
26
|
catch (error) {
|
|
35
27
|
rethrowIfGraphQLError(error);
|
|
@@ -38,9 +30,89 @@ export async function fetchTopologyAndSensors() {
|
|
|
38
30
|
const sites = topoResult.data?.sites?.data || [];
|
|
39
31
|
const buildings = sites.flatMap((s) => s.buildings || []);
|
|
40
32
|
const floors = buildings.flatMap((b) => b.floors || []);
|
|
33
|
+
return { sites, buildings, floors };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Fetch the org's full sensor inventory, test/mirror devices removed.
|
|
37
|
+
*/
|
|
38
|
+
export async function fetchProductionSensors() {
|
|
39
|
+
let sensorsResult;
|
|
40
|
+
try {
|
|
41
|
+
sensorsResult = await apolloClient.query({
|
|
42
|
+
query: GET_ALL_SENSORS,
|
|
43
|
+
fetchPolicy: "network-only",
|
|
44
|
+
});
|
|
45
|
+
throwIfGraphQLErrors(sensorsResult);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
rethrowIfGraphQLError(error);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
41
51
|
const allSensors = sensorsResult.data?.sensors?.data || [];
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
return allSensors.filter(isProductionSensor);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Fetch specific sensors by ID.
|
|
56
|
+
*
|
|
57
|
+
* Unlike fetchProductionSensors this does NOT filter test devices: the caller
|
|
58
|
+
* asked for these exact IDs, so a mirror device has to come back so the caller
|
|
59
|
+
* can say so, rather than silently becoming "not found".
|
|
60
|
+
*/
|
|
61
|
+
export async function fetchSensorsByIds(ids) {
|
|
62
|
+
if (ids.length === 0)
|
|
63
|
+
return [];
|
|
64
|
+
let result;
|
|
65
|
+
try {
|
|
66
|
+
result = await apolloClient.query({
|
|
67
|
+
query: GET_SENSORS_BY_IDS,
|
|
68
|
+
variables: { ids },
|
|
69
|
+
fetchPolicy: "network-only",
|
|
70
|
+
});
|
|
71
|
+
throwIfGraphQLErrors(result);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
rethrowIfGraphQLError(error);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
return result.data?.sensors?.data || [];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Fetch the sensors bound to specific rooms via `sensors(room_ids:)`.
|
|
81
|
+
*
|
|
82
|
+
* Like fetchSensorsByIds this does NOT filter test devices: the caller scoped
|
|
83
|
+
* the query to rooms it already knows about, and the row set has to be
|
|
84
|
+
* complete so the caller can apply whatever gate fits its use (e.g.
|
|
85
|
+
* isKnownTestSensor for a refusal gate that must not drop MAC-less
|
|
86
|
+
* placeholder rows).
|
|
87
|
+
*/
|
|
88
|
+
export async function fetchSensorsByRoomIds(roomIds) {
|
|
89
|
+
if (roomIds.length === 0)
|
|
90
|
+
return [];
|
|
91
|
+
let result;
|
|
92
|
+
try {
|
|
93
|
+
result = await apolloClient.query({
|
|
94
|
+
query: GET_SENSORS_BY_ROOM_IDS,
|
|
95
|
+
variables: { roomIds },
|
|
96
|
+
fetchPolicy: "network-only",
|
|
97
|
+
});
|
|
98
|
+
throwIfGraphQLErrors(result);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
rethrowIfGraphQLError(error);
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
return result.data?.sensors?.data || [];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Fetch topology and production sensors in a single parallel call.
|
|
108
|
+
* Shared by both current-occupancy and timeseries tools.
|
|
109
|
+
*/
|
|
110
|
+
export async function fetchTopologyAndSensors() {
|
|
111
|
+
const [topology, productionSensors] = await Promise.all([
|
|
112
|
+
fetchTopology(),
|
|
113
|
+
fetchProductionSensors(),
|
|
114
|
+
]);
|
|
115
|
+
return { ...topology, productionSensors };
|
|
44
116
|
}
|
|
45
117
|
/**
|
|
46
118
|
* Resolve full context for an asset ID: type validation, name, timezone, sensor partitioning.
|
|
@@ -110,6 +182,45 @@ export function resolveAssetContext(assetId, ctx) {
|
|
|
110
182
|
trafficSensors,
|
|
111
183
|
};
|
|
112
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Resolve a single sensor's display name, timezone and breadcrumb path.
|
|
187
|
+
*
|
|
188
|
+
* Room first, floor second, for BOTH timezone and path. The room's own floor
|
|
189
|
+
* is authoritative: `sensor.floor_id` can be unset while `room_id` still
|
|
190
|
+
* resolves, and it can disagree with the room's actual floor. Keying the path
|
|
191
|
+
* off `floor_id` (while keying the timezone off `room_id`) drops every path
|
|
192
|
+
* segment in the first case and names the wrong floor in the second.
|
|
193
|
+
*
|
|
194
|
+
* Only snake_case linkage fields are read. Both queries that feed this
|
|
195
|
+
* (GET_ALL_SENSORS, GET_SENSORS_BY_IDS) select `floor_id`/`room_id` and not
|
|
196
|
+
* the camelCase resolvers, which are buggy for NULL values.
|
|
197
|
+
*/
|
|
198
|
+
export function resolveSensorContext(sensor, ctx) {
|
|
199
|
+
const roomId = sensor.room_id || undefined;
|
|
200
|
+
const floorId = sensor.floor_id || undefined;
|
|
201
|
+
const floorByRoom = roomId
|
|
202
|
+
? ctx.floors.find((f) => f.rooms?.some((r) => r.id === roomId))
|
|
203
|
+
: undefined;
|
|
204
|
+
const room = floorByRoom?.rooms?.find((r) => r.id === roomId);
|
|
205
|
+
const floor = floorByRoom ?? (floorId ? ctx.floors.find((f) => f.id === floorId) : undefined);
|
|
206
|
+
const building = floor ? ctx.buildings.find((b) => b.id === floor.building_id) : undefined;
|
|
207
|
+
// A dangling room reference (deleted room) falls through to the floor, and
|
|
208
|
+
// an unassigned sensor falls through to the UTC fallback with isFallback set.
|
|
209
|
+
const resolved = room
|
|
210
|
+
? getTimezoneForAsset(room.id, "room", ctx.floors, ctx.buildings, ctx.sites)
|
|
211
|
+
: getTimezoneForAsset(floor?.id ?? "", "floor", ctx.floors, ctx.buildings, ctx.sites);
|
|
212
|
+
const name = sensor.name || sensor.id;
|
|
213
|
+
return {
|
|
214
|
+
name,
|
|
215
|
+
timezone: resolved.timezone,
|
|
216
|
+
tzMetadata: buildTimezoneMetadata(resolved.timezone),
|
|
217
|
+
timezoneFallback: resolved.isFallback,
|
|
218
|
+
path: [building?.name, floor?.name, room?.name, name].filter(Boolean).join(" > "),
|
|
219
|
+
room,
|
|
220
|
+
floor,
|
|
221
|
+
building,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
113
224
|
/**
|
|
114
225
|
* Find the display name for an asset by searching the topology.
|
|
115
226
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"occupancy-helpers.js","sourceRoot":"","sources":["../../src/utils/occupancy-helpers.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"occupancy-helpers.js","sourceRoot":"","sources":["../../src/utils/occupancy-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared topology/device merge.
|
|
3
|
+
*
|
|
4
|
+
* Two tools need floors to carry their `sensors` and `hives` arrays:
|
|
5
|
+
* `butlr_list_topology` renders them, and `butlr_search_assets` flattens them
|
|
6
|
+
* into its search corpus. Keeping the merge in one place is what lets both
|
|
7
|
+
* read the same `devicesMerged: true` cache entry.
|
|
8
|
+
*/
|
|
9
|
+
import type { Site, Sensor, Hive } from "../clients/types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Merge sensors and hives into topology structure.
|
|
12
|
+
* Groups by floor_id and nests under appropriate floors.
|
|
13
|
+
*
|
|
14
|
+
* IN-PLACE MUTATION: assigns `floor.sensors` and `floor.hives` directly on
|
|
15
|
+
* the input site tree (returned for chaining; no new array is allocated).
|
|
16
|
+
* `setCachedTopology` reads from the same `sites` reference that this
|
|
17
|
+
* function mutates — any caller that captures the pre-merge `sites` (via
|
|
18
|
+
* Apollo cache-restore, structural clone, or fork-then-await) would
|
|
19
|
+
* observe the un-merged shape and could write a device-incomplete tree
|
|
20
|
+
* to the cache. If you change this to immutable assignment, audit the
|
|
21
|
+
* cache write site to confirm it sees the merged result.
|
|
22
|
+
*/
|
|
23
|
+
export declare function mergeSensorsAndHivesIntoTopology(sites: Site[], allSensors: Sensor[], allHives: Hive[]): Site[];
|
|
24
|
+
//# sourceMappingURL=topology-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topology-merge.d.ts","sourceRoot":"","sources":["../../src/utils/topology-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,IAAI,EAAE,EACb,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,IAAI,EAAE,GACf,IAAI,EAAE,CAqCR"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared topology/device merge.
|
|
3
|
+
*
|
|
4
|
+
* Two tools need floors to carry their `sensors` and `hives` arrays:
|
|
5
|
+
* `butlr_list_topology` renders them, and `butlr_search_assets` flattens them
|
|
6
|
+
* into its search corpus. Keeping the merge in one place is what lets both
|
|
7
|
+
* read the same `devicesMerged: true` cache entry.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Merge sensors and hives into topology structure.
|
|
11
|
+
* Groups by floor_id and nests under appropriate floors.
|
|
12
|
+
*
|
|
13
|
+
* IN-PLACE MUTATION: assigns `floor.sensors` and `floor.hives` directly on
|
|
14
|
+
* the input site tree (returned for chaining; no new array is allocated).
|
|
15
|
+
* `setCachedTopology` reads from the same `sites` reference that this
|
|
16
|
+
* function mutates — any caller that captures the pre-merge `sites` (via
|
|
17
|
+
* Apollo cache-restore, structural clone, or fork-then-await) would
|
|
18
|
+
* observe the un-merged shape and could write a device-incomplete tree
|
|
19
|
+
* to the cache. If you change this to immutable assignment, audit the
|
|
20
|
+
* cache write site to confirm it sees the merged result.
|
|
21
|
+
*/
|
|
22
|
+
export function mergeSensorsAndHivesIntoTopology(sites, allSensors, allHives) {
|
|
23
|
+
// Group sensors by floor_id
|
|
24
|
+
const sensorsByFloor = {};
|
|
25
|
+
for (const sensor of allSensors) {
|
|
26
|
+
const floorId = sensor.floor_id || sensor.floorID;
|
|
27
|
+
if (floorId) {
|
|
28
|
+
if (!sensorsByFloor[floorId]) {
|
|
29
|
+
sensorsByFloor[floorId] = [];
|
|
30
|
+
}
|
|
31
|
+
sensorsByFloor[floorId].push(sensor);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Group hives by floor_id
|
|
35
|
+
const hivesByFloor = {};
|
|
36
|
+
for (const hive of allHives) {
|
|
37
|
+
const floorId = hive.floor_id || hive.floorID;
|
|
38
|
+
if (floorId) {
|
|
39
|
+
if (!hivesByFloor[floorId]) {
|
|
40
|
+
hivesByFloor[floorId] = [];
|
|
41
|
+
}
|
|
42
|
+
hivesByFloor[floorId].push(hive);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Merge into topology
|
|
46
|
+
for (const site of sites) {
|
|
47
|
+
for (const building of site.buildings || []) {
|
|
48
|
+
for (const floor of building.floors || []) {
|
|
49
|
+
// Add sensors and hives to this floor
|
|
50
|
+
floor.sensors = sensorsByFloor[floor.id] || [];
|
|
51
|
+
floor.hives = hivesByFloor[floor.id] || [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return sites;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=topology-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topology-merge.js","sourceRoot":"","sources":["../../src/utils/topology-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gCAAgC,CAC9C,KAAa,EACb,UAAoB,EACpB,QAAgB;IAEhB,4BAA4B;IAC5B,MAAM,cAAc,GAA6B,EAAE,CAAC;IACpD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC;QAClD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7B,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC/B,CAAC;YACD,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC7B,CAAC;YACD,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YAC5C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBAC1C,sCAAsC;gBACtC,KAAK,CAAC,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;gBAC/C,KAAK,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/llms.txt
CHANGED
|
@@ -112,7 +112,7 @@ Users need edit access to Butlr Studio to create tokens. If they don't have edit
|
|
|
112
112
|
- `butlr_hardware_snapshot` — Device health check: online/offline status and battery levels
|
|
113
113
|
- `butlr_available_rooms` — Find currently unoccupied rooms, filterable by capacity and tags
|
|
114
114
|
- `butlr_space_busyness` — Current occupancy with qualitative labels (quiet/moderate/busy) and trend comparison
|
|
115
|
-
- `butlr_traffic_flow` — Entry/exit counts with hourly breakdown for traffic-mode
|
|
115
|
+
- `butlr_traffic_flow` — Entry/exit counts with hourly breakdown, for a room or for one traffic-mode sensor. Accepts a room ID, a sensor ID (`sensor_...`) for per-access-point counts, or a name to search. A sensor does not need to be assigned to a room to be queried directly
|
|
116
116
|
- `butlr_list_topology` — Display org hierarchy tree with flexible depth control
|
|
117
117
|
- `butlr_fetch_entity_details` — Retrieve specific fields for entities by ID (minimal token usage)
|
|
118
118
|
- `butlr_get_occupancy_timeseries` — Historical occupancy data with configurable time ranges
|
package/package.json
CHANGED