I'm doing my very best, man

This commit is contained in:
XANTRONIX Development 2024-01-04 18:18:42 -05:00
parent 8459129b49
commit 7fdf256448
3 changed files with 101 additions and 61 deletions

View file

@ -11,6 +11,7 @@ from hexagram.speedo import Speedo
from hexagram.tacho import Tacho from hexagram.tacho import Tacho
from hexagram.fuel import FuelGauge from hexagram.fuel import FuelGauge
from hexagram.thermo import Thermometer from hexagram.thermo import Thermometer
from hexagram.icons import StatusIconBox
class ShiftIndicator(Gauge): class ShiftIndicator(Gauge):
__slots__ = 'x', 'y', 'rpm_min', 'rpm_redline', 'rpm_max', __slots__ = 'x', 'y', 'rpm_min', 'rpm_redline', 'rpm_max',
@ -114,7 +115,7 @@ class Clock(TextGauge):
class Cluster(): class Cluster():
__slots__ = 'gauges', 'speedo', 'fuel', 'tacho', 'thermo', 'odo', \ __slots__ = 'gauges', 'speedo', 'fuel', 'tacho', 'thermo', 'odo', \
'ambient', 'clock', 'shift_indicator', 'ambient', 'clock', 'shift_indicator', 'status',
WIDTH = 1280 WIDTH = 1280
HEIGHT = 480 HEIGHT = 480
@ -153,6 +154,10 @@ class Cluster():
rpm_redline, rpm_redline,
rpm_max) rpm_max)
self.status = StatusIconBox(478, 276,
StatusIconBox.ICON_WIDTH * 10,
StatusIconBox.ICON_HEIGHT * 2)
self.gauges.append(self.speedo) self.gauges.append(self.speedo)
self.gauges.append(self.fuel) self.gauges.append(self.fuel)
self.gauges.append(self.tacho) self.gauges.append(self.tacho)
@ -161,6 +166,7 @@ class Cluster():
self.gauges.append(self.ambient) self.gauges.append(self.ambient)
self.gauges.append(self.clock) self.gauges.append(self.clock)
self.gauges.append(self.shift_indicator) self.gauges.append(self.shift_indicator)
self.gauges.append(self.status)
def draw_bg(self, cr: cairo.Context): def draw_bg(self, cr: cairo.Context):
cr.set_source_rgb(0.1, 0.1, 0.1) cr.set_source_rgb(0.1, 0.1, 0.1)

View file

@ -1,57 +1,22 @@
import os import os
import cairo import cairo
from typing import Optional
from hexagram.gauge import Gauge
from hexagram.status import VehicleStatus from hexagram.status import VehicleStatus
from hexagram.svg import render_to_image from hexagram.svg import render_to_image
class ISO7000Icon(): class ISO7000Icon():
__slots__ = 'status', 'name', 'color', __slots__ = 'status', 'name', 'width', 'height', 'color', 'surface',
def __init__(self, status: VehicleStatus, name: str, color: str):
self.status = status
self.name = name
self.color = color
class ISO7000():
__slots__ = 'icons', 'width', 'height',
__dirs__ = ('./icons', __dirs__ = ('./icons',
'/usr/local/share/hexagram/icons' '/usr/local/share/hexagram/icons'
'/usr/share/hexagram/icons') '/usr/share/hexagram/icons')
__icons__ = (
(VehicleStatus.ABS_FAULT, 'abs', '#fa0'),
(VehicleStatus.AIRBAG_FAULT, 'airbag', '#fa0'),
(VehicleStatus.BATTERY_FAULT, 'beams-fog', '#f00'),
(VehicleStatus.BEAMS_FOG, 'beams-fog', '#0f0'),
(VehicleStatus.BEAMS_HIGH, 'beams-high', '#00f'),
(VehicleStatus.BEAMS_LOW, 'beams-low', '#0f0'),
(VehicleStatus.BEAMS_PARKING, 'beams-parking', '#ff0'),
(VehicleStatus.BELT, 'belt', '#f00'),
(VehicleStatus.CAUTION, 'caution', '#fa0'),
(VehicleStatus.COLD, 'cold', '#eef'),
(VehicleStatus.COLLISION, 'coolant', '#f00'),
(VehicleStatus.COOLANT_LOW, 'coolant', '#fa0'),
(VehicleStatus.COOLANT_OVERHEAT, 'coolant', '#f00'),
(VehicleStatus.CRUISE, 'cruise', '#0f0'),
(VehicleStatus.FUEL_LOW, 'fuel', '#fa0'),
(VehicleStatus.LANEKEEP_OFF, 'lane-departure', '#fa0'),
(VehicleStatus.ENGINE_FAULT, 'mil', '#fa0'),
(VehicleStatus.OIL_LOW, 'oil', '#fa0'),
(VehicleStatus.OIL_OVERHEAT, 'oil', '#f00'),
(VehicleStatus.PARKING_BRAKE_ON, 'parking', '#fa0'),
(VehicleStatus.PARKING_BRAKE_FAULT, 'parking', '#f00'),
(VehicleStatus.STABILITY_OFF, 'stability', '#fa0'),
(VehicleStatus.TPMS_WARNING, 'tpms', '#f00'),
(VehicleStatus.TRACTION_OFF, 'traction', '#fa0'),
(VehicleStatus.TRACTION_FAULT, 'traction', '#f00'),
(VehicleStatus.WARNING, 'warning', '#f00'),
(VehicleStatus.WIPER_WASHER_LOW, 'wiper-washer', '#fa0'),
)
@staticmethod @staticmethod
def _locate(name: str): def _locate(name: str):
for dir in ISO7000.__dirs__: for dir in ISO7000Icon.__dirs__:
path = "%s/%s.svg" % (dir, name) path = "%s/%s.svg" % (dir, name)
if os.path.exists(path): if os.path.exists(path):
@ -59,34 +24,103 @@ class ISO7000():
raise FileNotFoundError(name + '.svg') raise FileNotFoundError(name + '.svg')
def __init__(self, width: float, height: float): def __init__(self, status: VehicleStatus, name: str, width: float, height: float, color: str):
self.icons = dict() self.status = status
self.name = name
self.width = width self.width = width
self.height = height self.height = height
self.color = color
for item in self.__icons__: style = 'rect,path,circle{stroke:%(s)s;fill:%(s)s}' % {'s': color}
icon = ISO7000Icon(*item) path = ISO7000Icon._locate(name)
style = 'rect,path,circle{stroke:%(s)s;fill:%(s)s}' % {'s': icon.color}
path = ISO7000._locate(icon.name)
self.icons[icon.status.value] = render_to_image(path, width, height, style) self.surface = render_to_image(path, width, height, style)
def __del__(self): def __del__(self):
for status_value in self.icons: self.surface.finish()
self.icons[status_value].finish()
def draw(self, cr: cairo.Context, status: VehicleStatus, x: float, y: float): def draw(self, cr: cairo.Context, x: float, y: float):
icon = self.icons[status.value] print(f"Drawing! {self.status}, {x}, {y}, {self.width}, {self.height}, {self.color}")
cr.set_source_surface(self.surface, 0, 0)
cr.set_source_surface(icon, 0, 0)
cr.rectangle(x, y, self.width, self.height) cr.rectangle(x, y, self.width, self.height)
cr.fill() cr.fill()
class StatusIconBox(): class ISO7000():
__slots__ = 'x', 'y', 'width', 'height', __slots__ = 'icons',
__icons__ = (
(VehicleStatus.BATTERY_FAULT, 'beams-fog', '#f00'),
(VehicleStatus.BEAMS_FOG, 'beams-fog', '#0f0'),
(VehicleStatus.BEAMS_HIGH, 'beams-high', '#00f'),
(VehicleStatus.BEAMS_LOW, 'beams-low', '#0f0'),
(VehicleStatus.BEAMS_PARKING, 'beams-parking', '#ff0'),
(VehicleStatus.BELT, 'belt', '#f00'),
(VehicleStatus.COLD, 'cold', '#eef'),
(VehicleStatus.COLLISION, 'coolant', '#f00'),
(VehicleStatus.COOLANT_LOW, 'coolant', '#fa0'),
(VehicleStatus.COOLANT_OVERHEAT, 'coolant', '#f00'),
(VehicleStatus.CRUISE, 'cruise', '#0f0'),
(VehicleStatus.FUEL_LOW, 'fuel', '#fa0'),
(VehicleStatus.LANEKEEP_OFF, 'lane-departure', '#fa0'),
(VehicleStatus.OIL_LOW, 'oil', '#fa0'),
(VehicleStatus.OIL_OVERHEAT, 'oil', '#f00'),
(VehicleStatus.PARKING_BRAKE_ON, 'parking', '#fa0'),
(VehicleStatus.PARKING_BRAKE_FAULT, 'parking', '#f00'),
(VehicleStatus.STABILITY_OFF, 'stability', '#fa0'),
(VehicleStatus.TPMS_WARNING, 'tpms', '#fa0'),
(VehicleStatus.WIPER_WASHER_LOW, 'wiper-washer', '#fa0'),
)
def __init__(self, width: float, height: float):
self.icons = dict()
for item in self.__icons__:
status, name, color = item
self.icons[status.value] = ISO7000Icon(status,
name,
width,
height,
color)
class StatusIconBox(Gauge):
__slots__ = 'x', 'y', 'width', 'height', 'iso7000', 'value',
ICON_WIDTH = 32
ICON_HEIGHT = 32
def __init__(self, x: float, y: float, width: float, height: float): def __init__(self, x: float, y: float, width: float, height: float):
self.x = x self.x = x
self.y = y self.y = y
self.width = width self.width = width
self.height = height self.height = height
self.iso7000 = ISO7000(self.ICON_WIDTH, self.ICON_HEIGHT)
self.value = VehicleStatus.OK.value
def reset(self):
self.value = VehicleStatus.OK.value
def set_status(self, status: VehicleStatus):
self.value |= status.value
def clear_status(self, status: VehicleStatus):
self.value &= ~status.value
def draw_bg(self, cr: cairo.Context):
pass
def draw_fg(self, cr: cairo.Context):
x, y = 0, 0
for status_value in self.iso7000.icons:
icon = self.iso7000.icons[status_value]
if self.value & status_value:
if icon is not None:
icon.draw(cr, self.x + x, self.y + y)
x += self.ICON_WIDTH
if x >= self.width:
x = 0
y += self.ICON_HEIGHT

View file

@ -36,7 +36,7 @@ class VehicleStatus(enum.Enum):
BATTERY_FAULT: "low battery voltage", BEAMS_FOG: "foglights on", BATTERY_FAULT: "low battery voltage", BEAMS_FOG: "foglights on",
BEAMS_HIGH: "highbeams on", BEAMS_LOW: "lowbeams on", BEAMS_HIGH: "highbeams on", BEAMS_LOW: "lowbeams on",
BEAMS_PARKING: "parking beams on", BELT: "warning: fasten seatbelt", BEAMS_PARKING: "parking beams on", BELT: "warning: fasten seatbelt",
CAUTION: "caution", COLLISION: "collision detected", CAUTION: "caution", COLLISION: "collision detected", COLD: "outside temperatures cold",
COOLANT_LOW: "coolant low", COOLANT_OVERHEAT: "engine overheating", COOLANT_LOW: "coolant low", COOLANT_OVERHEAT: "engine overheating",
CRUISE: "cruise control on", FUEL_LOW: "fuel low", CRUISE: "cruise control on", FUEL_LOW: "fuel low",
LANEKEEP_OFF: "lane assist deactivated", ENGINE_FAULT: "check engine", LANEKEEP_OFF: "lane assist deactivated", ENGINE_FAULT: "check engine",