@oneuptime/common 11.1.2 → 11.2.1

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.
Files changed (155) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/Incident.ts +55 -0
  3. package/Models/DatabaseModels/Index.ts +12 -0
  4. package/Models/DatabaseModels/IoTDevice.ts +690 -0
  5. package/Models/DatabaseModels/IoTFleet.ts +862 -0
  6. package/Models/DatabaseModels/IoTFleetLabelRule.ts +514 -0
  7. package/Models/DatabaseModels/IoTFleetOwnerRule.ts +596 -0
  8. package/Models/DatabaseModels/IoTFleetOwnerTeam.ts +485 -0
  9. package/Models/DatabaseModels/IoTFleetOwnerUser.ts +484 -0
  10. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  11. package/Server/API/IoTDeviceAPI.ts +128 -0
  12. package/Server/API/TelemetryAPI.ts +104 -35
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1782900000000-AddIoTFleetAndDeviceTables.ts +399 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1783000000000-AddIoTFleetActivityJoinTables.ts +97 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1783010000000-MigrationName.ts +979 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  17. package/Server/Services/AlertService.ts +24 -3
  18. package/Server/Services/IncidentService.ts +24 -3
  19. package/Server/Services/IoTDeviceService.ts +356 -0
  20. package/Server/Services/IoTFleetLabelRuleEngineService.ts +198 -0
  21. package/Server/Services/IoTFleetLabelRuleService.ts +14 -0
  22. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +216 -0
  23. package/Server/Services/IoTFleetOwnerRuleService.ts +14 -0
  24. package/Server/Services/IoTFleetOwnerTeamService.ts +10 -0
  25. package/Server/Services/IoTFleetOwnerUserService.ts +10 -0
  26. package/Server/Services/IoTFleetService.ts +376 -0
  27. package/Server/Services/OpenTelemetryIngestService.ts +16 -0
  28. package/Server/Services/StatusPageService.ts +69 -26
  29. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +36 -0
  30. package/Server/Services/TelemetryUsageBillingService.ts +18 -0
  31. package/Server/Services/TraceAggregationService.ts +174 -0
  32. package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +1 -1
  33. package/Server/Utils/Monitor/MonitorAlert.ts +24 -4
  34. package/Server/Utils/Monitor/MonitorClusterContext.ts +26 -2
  35. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +4 -2
  36. package/Server/Utils/Monitor/MonitorIncident.ts +39 -5
  37. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +14 -0
  38. package/Server/Utils/Monitor/SeriesResourceLabels.ts +22 -0
  39. package/Server/Utils/Telemetry/IoTSnapshotScan.ts +408 -0
  40. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +36 -0
  41. package/Types/Icon/IconProp.ts +1 -0
  42. package/Types/Monitor/IotAlertTemplates.ts +593 -0
  43. package/Types/Monitor/IotMetricCatalog.ts +146 -0
  44. package/Types/Monitor/MonitorStep.ts +31 -0
  45. package/Types/Monitor/MonitorStepIoTMonitor.ts +65 -0
  46. package/Types/Monitor/MonitorType.ts +12 -1
  47. package/Types/Permission.ts +230 -0
  48. package/Types/StatusPage/StatusPageSubscriberNotificationEventType.ts +3 -0
  49. package/Types/Telemetry/ServiceType.ts +1 -0
  50. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +5 -5
  51. package/UI/Components/Icon/Icon.tsx +18 -2
  52. package/UI/Components/Page/Page.tsx +1 -2
  53. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  54. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  55. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  56. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  57. package/build/dist/Models/DatabaseModels/Index.js +12 -0
  58. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  59. package/build/dist/Models/DatabaseModels/IoTDevice.js +722 -0
  60. package/build/dist/Models/DatabaseModels/IoTDevice.js.map +1 -0
  61. package/build/dist/Models/DatabaseModels/IoTFleet.js +882 -0
  62. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -0
  63. package/build/dist/Models/DatabaseModels/IoTFleetLabelRule.js +522 -0
  64. package/build/dist/Models/DatabaseModels/IoTFleetLabelRule.js.map +1 -0
  65. package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js +603 -0
  66. package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js.map +1 -0
  67. package/build/dist/Models/DatabaseModels/IoTFleetOwnerTeam.js +503 -0
  68. package/build/dist/Models/DatabaseModels/IoTFleetOwnerTeam.js.map +1 -0
  69. package/build/dist/Models/DatabaseModels/IoTFleetOwnerUser.js +502 -0
  70. package/build/dist/Models/DatabaseModels/IoTFleetOwnerUser.js.map +1 -0
  71. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  72. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  73. package/build/dist/Server/API/IoTDeviceAPI.js +92 -0
  74. package/build/dist/Server/API/IoTDeviceAPI.js.map +1 -0
  75. package/build/dist/Server/API/TelemetryAPI.js +76 -27
  76. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  77. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782900000000-AddIoTFleetAndDeviceTables.js +187 -0
  78. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782900000000-AddIoTFleetAndDeviceTables.js.map +1 -0
  79. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783000000000-AddIoTFleetActivityJoinTables.js +48 -0
  80. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783000000000-AddIoTFleetActivityJoinTables.js.map +1 -0
  81. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783010000000-MigrationName.js +340 -0
  82. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783010000000-MigrationName.js.map +1 -0
  83. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  84. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  85. package/build/dist/Server/Services/AlertService.js +22 -3
  86. package/build/dist/Server/Services/AlertService.js.map +1 -1
  87. package/build/dist/Server/Services/IncidentService.js +22 -3
  88. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  89. package/build/dist/Server/Services/IoTDeviceService.js +249 -0
  90. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -0
  91. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +166 -0
  92. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -0
  93. package/build/dist/Server/Services/IoTFleetLabelRuleService.js +13 -0
  94. package/build/dist/Server/Services/IoTFleetLabelRuleService.js.map +1 -0
  95. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +186 -0
  96. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -0
  97. package/build/dist/Server/Services/IoTFleetOwnerRuleService.js +13 -0
  98. package/build/dist/Server/Services/IoTFleetOwnerRuleService.js.map +1 -0
  99. package/build/dist/Server/Services/IoTFleetOwnerTeamService.js +9 -0
  100. package/build/dist/Server/Services/IoTFleetOwnerTeamService.js.map +1 -0
  101. package/build/dist/Server/Services/IoTFleetOwnerUserService.js +9 -0
  102. package/build/dist/Server/Services/IoTFleetOwnerUserService.js.map +1 -0
  103. package/build/dist/Server/Services/IoTFleetService.js +340 -0
  104. package/build/dist/Server/Services/IoTFleetService.js.map +1 -0
  105. package/build/dist/Server/Services/OpenTelemetryIngestService.js +26 -11
  106. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  107. package/build/dist/Server/Services/StatusPageService.js +57 -23
  108. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  109. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +34 -0
  110. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  111. package/build/dist/Server/Services/TelemetryUsageBillingService.js +13 -0
  112. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  113. package/build/dist/Server/Services/TraceAggregationService.js +136 -0
  114. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  115. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +15 -15
  116. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
  117. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +37 -19
  118. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  119. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +27 -4
  120. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +1 -1
  121. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +4 -2
  122. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  123. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +39 -11
  124. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  125. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +8 -0
  126. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  127. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +17 -0
  128. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  129. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js +300 -0
  130. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js.map +1 -0
  131. package/build/dist/Types/Icon/IconProp.js +1 -0
  132. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  133. package/build/dist/Types/Monitor/IotAlertTemplates.js +467 -0
  134. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -0
  135. package/build/dist/Types/Monitor/IotMetricCatalog.js +108 -0
  136. package/build/dist/Types/Monitor/IotMetricCatalog.js.map +1 -0
  137. package/build/dist/Types/Monitor/MonitorStep.js +23 -0
  138. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  139. package/build/dist/Types/Monitor/MonitorStepIoTMonitor.js +32 -0
  140. package/build/dist/Types/Monitor/MonitorStepIoTMonitor.js.map +1 -0
  141. package/build/dist/Types/Monitor/MonitorType.js +11 -1
  142. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  143. package/build/dist/Types/Permission.js +204 -0
  144. package/build/dist/Types/Permission.js.map +1 -1
  145. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js +2 -0
  146. package/build/dist/Types/StatusPage/StatusPageSubscriberNotificationEventType.js.map +1 -1
  147. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  148. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  149. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +3 -3
  150. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  151. package/build/dist/UI/Components/Icon/Icon.js +12 -2
  152. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  153. package/build/dist/UI/Components/Page/Page.js +1 -2
  154. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  155. package/package.json +1 -1
@@ -0,0 +1,146 @@
1
+ import { IoTResourceScope } from "./MonitorStepIoTMonitor";
2
+ import MetricsAggregationType from "../Metrics/MetricsAggregationType";
3
+
4
+ export type IoTMetricCategory =
5
+ | "Availability"
6
+ | "Power"
7
+ | "Connectivity"
8
+ | "Environment"
9
+ | "System";
10
+
11
+ export interface IoTMetricDefinition {
12
+ id: string;
13
+ friendlyName: string;
14
+ description: string;
15
+ metricName: string;
16
+ category: IoTMetricCategory;
17
+ defaultAggregation: MetricsAggregationType;
18
+ defaultResourceScope: IoTResourceScope;
19
+ unit?: string;
20
+ }
21
+
22
+ /*
23
+ * Metric names follow the OneUptime IoT naming scheme. Each series carries a
24
+ * `device.id` datapoint label identifying the IoT device it belongs to, plus
25
+ * the agent stamps `iot.scope` (fleet | device), `iot.device.type` and
26
+ * `iot.device.kind` as datapoint attributes — `defaultResourceScope` is the
27
+ * `iot.scope` value the metric is usually filtered to (Fleet = spans the whole
28
+ * fleet; don't pre-filter).
29
+ */
30
+ const iotMetricCatalog: Array<IoTMetricDefinition> = [
31
+ // Availability Metrics
32
+ {
33
+ id: "iot-device-up",
34
+ friendlyName: "Device Up",
35
+ description:
36
+ "Whether an IoT device is up (1) or down/offline (0). Reported per device — filter on the device.id label to scope to one device.",
37
+ metricName: "iot_device_up",
38
+ category: "Availability",
39
+ defaultAggregation: MetricsAggregationType.Min,
40
+ defaultResourceScope: IoTResourceScope.Device,
41
+ },
42
+
43
+ // Power Metrics
44
+ {
45
+ id: "iot-battery-percent",
46
+ friendlyName: "Battery Level",
47
+ description:
48
+ "Remaining battery charge of a device as a percentage (0 to 100). Falling levels indicate a device that will soon go offline.",
49
+ metricName: "iot_battery_percent",
50
+ category: "Power",
51
+ defaultAggregation: MetricsAggregationType.Avg,
52
+ defaultResourceScope: IoTResourceScope.Device,
53
+ unit: "%",
54
+ },
55
+
56
+ // Connectivity Metrics
57
+ {
58
+ id: "iot-signal-strength",
59
+ friendlyName: "Signal Strength",
60
+ description:
61
+ "Wireless signal strength of a device in dBm (closer to 0 is stronger; more negative is weaker). Weak signal precedes connectivity loss.",
62
+ metricName: "iot_signal_strength_dbm",
63
+ category: "Connectivity",
64
+ defaultAggregation: MetricsAggregationType.Avg,
65
+ defaultResourceScope: IoTResourceScope.Device,
66
+ unit: "dBm",
67
+ },
68
+
69
+ // Environment Metrics
70
+ {
71
+ id: "iot-temperature",
72
+ friendlyName: "Temperature",
73
+ description:
74
+ "Temperature reported by a device in degrees Celsius. High readings can indicate overheating hardware or an environmental issue.",
75
+ metricName: "iot_temperature_celsius",
76
+ category: "Environment",
77
+ defaultAggregation: MetricsAggregationType.Avg,
78
+ defaultResourceScope: IoTResourceScope.Device,
79
+ unit: "°C",
80
+ },
81
+
82
+ // System Metrics
83
+ {
84
+ id: "iot-cpu-usage",
85
+ friendlyName: "CPU Usage Ratio",
86
+ description:
87
+ "CPU usage of a device as a ratio of available CPU (0 to 1, where 1 = fully used).",
88
+ metricName: "iot_cpu_usage_ratio",
89
+ category: "System",
90
+ defaultAggregation: MetricsAggregationType.Avg,
91
+ defaultResourceScope: IoTResourceScope.Device,
92
+ unit: "ratio",
93
+ },
94
+ {
95
+ id: "iot-memory-usage",
96
+ friendlyName: "Memory Usage",
97
+ description:
98
+ "Memory currently in use by a device, in bytes. Compare against the device's total memory to gauge memory pressure.",
99
+ metricName: "iot_memory_usage_bytes",
100
+ category: "System",
101
+ defaultAggregation: MetricsAggregationType.Avg,
102
+ defaultResourceScope: IoTResourceScope.Device,
103
+ unit: "bytes",
104
+ },
105
+ {
106
+ id: "iot-uptime",
107
+ friendlyName: "Uptime",
108
+ description:
109
+ "How long a device has been running. Drops to zero when the device is restarted or rebooted.",
110
+ metricName: "iot_uptime_seconds",
111
+ category: "System",
112
+ defaultAggregation: MetricsAggregationType.Max,
113
+ defaultResourceScope: IoTResourceScope.Device,
114
+ unit: "s",
115
+ },
116
+ ];
117
+
118
+ export function getAllIoTMetrics(): Array<IoTMetricDefinition> {
119
+ return iotMetricCatalog;
120
+ }
121
+
122
+ export function getIoTMetricsByCategory(
123
+ category: IoTMetricCategory,
124
+ ): Array<IoTMetricDefinition> {
125
+ return iotMetricCatalog.filter((m: IoTMetricDefinition) => {
126
+ return m.category === category;
127
+ });
128
+ }
129
+
130
+ export function getIoTMetricById(id: string): IoTMetricDefinition | undefined {
131
+ return iotMetricCatalog.find((m: IoTMetricDefinition) => {
132
+ return m.id === id;
133
+ });
134
+ }
135
+
136
+ export function getIoTMetricByMetricName(
137
+ metricName: string,
138
+ ): IoTMetricDefinition | undefined {
139
+ return iotMetricCatalog.find((m: IoTMetricDefinition) => {
140
+ return m.metricName === metricName;
141
+ });
142
+ }
143
+
144
+ export function getAllIoTMetricCategories(): Array<IoTMetricCategory> {
145
+ return ["Availability", "Power", "Connectivity", "Environment", "System"];
146
+ }
@@ -65,6 +65,9 @@ import MonitorStepDockerSwarmMonitor, {
65
65
  import MonitorStepCephMonitor, {
66
66
  MonitorStepCephMonitorUtil,
67
67
  } from "./MonitorStepCephMonitor";
68
+ import MonitorStepIoTMonitor, {
69
+ MonitorStepIoTMonitorUtil,
70
+ } from "./MonitorStepIoTMonitor";
68
71
  import Zod, { ZodSchema } from "../../Utils/Schema/Zod";
69
72
 
70
73
  /*
@@ -199,6 +202,9 @@ export interface MonitorStepType {
199
202
 
200
203
  // Ceph monitor
201
204
  cephMonitor?: MonitorStepCephMonitor | undefined;
205
+
206
+ // IoT monitor
207
+ iotMonitor?: MonitorStepIoTMonitor | undefined;
202
208
  }
203
209
 
204
210
  export default class MonitorStep extends DatabaseProperty {
@@ -243,6 +249,7 @@ export default class MonitorStep extends DatabaseProperty {
243
249
  proxmoxMonitor: undefined,
244
250
  dockerSwarmMonitor: undefined,
245
251
  cephMonitor: undefined,
252
+ iotMonitor: undefined,
246
253
  };
247
254
  }
248
255
 
@@ -292,6 +299,7 @@ export default class MonitorStep extends DatabaseProperty {
292
299
  proxmoxMonitor: undefined,
293
300
  dockerSwarmMonitor: undefined,
294
301
  cephMonitor: undefined,
302
+ iotMonitor: undefined,
295
303
  };
296
304
 
297
305
  return monitorStep;
@@ -512,6 +520,11 @@ export default class MonitorStep extends DatabaseProperty {
512
520
  return this;
513
521
  }
514
522
 
523
+ public setIoTMonitor(iotMonitor: MonitorStepIoTMonitor): MonitorStep {
524
+ this.data!.iotMonitor = iotMonitor;
525
+ return this;
526
+ }
527
+
515
528
  public setCustomCode(customCode: string): MonitorStep {
516
529
  this.data!.customCode = customCode;
517
530
  return this;
@@ -553,6 +566,7 @@ export default class MonitorStep extends DatabaseProperty {
553
566
  proxmoxMonitor: undefined,
554
567
  dockerSwarmMonitor: undefined,
555
568
  cephMonitor: undefined,
569
+ iotMonitor: undefined,
556
570
  },
557
571
  };
558
572
  }
@@ -769,6 +783,16 @@ export default class MonitorStep extends DatabaseProperty {
769
783
  }
770
784
  }
771
785
 
786
+ if (monitorType === MonitorType.IoTDevice) {
787
+ if (!value.data.iotMonitor) {
788
+ return "IoT monitor configuration is required";
789
+ }
790
+
791
+ if (!value.data.iotMonitor.fleetIdentifier) {
792
+ return "IoT fleet is required";
793
+ }
794
+ }
795
+
772
796
  return null;
773
797
  }
774
798
 
@@ -869,6 +893,9 @@ export default class MonitorStep extends DatabaseProperty {
869
893
  cephMonitor: this.data.cephMonitor
870
894
  ? MonitorStepCephMonitorUtil.toJSON(this.data.cephMonitor)
871
895
  : undefined,
896
+ iotMonitor: this.data.iotMonitor
897
+ ? MonitorStepIoTMonitorUtil.toJSON(this.data.iotMonitor)
898
+ : undefined,
872
899
  },
873
900
  });
874
901
  }
@@ -1022,6 +1049,9 @@ export default class MonitorStep extends DatabaseProperty {
1022
1049
  cephMonitor: json["cephMonitor"]
1023
1050
  ? (json["cephMonitor"] as JSONObject)
1024
1051
  : undefined,
1052
+ iotMonitor: json["iotMonitor"]
1053
+ ? (json["iotMonitor"] as JSONObject)
1054
+ : undefined,
1025
1055
  }) as any;
1026
1056
 
1027
1057
  return monitorStep;
@@ -1065,6 +1095,7 @@ export default class MonitorStep extends DatabaseProperty {
1065
1095
  proxmoxMonitor: Zod.any().optional(),
1066
1096
  dockerSwarmMonitor: Zod.any().optional(),
1067
1097
  cephMonitor: Zod.any().optional(),
1098
+ iotMonitor: Zod.any().optional(),
1068
1099
  }).openapi({
1069
1100
  type: "object",
1070
1101
  example: {
@@ -0,0 +1,65 @@
1
+ import { JSONObject } from "../JSON";
2
+ import MetricsViewConfig from "../Metrics/MetricsViewConfig";
3
+ import RollingTime from "../RollingTime/RollingTime";
4
+
5
+ /**
6
+ * The kind of IoT resource a metric series belongs to. Enum values are
7
+ * byte-equal to the `iot.scope` datapoint attribute stamped by the IoT
8
+ * agent / gateway, so the monitor worker can map a scope filter to an
9
+ * attribute-equality clause with no translation.
10
+ */
11
+ export enum IoTResourceScope {
12
+ Fleet = "fleet",
13
+ Device = "device",
14
+ }
15
+
16
+ /*
17
+ * IoT datapoint label semantics: device-level data metrics (iot_device_up,
18
+ * iot_battery_percent, iot_signal_strength_dbm, iot_temperature_celsius,
19
+ * iot_cpu_usage_ratio, iot_memory_usage_bytes, iot_uptime_seconds) carry the
20
+ * `device.id` datapoint label and the agent-stamped `iot.scope` /
21
+ * `iot.device.type` attributes. Filters therefore target those keys.
22
+ */
23
+ export interface IoTDeviceFilters {
24
+ /**
25
+ * → equality on the `iot.scope` datapoint attribute (fleet | device).
26
+ */
27
+ scope?: IoTResourceScope | undefined;
28
+ /**
29
+ * → equality on the `device.id` datapoint label.
30
+ */
31
+ deviceId?: string | undefined;
32
+ /**
33
+ * → equality on the `iot.device.type` attribute.
34
+ */
35
+ deviceType?: string | undefined;
36
+ }
37
+
38
+ export default interface MonitorStepIoTMonitor {
39
+ fleetIdentifier: string;
40
+ resourceFilters: IoTDeviceFilters;
41
+ metricViewConfig: MetricsViewConfig;
42
+ rollingTime: RollingTime;
43
+ }
44
+
45
+ export class MonitorStepIoTMonitorUtil {
46
+ public static getDefault(): MonitorStepIoTMonitor {
47
+ return {
48
+ fleetIdentifier: "",
49
+ resourceFilters: {},
50
+ metricViewConfig: {
51
+ queryConfigs: [],
52
+ formulaConfigs: [],
53
+ },
54
+ rollingTime: RollingTime.Past1Minute,
55
+ };
56
+ }
57
+
58
+ public static fromJSON(json: JSONObject): MonitorStepIoTMonitor {
59
+ return json as any as MonitorStepIoTMonitor;
60
+ }
61
+
62
+ public static toJSON(monitor: MonitorStepIoTMonitor): JSONObject {
63
+ return monitor as any as JSONObject;
64
+ }
65
+ }
@@ -13,6 +13,7 @@ enum MonitorType {
13
13
  DockerSwarm = "Docker Swarm",
14
14
  Proxmox = "Proxmox",
15
15
  Ceph = "Ceph",
16
+ IoTDevice = "IoT Device",
16
17
  IP = "IP",
17
18
  IncomingRequest = "Incoming Request",
18
19
  IncomingEmail = "Incoming Email",
@@ -106,6 +107,7 @@ export class MonitorTypeHelper {
106
107
  MonitorType.DockerSwarm,
107
108
  MonitorType.Proxmox,
108
109
  MonitorType.Ceph,
110
+ MonitorType.IoTDevice,
109
111
  ],
110
112
  },
111
113
  {
@@ -145,7 +147,8 @@ export class MonitorTypeHelper {
145
147
  monitorType === MonitorType.Podman ||
146
148
  monitorType === MonitorType.DockerSwarm ||
147
149
  monitorType === MonitorType.Proxmox ||
148
- monitorType === MonitorType.Ceph
150
+ monitorType === MonitorType.Ceph ||
151
+ monitorType === MonitorType.IoTDevice
149
152
  );
150
153
  }
151
154
 
@@ -232,6 +235,13 @@ export class MonitorTypeHelper {
232
235
  "This monitor type lets you monitor Ceph storage clusters — cluster health, monitor quorum, OSD availability, pool capacity, and placement group states.",
233
236
  icon: IconProp.Ceph,
234
237
  },
238
+ {
239
+ monitorType: MonitorType.IoTDevice,
240
+ title: "IoT Device",
241
+ description:
242
+ "This monitor type lets you monitor IoT device fleets — device availability, battery level, connectivity and signal strength, temperature, and system health across your devices and gateways.",
243
+ icon: IconProp.IoT,
244
+ },
235
245
  {
236
246
  monitorType: MonitorType.IP,
237
247
  title: "IP",
@@ -439,6 +449,7 @@ export class MonitorTypeHelper {
439
449
  MonitorType.DockerSwarm,
440
450
  MonitorType.Proxmox,
441
451
  MonitorType.Ceph,
452
+ MonitorType.IoTDevice,
442
453
  ];
443
454
  }
444
455
 
@@ -548,6 +548,12 @@ enum Permission {
548
548
  ReadProxmoxClusterOwnerRule = "ReadProxmoxClusterOwnerRule",
549
549
  ReadDockerSwarmClusterOwnerRule = "ReadDockerSwarmClusterOwnerRule",
550
550
 
551
+ // IoT Fleet Owner Rule Permissions
552
+ CreateIoTFleetOwnerRule = "CreateIoTFleetOwnerRule",
553
+ DeleteIoTFleetOwnerRule = "DeleteIoTFleetOwnerRule",
554
+ EditIoTFleetOwnerRule = "EditIoTFleetOwnerRule",
555
+ ReadIoTFleetOwnerRule = "ReadIoTFleetOwnerRule",
556
+
551
557
  /*
552
558
  * Proxmox Cluster Label Rule Permissions
553
559
  * Docker Swarm Cluster Label Rule Permissions
@@ -561,6 +567,12 @@ enum Permission {
561
567
  ReadProxmoxClusterLabelRule = "ReadProxmoxClusterLabelRule",
562
568
  ReadDockerSwarmClusterLabelRule = "ReadDockerSwarmClusterLabelRule",
563
569
 
570
+ // IoT Fleet Label Rule Permissions
571
+ CreateIoTFleetLabelRule = "CreateIoTFleetLabelRule",
572
+ DeleteIoTFleetLabelRule = "DeleteIoTFleetLabelRule",
573
+ EditIoTFleetLabelRule = "EditIoTFleetLabelRule",
574
+ ReadIoTFleetLabelRule = "ReadIoTFleetLabelRule",
575
+
564
576
  // Ceph Cluster Owner Rule Permissions
565
577
  CreateCephClusterOwnerRule = "CreateCephClusterOwnerRule",
566
578
  DeleteCephClusterOwnerRule = "DeleteCephClusterOwnerRule",
@@ -1183,6 +1195,11 @@ enum Permission {
1183
1195
  ReadProxmoxCluster = "ReadProxmoxCluster",
1184
1196
  ReadDockerSwarmCluster = "ReadDockerSwarmCluster",
1185
1197
 
1198
+ CreateIoTFleet = "CreateIoTFleet",
1199
+ DeleteIoTFleet = "DeleteIoTFleet",
1200
+ EditIoTFleet = "EditIoTFleet",
1201
+ ReadIoTFleet = "ReadIoTFleet",
1202
+
1186
1203
  CreateCephCluster = "CreateCephCluster",
1187
1204
  DeleteCephCluster = "DeleteCephCluster",
1188
1205
  EditCephCluster = "EditCephCluster",
@@ -1197,6 +1214,11 @@ enum Permission {
1197
1214
  ReadProxmoxClusterOwnerTeam = "ReadProxmoxClusterOwnerTeam",
1198
1215
  ReadDockerSwarmClusterOwnerTeam = "ReadDockerSwarmClusterOwnerTeam",
1199
1216
 
1217
+ CreateIoTFleetOwnerTeam = "CreateIoTFleetOwnerTeam",
1218
+ DeleteIoTFleetOwnerTeam = "DeleteIoTFleetOwnerTeam",
1219
+ EditIoTFleetOwnerTeam = "EditIoTFleetOwnerTeam",
1220
+ ReadIoTFleetOwnerTeam = "ReadIoTFleetOwnerTeam",
1221
+
1200
1222
  CreateProxmoxClusterOwnerUser = "CreateProxmoxClusterOwnerUser",
1201
1223
  CreateDockerSwarmClusterOwnerUser = "CreateDockerSwarmClusterOwnerUser",
1202
1224
  DeleteProxmoxClusterOwnerUser = "DeleteProxmoxClusterOwnerUser",
@@ -1206,6 +1228,11 @@ enum Permission {
1206
1228
  ReadProxmoxClusterOwnerUser = "ReadProxmoxClusterOwnerUser",
1207
1229
  ReadDockerSwarmClusterOwnerUser = "ReadDockerSwarmClusterOwnerUser",
1208
1230
 
1231
+ CreateIoTFleetOwnerUser = "CreateIoTFleetOwnerUser",
1232
+ DeleteIoTFleetOwnerUser = "DeleteIoTFleetOwnerUser",
1233
+ EditIoTFleetOwnerUser = "EditIoTFleetOwnerUser",
1234
+ ReadIoTFleetOwnerUser = "ReadIoTFleetOwnerUser",
1235
+
1209
1236
  CreateCephClusterOwnerTeam = "CreateCephClusterOwnerTeam",
1210
1237
  DeleteCephClusterOwnerTeam = "DeleteCephClusterOwnerTeam",
1211
1238
  EditCephClusterOwnerTeam = "EditCephClusterOwnerTeam",
@@ -7576,6 +7603,43 @@ export class PermissionHelper {
7576
7603
  group: PermissionGroup.Telemetry,
7577
7604
  },
7578
7605
 
7606
+ {
7607
+ permission: Permission.CreateIoTFleet,
7608
+ title: "Create IoT Fleet",
7609
+ description: "This permission can create IoT Fleet in this project.",
7610
+ isAssignableToTenant: true,
7611
+ isAccessControlPermission: false,
7612
+ isRolePermission: false,
7613
+ group: PermissionGroup.Telemetry,
7614
+ },
7615
+ {
7616
+ permission: Permission.DeleteIoTFleet,
7617
+ title: "Delete IoT Fleet",
7618
+ description: "This permission can delete IoT Fleet of this project.",
7619
+ isAssignableToTenant: true,
7620
+ isAccessControlPermission: true,
7621
+ isRolePermission: false,
7622
+ group: PermissionGroup.Telemetry,
7623
+ },
7624
+ {
7625
+ permission: Permission.EditIoTFleet,
7626
+ title: "Edit IoT Fleet",
7627
+ description: "This permission can edit IoT Fleet of this project.",
7628
+ isAssignableToTenant: true,
7629
+ isAccessControlPermission: true,
7630
+ isRolePermission: false,
7631
+ group: PermissionGroup.Telemetry,
7632
+ },
7633
+ {
7634
+ permission: Permission.ReadIoTFleet,
7635
+ title: "Read IoT Fleet",
7636
+ description: "This permission can read IoT Fleet of this project.",
7637
+ isAssignableToTenant: true,
7638
+ isAccessControlPermission: true,
7639
+ isRolePermission: false,
7640
+ group: PermissionGroup.Telemetry,
7641
+ },
7642
+
7579
7643
  {
7580
7644
  permission: Permission.CreateCephCluster,
7581
7645
  title: "Create Ceph Cluster",
@@ -8394,6 +8458,47 @@ export class PermissionHelper {
8394
8458
  group: PermissionGroup.Telemetry,
8395
8459
  },
8396
8460
 
8461
+ {
8462
+ permission: Permission.CreateIoTFleetOwnerTeam,
8463
+ title: "Create IoT Fleet Team Owner",
8464
+ description:
8465
+ "This permission can create IoT Fleet Team Owner of this project.",
8466
+ isAssignableToTenant: true,
8467
+ isAccessControlPermission: false,
8468
+ isRolePermission: false,
8469
+ group: PermissionGroup.Telemetry,
8470
+ },
8471
+ {
8472
+ permission: Permission.DeleteIoTFleetOwnerTeam,
8473
+ title: "Delete IoT Fleet Team Owner",
8474
+ description:
8475
+ "This permission can delete IoT Fleet Team Owner of this project.",
8476
+ isAssignableToTenant: true,
8477
+ isAccessControlPermission: false,
8478
+ isRolePermission: false,
8479
+ group: PermissionGroup.Telemetry,
8480
+ },
8481
+ {
8482
+ permission: Permission.EditIoTFleetOwnerTeam,
8483
+ title: "Edit IoT Fleet Team Owner",
8484
+ description:
8485
+ "This permission can edit IoT Fleet Team Owner of this project.",
8486
+ isAssignableToTenant: true,
8487
+ isAccessControlPermission: false,
8488
+ isRolePermission: false,
8489
+ group: PermissionGroup.Telemetry,
8490
+ },
8491
+ {
8492
+ permission: Permission.ReadIoTFleetOwnerTeam,
8493
+ title: "Read IoT Fleet Team Owner",
8494
+ description:
8495
+ "This permission can read IoT Fleet Team Owner of this project.",
8496
+ isAssignableToTenant: true,
8497
+ isAccessControlPermission: false,
8498
+ isRolePermission: false,
8499
+ group: PermissionGroup.Telemetry,
8500
+ },
8501
+
8397
8502
  {
8398
8503
  permission: Permission.CreateProxmoxClusterOwnerUser,
8399
8504
  title: "Create Proxmox Cluster User Owner",
@@ -8475,6 +8580,47 @@ export class PermissionHelper {
8475
8580
  group: PermissionGroup.Telemetry,
8476
8581
  },
8477
8582
 
8583
+ {
8584
+ permission: Permission.CreateIoTFleetOwnerUser,
8585
+ title: "Create IoT Fleet User Owner",
8586
+ description:
8587
+ "This permission can create IoT Fleet User Owner of this project.",
8588
+ isAssignableToTenant: true,
8589
+ isAccessControlPermission: false,
8590
+ isRolePermission: false,
8591
+ group: PermissionGroup.Telemetry,
8592
+ },
8593
+ {
8594
+ permission: Permission.DeleteIoTFleetOwnerUser,
8595
+ title: "Delete IoT Fleet User Owner",
8596
+ description:
8597
+ "This permission can delete IoT Fleet User Owner of this project.",
8598
+ isAssignableToTenant: true,
8599
+ isAccessControlPermission: false,
8600
+ isRolePermission: false,
8601
+ group: PermissionGroup.Telemetry,
8602
+ },
8603
+ {
8604
+ permission: Permission.EditIoTFleetOwnerUser,
8605
+ title: "Edit IoT Fleet User Owner",
8606
+ description:
8607
+ "This permission can edit IoT Fleet User Owner of this project.",
8608
+ isAssignableToTenant: true,
8609
+ isAccessControlPermission: false,
8610
+ isRolePermission: false,
8611
+ group: PermissionGroup.Telemetry,
8612
+ },
8613
+ {
8614
+ permission: Permission.ReadIoTFleetOwnerUser,
8615
+ title: "Read IoT Fleet User Owner",
8616
+ description:
8617
+ "This permission can read IoT Fleet User Owner of this project.",
8618
+ isAssignableToTenant: true,
8619
+ isAccessControlPermission: false,
8620
+ isRolePermission: false,
8621
+ group: PermissionGroup.Telemetry,
8622
+ },
8623
+
8478
8624
  {
8479
8625
  permission: Permission.CreateCephClusterOwnerTeam,
8480
8626
  title: "Create Ceph Cluster Team Owner",
@@ -10779,6 +10925,48 @@ export class PermissionHelper {
10779
10925
  group: PermissionGroup.Telemetry,
10780
10926
  },
10781
10927
 
10928
+ // IoT Fleet Owner Rule Permissions
10929
+ {
10930
+ permission: Permission.CreateIoTFleetOwnerRule,
10931
+ title: "Create IoT Fleet Owner Rule",
10932
+ description:
10933
+ "This permission can create IoT Fleet Owner Rules in this project.",
10934
+ isAssignableToTenant: true,
10935
+ isAccessControlPermission: false,
10936
+ isRolePermission: false,
10937
+ group: PermissionGroup.Telemetry,
10938
+ },
10939
+ {
10940
+ permission: Permission.DeleteIoTFleetOwnerRule,
10941
+ title: "Delete IoT Fleet Owner Rule",
10942
+ description:
10943
+ "This permission can delete IoT Fleet Owner Rules of this project.",
10944
+ isAssignableToTenant: true,
10945
+ isAccessControlPermission: false,
10946
+ isRolePermission: false,
10947
+ group: PermissionGroup.Telemetry,
10948
+ },
10949
+ {
10950
+ permission: Permission.EditIoTFleetOwnerRule,
10951
+ title: "Edit IoT Fleet Owner Rule",
10952
+ description:
10953
+ "This permission can edit IoT Fleet Owner Rules of this project.",
10954
+ isAssignableToTenant: true,
10955
+ isAccessControlPermission: false,
10956
+ isRolePermission: false,
10957
+ group: PermissionGroup.Telemetry,
10958
+ },
10959
+ {
10960
+ permission: Permission.ReadIoTFleetOwnerRule,
10961
+ title: "Read IoT Fleet Owner Rule",
10962
+ description:
10963
+ "This permission can read IoT Fleet Owner Rules of this project.",
10964
+ isAssignableToTenant: true,
10965
+ isAccessControlPermission: false,
10966
+ isRolePermission: false,
10967
+ group: PermissionGroup.Telemetry,
10968
+ },
10969
+
10782
10970
  /*
10783
10971
  * Proxmox Cluster Label Rule Permissions
10784
10972
  * Docker Swarm Cluster Label Rule Permissions
@@ -10864,6 +11052,48 @@ export class PermissionHelper {
10864
11052
  group: PermissionGroup.Telemetry,
10865
11053
  },
10866
11054
 
11055
+ // IoT Fleet Label Rule Permissions
11056
+ {
11057
+ permission: Permission.CreateIoTFleetLabelRule,
11058
+ title: "Create IoT Fleet Label Rule",
11059
+ description:
11060
+ "This permission can create IoT Fleet Label Rules in this project.",
11061
+ isAssignableToTenant: true,
11062
+ isAccessControlPermission: false,
11063
+ isRolePermission: false,
11064
+ group: PermissionGroup.Telemetry,
11065
+ },
11066
+ {
11067
+ permission: Permission.DeleteIoTFleetLabelRule,
11068
+ title: "Delete IoT Fleet Label Rule",
11069
+ description:
11070
+ "This permission can delete IoT Fleet Label Rules of this project.",
11071
+ isAssignableToTenant: true,
11072
+ isAccessControlPermission: false,
11073
+ isRolePermission: false,
11074
+ group: PermissionGroup.Telemetry,
11075
+ },
11076
+ {
11077
+ permission: Permission.EditIoTFleetLabelRule,
11078
+ title: "Edit IoT Fleet Label Rule",
11079
+ description:
11080
+ "This permission can edit IoT Fleet Label Rules of this project.",
11081
+ isAssignableToTenant: true,
11082
+ isAccessControlPermission: false,
11083
+ isRolePermission: false,
11084
+ group: PermissionGroup.Telemetry,
11085
+ },
11086
+ {
11087
+ permission: Permission.ReadIoTFleetLabelRule,
11088
+ title: "Read IoT Fleet Label Rule",
11089
+ description:
11090
+ "This permission can read IoT Fleet Label Rules of this project.",
11091
+ isAssignableToTenant: true,
11092
+ isAccessControlPermission: false,
11093
+ isRolePermission: false,
11094
+ group: PermissionGroup.Telemetry,
11095
+ },
11096
+
10867
11097
  // Ceph Cluster Owner Rule Permissions
10868
11098
  {
10869
11099
  permission: Permission.CreateCephClusterOwnerRule,
@@ -27,6 +27,9 @@ enum StatusPageSubscriberNotificationEventType {
27
27
  SubscriberScheduledMaintenanceCreated = "Subscriber Scheduled Maintenance Created",
28
28
  SubscriberScheduledMaintenanceStateChanged = "Subscriber Scheduled Maintenance State Changed",
29
29
  SubscriberScheduledMaintenanceNoteCreated = "Subscriber Scheduled Maintenance Note Created",
30
+
31
+ // Recurring report events
32
+ SubscriberReport = "Subscriber Report",
30
33
  }
31
34
 
32
35
  export default StatusPageSubscriberNotificationEventType;
@@ -18,6 +18,7 @@ enum ServiceType {
18
18
  ProxmoxCluster = "ProxmoxCluster",
19
19
  CephCluster = "CephCluster",
20
20
  DockerSwarmCluster = "DockerSwarmCluster",
21
+ IoTDevice = "IoTDevice",
21
22
  ServerlessFunction = "ServerlessFunction",
22
23
  CloudResource = "CloudResource",
23
24
  RealUserMonitor = "RealUserMonitor",
@@ -288,7 +288,7 @@ const ChartGroup: FunctionComponent<ComponentProps> = (
288
288
  return (
289
289
  <div
290
290
  key={index}
291
- className={`p-5 rounded-lg border border-gray-200 bg-white shadow-sm ${props.chartCssClass || ""}`}
291
+ className={`p-5 rounded-lg border border-gray-200 bg-white shadow-sm flex flex-col gap-3 ${props.chartCssClass || ""}`}
292
292
  >
293
293
  <div className="flex items-center">
294
294
  <h2
@@ -308,10 +308,10 @@ const ChartGroup: FunctionComponent<ComponentProps> = (
308
308
  {chart.description}
309
309
  </p>
310
310
  )}
311
- {chart.seriesControls ? (
312
- <div className="mt-3">{chart.seriesControls}</div>
313
- ) : null}
314
- {getChartContent(chart, index)}
311
+ {chart.seriesControls ? chart.seriesControls : null}
312
+ <div className="flex-1 flex flex-col min-h-80">
313
+ {getChartContent(chart, index)}
314
+ </div>
315
315
  </div>
316
316
  );
317
317
  })}