Source code for ska_low_cbf_fpga.xrt_info

# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 CSIRO Space and Astronomy.
#
# Distributed under the terms of the CSIRO Open Source Software Licence
# Agreement. See LICENSE for more info.
import json
import typing

import pyxrt

from ska_low_cbf_fpga.fpga_icl import IclField
from ska_low_cbf_fpga.hardware_info import FpgaHardwareInfo


[docs]class XrtInfo(FpgaHardwareInfo): """ Hardware info monitoring via pyxrt xrt_info_device. Access via item index, e.g. ``my_xrt_info["thermal"]``. Some flattening of data structures is performed. """
[docs] def __init__(self, device: typing.Union[str, pyxrt.device]): if isinstance(device, str): self._device = pyxrt.device(device) elif isinstance(device, pyxrt.device): self._device = device else: raise TypeError( "device must be str or pyxrt.device. " f"{type(device)} not supported." )
@property def xclbin_uuid(self) -> str: """Get the UUID of the active xclbin firmware.""" return self._device.get_xclbin_uuid().to_string() @property def fpga_temperature(self) -> IclField[int]: """ Get FPGA temperature in degrees Celsius. """ LOC_KEY = "fpga0" # others locations are: pcb_top_front/rear etc readings = self["thermal"] temperature = 0 for i in readings: if i["location_id"] == LOC_KEY and i["is_present"] == "true": temperature = int(i["temp_C"]) break return IclField( description="FPGA temperture in °C", format="%d", type_=int, value=temperature, user_write=False, ) @property def fpga_power(self) -> IclField[float]: """ Get FPGA power consumption in Watts. """ # drv = self._driver POWER_KEY = "power_consumption_watts" readings = self["electrical"] power = float(readings[POWER_KEY]) if POWER_KEY in readings else 0 return IclField( description="FPGA power consumption in W", format="%f", type_=float, value=power, user_write=False, )
[docs] def __getitem__(self, item: str): """Access info parameters via item index syntax. :param item: probably one of the values defined in ``_INFO_PARAMS`` """ if item not in self._INFO_PARAMS.keys(): raise KeyError(f"{item} is not an available health parameter") raw = self._device.get_info(getattr(pyxrt.xrt_info_device, item)) type_ = self._INFO_PARAMS[item] if type_ == "json": parsed = json.loads(raw) # many of these are dicts with one top-level key if len(parsed.keys()) == 1: parsed = parsed[next(iter(parsed))] # and then often a list with one element if type(parsed) == list and len(parsed) == 1: parsed = parsed[0] return parsed elif type(type_) == type: if type_ == bool: # We need str '0' to evaluate as False return bool(int(raw)) return type_(raw) else: raise ValueError(f"Unsupported type {self._INFO_PARAMS[item]}")