tis-audit-battery icon

Audit Battery

Paquet d’installation silencieuse pour Audit Battery

1.1-3

  • package: tis-audit-battery
  • name: Audit Battery
  • version: 1.1-3
  • categories: System and network
  • maintainer: WAPT Team,Tranquil IT,Jimmy PELÉ
  • licence: wapt_public
  • target_os: windows
  • architecture: all
  • signature_date:
  • size: 7.72 Ko

package           : tis-audit-battery
version           : 1.1-3
architecture      : all
section           : base
priority          : optional
name              : Audit Battery
categories        : System and network
maintainer        : WAPT Team,Tranquil IT,Jimmy PELÉ
description       : Audit batteries capabilities with "powercfg /batteryreport" and dmi_info(). You will be able to pin the health of your batteries in WAPT Console
depends           : 
conflicts         : 
maturity          : PROD
locale            : 
target_os         : windows
min_wapt_version  : 2.3
sources           : https://support.microsoft.com/windows/caring-for-your-battery-in-windows-2db3e37f-5e7d-488e-9086-ed15320519e4
installed_size    : 
impacted_process  : 
description_fr    : Vérifiez les capacités des batteries avec "powercfg /batteryreport" et dmi_info(). Vous serez en mesure d'épingler l'état de santé de vos batteries dans la console WAPT
description_pl    : Audyt możliwości baterii za pomocą "powercfg /batteryreport" i dmi_info(). Będziesz mógł sprawdzić stan baterii w konsoli WAPT
description_de    : Überprüfen Sie die Fähigkeiten der Batterien mit "powercfg /batteryreport" und dmi_info(). Sie können den Zustand Ihrer Batterien in der WAPT-Konsole anzeigen lassen
description_es    : Audite las capacidades de las baterías con "powercfg /batteryreport" y dmi_info(). Usted será capaz de fijar la Salud de sus baterías en WAPT Consola
description_pt    : Auditar as capacidades das baterias com "powercfg /batteryreport" e dmi_info(). Poderá identificar o estado das suas baterias na consola WAPT
description_it    : Verificare le capacità delle batterie con "powercfg /batteryreport" e dmi_info(). Sarà possibile visualizzare lo stato di salute delle batterie nella console WAPT
description_nl    : Controleer de mogelijkheden van de batterijen met "powercfg /batteryreport" en dmi_info(). U kunt de gezondheid van uw accu's vastleggen in WAPT Console
description_ru    : Проведите аудит состояния батарей с помощью функций "powercfg /batteryreport" и dmi_info(). Вы сможете вывести информацию о состоянии батарей в WAPT-консоль
audit_schedule    : 7d
editor            : 
keywords          : 
licence           : wapt_public
homepage          : 
package_uuid      : e140f442-e9e0-4297-8b80-4c8669cc4021
valid_from        : 
valid_until       : 
forced_install_on : 
changelog         : 
min_os_version    : 
max_os_version    : 
icon_sha256sum    : 0c223120ac1a6e4cd0d0abe04cd831c7d4a4c2661947e758c0f703b656933d9a
signer            : Tranquil IT
signer_fingerprint: 8c5127a75392be9cc9afd0dbae1222a673072c308c14d88ab246e23832e8c6bb
signature_date    : 2025-05-03T09:31:06.000000
signed_attributes : package,version,architecture,section,priority,name,categories,maintainer,description,depends,conflicts,maturity,locale,target_os,min_wapt_version,sources,installed_size,impacted_process,description_fr,description_pl,description_de,description_es,description_pt,description_it,description_nl,description_ru,audit_schedule,editor,keywords,licence,homepage,package_uuid,valid_from,valid_until,forced_install_on,changelog,min_os_version,max_os_version,icon_sha256sum,signer,signer_fingerprint,signature_date,signed_attributes
signature         : EBBcCKYCauaGMXjku37WC8iwcD8thGy7vBILneq/zggQ1iX0gZY9TwSWcG+/j2CPyBjwj6shxIxbWJgC0fvhYiTtzRfRhu7Dl0sKp4R9buG3nReFl0b7z2uPcrH0n3mK785ZhgPBeyGF4lXZ9kY3NA8N3qlBio6pLdsQc1jvjjjXbGpIIacaP4h5timUJyoZegc3OwkbslBR8y4czRo6KOpLESPFHqdf3oQ1iGIcH5xHtoKy+tmLrO72GmEiX8sg1bGbayj3qCamo0Una6/6Zi2UL2otTK1Yb6eYetU2xFEQwdeBf9s1mD4l5zDzVccwLhhNED7FLqJNE6gT1bpHLg==

# -*- coding: utf-8 -*-
from setuphelpers import *


def install():
    pass


"""
powercfg /batteryreport /?

POWERCFG /BATTERYREPORT [/OUTPUT <FILENAME>] [/XML] [/TRANSFORMXML <FILENAME.XML>]


Description:
  Generates a report of battery usage characteristics over the lifetime of the
  system. The BATTERYREPORT command will generate an HTML report file in the
  current path.

Parameter List:
  /OUTPUT <FILENAME>     Specify the path and filename to store the battery
                         report HTML or XML file.

  /XML                   Format the report file as XML.

  /DURATION <DAYS>       Specify the number of days to analyze for the report.

  /TRANSFORMXML <FILENAME.XML>   Reformat an XML report file as HTML.

Examples:
  POWERCFG /BATTERYREPORT
  POWERCFG /BATTERYREPORT /OUTPUT "batteryreport.html"
  POWERCFG /BATTERYREPORT /OUTPUT "batteryreport.xml" /XML
  POWERCFG /BATTERYREPORT /TRANSFORMXML "batteryreport.xml"
  POWERCFG /BATTERYREPORT /TRANSFORMXML "batteryreport.xml" /OUTPUT "batteryreport.html"

"""


def get_battery_capacities_from_xml(xml_file):
    def element_to_dict(element, remove_namespace=True):
        result = {}
        for child in element:
            tag = child.tag
            if remove_namespace:
                tag = tag.split("}", 1)[-1]
            if child:
                result[tag] = element_to_dict(child, remove_namespace)
            else:
                result[tag] = child.text
        return result

    import xml.etree.ElementTree as ET

    ET.register_namespace("", "b")
    tree = ET.parse(xml_file)
    root = tree.getroot()

    """
    # Print element names and text content for debug
    elements = root.findall('.//*')
    for element in elements:
        print(f"{element.tag}: {element.text}")
    """

    batteries_dict_list = []
    for battery in root.findall("{http://schemas.microsoft.com/battery/2012}Batteries/{http://schemas.microsoft.com/battery/2012}Battery"):
        batteries_dict_list.append(element_to_dict(battery))
    return batteries_dict_list


def get_batteryreport(output_file):
    if "html" in output_file.lower():
        run(f'POWERCFG /BATTERYREPORT /OUTPUT "{output_file}"')
    else:
        run(f'POWERCFG /BATTERYREPORT /OUTPUT "{output_file}" /XML')


def audit():
    audit_status = "OK"
    battery_report_file = get_private_persistent_package_file("batteryreport.xml")
    dmi_info_portable_battery = dmi_info().get("Portable_Battery", None)

    if type(dmi_info_portable_battery) == dict:
        dmi_info_portable_battery = [dmi_info_portable_battery]

    if dmi_info_portable_battery:
        get_batteryreport(battery_report_file)
        battery_report_dict = {}
        batteries_dict_list = get_battery_capacities_from_xml(battery_report_file)

        battery_count = len(batteries_dict_list)
        battery_report_dict.update({"battery_count": str(battery_count)})

        # WAPT.write_audit_data_if_changed("audit-battery",, str(battery_count))

        for i in range(0, battery_count, 1):
            battery_number_name = f"BATTERY_{str(i+1)}"
            # print(battery_number_name + ":")
            full_charge_capacity = batteries_dict_list[i]["FullChargeCapacity"]
            design_capacity = batteries_dict_list[i]["DesignCapacity"]

            battery_health = int(int(full_charge_capacity) * 100 / int(design_capacity))
            if battery_health <= 50:
                audit_status = "WARNING"

            if battery_health <= 30:
                audit_status = "ERROR"

            str_battery_health = str(int(int(full_charge_capacity) * 100 / int(design_capacity))) + " %"

            batteries_dict_list[i].update({"Health": str_battery_health})
            batteries_dict_list[i].update(dmi_info_portable_battery[i])

            # WAPT.write_audit_data_if_changed("audit-battery", battery_number_name, batteries_dict_list[i])
            # print(batteries_dict_list[i])
            print(
                f'{battery_number_name} ({batteries_dict_list[i]["Location"]}) Health is {batteries_dict_list[i]["Health"]} for the DesignCapacity {batteries_dict_list[i]["DesignCapacity"]} mWh with Design_Voltage {batteries_dict_list[i]["Design_Voltage"]}.'
            )
            battery_report_dict.update({battery_number_name: batteries_dict_list[i]})

        WAPT.write_audit_data_if_changed("audit-battery", "audit-battery", battery_report_dict)

    else:
        WAPT.write_audit_data_if_changed("audit-battery", "audit-battery", {"battery_count": "0"})
        print("No battery detected.")

    return audit_status


def get_battery_capacities_from_html(html_file):
    chars_to_delete = [" ", "Â\xa0", " mWh"]

    datas = {}

    # Opening the html file
    HTMLFile = open(html_file, "r")
    # Reading the file
    index = HTMLFile.read()
    # Creating a BeautifulSoup object and specifying the parser
    soup = BeautifulSoup(index, "html.parser")

    for div in soup.findAll("table"):
        rows = div.findAll("tr")
        for row in rows:
            if row.text.find("mWh") > -1:
                if "DESIGN CAPACITY" in (row.text):
                    design_capacity = "".join([i for i in row.text.split("DESIGN CAPACITY")[-1].rstrip() if i.isdigit()])
                    for chars in chars_to_delete:
                        design_capacity = design_capacity.replace(chars, "")
                    datas["design_capacity"] = design_capacity
                if "FULL CHARGE CAPACITY" in (row.text):
                    full_charge_capacity = "".join([i for i in row.text.split("FULL CHARGE CAPACITY")[-1].rstrip() if i.isdigit()])
                    for chars in chars_to_delete:
                        full_charge_capacity = full_charge_capacity.replace(chars, "")
                    datas["full_charge_capacity"] = full_charge_capacity

    datas["Health"] = f"{int(int(full_charge_capacity) * 100 / int(design_capacity))}%"

    return datas

def get_private_persistent_package_file(file_name):
    file_name = os.path.basename(file_name)
    if control.package_uuid:
        if control.package_uuid == WAPT.is_installed(control.package)["package_uuid"]:
            return makepath(WAPT.persistent_root_dir, control.package_uuid, file_name)
    return makepath(os.getcwd(), "WAPT", "persistent", file_name)

38d056ab130f7bf7c481c12636a4e9959de36561d3dfcbe54c6e3571bc0c1dc3 : WAPT/certificate.crt
b35250802a8b2d9be5bef16c25cf4605a15c89a0625e5b9c5ad8eb84f26ef132 : WAPT/control
0c223120ac1a6e4cd0d0abe04cd831c7d4a4c2661947e758c0f703b656933d9a : WAPT/icon.png
28aaa3e3dda5ed86f832b6c2d93d8ed2b482738a56e09cee283caa397b32cf66 : luti.json
b413e35cf10ff8068274bf51aaced2e1ff09896edecd89269326cc4f0852b148 : setup.py