@butlr/butlr-mcp-server 0.1.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/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/cache/occupancy-cache.d.ts +72 -0
- package/dist/cache/occupancy-cache.d.ts.map +1 -0
- package/dist/cache/occupancy-cache.js +166 -0
- package/dist/cache/occupancy-cache.js.map +1 -0
- package/dist/cache/topology-cache.d.ts +36 -0
- package/dist/cache/topology-cache.d.ts.map +1 -0
- package/dist/cache/topology-cache.js +74 -0
- package/dist/cache/topology-cache.js.map +1 -0
- package/dist/clients/auth-client.d.ts +22 -0
- package/dist/clients/auth-client.d.ts.map +1 -0
- package/dist/clients/auth-client.js +82 -0
- package/dist/clients/auth-client.js.map +1 -0
- package/dist/clients/graphql-client.d.ts +6 -0
- package/dist/clients/graphql-client.d.ts.map +1 -0
- package/dist/clients/graphql-client.js +106 -0
- package/dist/clients/graphql-client.js.map +1 -0
- package/dist/clients/queries/topology.d.ts +36 -0
- package/dist/clients/queries/topology.d.ts.map +1 -0
- package/dist/clients/queries/topology.js +252 -0
- package/dist/clients/queries/topology.js.map +1 -0
- package/dist/clients/reporting-client.d.ts +191 -0
- package/dist/clients/reporting-client.d.ts.map +1 -0
- package/dist/clients/reporting-client.js +353 -0
- package/dist/clients/reporting-client.js.map +1 -0
- package/dist/clients/stats-client.d.ts +119 -0
- package/dist/clients/stats-client.d.ts.map +1 -0
- package/dist/clients/stats-client.js +238 -0
- package/dist/clients/stats-client.js.map +1 -0
- package/dist/clients/types.d.ts +215 -0
- package/dist/clients/types.d.ts.map +1 -0
- package/dist/clients/types.js +6 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors/mcp-errors.d.ts +63 -0
- package/dist/errors/mcp-errors.d.ts.map +1 -0
- package/dist/errors/mcp-errors.js +144 -0
- package/dist/errors/mcp-errors.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/butlr-available-rooms.d.ts +49 -0
- package/dist/tools/butlr-available-rooms.d.ts.map +1 -0
- package/dist/tools/butlr-available-rooms.js +492 -0
- package/dist/tools/butlr-available-rooms.js.map +1 -0
- package/dist/tools/butlr-fetch-entity-details.d.ts +42 -0
- package/dist/tools/butlr-fetch-entity-details.d.ts.map +1 -0
- package/dist/tools/butlr-fetch-entity-details.js +276 -0
- package/dist/tools/butlr-fetch-entity-details.js.map +1 -0
- package/dist/tools/butlr-get-asset-details.d.ts +51 -0
- package/dist/tools/butlr-get-asset-details.d.ts.map +1 -0
- package/dist/tools/butlr-get-asset-details.js +391 -0
- package/dist/tools/butlr-get-asset-details.js.map +1 -0
- package/dist/tools/butlr-get-current-occupancy.d.ts +21 -0
- package/dist/tools/butlr-get-current-occupancy.d.ts.map +1 -0
- package/dist/tools/butlr-get-current-occupancy.js +126 -0
- package/dist/tools/butlr-get-current-occupancy.js.map +1 -0
- package/dist/tools/butlr-get-occupancy-timeseries.d.ts +31 -0
- package/dist/tools/butlr-get-occupancy-timeseries.d.ts.map +1 -0
- package/dist/tools/butlr-get-occupancy-timeseries.js +145 -0
- package/dist/tools/butlr-get-occupancy-timeseries.js.map +1 -0
- package/dist/tools/butlr-hardware-snapshot.d.ts +55 -0
- package/dist/tools/butlr-hardware-snapshot.d.ts.map +1 -0
- package/dist/tools/butlr-hardware-snapshot.js +556 -0
- package/dist/tools/butlr-hardware-snapshot.js.map +1 -0
- package/dist/tools/butlr-list-topology.d.ts +27 -0
- package/dist/tools/butlr-list-topology.d.ts.map +1 -0
- package/dist/tools/butlr-list-topology.js +241 -0
- package/dist/tools/butlr-list-topology.js.map +1 -0
- package/dist/tools/butlr-search-assets.d.ts +53 -0
- package/dist/tools/butlr-search-assets.d.ts.map +1 -0
- package/dist/tools/butlr-search-assets.js +206 -0
- package/dist/tools/butlr-search-assets.js.map +1 -0
- package/dist/tools/butlr-space-busyness.d.ts +23 -0
- package/dist/tools/butlr-space-busyness.d.ts.map +1 -0
- package/dist/tools/butlr-space-busyness.js +304 -0
- package/dist/tools/butlr-space-busyness.js.map +1 -0
- package/dist/tools/butlr-traffic-flow.d.ts +39 -0
- package/dist/tools/butlr-traffic-flow.d.ts.map +1 -0
- package/dist/tools/butlr-traffic-flow.js +369 -0
- package/dist/tools/butlr-traffic-flow.js.map +1 -0
- package/dist/types/responses.d.ts +253 -0
- package/dist/types/responses.d.ts.map +1 -0
- package/dist/types/responses.js +8 -0
- package/dist/types/responses.js.map +1 -0
- package/dist/utils/asset-flattener.d.ts +50 -0
- package/dist/utils/asset-flattener.d.ts.map +1 -0
- package/dist/utils/asset-flattener.js +131 -0
- package/dist/utils/asset-flattener.js.map +1 -0
- package/dist/utils/asset-helpers.d.ts +8 -0
- package/dist/utils/asset-helpers.d.ts.map +1 -0
- package/dist/utils/asset-helpers.js +24 -0
- package/dist/utils/asset-helpers.js.map +1 -0
- package/dist/utils/field-validator.d.ts +29 -0
- package/dist/utils/field-validator.d.ts.map +1 -0
- package/dist/utils/field-validator.js +197 -0
- package/dist/utils/field-validator.js.map +1 -0
- package/dist/utils/fuzzy-match.d.ts +29 -0
- package/dist/utils/fuzzy-match.d.ts.map +1 -0
- package/dist/utils/fuzzy-match.js +70 -0
- package/dist/utils/fuzzy-match.js.map +1 -0
- package/dist/utils/graphql-helpers.d.ts +29 -0
- package/dist/utils/graphql-helpers.d.ts.map +1 -0
- package/dist/utils/graphql-helpers.js +43 -0
- package/dist/utils/graphql-helpers.js.map +1 -0
- package/dist/utils/natural-language.d.ts +73 -0
- package/dist/utils/natural-language.d.ts.map +1 -0
- package/dist/utils/natural-language.js +172 -0
- package/dist/utils/natural-language.js.map +1 -0
- package/dist/utils/occupancy-helpers.d.ts +63 -0
- package/dist/utils/occupancy-helpers.d.ts.map +1 -0
- package/dist/utils/occupancy-helpers.js +203 -0
- package/dist/utils/occupancy-helpers.js.map +1 -0
- package/dist/utils/path-builder.d.ts +10 -0
- package/dist/utils/path-builder.d.ts.map +1 -0
- package/dist/utils/path-builder.js +34 -0
- package/dist/utils/path-builder.js.map +1 -0
- package/dist/utils/time-range-validator.d.ts +13 -0
- package/dist/utils/time-range-validator.d.ts.map +1 -0
- package/dist/utils/time-range-validator.js +65 -0
- package/dist/utils/time-range-validator.js.map +1 -0
- package/dist/utils/timezone-helpers.d.ts +49 -0
- package/dist/utils/timezone-helpers.d.ts.map +1 -0
- package/dist/utils/timezone-helpers.js +209 -0
- package/dist/utils/timezone-helpers.js.map +1 -0
- package/dist/utils/tree-formatter.d.ts +23 -0
- package/dist/utils/tree-formatter.d.ts.map +1 -0
- package/dist/utils/tree-formatter.js +258 -0
- package/dist/utils/tree-formatter.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
dotenv.config();
|
|
3
|
+
const BASE_URL = process.env.BUTLR_BASE_URL || "https://api.butlr.io";
|
|
4
|
+
const AUTH_ENDPOINT = `${BASE_URL}/api/v2/clients/login`;
|
|
5
|
+
/**
|
|
6
|
+
* Butlr Authentication Client
|
|
7
|
+
* Manages OAuth2 client credentials flow for API authentication
|
|
8
|
+
*/
|
|
9
|
+
class ButlrAuthClient {
|
|
10
|
+
token = null;
|
|
11
|
+
tokenExpiry = null;
|
|
12
|
+
clientId;
|
|
13
|
+
clientSecret;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.clientId = process.env.BUTLR_CLIENT_ID || "";
|
|
16
|
+
this.clientSecret = process.env.BUTLR_CLIENT_SECRET || "";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get a valid access token, fetching a new one if needed
|
|
20
|
+
*/
|
|
21
|
+
async getToken() {
|
|
22
|
+
// Validate credentials on first use (deferred from constructor)
|
|
23
|
+
if (!this.clientId || !this.clientSecret) {
|
|
24
|
+
throw new Error("BUTLR_CLIENT_ID and BUTLR_CLIENT_SECRET environment variables are required. " +
|
|
25
|
+
"See README.md for configuration instructions.");
|
|
26
|
+
}
|
|
27
|
+
// Return cached token if still valid (with 5 minute buffer)
|
|
28
|
+
if (this.token && this.tokenExpiry && Date.now() < this.tokenExpiry.getTime() - 5 * 60 * 1000) {
|
|
29
|
+
if (process.env.DEBUG) {
|
|
30
|
+
console.error("[auth-client] Using cached token");
|
|
31
|
+
}
|
|
32
|
+
return this.token;
|
|
33
|
+
}
|
|
34
|
+
if (process.env.DEBUG) {
|
|
35
|
+
console.error("[auth-client] Fetching new token...");
|
|
36
|
+
}
|
|
37
|
+
// Fetch new token
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetch(AUTH_ENDPOINT, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: {
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
},
|
|
44
|
+
body: JSON.stringify({
|
|
45
|
+
client_id: this.clientId,
|
|
46
|
+
client_secret: this.clientSecret,
|
|
47
|
+
audience: "https://butlrauth/",
|
|
48
|
+
grant_type: "client_credentials",
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
const errorText = await response.text();
|
|
53
|
+
throw new Error(`Authentication failed (${response.status}): ${errorText}`);
|
|
54
|
+
}
|
|
55
|
+
const data = (await response.json());
|
|
56
|
+
if (!data.access_token) {
|
|
57
|
+
throw new Error("No access_token in response");
|
|
58
|
+
}
|
|
59
|
+
// Cache the token
|
|
60
|
+
this.token = data.access_token;
|
|
61
|
+
this.tokenExpiry = new Date(Date.now() + data.expires_in * 1000);
|
|
62
|
+
if (process.env.DEBUG) {
|
|
63
|
+
console.error(`[auth-client] Token acquired, expires at ${this.tokenExpiry.toISOString()}`);
|
|
64
|
+
}
|
|
65
|
+
return this.token;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error("[auth-client] Token fetch failed:", error);
|
|
69
|
+
throw new Error(`Failed to authenticate with Butlr API: ${error instanceof Error ? error.message : String(error)}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Clear cached token (useful for testing)
|
|
74
|
+
*/
|
|
75
|
+
clearToken() {
|
|
76
|
+
this.token = null;
|
|
77
|
+
this.tokenExpiry = null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Singleton instance
|
|
81
|
+
export const authClient = new ButlrAuthClient();
|
|
82
|
+
//# sourceMappingURL=auth-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../src/clients/auth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql-client.d.ts","sourceRoot":"","sources":["../../src/clients/graphql-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AAiFnF;;GAEG;AACH,eAAO,MAAM,YAAY,cAkCvB,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ApolloClient, InMemoryCache, createHttpLink, from } from "@apollo/client";
|
|
2
|
+
import { setContext } from "@apollo/client/link/context";
|
|
3
|
+
import { onError } from "@apollo/client/link/error";
|
|
4
|
+
import { authClient } from "./auth-client.js";
|
|
5
|
+
const BASE_URL = process.env.BUTLR_BASE_URL || "https://api.butlr.io";
|
|
6
|
+
const GRAPHQL_ENDPOINT = `${BASE_URL}/api/v3/graphql`;
|
|
7
|
+
/**
|
|
8
|
+
* HTTP link for GraphQL endpoint
|
|
9
|
+
*/
|
|
10
|
+
const httpLink = createHttpLink({
|
|
11
|
+
uri: GRAPHQL_ENDPOINT,
|
|
12
|
+
fetch,
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Authentication link - adds Bearer token to every request
|
|
16
|
+
*/
|
|
17
|
+
const authLink = setContext(async (_, { headers }) => {
|
|
18
|
+
try {
|
|
19
|
+
const token = await authClient.getToken();
|
|
20
|
+
return {
|
|
21
|
+
headers: {
|
|
22
|
+
...headers,
|
|
23
|
+
authorization: `Bearer ${token}`,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error("[graphql-client] Failed to get auth token:", error);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Error handling link - logs errors and provides debugging info
|
|
34
|
+
*/
|
|
35
|
+
const errorLink = onError((errorResponse) => {
|
|
36
|
+
const { operation } = errorResponse;
|
|
37
|
+
// Apollo 4.x ErrorHandlerOptions has a single 'error' field.
|
|
38
|
+
// Cast to access graphQLErrors/networkError which may exist at runtime
|
|
39
|
+
// depending on the Apollo version's actual implementation.
|
|
40
|
+
const resp = errorResponse;
|
|
41
|
+
const graphQLErrors = resp.graphQLErrors;
|
|
42
|
+
const networkError = resp.networkError;
|
|
43
|
+
const topError = resp.error;
|
|
44
|
+
if (graphQLErrors) {
|
|
45
|
+
for (const err of graphQLErrors) {
|
|
46
|
+
console.error(`[graphql-client] GraphQL error in ${operation.operationName}:`, err.message);
|
|
47
|
+
if (err.extensions?.code === "UNAUTHENTICATED") {
|
|
48
|
+
authClient.clearToken();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (networkError) {
|
|
53
|
+
console.error(`[graphql-client] Network error in ${operation.operationName}:`, networkError.message);
|
|
54
|
+
if (networkError.statusCode === 401 || networkError.statusCode === 403) {
|
|
55
|
+
authClient.clearToken();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Fallback for Apollo 4.x single error field
|
|
59
|
+
if (!graphQLErrors && !networkError && topError) {
|
|
60
|
+
console.error(`[graphql-client] Error in ${operation.operationName}:`, topError.message);
|
|
61
|
+
if (topError.message?.includes("UNAUTHENTICATED") ||
|
|
62
|
+
topError.message?.includes("401") ||
|
|
63
|
+
topError.message?.includes("403")) {
|
|
64
|
+
authClient.clearToken();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
/**
|
|
69
|
+
* Apollo Client instance with authentication and error handling
|
|
70
|
+
*/
|
|
71
|
+
export const apolloClient = new ApolloClient({
|
|
72
|
+
link: from([errorLink, authLink, httpLink]),
|
|
73
|
+
cache: new InMemoryCache({
|
|
74
|
+
typePolicies: {
|
|
75
|
+
// Customize caching behavior if needed
|
|
76
|
+
Site: {
|
|
77
|
+
keyFields: ["id"],
|
|
78
|
+
},
|
|
79
|
+
Building: {
|
|
80
|
+
keyFields: ["id"],
|
|
81
|
+
},
|
|
82
|
+
Floor: {
|
|
83
|
+
keyFields: ["id"],
|
|
84
|
+
},
|
|
85
|
+
Room: {
|
|
86
|
+
keyFields: ["id"],
|
|
87
|
+
},
|
|
88
|
+
Zone: {
|
|
89
|
+
keyFields: ["id"],
|
|
90
|
+
},
|
|
91
|
+
Sensor: {
|
|
92
|
+
keyFields: ["id"],
|
|
93
|
+
},
|
|
94
|
+
Hive: {
|
|
95
|
+
keyFields: ["id"],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
defaultOptions: {
|
|
100
|
+
query: {
|
|
101
|
+
fetchPolicy: "network-only", // Always fetch fresh data from API
|
|
102
|
+
errorPolicy: "all", // Return partial data on errors
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=graphql-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql-client.js","sourceRoot":"","sources":["../../src/clients/graphql-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL queries for topology retrieval
|
|
3
|
+
* Adapted from gauntlet-app for MCP server use
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Minimal sites list - fast loading, no nested data
|
|
7
|
+
*/
|
|
8
|
+
export declare const GET_SITES_LIST: import("@apollo/client").DocumentNode;
|
|
9
|
+
/**
|
|
10
|
+
* Single site structure without sensors/hives
|
|
11
|
+
* Good for quick hierarchy lookup
|
|
12
|
+
*/
|
|
13
|
+
export declare const GET_SITE_STRUCTURE: import("@apollo/client").DocumentNode;
|
|
14
|
+
/**
|
|
15
|
+
* Full topology with all sites, buildings, floors, rooms, zones
|
|
16
|
+
* NOTE: Does NOT include sensors/hives in nested fields (broken - only returns 5 sensors)
|
|
17
|
+
* Use GET_ALL_SENSORS and GET_ALL_HIVES separately, then merge by floor_id/room_id
|
|
18
|
+
*/
|
|
19
|
+
export declare const GET_FULL_TOPOLOGY: import("@apollo/client").DocumentNode;
|
|
20
|
+
/**
|
|
21
|
+
* Get all sensors for the organization
|
|
22
|
+
* Uses snake_case fields (floor_id, room_id) which work correctly
|
|
23
|
+
* CamelCase fields (floorID, roomID) have buggy resolvers that fail for NULL values
|
|
24
|
+
*/
|
|
25
|
+
export declare const GET_ALL_SENSORS: import("@apollo/client").DocumentNode;
|
|
26
|
+
/**
|
|
27
|
+
* Get all hives for the organization
|
|
28
|
+
* Uses snake_case fields (floor_id, room_id) for consistency
|
|
29
|
+
*/
|
|
30
|
+
export declare const GET_ALL_HIVES: import("@apollo/client").DocumentNode;
|
|
31
|
+
/**
|
|
32
|
+
* Lightweight topology without devices
|
|
33
|
+
* Faster when sensor/hive data isn't needed
|
|
34
|
+
*/
|
|
35
|
+
export declare const GET_TOPOLOGY_NO_DEVICES: import("@apollo/client").DocumentNode;
|
|
36
|
+
//# sourceMappingURL=topology.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topology.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,uCAY1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,uCA6B9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,uCAiE7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,uCAwB3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,uCAqBzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,uCAgEnC,CAAC"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { gql } from "@apollo/client";
|
|
2
|
+
/**
|
|
3
|
+
* GraphQL queries for topology retrieval
|
|
4
|
+
* Adapted from gauntlet-app for MCP server use
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Minimal sites list - fast loading, no nested data
|
|
8
|
+
*/
|
|
9
|
+
export const GET_SITES_LIST = gql `
|
|
10
|
+
query GetSitesList {
|
|
11
|
+
sites {
|
|
12
|
+
data {
|
|
13
|
+
id
|
|
14
|
+
name
|
|
15
|
+
timezone
|
|
16
|
+
siteNumber
|
|
17
|
+
customID
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
/**
|
|
23
|
+
* Single site structure without sensors/hives
|
|
24
|
+
* Good for quick hierarchy lookup
|
|
25
|
+
*/
|
|
26
|
+
export const GET_SITE_STRUCTURE = gql `
|
|
27
|
+
query GetSiteStructure($siteId: ID!) {
|
|
28
|
+
site(id: $siteId) {
|
|
29
|
+
id
|
|
30
|
+
name
|
|
31
|
+
timezone
|
|
32
|
+
siteNumber
|
|
33
|
+
customID
|
|
34
|
+
buildings {
|
|
35
|
+
id
|
|
36
|
+
name
|
|
37
|
+
building_number
|
|
38
|
+
capacity {
|
|
39
|
+
max
|
|
40
|
+
mid
|
|
41
|
+
}
|
|
42
|
+
address {
|
|
43
|
+
lines
|
|
44
|
+
country
|
|
45
|
+
}
|
|
46
|
+
floors {
|
|
47
|
+
id
|
|
48
|
+
name
|
|
49
|
+
floorNumber
|
|
50
|
+
timezone
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
/**
|
|
57
|
+
* Full topology with all sites, buildings, floors, rooms, zones
|
|
58
|
+
* NOTE: Does NOT include sensors/hives in nested fields (broken - only returns 5 sensors)
|
|
59
|
+
* Use GET_ALL_SENSORS and GET_ALL_HIVES separately, then merge by floor_id/room_id
|
|
60
|
+
*/
|
|
61
|
+
export const GET_FULL_TOPOLOGY = gql `
|
|
62
|
+
query GetFullTopology {
|
|
63
|
+
sites {
|
|
64
|
+
data {
|
|
65
|
+
id
|
|
66
|
+
name
|
|
67
|
+
timezone
|
|
68
|
+
siteNumber
|
|
69
|
+
customID
|
|
70
|
+
org_id
|
|
71
|
+
buildings {
|
|
72
|
+
id
|
|
73
|
+
name
|
|
74
|
+
building_number
|
|
75
|
+
site_id
|
|
76
|
+
customID
|
|
77
|
+
capacity {
|
|
78
|
+
max
|
|
79
|
+
mid
|
|
80
|
+
}
|
|
81
|
+
address {
|
|
82
|
+
lines
|
|
83
|
+
country
|
|
84
|
+
}
|
|
85
|
+
floors {
|
|
86
|
+
id
|
|
87
|
+
name
|
|
88
|
+
floorNumber
|
|
89
|
+
building_id
|
|
90
|
+
timezone
|
|
91
|
+
installation_date
|
|
92
|
+
customID
|
|
93
|
+
capacity {
|
|
94
|
+
max
|
|
95
|
+
mid
|
|
96
|
+
}
|
|
97
|
+
area {
|
|
98
|
+
value
|
|
99
|
+
unit
|
|
100
|
+
}
|
|
101
|
+
rooms {
|
|
102
|
+
id
|
|
103
|
+
name
|
|
104
|
+
floor_id
|
|
105
|
+
roomType
|
|
106
|
+
customID
|
|
107
|
+
capacity {
|
|
108
|
+
max
|
|
109
|
+
mid
|
|
110
|
+
}
|
|
111
|
+
coordinates
|
|
112
|
+
}
|
|
113
|
+
zones {
|
|
114
|
+
id
|
|
115
|
+
name
|
|
116
|
+
floor_id
|
|
117
|
+
room_id
|
|
118
|
+
customID
|
|
119
|
+
coordinates
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
`;
|
|
127
|
+
/**
|
|
128
|
+
* Get all sensors for the organization
|
|
129
|
+
* Uses snake_case fields (floor_id, room_id) which work correctly
|
|
130
|
+
* CamelCase fields (floorID, roomID) have buggy resolvers that fail for NULL values
|
|
131
|
+
*/
|
|
132
|
+
export const GET_ALL_SENSORS = gql `
|
|
133
|
+
query GetAllSensors {
|
|
134
|
+
sensors {
|
|
135
|
+
data {
|
|
136
|
+
id
|
|
137
|
+
name
|
|
138
|
+
mac_address
|
|
139
|
+
mode
|
|
140
|
+
model
|
|
141
|
+
floor_id
|
|
142
|
+
room_id
|
|
143
|
+
hive_serial
|
|
144
|
+
is_entrance
|
|
145
|
+
is_online
|
|
146
|
+
is_streaming
|
|
147
|
+
power_type
|
|
148
|
+
last_battery_change_date
|
|
149
|
+
next_battery_change_date
|
|
150
|
+
battery_change_by_date
|
|
151
|
+
last_heartbeat
|
|
152
|
+
installation_status
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
`;
|
|
157
|
+
/**
|
|
158
|
+
* Get all hives for the organization
|
|
159
|
+
* Uses snake_case fields (floor_id, room_id) for consistency
|
|
160
|
+
*/
|
|
161
|
+
export const GET_ALL_HIVES = gql `
|
|
162
|
+
query GetAllHives {
|
|
163
|
+
hives {
|
|
164
|
+
data {
|
|
165
|
+
id
|
|
166
|
+
name
|
|
167
|
+
serialNumber
|
|
168
|
+
floor_id
|
|
169
|
+
room_id
|
|
170
|
+
isOnline
|
|
171
|
+
coordinates
|
|
172
|
+
isStreaming
|
|
173
|
+
hiveVersion
|
|
174
|
+
hiveType
|
|
175
|
+
note
|
|
176
|
+
lastHeartbeat
|
|
177
|
+
netPathStability
|
|
178
|
+
installed
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
`;
|
|
183
|
+
/**
|
|
184
|
+
* Lightweight topology without devices
|
|
185
|
+
* Faster when sensor/hive data isn't needed
|
|
186
|
+
*/
|
|
187
|
+
export const GET_TOPOLOGY_NO_DEVICES = gql `
|
|
188
|
+
query GetTopologyNoDevices {
|
|
189
|
+
sites {
|
|
190
|
+
data {
|
|
191
|
+
id
|
|
192
|
+
name
|
|
193
|
+
timezone
|
|
194
|
+
siteNumber
|
|
195
|
+
customID
|
|
196
|
+
org_id
|
|
197
|
+
buildings {
|
|
198
|
+
id
|
|
199
|
+
name
|
|
200
|
+
building_number
|
|
201
|
+
site_id
|
|
202
|
+
customID
|
|
203
|
+
capacity {
|
|
204
|
+
max
|
|
205
|
+
mid
|
|
206
|
+
}
|
|
207
|
+
address {
|
|
208
|
+
lines
|
|
209
|
+
country
|
|
210
|
+
}
|
|
211
|
+
floors {
|
|
212
|
+
id
|
|
213
|
+
name
|
|
214
|
+
floorNumber
|
|
215
|
+
building_id
|
|
216
|
+
timezone
|
|
217
|
+
installation_date
|
|
218
|
+
customID
|
|
219
|
+
capacity {
|
|
220
|
+
max
|
|
221
|
+
mid
|
|
222
|
+
}
|
|
223
|
+
area {
|
|
224
|
+
value
|
|
225
|
+
unit
|
|
226
|
+
}
|
|
227
|
+
rooms {
|
|
228
|
+
id
|
|
229
|
+
name
|
|
230
|
+
floor_id
|
|
231
|
+
customID
|
|
232
|
+
capacity {
|
|
233
|
+
max
|
|
234
|
+
mid
|
|
235
|
+
}
|
|
236
|
+
coordinates
|
|
237
|
+
}
|
|
238
|
+
zones {
|
|
239
|
+
id
|
|
240
|
+
name
|
|
241
|
+
floor_id
|
|
242
|
+
room_id
|
|
243
|
+
customID
|
|
244
|
+
coordinates
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
`;
|
|
252
|
+
//# sourceMappingURL=topology.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC;;;GAGG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;CAYhC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiEnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwBjC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEzC,CAAC"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured API error with status code for proper error translation
|
|
3
|
+
*/
|
|
4
|
+
export declare class ApiError extends Error {
|
|
5
|
+
statusCode: number;
|
|
6
|
+
constructor(statusCode: number, message: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* v3 Reporting API Request Structure
|
|
10
|
+
* Based on butlr-api-container/pkg/reporting/models/request.go
|
|
11
|
+
*/
|
|
12
|
+
export interface ReportingRequest {
|
|
13
|
+
group_by?: {
|
|
14
|
+
order?: string[];
|
|
15
|
+
raw?: boolean;
|
|
16
|
+
};
|
|
17
|
+
window?: {
|
|
18
|
+
every: string;
|
|
19
|
+
function: string;
|
|
20
|
+
offset?: string;
|
|
21
|
+
timezone?: string;
|
|
22
|
+
create_empty?: boolean;
|
|
23
|
+
fill?: {
|
|
24
|
+
use_previous?: boolean;
|
|
25
|
+
value?: number;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
filter: {
|
|
29
|
+
measurements: string[];
|
|
30
|
+
start: string;
|
|
31
|
+
stop?: string;
|
|
32
|
+
spaces?: {
|
|
33
|
+
eq: string[];
|
|
34
|
+
};
|
|
35
|
+
rooms?: {
|
|
36
|
+
eq: string[];
|
|
37
|
+
};
|
|
38
|
+
zones?: {
|
|
39
|
+
eq: string[];
|
|
40
|
+
};
|
|
41
|
+
tags?: {
|
|
42
|
+
eq: string[];
|
|
43
|
+
};
|
|
44
|
+
clients?: {
|
|
45
|
+
eq: string[];
|
|
46
|
+
};
|
|
47
|
+
buildings?: {
|
|
48
|
+
eq: string[];
|
|
49
|
+
};
|
|
50
|
+
value?: {
|
|
51
|
+
gte?: number;
|
|
52
|
+
lte?: number;
|
|
53
|
+
gt?: number;
|
|
54
|
+
lt?: number;
|
|
55
|
+
};
|
|
56
|
+
calibrated?: string;
|
|
57
|
+
time_constraints?: {
|
|
58
|
+
time_ranges?: Array<{
|
|
59
|
+
start: string;
|
|
60
|
+
stop: string;
|
|
61
|
+
}>;
|
|
62
|
+
exclude_days_of_week?: string[];
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
options?: {
|
|
66
|
+
format?: "json" | "csv";
|
|
67
|
+
precision?: "s" | "ms" | "us" | "ns";
|
|
68
|
+
timestamp?: "RFC3339";
|
|
69
|
+
includeCalibrationPoints?: boolean;
|
|
70
|
+
};
|
|
71
|
+
paginate?: {
|
|
72
|
+
page: number;
|
|
73
|
+
limit: number;
|
|
74
|
+
};
|
|
75
|
+
calibrationPoints?: Array<{
|
|
76
|
+
timestamp: string;
|
|
77
|
+
occupancy: number;
|
|
78
|
+
type: "user_provided" | "pir_zero";
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* v3 Reporting API Response Structure
|
|
83
|
+
*/
|
|
84
|
+
export interface ReportingResponse {
|
|
85
|
+
data: Array<{
|
|
86
|
+
field: string;
|
|
87
|
+
measurement: string;
|
|
88
|
+
time: string;
|
|
89
|
+
value: number;
|
|
90
|
+
timezone_offset?: string;
|
|
91
|
+
building_id?: string;
|
|
92
|
+
building_name?: string;
|
|
93
|
+
space_id?: string;
|
|
94
|
+
space_name?: string;
|
|
95
|
+
room_id?: string;
|
|
96
|
+
room_name?: string;
|
|
97
|
+
zone_id?: string;
|
|
98
|
+
hive_id?: string;
|
|
99
|
+
sensor_id?: string;
|
|
100
|
+
mac_address?: string;
|
|
101
|
+
[key: string]: unknown;
|
|
102
|
+
}>;
|
|
103
|
+
page_info?: {
|
|
104
|
+
page: number;
|
|
105
|
+
page_item_count: number;
|
|
106
|
+
total_item_count: number;
|
|
107
|
+
total_pages: number;
|
|
108
|
+
};
|
|
109
|
+
calibrationPoints?: unknown[];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Normalized data point (RFC3339 → ISO-8601)
|
|
113
|
+
*/
|
|
114
|
+
export interface NormalizedDataPoint {
|
|
115
|
+
start: string;
|
|
116
|
+
stop?: string;
|
|
117
|
+
measurement: string;
|
|
118
|
+
value: number;
|
|
119
|
+
asset_id?: string;
|
|
120
|
+
asset_name?: string;
|
|
121
|
+
[key: string]: unknown;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Helper to get filter field name for asset type
|
|
125
|
+
*/
|
|
126
|
+
export declare function getFilterField(assetType: string): string;
|
|
127
|
+
/**
|
|
128
|
+
* Helper to get measurement name for asset type
|
|
129
|
+
*/
|
|
130
|
+
export declare function getMeasurement(assetType: string): string;
|
|
131
|
+
/**
|
|
132
|
+
* Normalize RFC3339 timestamp to ISO-8601
|
|
133
|
+
*/
|
|
134
|
+
export declare function normalizeTimestamp(rfc3339: string): string;
|
|
135
|
+
/**
|
|
136
|
+
* Query v3 Reporting API
|
|
137
|
+
*/
|
|
138
|
+
export declare function queryReporting(requestBody: ReportingRequest): Promise<ReportingResponse>;
|
|
139
|
+
/**
|
|
140
|
+
* Request builder for common occupancy queries
|
|
141
|
+
*/
|
|
142
|
+
export declare class ReportingRequestBuilder {
|
|
143
|
+
private request;
|
|
144
|
+
constructor();
|
|
145
|
+
/**
|
|
146
|
+
* Set asset IDs to query
|
|
147
|
+
*/
|
|
148
|
+
assets(assetType: string, ids: string[]): this;
|
|
149
|
+
/**
|
|
150
|
+
* Set measurements (auto-mapped from asset type if not provided)
|
|
151
|
+
*/
|
|
152
|
+
measurements(measurements: string[]): this;
|
|
153
|
+
/**
|
|
154
|
+
* Auto-set measurement based on asset type
|
|
155
|
+
*/
|
|
156
|
+
measurementForAssetType(assetType: string): this;
|
|
157
|
+
/**
|
|
158
|
+
* Set time range (ISO-8601 or relative like '-24h')
|
|
159
|
+
*/
|
|
160
|
+
timeRange(start: string, stop?: string): this;
|
|
161
|
+
/**
|
|
162
|
+
* Set window aggregation
|
|
163
|
+
*/
|
|
164
|
+
window(every: string, func: "mean" | "max" | "min" | "sum" | "first" | "last" | "median", timezone?: string): this;
|
|
165
|
+
/**
|
|
166
|
+
* Set grouping
|
|
167
|
+
*/
|
|
168
|
+
groupBy(order: string[], raw?: boolean): this;
|
|
169
|
+
/**
|
|
170
|
+
* Set pagination
|
|
171
|
+
*/
|
|
172
|
+
paginate(page: number, limit: number): this;
|
|
173
|
+
/**
|
|
174
|
+
* Set tags filter
|
|
175
|
+
*/
|
|
176
|
+
tags(tags: string[]): this;
|
|
177
|
+
/**
|
|
178
|
+
* Build and return the request
|
|
179
|
+
*/
|
|
180
|
+
build(): ReportingRequest;
|
|
181
|
+
/**
|
|
182
|
+
* Build and execute the query
|
|
183
|
+
*/
|
|
184
|
+
execute(): Promise<ReportingResponse>;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Convenience function: Get current occupancy for assets
|
|
188
|
+
* Implements fallback strategy: presence first, then traffic (matches dashboard behavior)
|
|
189
|
+
*/
|
|
190
|
+
export declare function getCurrentOccupancy(assetType: string, assetIds: string[]): Promise<NormalizedDataPoint[]>;
|
|
191
|
+
//# sourceMappingURL=reporting-client.d.ts.map
|