Esempio n. 1
0
class BarChartDashboardWidget(DashboardWidget):
    def __init__(self, display, page, title, value=0, range_low=0, range_high=100, status=DashboardStatus.Passive):
        super(BarChartDashboardWidget, self).__init__(display, page, status)

        self.width = 150

        self.title = title
        self.value = value

        self.panel = StackPanel(display, page)

        self.lbl_title = TextBlock(display, page, title, is_highlighted=True)
        self.lbl_title.font = display.fonts.list
        self.panel.children.append(self.lbl_title)

        self.chart = BarChart(display, page, value=value, range_low=range_low, range_high=range_high)
        self.chart.width = self.width
        self.chart.height = 15
        self.panel.children.append(self.chart)

    def arrange(self):

        self.lbl_title.text = self.title
        self.chart.value = self.value
        self.panel.arrange()
        self.desired_size = 150 + (self.padding * 2), self.panel.desired_size[1] + (self.padding * 2)

        return self.desired_size

    def render(self):

        # Colorize as needed
        color = self.get_color()
        self.chart.color = color
        self.lbl_title.color = self.get_title_color()

        # Render an outline around the entire control
        rect = Rect(self.pos[0], self.pos[1], self.desired_size[0], self.desired_size[1])

        # Some statuses need custom backgrounds
        if self.status == DashboardStatus.Caution:
            render_rectangle(self.display, self.display.color_scheme.caution_bg, rect, width=0)
        elif self.status == DashboardStatus.Critical:
            render_rectangle(self.display, self.display.color_scheme.critical_bg, rect, width=0)

        # Render the outline
        render_rectangle(self.display, color, rect)

        # Render the base content with some padding
        pos = self.pos[0] + self.padding, self.pos[1] + self.padding
        self.panel.render_at(pos)

        # Assume the width of the outer outline
        return self.set_dimensions_from_rect(rect)
Esempio n. 2
0
class CpuDashboardWidget(DashboardWidget):
    charts = None

    def __init__(self,
                 display,
                 page,
                 title="CPU",
                 values=None,
                 status=DashboardStatus.Passive):
        super(CpuDashboardWidget, self).__init__(display, page, status)

        self.title = title
        self.values = values

        self.panel = StackPanel(display, page)

        self.lbl_title = TextBlock(display, page, title, is_highlighted=True)
        self.lbl_title.font = display.fonts.list
        self.panel.children.append(self.lbl_title)

        self.pnl_charts = StackPanel(display, page, is_horizontal=True)
        self.pnl_charts.padding = 2, 0
        self.panel.children.append(self.pnl_charts)

    def get_percent_status(self, percentage):

        if percentage > 95:
            return DashboardStatus.Critical
        elif percentage > 80:
            return DashboardStatus.Caution
        elif percentage < 0:
            return DashboardStatus.Inactive
        else:
            return DashboardStatus.Passive

    def arrange(self):

        max_value = -1

        if not self.charts and self.values and len(self.values) > 0:
            self.charts = []

            chart_width = (150 - (len(self.values) * 1)) / len(self.values)

            for value in self.values:
                chart = BarChart(self.display, self.page, value=value)
                chart.width = chart_width
                chart.height = 15
                chart.color = self.get_status_color(
                    self.get_percent_status(value))
                self.charts.append(chart)
                self.pnl_charts.children.append(chart)
                max_value = max(value, max_value)

        elif self.charts and self.values and len(self.values) > 0:

            for chart, value in zip(self.charts, self.values):
                chart.value = value
                chart.color = self.get_status_color(
                    self.get_percent_status(value))
                max_value = max(value, max_value)

        self.status = self.get_percent_status(max_value)

        self.lbl_title.text = self.title

        self.panel.arrange()
        self.desired_size = 150 + (
            self.padding * 2), self.panel.desired_size[1] + (self.padding * 2)
        return self.desired_size

    def render(self):

        # Colorize as needed
        color = self.get_color()
        self.lbl_title.color = self.get_title_color()

        # Render an outline around the entire control
        rect = Rect(self.pos[0], self.pos[1], self.desired_size[0],
                    self.desired_size[1])

        # Some statuses need custom backgrounds
        if self.status == DashboardStatus.Caution:
            render_rectangle(self.display,
                             self.display.color_scheme.caution_bg,
                             rect,
                             width=0)
        elif self.status == DashboardStatus.Critical:
            render_rectangle(self.display,
                             self.display.color_scheme.critical_bg,
                             rect,
                             width=0)

        # Render the outline
        render_rectangle(self.display, color, rect)

        # Render the base content with some padding
        pos = self.pos[0] + self.padding, self.pos[1] + self.padding
        self.panel.render_at(pos)

        # Assume the width of the outer outline
        return self.set_dimensions_from_rect(rect)
Esempio n. 3
0
class WeatherForecastDashboardWidget(DashboardWidget):
    """
    A dashboard widget containing weather condition information
    :type display: PiMFD.UI.DisplayManager.DisplayManager
    :type page: PiMFD.Applications.Core.DashboardPages.DashboardPage
    :type title: str The name of the widget
    :type value: str The value used in the widget
    """
    def __init__(self,
                 display,
                 page,
                 title,
                 weather=None,
                 forecast=None,
                 is_forecast=True):
        super(WeatherForecastDashboardWidget,
              self).__init__(display, page, DashboardStatus.Inactive)

        self.title = title
        self.forecast = forecast
        self.weather = weather
        self.is_forecast = is_forecast
        self.minutes_to_clean_frost = None

        self.panel = StackPanel(display, page)

        self.lbl_title = TextBlock(display, page, title, is_highlighted=True)
        self.lbl_title.font = display.fonts.list
        self.panel.children.append(self.lbl_title)

        pnl_value = StackPanel(display, page, is_horizontal=True)
        pnl_value.center_align = True

        self.lbl_condition = TextBlock(display, page, "{}")
        self.lbl_condition.font = display.fonts.weather

        self.lbl_value = TextBlock(display, page, "Offline")
        self.lbl_value.font = display.fonts.list

        pnl_value.children = [self.lbl_value, self.lbl_condition]

        self.panel.children.append(pnl_value)

        self.chart = BoxChart(display, page)
        self.chart.width = 150
        self.chart.range_low = -20
        self.chart.range_high = 120
        self.chart.is_highlighted = False
        self.chart.box_width = 0
        self.chart.ticks = (0, 32, 100)
        self.panel.children.append(self.chart)

        self.lbl_frost = TextBlock(display, page, None)
        self.lbl_frost.font = display.fonts.list
        self.panel.children.append(self.lbl_frost)

    def render(self):

        # Colorize as needed
        color = self.get_color()
        self.lbl_value.color = color
        self.lbl_title.color = self.get_title_color()
        self.lbl_condition.color = color
        self.chart.color = color

        # Render an outline around the entire control
        rect = Rect(self.pos[0], self.pos[1],
                    self.panel.desired_size[0] + (self.padding * 2),
                    self.panel.desired_size[1] + (self.padding * 2))

        # Some statuses need custom backgrounds
        if self.status == DashboardStatus.Caution:
            render_rectangle(self.display,
                             self.display.color_scheme.caution_bg,
                             rect,
                             width=0)
        elif self.status == DashboardStatus.Critical:
            render_rectangle(self.display,
                             self.display.color_scheme.critical_bg,
                             rect,
                             width=0)

        # Render the outline
        render_rectangle(self.display, color, rect)

        # Render the base content with some padding
        pos = self.pos[0] + self.padding, self.pos[1] + self.padding
        self.panel.render_at(pos)

        # Assume the width of the outer outline
        return self.set_dimensions_from_rect(rect)

    def arrange(self):

        self.status = self.get_status()
        self.lbl_title.text = self.title
        if self.forecast and self.weather:
            if not self.is_forecast:
                self.lbl_condition.text_data = get_condition_icon(
                    self.weather.code)
                self.lbl_value.text = u'{}{}'.format(self.weather.temperature,
                                                     self.weather.temp_units)
            else:
                self.lbl_condition.text_data = get_condition_icon(
                    self.forecast.code)
                self.lbl_value.text = u'{}'.format(self.forecast.temp_range)
        else:
            self.lbl_condition.text_data = None
            self.lbl_value.text = 'Offline'

        if self.minutes_to_clean_frost and self.minutes_to_clean_frost > 0.1:
            self.lbl_frost.visible = True
            self.lbl_frost.text = '{} Minutes Frost'.format(
                round(self.minutes_to_clean_frost, 1))
        else:
            self.lbl_frost.visible = False
            self.lbl_frost.text = None

        if self.forecast:

            if not self.is_forecast:
                temp = float(self.weather.temperature)
                if temp >= 0:
                    self.chart.value_low = 0
                    self.chart.value_high = temp
                else:
                    self.chart.value_low = temp
                    self.chart.value_high = 0

            else:
                self.chart.value_low = self.forecast.low
                self.chart.value_high = self.forecast.high

        self.panel.arrange()
        self.desired_size = self.panel.desired_size[0] + (
            self.padding * 2), self.panel.desired_size[1] + (self.padding * 2)
        return self.desired_size

    def get_status(self):

        if not self.weather or not self.forecast:
            return DashboardStatus.Inactive

        temp_status = self.get_temperature_status()
        cond_status = get_condition_status(self.forecast.code)

        if cond_status == DashboardStatus.Critical or temp_status == DashboardStatus.Critical:
            return DashboardStatus.Critical

        if cond_status == DashboardStatus.Caution or temp_status == DashboardStatus.Caution:
            return DashboardStatus.Caution

        return temp_status

    def get_temperature_status(self):

        if not self.weather or not self.forecast:
            return DashboardStatus.Inactive

        # Certain Temperatures should function as alerts
        low = self.forecast.low
        high = self.forecast.high

        # If it's today, we don't care about forecast - go off of current temperature
        if not self.is_forecast:
            low = high = float(self.weather.temperature)

        if low <= 10 or high >= 100:
            return DashboardStatus.Critical
        elif low <= 32 or high >= 90:
            return DashboardStatus.Caution
        else:
            return DashboardStatus.Passive
Esempio n. 4
0
class TextDashboardWidget(DashboardWidget):
    """
    A simple labeled dashboard widget
    :type display: PiMFD.UI.DisplayManager.DisplayManager
    :type page: PiMFD.Applications.Core.DashboardPages.DashboardPage
    :type title: str The name of the widget
    :type value: str The value used in the widget
    """

    def __init__(self, display, page, title, value, status=DashboardStatus.Passive):
        super(TextDashboardWidget, self).__init__(display, page, status)

        self.title = title
        self.value = value
        self.width = 150
        self.value_font = display.fonts.list

        self.panel = StackPanel(display, page)

        self.lbl_title = TextBlock(display, page, title, is_highlighted=True)
        self.lbl_title.font = display.fonts.list
        self.panel.children.append(self.lbl_title)

        self.lbl_value = TextBlock(display, page, value)
        self.lbl_value.font = display.fonts.list
        self.panel.children.append(self.lbl_value)

    def render(self):

        # Colorize as needed
        color = self.get_color()        
        self.lbl_value.color = color
        self.lbl_title.color = self.get_title_color()

        # Render an outline around the entire control
        rect = Rect(self.pos[0], self.pos[1], self.desired_size[0], self.desired_size[1])
        
        # Some statuses need custom backgrounds
        if self.status == DashboardStatus.Caution:
            render_rectangle(self.display, self.display.color_scheme.caution_bg, rect, width=0)
        elif self.status == DashboardStatus.Critical:
            render_rectangle(self.display, self.display.color_scheme.critical_bg, rect, width=0)
            
        # Render the outline
        render_rectangle(self.display, color, rect)

        # Render the base content with some padding
        pos = self.pos[0] + self.padding, self.pos[1] + self.padding
        self.panel.render_at(pos)

        # Assume the width of the outer outline
        return self.set_dimensions_from_rect(rect) 

    def arrange(self):
        self.lbl_title.text = self.title
        self.lbl_value.text = self.value
        self.lbl_value.font = self.value_font

        self.panel.arrange()
        self.desired_size = 150 + (self.padding * 2), self.panel.desired_size[1] + (self.padding * 2)
        return self.desired_size
Esempio n. 5
0
class SpinnerBox(FocusableWidget):
    """
    Represents a segment of text
    """

    label_block = None
    label = None
    value_block = None
    value = None
    panel = None
    items = []

    def __init__(self, display, page, label, value, items=None):

        """
        :type items: list
        """
        if not items:
            items = []

        super(SpinnerBox, self).__init__(display, page)
        self.label = label
        self.value = value
        self.label_block = TextBlock(display, page, label)
        self.value_block = TextBlock(display, page, value)
        self.panel = StackPanel(display, page, is_horizontal=True)
        self.panel.children = [self.label_block, self.value_block]
        self.items = items

    def arrange(self):

        self.label_block.text = self.label
        self.value_block.text = self.value
        self.label_block.is_highlighted = self.is_focused()
        self.value_block.is_highlighted = self.is_focused()

        self.desired_size = self.panel.arrange()

        return super(SpinnerBox, self).arrange()

    def render(self):
        """
        Renders the textblock to the default surface using the current properties of this object
        :rtype : RectType
        """

        return self.set_dimensions_from_rect(self.panel.render_at(self.pos))

    def handle_key(self, key):

        if is_plus_key(key) or is_right_key(key) or is_enter_key(key):
            self.move_next()
            return True

        if is_minus_key(key) or is_left_key(key):
            self.move_previous()
            return True

        return super(SpinnerBox, self).handle_key(key)

    def get_selected_index(self):

        if not self.items or self.value not in self.items:
            return -1

        return self.items.index(self.value)

    def move_next(self):

        if not self.items or len(self.items) <= 0:
            return

        current_index = self.get_selected_index()

        if current_index < 0:
            current_index = 0
        elif current_index >= len(self.items) - 1:
            current_index = 0
        else:
            current_index += 1

        new_value = self.items[current_index]
        if self.value != new_value:
            self.value = new_value
            self.state_changed()

    def move_previous(self):

        if not self.items or len(self.items) <= 0:
            return

        current_index = self.get_selected_index()

        if current_index < 0:
            current_index = len(self.items) - 1
        elif current_index >= len(self.items):
            current_index = 0
        else:
            current_index -= 1

        new_value = self.items[current_index]
        if self.value != new_value:
            self.value = new_value
            self.state_changed()