Skip to content

Commit c69fc66

Browse files
committed
Export state as native metric for state timeline grafana
1 parent 2bb9fda commit c69fc66

3 files changed

Lines changed: 71 additions & 0 deletions

File tree

src/isar/state_machine/state_machine.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
)
1515
from isar.services.utilities.mqtt_utilities import publish_isar_status
1616
from isar.state_machine.state import State, Transition
17+
from isar.state_machine.state_metrics import StateMetricsPublisher
1718
from isar.state_machine.states.going_to_lockdown import GoingToLockdown
1819
from isar.state_machine.states.maintenance import Maintenance
1920
from isar.state_machine.states.unknown_status import UnknownStatus
@@ -71,6 +72,10 @@ def __init__(
7172
[], settings.STATE_TRANSITIONS_LOG_LENGTH
7273
)
7374

75+
self.state_metrics_publisher: StateMetricsPublisher = StateMetricsPublisher(
76+
current_state_provider=lambda: self.current_state.name
77+
)
78+
7479
#################################################################################
7580

7681
def run(self) -> None:
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from typing import Callable, List
2+
3+
from opentelemetry import metrics
4+
from opentelemetry.metrics import CallbackOptions, Meter, Observation
5+
6+
from isar.config.settings import settings
7+
from isar.state_machine.states_enum import STATE_TO_CODE, States
8+
9+
UNKNOWN_STATE_CODE: int = -1
10+
11+
12+
class StateMetricsPublisher:
13+
def __init__(self, current_state_provider: Callable[[], States]) -> None:
14+
self._current_state_provider = current_state_provider
15+
16+
self.meter: Meter = metrics.get_meter("isar.state_machine")
17+
self.meter.create_observable_gauge(
18+
name="isar.state",
19+
callbacks=[self._observe_state],
20+
description="Current state of the ISAR state machine (see STATE_TO_CODE)",
21+
)
22+
23+
def _observe_state(self, _: CallbackOptions) -> List[Observation]:
24+
state: States = self._current_state_provider()
25+
code: int = STATE_TO_CODE.get(state, UNKNOWN_STATE_CODE)
26+
return [
27+
Observation(
28+
value=code,
29+
attributes={
30+
"robot_name": settings.ROBOT_NAME,
31+
"isar_id": settings.ISAR_ID,
32+
},
33+
)
34+
]

src/isar/state_machine/states_enum.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,35 @@ class States(str, Enum):
3333

3434
def __repr__(self) -> str:
3535
return self.value
36+
37+
38+
STATE_TO_CODE: dict["States", int] = {
39+
States.Home: 0,
40+
States.AwaitNextMission: 1,
41+
States.Monitor: 2,
42+
States.ReturningHome: 3,
43+
States.Offline: 4,
44+
States.InterventionNeeded: 5,
45+
States.Maintenance: 6,
46+
States.Paused: 7,
47+
States.Pausing: 8,
48+
States.Resuming: 9,
49+
States.PausingReturnHome: 10,
50+
States.ResumingReturnHome: 11,
51+
States.ReturnHomePaused: 12,
52+
States.Stopping: 13,
53+
States.StoppingUnknownMission: 14,
54+
States.StoppingReturnHome: 15,
55+
States.StoppingPausedMission: 16,
56+
States.StoppingPausedReturnHome: 17,
57+
States.StoppingDueToMaintenance: 18,
58+
States.StoppingGoToLockdown: 19,
59+
States.StoppingGoToRecharge: 20,
60+
States.Recharging: 21,
61+
States.RechargingWithMission: 22,
62+
States.GoingToRecharging: 23,
63+
States.GoingToRechargingWithMission: 24,
64+
States.GoingToLockdown: 25,
65+
States.Lockdown: 26,
66+
States.UnknownStatus: 27,
67+
}

0 commit comments

Comments
 (0)