machine_access_control 0.3.0__tar.gz → 0.4.0__tar.gz

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 (17) hide show
  1. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/PKG-INFO +1 -1
  2. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/pyproject.toml +1 -1
  3. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/models/machine.py +53 -26
  4. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/slack_handler.py +24 -24
  5. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/prometheus.py +19 -36
  6. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/LICENSE +0 -0
  7. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/README.rst +0 -0
  8. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/__init__.py +0 -0
  9. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/cli_utils.py +0 -0
  10. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/models/__init__.py +0 -0
  11. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/models/users.py +0 -0
  12. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/neongetter.py +0 -0
  13. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/py.typed +0 -0
  14. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/utils.py +0 -0
  15. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/__init__.py +0 -0
  16. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/api.py +0 -0
  17. {machine_access_control-0.3.0 → machine_access_control-0.4.0}/src/dm_mac/views/machine.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machine_access_control
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Decatur Makers Machine Access Control package
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "machine_access_control"
3
- version = "0.3.0"
3
+ version = "0.4.0"
4
4
  description = "Decatur Makers Machine Access Control package"
5
5
  authors = ["Jason Antman <jason@jasonantman.com>"]
6
6
  license = "MIT"
@@ -60,6 +60,11 @@ CONFIG_SCHEMA: Dict[str, Any] = {
60
60
  "Displays 'Always On' and relay is always "
61
61
  "on unless Oopsed or Locked.",
62
62
  },
63
+ "alias": {
64
+ "type": "string",
65
+ "description": "Optional human-friendly alias for the machine. "
66
+ "Used in Slack messages and logs instead of the machine name.",
67
+ },
63
68
  },
64
69
  "additionalProperties": False,
65
70
  "description": "Unique machine name, alphanumeric _ and - only.",
@@ -77,6 +82,7 @@ class Machine:
77
82
  authorizations_or: List[str],
78
83
  unauthorized_warn_only: bool = False,
79
84
  always_enabled: bool = False,
85
+ alias: Optional[str] = None,
80
86
  ):
81
87
  """Initialize a new MachineState instance."""
82
88
  #: The name of the machine
@@ -88,6 +94,8 @@ class Machine:
88
94
  self.unauthorized_warn_only: bool = unauthorized_warn_only
89
95
  #: Whether machine is always enabled without RFID authentication
90
96
  self.always_enabled: bool = always_enabled
97
+ #: Optional human-friendly alias for the machine
98
+ self.alias: Optional[str] = alias
91
99
  #: state of the machine
92
100
  self.state: "MachineState" = MachineState(self)
93
101
 
@@ -145,6 +153,11 @@ class Machine:
145
153
  return
146
154
  await slack.log_unoops(self, source)
147
155
 
156
+ @property
157
+ def display_name(self) -> str:
158
+ """Return the display name for this machine (alias if present, else name)."""
159
+ return self.alias if self.alias else self.name
160
+
148
161
  @property
149
162
  def as_dict(self) -> Dict[str, Any]:
150
163
  """Return a dict representation of this machine."""
@@ -153,6 +166,7 @@ class Machine:
153
166
  "authorizations_or": self.authorizations_or,
154
167
  "unauthorized_warn_only": self.unauthorized_warn_only,
155
168
  "always_enabled": self.always_enabled,
169
+ "alias": self.alias,
156
170
  }
157
171
 
158
172
 
@@ -163,6 +177,7 @@ class MachinesConfig:
163
177
  """Initialize MachinesConfig."""
164
178
  logger.debug("Initializing MachinesConfig")
165
179
  self.machines_by_name: Dict[str, Machine] = {}
180
+ self.machines_by_alias: Dict[str, Machine] = {}
166
181
  self.machines: List[Machine] = []
167
182
  mdict: Dict[str, Any]
168
183
  mname: str
@@ -170,8 +185,16 @@ class MachinesConfig:
170
185
  mach: Machine = Machine(name=mname, **mdict)
171
186
  self.machines.append(mach)
172
187
  self.machines_by_name[mach.name] = mach
188
+ if mach.alias:
189
+ self.machines_by_alias[mach.alias] = mach
173
190
  self.load_time: float = time()
174
191
 
192
+ def get_machine(self, name_or_alias: str) -> Optional[Machine]:
193
+ """Get a machine by name or alias."""
194
+ return self.machines_by_name.get(name_or_alias) or self.machines_by_alias.get(
195
+ name_or_alias
196
+ )
197
+
175
198
  def _load_and_validate_config(self) -> Dict[str, Dict[str, Any]]:
176
199
  """Load and validate the config file."""
177
200
  config: Dict[str, Dict[str, Any]] = cast(
@@ -307,7 +330,8 @@ class MachineState:
307
330
  For always-enabled machines, restores the always-on state.
308
331
  """
309
332
  logging.getLogger("AUTH").warning(
310
- "Machine %s rebooted; resetting relay and RFID state", self.machine.name
333
+ "Machine %s rebooted; resetting relay and RFID state",
334
+ self.machine.display_name,
311
335
  )
312
336
  # locking handled in update()
313
337
  self.current_user = None
@@ -327,12 +351,12 @@ class MachineState:
327
351
  if not slack:
328
352
  # Slack integration is not enabled
329
353
  return
330
- await slack.admin_log(f"Machine {self.machine.name} has rebooted.")
354
+ await slack.admin_log(f"Machine {self.machine.display_name} has rebooted.")
331
355
 
332
356
  def lockout(self) -> None:
333
357
  """Lock-out the machine."""
334
358
  logging.getLogger("OOPS").warning(
335
- "Machine %s was locked out for maintenance.", self.machine.name
359
+ "Machine %s was locked out for maintenance.", self.machine.display_name
336
360
  )
337
361
  with self._lock:
338
362
  self.is_locked_out = True
@@ -345,7 +369,8 @@ class MachineState:
345
369
  def unlock(self) -> None:
346
370
  """Un-lock-out the machine."""
347
371
  logging.getLogger("OOPS").warning(
348
- "Machine %s was removed from maintenance lock-out.", self.machine.name
372
+ "Machine %s was removed from maintenance lock-out.",
373
+ self.machine.display_name,
349
374
  )
350
375
  with self._lock:
351
376
  self.is_locked_out = False
@@ -364,7 +389,9 @@ class MachineState:
364
389
 
365
390
  def oops(self, do_locking: bool = True) -> None:
366
391
  """Oops the machine."""
367
- logging.getLogger("OOPS").warning("Machine %s was Oopsed.", self.machine.name)
392
+ logging.getLogger("OOPS").warning(
393
+ "Machine %s was Oopsed.", self.machine.display_name
394
+ )
368
395
  locker = self._lock if do_locking else nullcontext()
369
396
  with locker:
370
397
  self.is_oopsed = True
@@ -377,7 +404,7 @@ class MachineState:
377
404
  def unoops(self, do_locking: bool = True) -> None:
378
405
  """Un-oops the machine."""
379
406
  logging.getLogger("OOPS").warning(
380
- "Machine %s was un-Oopsed.", self.machine.name
407
+ "Machine %s was un-Oopsed.", self.machine.display_name
381
408
  )
382
409
  locker = self._lock if do_locking else nullcontext()
383
410
  with locker:
@@ -465,7 +492,7 @@ class MachineState:
465
492
  ustr = f" Current user is: {user.full_name}."
466
493
  uname = user.full_name
467
494
  logging.getLogger("OOPS").warning(
468
- "Machine %s was Oopsed.%s", self.machine.name, ustr
495
+ "Machine %s was Oopsed.%s", self.machine.display_name, ustr
469
496
  )
470
497
  # locking handled in update()
471
498
  self.oops(do_locking=False)
@@ -485,12 +512,12 @@ class MachineState:
485
512
  """Handle RFID card removed."""
486
513
  logging.getLogger("AUTH").info(
487
514
  "RFID logout on %s by %s; session duration %d seconds",
488
- self.machine.name,
515
+ self.machine.display_name,
489
516
  self.current_user.full_name if self.current_user else self.rfid_value,
490
517
  time() - cast(float, self.rfid_present_since),
491
518
  )
492
519
  log_str: str = (
493
- f"RFID logout on {self.machine.name} by "
520
+ f"RFID logout on {self.machine.display_name} by "
494
521
  + (self.current_user.full_name if self.current_user else "unknown")
495
522
  + "; session duration "
496
523
  + naturaldelta(time() - cast(float, self.rfid_present_since))
@@ -521,13 +548,13 @@ class MachineState:
521
548
  if not user:
522
549
  logging.getLogger("AUTH").warning(
523
550
  "RFID login attempt on %s by unknown fob %s",
524
- self.machine.name,
551
+ self.machine.display_name,
525
552
  rfid_value,
526
553
  )
527
554
  if self.is_oopsed or self.is_locked_out:
528
555
  if slack:
529
556
  await slack.admin_log(
530
- f"RFID login attempt on {self.machine.name} "
557
+ f"RFID login attempt on {self.machine.display_name} "
531
558
  "by unknown fob when oopsed or locked out."
532
559
  )
533
560
  return
@@ -536,7 +563,7 @@ class MachineState:
536
563
  self.status_led_brightness = self.STATUS_LED_BRIGHTNESS
537
564
  if slack:
538
565
  await slack.admin_log(
539
- f"RFID login attempt on {self.machine.name} by unknown fob"
566
+ f"RFID login attempt on {self.machine.display_name} by unknown fob"
540
567
  )
541
568
  return
542
569
  # ok, we have a known user
@@ -544,26 +571,26 @@ class MachineState:
544
571
  if self.is_oopsed:
545
572
  logging.getLogger("AUTH").warning(
546
573
  "RFID login attempt while oopsed on %s by %s",
547
- self.machine.name,
574
+ self.machine.display_name,
548
575
  logname,
549
576
  )
550
577
  # don't change anything
551
578
  if slack:
552
579
  await slack.admin_log(
553
- f"RFID login attempt on {self.machine.name} by "
580
+ f"RFID login attempt on {self.machine.display_name} by "
554
581
  f"{user.full_name} when oopsed."
555
582
  )
556
583
  return
557
584
  if self.is_locked_out:
558
585
  logging.getLogger("AUTH").warning(
559
586
  "RFID login attempt while locked out on %s by %s",
560
- self.machine.name,
587
+ self.machine.display_name,
561
588
  logname,
562
589
  )
563
590
  # don't change anything
564
591
  if slack:
565
592
  await slack.admin_log(
566
- f"RFID login attempt on {self.machine.name} by "
593
+ f"RFID login attempt on {self.machine.display_name} by "
567
594
  f"{user.full_name} when machine locked-out."
568
595
  )
569
596
  return
@@ -572,7 +599,7 @@ class MachineState:
572
599
  "User %s (%s) authorized for %s; session start",
573
600
  user.full_name,
574
601
  user.account_id,
575
- self.machine.name,
602
+ self.machine.display_name,
576
603
  )
577
604
  self.current_user = user
578
605
  self.relay_desired_state = True
@@ -581,7 +608,7 @@ class MachineState:
581
608
  self.status_led_brightness = self.STATUS_LED_BRIGHTNESS
582
609
  if slack:
583
610
  await slack.admin_log(
584
- f"RFID login on {self.machine.name} by authorized user "
611
+ f"RFID login on {self.machine.display_name} by authorized user "
585
612
  f"{user.full_name}"
586
613
  )
587
614
  else:
@@ -589,7 +616,7 @@ class MachineState:
589
616
  "User %s (%s) UNAUTHORIZED for %s",
590
617
  user.full_name,
591
618
  user.account_id,
592
- self.machine.name,
619
+ self.machine.display_name,
593
620
  )
594
621
  self.relay_desired_state = False
595
622
  self.display_text = "Unauthorized"
@@ -597,7 +624,7 @@ class MachineState:
597
624
  self.status_led_brightness = self.STATUS_LED_BRIGHTNESS
598
625
  if slack:
599
626
  await slack.admin_log(
600
- f"rejected RFID login on {self.machine.name} by "
627
+ f"rejected RFID login on {self.machine.display_name} by "
601
628
  f"UNAUTHORIZED user {user.full_name}"
602
629
  )
603
630
 
@@ -614,7 +641,7 @@ class MachineState:
614
641
  # RFID removed
615
642
  logging.getLogger("AUTH").info(
616
643
  "RFID removed on always-enabled machine %s (was %s); session duration %d seconds",
617
- self.machine.name,
644
+ self.machine.display_name,
618
645
  self.current_user.full_name if self.current_user else self.rfid_value,
619
646
  (
620
647
  time() - cast(float, self.rfid_present_since)
@@ -635,14 +662,14 @@ class MachineState:
635
662
  self.current_user = user
636
663
  logging.getLogger("AUTH").info(
637
664
  "RFID inserted on always-enabled machine %s by %s (%s)",
638
- self.machine.name,
665
+ self.machine.display_name,
639
666
  user.full_name,
640
667
  rfid_value,
641
668
  )
642
669
  else:
643
670
  logging.getLogger("AUTH").warning(
644
671
  "RFID inserted on always-enabled machine %s by unknown fob %s",
645
- self.machine.name,
672
+ self.machine.display_name,
646
673
  rfid_value,
647
674
  )
648
675
  # State remains always-on (relay/display/LED not changed)
@@ -657,7 +684,7 @@ class MachineState:
657
684
  "User %s (%s) authorized for %s based on %s",
658
685
  user.full_name,
659
686
  user.account_id,
660
- self.machine.name,
687
+ self.machine.display_name,
661
688
  auth,
662
689
  )
663
690
  return True
@@ -667,12 +694,12 @@ class MachineState:
667
694
  "unauthorized_warn_only==True",
668
695
  user.full_name,
669
696
  user.account_id,
670
- self.machine.name,
697
+ self.machine.display_name,
671
698
  )
672
699
  if slack:
673
700
  await slack.admin_log(
674
701
  f"WARNING - Authorizing user {user.full_name} for "
675
- f"{self.machine.name} based on unauthorized_warn_only "
702
+ f"{self.machine.display_name} based on unauthorized_warn_only "
676
703
  "setting for machine. User is NOT authorized for this "
677
704
  "machine."
678
705
  )
@@ -160,11 +160,11 @@ class SlackHandler:
160
160
  msg.channel_id,
161
161
  )
162
162
  return None
163
- if msg.command[0] == "oops" and len(msg.command) == 2:
163
+ if msg.command[0] == "oops" and len(msg.command) >= 2:
164
164
  return await self.oops(msg, say)
165
- elif msg.command[0] == "lock" and len(msg.command) == 2:
165
+ elif msg.command[0] == "lock" and len(msg.command) >= 2:
166
166
  return await self.lock(msg, say)
167
- elif msg.command[0] == "clear" and len(msg.command) == 2:
167
+ elif msg.command[0] == "clear" and len(msg.command) >= 2:
168
168
  return await self.clear(msg, say)
169
169
  await say(self.HELP_RESPONSE)
170
170
 
@@ -175,7 +175,7 @@ class SlackHandler:
175
175
  mname: str
176
176
  mach: Machine
177
177
  for mname, mach in sorted(mconf.machines_by_name.items()):
178
- resp += mname + ": "
178
+ resp += mach.display_name + ": "
179
179
  if mach.state.is_oopsed or mach.state.is_locked_out:
180
180
  if mach.state.is_oopsed:
181
181
  resp += "Oopsed "
@@ -199,44 +199,44 @@ class SlackHandler:
199
199
 
200
200
  async def oops(self, msg: Message, say: AsyncSay) -> None:
201
201
  """Set oops status on a machine."""
202
- mname: str = msg.command[1]
202
+ mname: str = " ".join(msg.command[1:])
203
203
  mconf: MachinesConfig = self.quart.config["MACHINES"]
204
- mach: Optional[Machine] = mconf.machines_by_name.get(mname)
204
+ mach: Optional[Machine] = mconf.get_machine(mname)
205
205
  if not mach:
206
206
  await say(
207
- f"Invalid machine name '{mname}'. Use status command to "
207
+ f"Invalid machine name or alias '{mname}'. Use status command to "
208
208
  f"list all machines."
209
209
  )
210
210
  return
211
211
  if mach.state.is_oopsed:
212
- await say(f"Machine {mname} is already oopsed.")
212
+ await say(f"Machine {mach.display_name} is already oopsed.")
213
213
  return
214
214
  await mach.oops(slack=self)
215
215
 
216
216
  async def lock(self, msg: Message, say: AsyncSay) -> None:
217
217
  """Set lock status on a machine."""
218
- mname: str = msg.command[1]
218
+ mname: str = " ".join(msg.command[1:])
219
219
  mconf: MachinesConfig = self.quart.config["MACHINES"]
220
- mach: Optional[Machine] = mconf.machines_by_name.get(mname)
220
+ mach: Optional[Machine] = mconf.get_machine(mname)
221
221
  if not mach:
222
222
  await say(
223
- f"Invalid machine name '{mname}'. Use status command to "
223
+ f"Invalid machine name or alias '{mname}'. Use status command to "
224
224
  f"list all machines."
225
225
  )
226
226
  return
227
227
  if mach.state.is_locked_out:
228
- await say(f"Machine {mname} is already locked-out.")
228
+ await say(f"Machine {mach.display_name} is already locked-out.")
229
229
  return
230
230
  await mach.lockout(slack=self)
231
231
 
232
232
  async def clear(self, msg: Message, say: AsyncSay) -> None:
233
233
  """Clear oops and lock status on a machine."""
234
- mname: str = msg.command[1]
234
+ mname: str = " ".join(msg.command[1:])
235
235
  mconf: MachinesConfig = self.quart.config["MACHINES"]
236
- mach: Optional[Machine] = mconf.machines_by_name.get(mname)
236
+ mach: Optional[Machine] = mconf.get_machine(mname)
237
237
  if not mach:
238
238
  await say(
239
- f"Invalid machine name '{mname}'. Use status command to "
239
+ f"Invalid machine name or alias '{mname}'. Use status command to "
240
240
  f"list all machines."
241
241
  )
242
242
  return
@@ -248,7 +248,7 @@ class SlackHandler:
248
248
  await mach.unlock(slack=self)
249
249
  acted = True
250
250
  if not acted:
251
- await say(f"Machine {mname} is not oopsed or locked-out.")
251
+ await say(f"Machine {mach.display_name} is not oopsed or locked-out.")
252
252
 
253
253
  async def log_unoops(self, machine: Machine, source: str) -> None:
254
254
  """
@@ -262,13 +262,13 @@ class SlackHandler:
262
262
  create_task(
263
263
  self.app.client.chat_postMessage(
264
264
  channel=self.control_channel_id,
265
- text=f"Machine {machine.name} un-oopsed via {source}.",
265
+ text=f"Machine {machine.display_name} un-oopsed via {source}.",
266
266
  )
267
267
  )
268
268
  create_task(
269
269
  self.app.client.chat_postMessage(
270
270
  channel=self.oops_channel_id,
271
- text=f"Machine {machine.name} oops has been cleared.",
271
+ text=f"Machine {machine.display_name} oops has been cleared.",
272
272
  )
273
273
  )
274
274
 
@@ -286,13 +286,13 @@ class SlackHandler:
286
286
  create_task(
287
287
  self.app.client.chat_postMessage(
288
288
  channel=self.control_channel_id,
289
- text=f"Machine {machine.name} oopsed via {source} by {user_name}.",
289
+ text=f"Machine {machine.display_name} oopsed via {source} by {user_name}.",
290
290
  )
291
291
  )
292
292
  create_task(
293
293
  self.app.client.chat_postMessage(
294
294
  channel=self.oops_channel_id,
295
- text=f"Machine {machine.name} has been Oops'ed!",
295
+ text=f"Machine {machine.display_name} has been Oops'ed!",
296
296
  )
297
297
  )
298
298
 
@@ -308,13 +308,13 @@ class SlackHandler:
308
308
  create_task(
309
309
  self.app.client.chat_postMessage(
310
310
  channel=self.control_channel_id,
311
- text=f"Machine {machine.name} locked-out cleared via {source}.",
311
+ text=f"Machine {machine.display_name} locked-out cleared via {source}.",
312
312
  )
313
313
  )
314
314
  create_task(
315
315
  self.app.client.chat_postMessage(
316
316
  channel=self.oops_channel_id,
317
- text=f"Machine {machine.name} is no longer locked-out for "
317
+ text=f"Machine {machine.display_name} is no longer locked-out for "
318
318
  f"maintenance.",
319
319
  )
320
320
  )
@@ -331,13 +331,13 @@ class SlackHandler:
331
331
  create_task(
332
332
  self.app.client.chat_postMessage(
333
333
  channel=self.control_channel_id,
334
- text=f"Machine {machine.name} locked-out via {source}.",
334
+ text=f"Machine {machine.display_name} locked-out via {source}.",
335
335
  )
336
336
  )
337
337
  create_task(
338
338
  self.app.client.chat_postMessage(
339
339
  channel=self.oops_channel_id,
340
- text=f"Machine {machine.name} is locked-out for maintenance.",
340
+ text=f"Machine {machine.display_name} is locked-out for maintenance.",
341
341
  )
342
342
  )
343
343
 
@@ -134,52 +134,35 @@ class PromCustomCollector:
134
134
  )
135
135
  m: Machine
136
136
  for m in mconf.machines:
137
- relay_state.add_metric(
138
- {"machine_name": m.name}, 1 if m.state.relay_desired_state else 0
139
- )
140
- oops_state.add_metric(
141
- {"machine_name": m.name}, 1 if m.state.is_oopsed else 0
142
- )
143
- lockout_state.add_metric(
144
- {"machine_name": m.name}, 1 if m.state.is_locked_out else 0
145
- )
146
- unauth_state.add_metric(
147
- {"machine_name": m.name}, 1 if m.unauthorized_warn_only else 0
148
- )
149
- m_checkin.add_metric({"machine_name": m.name}, m.state.last_checkin or 0)
150
- m_update.add_metric({"machine_name": m.name}, m.state.last_update or 0)
151
- m_rfid_present.add_metric(
152
- {"machine_name": m.name}, 1 if m.state.rfid_value else 0
153
- )
154
- m_rfid_present_since.add_metric(
155
- {"machine_name": m.name}, m.state.rfid_present_since or 0
156
- )
157
- current_amps.add_metric({"machine_name": m.name}, m.state.current_amps)
158
- m_user.add_metric(
159
- {"machine_name": m.name}, 1 if m.state.current_user else 0
160
- )
161
- uptime.add_metric({"machine_name": m.name}, m.state.uptime)
162
- wifi_db.add_metric({"machine_name": m.name}, m.state.wifi_signal_db or 0)
163
- wifi_percent.add_metric(
164
- {"machine_name": m.name}, m.state.wifi_signal_percent or 0
165
- )
166
- temp_c.add_metric(
167
- {"machine_name": m.name}, m.state.internal_temperature_c or 0
168
- )
137
+ labels = {"machine_name": m.name, "display_name": m.display_name}
138
+ relay_state.add_metric(labels, 1 if m.state.relay_desired_state else 0)
139
+ oops_state.add_metric(labels, 1 if m.state.is_oopsed else 0)
140
+ lockout_state.add_metric(labels, 1 if m.state.is_locked_out else 0)
141
+ unauth_state.add_metric(labels, 1 if m.unauthorized_warn_only else 0)
142
+ m_checkin.add_metric(labels, m.state.last_checkin or 0)
143
+ m_update.add_metric(labels, m.state.last_update or 0)
144
+ m_rfid_present.add_metric(labels, 1 if m.state.rfid_value else 0)
145
+ m_rfid_present_since.add_metric(labels, m.state.rfid_present_since or 0)
146
+ current_amps.add_metric(labels, m.state.current_amps)
147
+ m_user.add_metric(labels, 1 if m.state.current_user else 0)
148
+ uptime.add_metric(labels, m.state.uptime)
149
+ wifi_db.add_metric(labels, m.state.wifi_signal_db or 0)
150
+ wifi_percent.add_metric(labels, m.state.wifi_signal_percent or 0)
151
+ temp_c.add_metric(labels, m.state.internal_temperature_c or 0)
169
152
  led.add_metric(
170
- {"machine_name": m.name, "led_attribute": "red"},
153
+ {**labels, "led_attribute": "red"},
171
154
  m.state.status_led_rgb[0],
172
155
  )
173
156
  led.add_metric(
174
- {"machine_name": m.name, "led_attribute": "green"},
157
+ {**labels, "led_attribute": "green"},
175
158
  m.state.status_led_rgb[1],
176
159
  )
177
160
  led.add_metric(
178
- {"machine_name": m.name, "led_attribute": "blue"},
161
+ {**labels, "led_attribute": "blue"},
179
162
  m.state.status_led_rgb[2],
180
163
  )
181
164
  led.add_metric(
182
- {"machine_name": m.name, "led_attribute": "brightness"},
165
+ {**labels, "led_attribute": "brightness"},
183
166
  m.state.status_led_brightness,
184
167
  )
185
168
  yield mconf_load