// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // Copyright (C) LibreHardwareMonitor and Contributors. // Partial Copyright (C) Michael Möller and Contributors. // All Rights Reserved. using System; using System.Collections.Generic; using System.Linq; using System.Text; using LibreHardwareMonitor.Hardware.Motherboard.Lpc; using LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC; using OperatingSystem = LibreHardwareMonitor.Software.OperatingSystem; namespace LibreHardwareMonitor.Hardware.Motherboard; /// /// Represents the motherboard of a computer with its and as . /// public class Motherboard : IHardware { private readonly LMSensors _lmSensors; private readonly LpcIO _lpcIO; private readonly string _name; private readonly ISettings _settings; private string _customName; /// /// Creates motherboard instance by retrieving information from and creates a new based on data from /// and . /// /// table containing motherboard data. /// Additional settings passed by . public Motherboard(SMBios smBios, ISettings settings) { IReadOnlyList superIO; _settings = settings; SMBios = smBios; Manufacturer = smBios.Board == null ? Manufacturer.Unknown : Identification.GetManufacturer(smBios.Board.ManufacturerName); Model = smBios.Board == null ? Model.Unknown : Identification.GetModel(smBios.Board.ProductName); if (smBios.Board != null) { if (!string.IsNullOrEmpty(smBios.Board.ProductName)) { if (Manufacturer == Manufacturer.Unknown) _name = smBios.Board.ProductName; else _name = Manufacturer + " " + smBios.Board.ProductName; } else { _name = Manufacturer.ToString(); } } else { _name = nameof(Manufacturer.Unknown); } _customName = settings.GetValue(new Identifier(Identifier, "name").ToString(), _name); if (OperatingSystem.IsUnix) { _lmSensors = new LMSensors(); superIO = _lmSensors.SuperIO; } else { _lpcIO = new LpcIO(this); superIO = _lpcIO.SuperIO; } EmbeddedController embeddedController = EmbeddedController.Create(Model, settings); List subHardwareList = new List(); // there may be more than 1 of the same SuperIO chip // group by chip foreach (IGrouping group in superIO.GroupBy(x => x.Chip)) { // index by group foreach ((ISuperIO superIo, int i) in group.Select((x, i) => (x, i))) { subHardwareList.Add(new SuperIOHardware(this, superIo, Manufacturer, Model, settings, i)); } } if (embeddedController != null) subHardwareList.Add(embeddedController); SubHardware = subHardwareList.ToArray(); } /// public event SensorEventHandler SensorAdded; /// public event SensorEventHandler SensorRemoved; /// public HardwareType HardwareType => HardwareType.Motherboard; /// public Identifier Identifier => new("motherboard"); /// /// Gets the . /// public Manufacturer Manufacturer { get; } /// /// Gets the . /// public Model Model { get; } /// /// Gets the name obtained from . /// public string Name { get { return _customName; } set { _customName = !string.IsNullOrEmpty(value) ? value : _name; _settings.SetValue(new Identifier(Identifier, "name").ToString(), _customName); } } /// /// Always public virtual IHardware Parent { get { return null; } } /// public virtual IDictionary Properties => new SortedDictionary(); /// public ISensor[] Sensors { get { return Array.Empty(); } } /// /// Gets the information. /// public SMBios SMBios { get; } /// public IHardware[] SubHardware { get; } /// public string GetReport() { StringBuilder r = new(); r.AppendLine("Motherboard"); r.AppendLine(); r.Append(SMBios.GetReport()); if (_lpcIO != null) r.Append(_lpcIO.GetReport()); return r.ToString(); } /// /// Motherboard itself cannot be updated. Update instead. /// public void Update() { } /// public void Accept(IVisitor visitor) { if (visitor == null) throw new ArgumentNullException(nameof(visitor)); visitor.VisitHardware(this); } /// public void Traverse(IVisitor visitor) { foreach (IHardware hardware in SubHardware) hardware.Accept(visitor); } /// /// Closes using . /// public void Close() { _lmSensors?.Close(); foreach (IHardware iHardware in SubHardware) { if (iHardware is Hardware hardware) hardware.Close(); } } }