Skip to content

Commit

Permalink
Implement a proxy class to manipulate battery time
Browse files Browse the repository at this point in the history
Because:
- Remaining battery time sensors, as supported by the UPS widget, can
  report remaining times in both minutes and seconds, depending on the
  source MIB.
- The UPS widget should be consistently reporting the remaining time in
  minutes.
- We want logic in the code, not in the template.
- The Django template that drives the widget only accepts sequences of
  Sensor objects, so it seem cleanest to use a proxy object to
  manipulate what the template sees.
  • Loading branch information
lunkwill42 committed Mar 17, 2021
1 parent 9a57e98 commit 7f5b9c7
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion python/nav/web/navlets/ups.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from django.db.models import Q
from django.utils.six.moves.urllib.parse import urlparse

from nav.models.manage import Netbox
from nav.models.manage import Netbox, Sensor
from . import Navlet


Expand Down Expand Up @@ -120,3 +120,35 @@ def post(self, request, **kwargs):
"""Save preferences"""
return super(UpsWidget, self).post(
request, form=UpsWidgetForm(request.POST))


class BatteryTimesProxy:
"""Proxies access to Sensor objects that represent remaining battery time.
For consistency, we want the widget to always display remaining time in minutes,
but we need to scale the value for sensors that report the remaining time in
seconds.
"""
def __init__(self, proxied_sensor: Sensor):
self.__proxied = proxied_sensor

def __getattr__(self, name):
return getattr(self.__proxied, name)

@property
def unit_of_measurement(self):
"""Reports unit as minutes for sensors that measure seconds"""
if self.__proxied.unit_of_measurement == Sensor.UNIT_SECONDS:
return Sensor.UNIT_MINUTES
else:
return self.__proxied.unit_of_measurement

def get_metric_name(self):
"""Surrounds the metric name in Graphite scale expressions if conversion from
seconds to minutes is needed for the proxied sensor.
"""
name = self.__proxied.get_metric_name()
if self.__proxied.unit_of_measurement == Sensor.UNIT_SECONDS:
return f"round(scale({name},0.0166),0)"
else:
return name

0 comments on commit 7f5b9c7

Please sign in to comment.