diff --git a/.gitignore b/.gitignore index 82a670da..9c7919bd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ *c4che* /foxbms*/ -tools/waf3-*/ +tools/*waf3-*/ tools/waf-sig* .lock-waf* *.bz2 diff --git a/conf/guidelines/rules.json b/conf/guidelines/rules.json index 6efda331..99c372b2 100644 --- a/conf/guidelines/rules.json +++ b/conf/guidelines/rules.json @@ -458,7 +458,8 @@ "macros.txt": { "exclude": [ "docs/general/team-ad-sc.rst", - "docs/general/team-dev.rst" + "docs/general/team-dev.rst", + "docs/general/team-former.rst" ], "regex": ".. include:: .{1,2}(/(..|\\w+))*/macros.txt" } @@ -468,7 +469,8 @@ "exclude": [ "docs/general/team.rst", "docs/general/team-ad-sc.rst", - "docs/general/team-dev.rst" + "docs/general/team-dev.rst", + "docs/general/team-former.rst" ], "regex": ".. include:: .{1,2}(/(..|\\w+))*/units.txt" } @@ -479,7 +481,8 @@ "name": "RST:005", "exclude": [ "docs/general/team-ad-sc.rst", - "docs/general/team-dev.rst" + "docs/general/team-dev.rst", + "docs/general/team-former.rst" ] }, "orphan": { diff --git a/conf/spa/.pylintrc b/conf/spa/.pylintrc index 7fa55328..56f5d372 100644 --- a/conf/spa/.pylintrc +++ b/conf/spa/.pylintrc @@ -16,7 +16,7 @@ ignore-patterns= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). -init-hook='import sys; sys.path.append("tools/waf3-2.0.22-1241519b19b496207abef1f72bbf61c2")' +init-hook='import sys; sys.path.extend(["tools/waf3-2.0.22-1241519b19b496207abef1f72bbf61c2", "tools/gui"])' # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the # number of processors available to use. @@ -528,7 +528,7 @@ max-locals=100 max-parents=7 # Maximum number of public methods for a class (see R0904). -max-public-methods=20 +max-public-methods=30 # Maximum number of return / yield for function / method body. max-returns=6 diff --git a/docs/conf.py b/docs/conf.py index 78b3a6c5..cba26457 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -103,6 +103,7 @@ "general/team.rst", "general/team-ad-sc.rst", "general/team-dev.rst", + "general/team-former.rst", ] # disable git contributor scanning in spelling module if no git repository try: diff --git a/docs/developer-manual/hardware-developer-manual.rst b/docs/developer-manual/hardware-developer-manual.rst index c8004b0d..2085debe 100644 --- a/docs/developer-manual/hardware-developer-manual.rst +++ b/docs/developer-manual/hardware-developer-manual.rst @@ -39,15 +39,15 @@ Release process The release process has the following steps: - #. Create the necessary footprints and components in a versioned DBLib. - #. Derive a new project from a project template and put it under version - control. - #. Define the schematic of the project and the design of the printed - circuit board. - #. Review the project together with a team member. - #. Create a release with the predefined set of output jobs. - #. Store the release in a pre-defined location so that it can be found. - #. Mark the released version in version control with a tag. +#. Create the necessary footprints and components in a versioned DBLib. +#. Derive a new project from a project template and put it under version + control. +#. Define the schematic of the project and the design of the printed + circuit board. +#. Review the project together with a team member. +#. Create a release with the predefined set of output jobs. +#. Store the release in a pre-defined location so that it can be found. +#. Mark the released version in version control with a tag. Modification process @@ -56,12 +56,12 @@ Modification process If modifications to the hardware are necessary, the following process has to be followed: - #. Create an issue in the GitLab project of the hardware component. - #. Describe the necessary changes as precise as possible. - #. Describe the impact of the changes to the software. - #. Describe the impact of the changes to the tests. - #. Enter the hardware release process :numref:`RELEASE_PROCESS` with - these changes. +#. Create an issue in the issue tracker of the hardware component project. +#. Describe the necessary changes as precise as possible. +#. Describe the impact of the changes to the software. +#. Describe the impact of the changes to the tests. +#. Enter the hardware release process :numref:`RELEASE_PROCESS` with + these changes. Checklist for releases diff --git a/docs/developer-manual/style-guide/guidelines_c.rst b/docs/developer-manual/style-guide/guidelines_c.rst index 9e9e9a01..421e3730 100644 --- a/docs/developer-manual/style-guide/guidelines_c.rst +++ b/docs/developer-manual/style-guide/guidelines_c.rst @@ -441,7 +441,7 @@ Function calls (``C:013``) - Multiple arguments **SHOULD** be put on a single line to reduce the number of lines necessary for calling a function unless there is a - specific readability problem. Some styleguides require formatting + specific readability problem. Some style guides require formatting strictly one argument on each line for simplifying editing the arguments. However, we prioritize readability over the ease of editing arguments, and most readability problems are better addressed with the diff --git a/docs/general/changelog.rst b/docs/general/changelog.rst index 30562720..c556689d 100644 --- a/docs/general/changelog.rst +++ b/docs/general/changelog.rst @@ -9,10 +9,12 @@ Changelog .. Comments: + Axivion is the company that builds the Axivion Bauhaus suite slaveplausibility is the old name of a plausibility module JUnit is a test system (originally for Java) .. spelling:: + Axivion slaveplausibility JUnit @@ -31,6 +33,46 @@ Versioning follows then these rules: - increasing ``MINOR`` adds functionality in a backwards compatible manner - increasing ``PATCH`` fixes bugs in a backwards compatible manner +******************** +[1.0.2] - 2021-04-30 +******************** + +Added +===== + +- Added number of valid cell voltages and temperatures used for calculating + minimum, maximum and average values to database entry + ``DATA_BLOCK_ID_MIN_MAX``. +- Added the build option ``--skip-doxygen`` to enable faster documentation + builds, if an API documentation is not required/does not need to be updated. + +Changed +======= + +- Do no longer hard code the EOL for the files in the VS Code settings, instead + just use the system EOL instead. + +Deprecated +========== + +Removed +======= + +Fixed +===== + +- Fixed typo in changelog. The LTC 6804-1 is basically an older version of the + LTC 6811-1 (previously it stated wrongly LTC 6812-1). +- ``linkcheck`` and ``spelling`` were not run when the documentation was built. +- The GUI searched for the wrong license file during startup routine and + therefore failed to start successfully. +- Improved the readability of the engine block schematic in the general + software documentation. +- Fixed an issue where the ``waf.sh``-wrapper would not print the error message + when the conda environment could not be found. +- Removed unused variables in build scripts. +- Fixed readmes in the tools directory and its subdirectories. + ******************** [1.0.1] - 2021-04-16 ******************** @@ -42,7 +84,7 @@ Added - Added testing for different versions of TI ARM CGT (versions 10.0.0 and 10.1.1). - Added a readme to the hardware directory. -- Added support for LTC 6804-1 (basically an older version of the LTC 6812-1). +- Added support for LTC 6804-1 (basically an older version of the LTC 6811-1). - Added the updated design files of the foxBMS 2 master v1.0.1. Changed @@ -90,7 +132,6 @@ Fixed ``CC-BY-4.0``. For more information see :ref:`LICENSE`. - Fixed the names of variables in bash scripts on Windows. - ******************** [1.0.0] - 2021-04-01 ******************** diff --git a/docs/general/releases.csv b/docs/general/releases.csv index f9e6b36c..4bcb4ebe 100644 --- a/docs/general/releases.csv +++ b/docs/general/releases.csv @@ -1,4 +1,5 @@ foxBMS 2; Release Date; Permanent link to documentation +v1.0.2; 2021-04-30; https://iisb-foxbms.iisb.fraunhofer.de/foxbms/gen2/docs/html/v1.0.2/ v1.0.1; 2021-04-16; https://iisb-foxbms.iisb.fraunhofer.de/foxbms/gen2/docs/html/v1.0.1/ v1.0.0; 2021-04-01; https://iisb-foxbms.iisb.fraunhofer.de/foxbms/gen2/docs/html/v1.0.0/ v0.3.0; 2021-03-16; \- diff --git a/docs/general/team-ad-sc.rst b/docs/general/team-ad-sc.rst index 74fe3c0b..c3076492 100644 --- a/docs/general/team-ad-sc.rst +++ b/docs/general/team-ad-sc.rst @@ -1,4 +1,3 @@ - Jürgen Lorenz -- Lothar Frey - Martin März - Vincent Lorentz diff --git a/docs/general/team-dev.rst b/docs/general/team-dev.rst index 5f4254e3..00bbe594 100644 --- a/docs/general/team-dev.rst +++ b/docs/general/team-dev.rst @@ -1,20 +1,11 @@ -- Christian Freund -- Christian Thomas -- Georg Kordowich +- Andreas Ochs - Johannes Wachtler -- Joshua Grosch -- Lucas Grunenberg -- Müsfik Akdere - Markus Gepp - Martin Wenger -- Martin Giegerich - Patrick Kanzler -- Pauline Thierauf - Radu Schwarz - Reinhold Waller -- Robin Heim - Sebastian Wacker - Stéphane Koffel - Stefan Waldhör -- Tim Fühner - Tobias Huf diff --git a/docs/general/team-former.rst b/docs/general/team-former.rst new file mode 100644 index 00000000..84961255 --- /dev/null +++ b/docs/general/team-former.rst @@ -0,0 +1,12 @@ +- Lothar Frey + +- Christian Freund +- Christian Thomas +- Georg Kordowich +- Joshua Grosch +- Lucas Grunenberg +- Müsfik Akdere +- Martin Giegerich +- Pauline Thierauf +- Robin Heim +- Tim Fühner diff --git a/docs/general/team.rst b/docs/general/team.rst index a6d721df..57c911aa 100644 --- a/docs/general/team.rst +++ b/docs/general/team.rst @@ -27,6 +27,12 @@ Development Team Fraunhofer IISB .. include:: ./team-dev.rst +*********************************** +Former Team Members Fraunhofer IISB +*********************************** + +.. include:: ./team-former.rst + ************ Contribution ************ diff --git a/docs/getting-started/software-installation.rst b/docs/getting-started/software-installation.rst index d17abf31..70a38bfa 100644 --- a/docs/getting-started/software-installation.rst +++ b/docs/getting-started/software-installation.rst @@ -70,9 +70,9 @@ later steps of this manual. :caption: Downloading a release :name: download-foxbms-2 - C:\Users\vulpes\Documents>curl -Ss -L -o foxbms-2-v1.0.1.zip https://github.com/foxBMS/foxbms-2/archive/v1.0.1.zip - C:\Users\vulpes\Documents>tar -x -f foxbms-2-v1.0.1.zip - C:\Users\vulpes\Documents>ren foxbms-2-v1.0.1 foxbms-2 + C:\Users\vulpes\Documents>curl -Ss -L -o foxbms-2-v1.0.2.zip https://github.com/foxBMS/foxbms-2/archive/v1.0.2.zip + C:\Users\vulpes\Documents>tar -x -f foxbms-2-v1.0.2.zip + C:\Users\vulpes\Documents>ren foxbms-2-1.0.2 foxbms-2 C:\Users\vulpes\Documents>cd foxbms-2 .. note:: diff --git a/docs/macros.txt b/docs/macros.txt index fec3b229..ad9cce9a 100644 --- a/docs/macros.txt +++ b/docs/macros.txt @@ -3,7 +3,7 @@ .. |timestamp| date:: %Y-%m-%d %H:%M:%S .. |foxbms| replace:: foxBMS 2 -.. |version_foxbms| replace:: ``1.0.1`` +.. |version_foxbms| replace:: ``1.0.2`` .. |github_foxbms| replace:: https://github.com/foxBMS/ .. |foxbms_repository| replace:: https://github.com/foxBMS/foxbms-2 .. _Fraunhofer IISB: https://www.iisb.fraunhofer.de diff --git a/docs/software/modules/driver/mic/ltc/6804-1.rst b/docs/software/modules/driver/mic/ltc/6804-1.rst index a06068a2..7e81b612 100644 --- a/docs/software/modules/driver/mic/ltc/6804-1.rst +++ b/docs/software/modules/driver/mic/ltc/6804-1.rst @@ -8,6 +8,6 @@ LTC 6804-1 The *LTC 6804-1* is the third generation measurement IC by Analog Devices (formerly Linear Technology). A *LTC 6804-1* compatible driver is implemented -in |foxbms| for the fourth generation *LTC 6812-1*. +in |foxbms| for the fourth generation *LTC 6811-1*. See :ref:`LTC_6812_1`. diff --git a/docs/software/overview/img/database_engine.vsdx b/docs/software/overview/img/database_engine.vsdx index 92d539e3..51046f5d 100644 Binary files a/docs/software/overview/img/database_engine.vsdx and b/docs/software/overview/img/database_engine.vsdx differ diff --git a/docs/software/overview/img/engine.png b/docs/software/overview/img/engine.png index 29c0e3e0..2674dc26 100644 Binary files a/docs/software/overview/img/engine.png and b/docs/software/overview/img/engine.png differ diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 247b2f5f..98b46f38 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -78,6 +78,8 @@ preprocess preprocessor programmatically pylint +readme +readmes redox reStructuredText roadmap @@ -107,6 +109,7 @@ suppressions teardown throughs toolchain +toolchains toolset TX txt diff --git a/docs/tools/debugger/debugger-lauterbach.rst b/docs/tools/debugger/debugger-lauterbach.rst index bc45904c..1b7f0a99 100644 --- a/docs/tools/debugger/debugger-lauterbach.rst +++ b/docs/tools/debugger/debugger-lauterbach.rst @@ -6,6 +6,13 @@ Lauterbach Trace32 debugger =========================== +.. + Comments: + Mictor is a connector + +.. spelling:: + Mictor + Some information can be found in ``tools/debugger/lauterbach/commands.md``. Please carefully read the `basic manual `_ @@ -37,6 +44,6 @@ TMS570LC4357 target. Please refer to their customer support for details. The setup of `Fraunhofer IISB`_ consists of a LA-3505 debugger connected to a LA-3500 trace probe. |foxbms| features a compliant Mictor-38 connector in order -to be able to connect trace ports with up to 8 bit. If you need more bandwith, +to be able to connect trace ports with up to 8 bit. If you need more bandwidth, please contact us. The standard design can be adapted to up to 32 bit trace -bandwith. +bandwidth. diff --git a/src/app/application/redundancy/redundancy.c b/src/app/application/redundancy/redundancy.c index 6b07782a..efc0b85d 100644 --- a/src/app/application/redundancy/redundancy.c +++ b/src/app/application/redundancy/redundancy.c @@ -803,6 +803,7 @@ static STD_RETURN_TYPE_e MRC_CalculateCellVoltageMinMaxAverage( pMinMaxAverageValues->maximumCellVoltage_mV[s] = max; pMinMaxAverageValues->nrCellMaximumCellVoltage[s] = cellNumberMaximum; pMinMaxAverageValues->nrModuleMaximumCellVoltage[s] = moduleNumberMaximum; + pMinMaxAverageValues->validMeasuredCellVoltages[s] = nrValidCellvoltages; /* Prevent division by 0, if all cell voltages are invalid */ if (nrValidCellvoltages > 0u) { @@ -859,12 +860,13 @@ static STD_RETURN_TYPE_e MRC_CalculateCellTemperatureMinMaxAverage( } } } - pMinMaxAverageValues->minimumTemperature_ddegC[s] = min; - pMinMaxAverageValues->nrSensorMinimumTemperature[s] = sensorNumberMinimum; - pMinMaxAverageValues->nrModuleMinimumTemperature[s] = moduleNumberMinimum; - pMinMaxAverageValues->maximumTemperature_ddegC[s] = max; - pMinMaxAverageValues->nrSensorMaximumTemperature[s] = sensorNumberMaximum; - pMinMaxAverageValues->nrModuleMaximumTemperature[s] = moduleNumberMaximum; + pMinMaxAverageValues->minimumTemperature_ddegC[s] = min; + pMinMaxAverageValues->nrSensorMinimumTemperature[s] = sensorNumberMinimum; + pMinMaxAverageValues->nrModuleMinimumTemperature[s] = moduleNumberMinimum; + pMinMaxAverageValues->maximumTemperature_ddegC[s] = max; + pMinMaxAverageValues->nrSensorMaximumTemperature[s] = sensorNumberMaximum; + pMinMaxAverageValues->nrModuleMaximumTemperature[s] = moduleNumberMaximum; + pMinMaxAverageValues->validMeasuredCellTemperatures[s] = nrValidCelltemperatures; /* Prevent division by 0, if all cell voltages are invalid */ if (nrValidCelltemperatures > 0u) { diff --git a/src/app/driver/mic/ltc/6804-1/wscript b/src/app/driver/mic/ltc/6804-1/wscript index f6e39125..f8e485c6 100644 --- a/src/app/driver/mic/ltc/6804-1/wscript +++ b/src/app/driver/mic/ltc/6804-1/wscript @@ -46,7 +46,7 @@ import os def build(bld): - """6804-1 is a build variant of 6812-1 (it mostly is an older version of + """6804-1 is a build variant of 6811-1 (it mostly is an older version of that IC) """ bld.recurse(os.path.join("..", "6813-1")) diff --git a/src/app/driver/mic/ltc/6813-1/config/ltc_6813-1_cfg.h b/src/app/driver/mic/ltc/6813-1/config/ltc_6813-1_cfg.h index 3a41dd0c..380b8bbf 100644 --- a/src/app/driver/mic/ltc/6813-1/config/ltc_6813-1_cfg.h +++ b/src/app/driver/mic/ltc/6813-1/config/ltc_6813-1_cfg.h @@ -47,8 +47,8 @@ * @ingroup DRIVERS_CONFIGURATION * @prefix LTC * - * @brief Header for the configuration for the LTC 6811-1, 6812-1, 6813-1 - * monitoring IC. + * @brief Header for the configuration for the LTC 6804-1 6811-1, 6812-1, + * and 6813-1 monitoring IC. * */ diff --git a/src/app/engine/config/database_cfg.h b/src/app/engine/config/database_cfg.h index 0f1d0662..feb6566b 100644 --- a/src/app/engine/config/database_cfg.h +++ b/src/app/engine/config/database_cfg.h @@ -161,24 +161,25 @@ typedef struct DATA_BLOCK_MIN_MAX { * respective database entry representation in enum DATA_BLOCK_ID_e. */ DATA_BLOCK_HEADER_s header; /*!< Data block header */ - int16_t averageCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< average cell voltages, unit: mV */ - int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< minimum cell voltages, unit: mV */ - int16_t previousMinimumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< previous minimum cell voltages, unit: mV */ - int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< maximum cell voltages, unit: mV */ - int16_t previousMaximumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< previous maximum cell voltages, unit: mV */ - - uint16_t nrModuleMinimumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the module with minimum cell voltage */ - uint16_t nrCellMinimumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the cell with minimum cell voltage */ - uint16_t nrModuleMaximumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the module with maximum cell voltage */ - uint16_t nrCellMaximumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the cell with maximum cell voltage */ - float averageTemperature_ddegC[BS_NR_OF_STRINGS]; /*!< unit: deci °C */ - int16_t minimumTemperature_ddegC[BS_NR_OF_STRINGS]; /*!< unit: deci °C */ - uint16_t nrModuleMinimumTemperature[BS_NR_OF_STRINGS]; /*!< number of the module with minimum temperature */ - uint16_t nrSensorMinimumTemperature[BS_NR_OF_STRINGS]; /*!< number of the sensor with minimum temperature */ - int16_t maximumTemperature_ddegC[BS_NR_OF_STRINGS]; /*!< unit: deci °C */ - uint16_t nrModuleMaximumTemperature[BS_NR_OF_STRINGS]; /*!< number of the module with maximum temperature */ - uint16_t nrSensorMaximumTemperature[BS_NR_OF_STRINGS]; /*!< number of the sensor with maximum temperature */ - uint8_t state; /*!< state of the min max module */ + int16_t averageCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< average cell voltages, unit: mV */ + int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< minimum cell voltages, unit: mV */ + int16_t previousMinimumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< previous minimum cell voltages, unit: mV */ + int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< maximum cell voltages, unit: mV */ + int16_t previousMaximumCellVoltage_mV[BS_NR_OF_STRINGS]; /*!< previous maximum cell voltages, unit: mV */ + uint16_t nrModuleMinimumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the module with minimum cell voltage */ + uint16_t nrCellMinimumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the cell with minimum cell voltage */ + uint16_t nrModuleMaximumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the module with maximum cell voltage */ + uint16_t nrCellMaximumCellVoltage[BS_NR_OF_STRINGS]; /*!< number of the cell with maximum cell voltage */ + uint16_t validMeasuredCellVoltages[BS_NR_OF_STRINGS]; /*!< number of valid measured cell voltages */ + float averageTemperature_ddegC[BS_NR_OF_STRINGS]; /*!< unit: deci °C */ + int16_t minimumTemperature_ddegC[BS_NR_OF_STRINGS]; /*!< unit: deci °C */ + uint16_t nrModuleMinimumTemperature[BS_NR_OF_STRINGS]; /*!< number of the module with minimum temperature */ + uint16_t nrSensorMinimumTemperature[BS_NR_OF_STRINGS]; /*!< number of the sensor with minimum temperature */ + int16_t maximumTemperature_ddegC[BS_NR_OF_STRINGS]; /*!< unit: deci °C */ + uint16_t nrModuleMaximumTemperature[BS_NR_OF_STRINGS]; /*!< number of the module with maximum temperature */ + uint16_t nrSensorMaximumTemperature[BS_NR_OF_STRINGS]; /*!< number of the sensor with maximum temperature */ + uint16_t validMeasuredCellTemperatures[BS_NR_OF_STRINGS]; /*!< number of valid measured cell temperatures */ + uint8_t state; /*!< state of the min max module */ } DATA_BLOCK_MIN_MAX_s; /** data block struct of pack measurement values */ diff --git a/tests/scripts/gui/__init__.py b/tests/scripts/gui/__init__.py new file mode 100644 index 00000000..e15328f0 --- /dev/null +++ b/tests/scripts/gui/__init__.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# We kindly request you to use one or more of the following phrases to refer to +# foxBMS in your hardware, software, documentation or advertising materials: +# +# - "This product uses parts of foxBMS®" +# - "This product includes parts of foxBMS®" +# - "This product is derived from foxBMS®" + +# waf-tools is not a proper python module name, but this is OK since we need +# it just for the unit test discovery +# pylint: disable-all diff --git a/tests/scripts/gui/test_foxbms_gui.py b/tests/scripts/gui/test_foxbms_gui.py new file mode 100644 index 00000000..a5935a4a --- /dev/null +++ b/tests/scripts/gui/test_foxbms_gui.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# We kindly request you to use one or more of the following phrases to refer to +# foxBMS in your hardware, software, documentation or advertising materials: +# +# - "This product uses parts of foxBMS®" +# - "This product includes parts of foxBMS®" +# - "This product is derived from foxBMS®" + +"""Implements tests for the foxBMS 2 GUI. +""" + +import unittest +import sys +import os +import wx + +HAVE_GIT = False +try: + from git import Repo + from git.exc import InvalidGitRepositoryError + + HAVE_GIT = True +except ImportError: + pass + + +def get_git_root(path: str) -> str: + """helper function to find the repository root + + Args: + path (string): path of test_f_guidelines + + Returns: + root (string): root path of the git repository + """ + root = os.path.join(os.path.dirname(path), "..", "..", "..") + if HAVE_GIT: + try: + repo = Repo(path, search_parent_directories=True) + root = repo.git.rev_parse("--show-toplevel") + except InvalidGitRepositoryError: + pass + return root + + +ROOT = get_git_root(os.path.realpath(__file__)) + +sys.path.insert(1, os.path.abspath(os.path.join(ROOT, "tools", "gui"))) +import foxbms_gui # pylint:disable=wrong-import-position,unused-import + + +class TestDialog(unittest.TestCase): + """Testing the info dialog""" + + def setUp(self): + self.app = wx.App() + self.frame = wx.Frame() + self.frame.Show() + + def tearDown(self): + wx.CallAfter(self.app.ExitMainLoop) + self.app.MainLoop() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/scripts/gui/test_info_dialog.py b/tests/scripts/gui/test_info_dialog.py new file mode 100644 index 00000000..2e7c8fab --- /dev/null +++ b/tests/scripts/gui/test_info_dialog.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# We kindly request you to use one or more of the following phrases to refer to +# foxBMS in your hardware, software, documentation or advertising materials: +# +# - "This product uses parts of foxBMS®" +# - "This product includes parts of foxBMS®" +# - "This product is derived from foxBMS®" + +"""Implements tests for the foxBMS 2 info dialog. +""" + +import unittest +import sys +import os +import wx + +HAVE_GIT = False +try: + from git import Repo + from git.exc import InvalidGitRepositoryError + + HAVE_GIT = True +except ImportError: + pass + + +def get_git_root(path: str) -> str: + """helper function to find the repository root + + Args: + path (string): path of test_f_guidelines + + Returns: + root (string): root path of the git repository + """ + root = os.path.join(os.path.dirname(path), "..", "..", "..") + if HAVE_GIT: + try: + repo = Repo(path, search_parent_directories=True) + root = repo.git.rev_parse("--show-toplevel") + except InvalidGitRepositoryError: + pass + return root + + +ROOT = get_git_root(os.path.realpath(__file__)) + +sys.path.insert(1, os.path.abspath(os.path.join(ROOT, "tools", "gui"))) +import info_dialog # pylint:disable=wrong-import-position + + +class TestDialog(unittest.TestCase): + """Testing the info dialog""" + + def setUp(self): + self.app = wx.App() + self.frame = wx.Frame() + self.frame.Show() + + def tearDown(self): + wx.CallAfter(self.app.ExitMainLoop) + self.app.MainLoop() + + def test_dialog(self): + """Tests the info dialog""" + + def click_ok(): + """programmatically click the 'ok' button""" + ok_clicked = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, wx.ID_OK) + self.info_diag.ProcessEvent(ok_clicked) + + wx.CallAfter(click_ok) + self.show_dialog() + + def show_dialog(self): + """Shows the dialog""" + + # pylint:disable=attribute-defined-outside-init + self.info_diag = info_dialog.FoxbmsInfoDialog(None) + self.info_diag.ShowModal() + self.info_diag.Destroy() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/scripts/run_tests.bat b/tests/scripts/run_tests.bat new file mode 100644 index 00000000..3317d875 --- /dev/null +++ b/tests/scripts/run_tests.bat @@ -0,0 +1,87 @@ +@REM Copyright (c) 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. +@REM All rights reserved. +@REM +@REM SPDX-License-Identifier: BSD-3-Clause +@REM +@REM Redistribution and use in source and binary forms, with or without +@REM modification, are permitted provided that the following conditions are met: +@REM +@REM 1. Redistributions of source code must retain the above copyright notice, this +@REM list of conditions and the following disclaimer. +@REM +@REM 2. Redistributions in binary form must reproduce the above copyright notice, +@REM this list of conditions and the following disclaimer in the documentation +@REM and/or other materials provided with the distribution. +@REM +@REM 3. Neither the name of the copyright holder nor the names of its +@REM contributors may be used to endorse or promote products derived from +@REM this software without specific prior written permission. +@REM +@REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +@REM AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@REM IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +@REM DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +@REM FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +@REM DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +@REM SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +@REM CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +@REM OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +@REM OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +@REM +@REM We kindly request you to use one or more of the following phrases to refer to +@REM foxBMS in your hardware, software, documentation or advertising materials: +@REM +@REM - "This product uses parts of foxBMS®" +@REM - "This product includes parts of foxBMS®" +@REM - "This product is derived from foxBMS®" + +@SET BASE_DIR=%~dp0\..\.. +@PUSHD %BASE_DIR%\tests\scripts +@ECHO ========================================================================= +@ECHO Unit testing waf-tools +@CALL %BASE_DIR%\tools\utils\cmd\run-python-coverage.bat run --source=%BASE_DIR%\tools\waf-tools -m unittest discover --start-directory waf-tools --top-level-directory . +@IF %ERRORLEVEL% NEQ 0 ( + @ECHO Unit testing waf tools failed + @EXIT /b %ERRORLEVEL% +) ELSE ( + @ECHO Unit testing waf tools successfull +) +@ECHO ========================================================================= +@ECHO Unit testing GUI +@CALL %BASE_DIR%\tools\utils\cmd\run-python-coverage.bat run --append --source=%BASE_DIR%\tools\gui -m unittest discover --start-directory gui --top-level-directory . +@IF %ERRORLEVEL% NEQ 0 ( + @ECHO Unit testing the GUI failed + @POPD + @EXIT /b %ERRORLEVEL% +) ELSE ( + @ECHO Unit testing GUI successfull +) +@ECHO ========================================================================= +@ECHO Creating report +@CALL %BASE_DIR%\tools\utils\cmd\run-python-coverage.bat report +@IF %ERRORLEVEL% NEQ 0 ( + @ECHO Could not create coverage report + @POPD + @EXIT /b %ERRORLEVEL% +) ELSE ( + @ECHO Coverage Report created +) +@CALL %BASE_DIR%\tools\utils\cmd\run-python-coverage.bat html --directory=%BASE_DIR%\build\unit_test_scripts\ +@IF %ERRORLEVEL% NEQ 0 ( + @ECHO Could not create html coverage report + @POPD + @EXIT /b %ERRORLEVEL% +) ELSE ( + @ECHO HTML Coverage Report created +) +@CALL %BASE_DIR%\tools\utils\cmd\run-python-coverage.bat xml -o %BASE_DIR%\build\unit_test_scripts\CoberturaCoverageScripts.xml +@IF %ERRORLEVEL% NEQ 0 ( + @ECHO Could not create xml coverage report + @POPD + @EXIT /b %ERRORLEVEL% +) ELSE ( + @ECHO XML Coverage Report created +) +@ECHO ========================================================================= +@ECHO Done +@POPD diff --git a/tests/scripts/waf-core/run_waf_core_unit_tests.sh b/tests/scripts/waf-core/run_waf_core_unit_tests.sh old mode 100644 new mode 100755 diff --git a/tests/scripts/waf-tools/f_guidelines/test_f_guidelines.py b/tests/scripts/waf-tools/f_guidelines/test_f_guidelines.py index a9923673..26b702f0 100644 --- a/tests/scripts/waf-tools/f_guidelines/test_f_guidelines.py +++ b/tests/scripts/waf-tools/f_guidelines/test_f_guidelines.py @@ -113,7 +113,7 @@ def get_results(tests_folder, result_json_file): def get_txt(f): """returns the content of file""" txt = None - with open(os.path.join(TEST_FILES_PATH, f), "r") as text_file: + with open(os.path.join(TEST_FILES_PATH, f), "r", newline=os.linesep) as text_file: txt = text_file.read() return txt @@ -281,7 +281,7 @@ def test_header(self): test_header = get_txt(os.path.join("header_tests", test_file)) # First line is skipped because file should start with header not # with comment - test_header = "\n".join(test_header.splitlines()[1:]) + "\n" + test_header = os.linesep.join(test_header.splitlines()[1:]) + os.linesep self.general_tester( result, f_guidelines.check_header.test(test_header, python_header) ) diff --git a/tools/README.md b/tools/README.md index 7817b390..1c304166 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,4 +1,18 @@ # Tools This directory contains a set of tools that support the development or usage -of foxBMS. +of foxBMS 2. + +| Script | Purpose | +|:----------------------|:----------------------------------------------------------------------------------------------| +| ``crc/*`` | Various [CRC](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) helpers and scripts. | +| ``dbc/`` | foxBMS 2 data base CAN. | +| ``debugger/*`` | Configuration files for debugger settings. | +| ``gui/*`` | foxBMS 2 GUI. | +| ``ide/vscode/*`` | Configuration file templates for VS Code settings. | +| ``utils/*`` | Helper scripts for batch and shellscript. | +| ``vendor/ceedling/*`` | Vendored ceedling files. | +| ``waf-tools/*`` | Tools required for the build toolchain that do not come bundled with the default waf binary. | +| ``waf`` | The build tool binary. | +| ``waf-pubkey.asc`` | This is the public key that is used by waf to sign the waf binary ``waf``. | +| ``waf-verify-sig.py`` | Script to verify the signature of the waf binary. | diff --git a/tools/gui/README.md b/tools/gui/README.md index 18a1a1d5..15829ede 100644 --- a/tools/gui/README.md +++ b/tools/gui/README.md @@ -1 +1,6 @@ -# foxBMS Interface +# foxBMS 2 GUI + + +## Starting the GUI + +In order to start the gui, run ``gui.bat``. diff --git a/tools/gui/fgui/__init__.py b/tools/gui/fgui/__init__.py index f6ce3e3e..19e8c95a 100644 --- a/tools/gui/fgui/__init__.py +++ b/tools/gui/fgui/__init__.py @@ -38,4 +38,11 @@ # - "This product includes parts of foxBMS®" # - "This product is derived from foxBMS®" -# init required to have an importable module +"""sets the version package etc.""" + +__version__ = "1.0.2" +__appname__ = "foxBMS 2" +__author__ = "The foxBMS Team" +__copyright__ = "(c) 2010 - 2021 foxBMS" +__author__ = "The foxBMS Team" +__email__ = "info@foxbms.org" diff --git a/tools/gui/foxbms_gui.py b/tools/gui/foxbms_gui.py index 32d44d32..2dde15a7 100644 --- a/tools/gui/foxbms_gui.py +++ b/tools/gui/foxbms_gui.py @@ -39,7 +39,6 @@ # - "This product is derived from foxBMS®" """This is the foxBMS GUI -It has many good features and so on https://foxbms.org """ @@ -49,31 +48,26 @@ import wx import wx.adv -import fgui # pylint: disable=unused-import +import fgui from log_parser import LogParserFrame +from info_dialog import FoxbmsInfoDialog -__author__ = "The foxBMS Team" -__version__ = "0.0.1" +__version__ = fgui.__version__ +__appname__ = fgui.__appname__ +__author__ = fgui.__author__ +__copyright__ = fgui.__copyright__ +__author__ = fgui.__author__ +__email__ = fgui.__email__ +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) +FOXBMS_LOGO = os.path.join(SCRIPT_DIR, "..", "..", "docs", "_static", "foxbms250px.png") -class FoxBMSMainFrame(wx.Frame): # pylint: disable=too-many-ancestors + +class foxBMSMainFrame(wx.Frame): """Main frame to construct the foxBMS GUI frame""" - foxbms_license_file = os.path.join( - os.path.dirname(os.path.realpath(__file__)), "..", "..", "LICENSE" - ) - with open(foxbms_license_file, "r", encoding="utf-8") as f: - foxbms_license = f.read() - - foxbms_logo = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "..", - "..", - "docs", - "_static", - "foxbms250px.png", - ) + # pylint: disable=too-many-ancestors,invalid-name def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -109,9 +103,9 @@ def initialize_gui(self): self.Bind(wx.EVT_MENU, self.cb_open_documentation, open_documentation_item) self.SetMenuBar(menu_bar) - # Add a + # Add logo _icon = wx.Icon() - logo_img = wx.Image(self.foxbms_logo) + logo_img = wx.Image(FOXBMS_LOGO) logo_img_size = logo_img.GetSize() resized = logo_img_size / 5 logo_img.Rescale(resized[0], resized[1]) @@ -138,42 +132,23 @@ def cb_start_log_parser(cls, event): def cb_open_documentation(cls, event): """Shows the foxBMS documentation from local source if it exists, from web if it does not""" - doc = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "..", - "..", - "build", - "docs", - "index.html", - ) + doc = os.path.join(SCRIPT_DIR, "..", "..", "build", "docs", "index.html") if not os.path.isfile(doc): - doc = "https://foxbms.org" + doc = "https://iisb-foxbms.iisb.fraunhofer.de/foxbms/gen2/docs/html/latest/" webbrowser.open(doc) - def cb_show_info(self, event): + @classmethod + def cb_show_info(cls, event): """Shows the program information""" - about_info = wx.adv.AboutDialogInfo() - about_info.SetName("foxBMS") - about_info.SetVersion(__version__) - about_info.Copyright = "(C) 2010 - 2019 foxBMS" - about_info.SetDescription(__doc__) - about_info.SetWebSite = ("https://foxbms.org", "foxbms.org") - about_info.License = self.foxbms_license - _icon = wx.Icon() - logo_img = wx.Image(self.foxbms_logo) - logo_img_size = logo_img.GetSize() - resized = logo_img_size / 3 - logo_img.Rescale(resized[0], resized[1]) - image = wx.Bitmap(logo_img) - _icon.CopyFromBitmap(image) - about_info.SetIcon(_icon) - wx.adv.AboutBox(about_info) + about_dialog = FoxbmsInfoDialog(None, title="About foxBMS 2") + about_dialog.ShowModal() + about_dialog.Destroy() def main(): """Starts the application""" app = wx.App(False) - FoxBMSMainFrame(None) + foxBMSMainFrame(None) app.MainLoop() diff --git a/tools/gui/info_dialog.py b/tools/gui/info_dialog.py new file mode 100644 index 00000000..336fa2c7 --- /dev/null +++ b/tools/gui/info_dialog.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# We kindly request you to use one or more of the following phrases to refer to +# foxBMS in your hardware, software, documentation or advertising materials: +# +# - "This product uses parts of foxBMS®" +# - "This product includes parts of foxBMS®" +# - "This product is derived from foxBMS®" + +"""helper for the info dialog""" + +import os +import pathlib +import wx +import wx.adv +import wx.html +import wx.grid +import wx.lib.agw.hyperlink as hl +import markdown + +import fgui + +__version__ = fgui.__version__ +__appname__ = fgui.__appname__ +__author__ = fgui.__author__ +__copyright__ = fgui.__copyright__ +__author__ = fgui.__author__ +__email__ = fgui.__email__ + +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) +README_FILE = os.path.join(SCRIPT_DIR, "README.md") +LICENSE_FILE = os.path.join(SCRIPT_DIR, "..", "..", "LICENSE.md") +FOXBMS_LOGO = os.path.join(SCRIPT_DIR, "..", "..", "docs", "_static", "foxbms250px.png") +FOXBMS_URL = "https://foxbms.org" +BASE_URL = "https://iisb-foxbms.iisb.fraunhofer.de/" +LICENSE_FALLBACK_URL = f"{BASE_URL}foxbms/gen2/docs/html/latest/general/license.html" + + +class FoxbmsInfoDialog(wx.Dialog): + """Dialog box for 'Info' message""" + + # pylint: disable=too-many-ancestors + + def __init__(self, *args, **kw): + super().__init__(*args, **kw) + self.SetSize((605, 1000)) + self.SetTitle("About foxBMS 2") + self.license_file = self.get_file(LICENSE_FILE) + self.readme_file = self.get_file(README_FILE) + self.license_text = self.get_license_text() + self.readme_text = self.get_readme_text() + self.init_foxbms_dialog() + self.SetPosition((0, 0)) + + def init_foxbms_dialog(self): + """Setup the text of the dialog box""" + # Add icon + _icon = wx.Icon() + logo_img = wx.Image(FOXBMS_LOGO) + logo_img_size = logo_img.GetSize() + resized = logo_img_size / 5 + logo_img.Rescale(resized[0], resized[1]) + image = wx.Bitmap(logo_img) + _icon.CopyFromBitmap(image) + self.SetIcon(_icon) + # fill panel + panel = wx.Panel(self, -1) + sizer = wx.GridBagSizer(4, 2) + # logo and heading + png = wx.Image(FOXBMS_LOGO, wx.BITMAP_TYPE_ANY).ConvertToBitmap() + logo = wx.StaticBitmap(self, -1, png, (5, 5), (png.GetWidth(), png.GetHeight())) + heading = wx.TextCtrl( + self, + -1, + f"foxBMS 2 GUI - {fgui.__version__}", + size=(275, 30), + style=wx.TE_READONLY | wx.BORDER_NONE, + ) + # pylint:disable=no-member + font = wx.Font(20, wx.DECORATIVE, wx.NORMAL, wx.BOLD) + heading.SetFont(font) + heading.SetBackgroundColour(panel.GetBackgroundColour()) + # copyright hyperlink to foxbms.org + foxbms_copyright = wx.TextCtrl( + self, + -1, + __copyright__, + (5, 5), + size=(275, 30), + style=wx.TE_READONLY | wx.BORDER_NONE, + ) + foxbms_url = hl.HyperLinkCtrl(panel, -1, "foxbms.org", URL=FOXBMS_URL) + # License text + license_html = markdown.markdown(self.license_text, output_format="html5") + license_ctrl = wx.html.HtmlWindow( + self, + -1, + pos=(5, 5), + size=(600, 550), + style=wx.TE_READONLY | wx.TE_MULTILINE | wx.TE_NO_VSCROLL | wx.BORDER_NONE, + ) + license_ctrl.SetPage(license_html) + # GUI description + readme_html = markdown.markdown(self.readme_text, output_format="html5") + description_ctrl = wx.html.HtmlWindow( + self, + -1, + pos=(5, 5), + size=(600, 400), + style=wx.TE_READONLY | wx.TE_MULTILINE | wx.BORDER_NONE, + ) + description_ctrl.SetBackgroundColour(panel.GetBackgroundColour()) + description_ctrl.SetPage(readme_html) + # add stuff to sizer + sizer.Add(logo, pos=(0, 0), flag=wx.ALIGN_CENTER) + sizer.Add(heading, pos=(0, 1), flag=wx.ALIGN_CENTER) + sizer.Add(foxbms_copyright, pos=(1, 0), flag=wx.ALIGN_CENTER) + sizer.Add(foxbms_url, pos=(1, 1), flag=wx.ALIGN_CENTER) + sizer.Add(license_ctrl, pos=(2, 0), span=(1, 2), flag=wx.EXPAND) + sizer.Add(description_ctrl, pos=(3, 0), span=(1, 2), flag=wx.EXPAND) + panel.SetSizerAndFit(sizer) + + @staticmethod + def get_file(_file): + """Returns the file, if it exists.""" + _file = pathlib.Path(_file) + if not _file.is_file(): + _file = None + return _file + + def get_license_text(self): + """Get the license text, if this is not possible link to the online + documentation of the license""" + + if self.license_file: + license_text = self.license_file.read_text() + else: + license_text = ( + "Could not find foxBMS 2 license file.\n" + f"Please check {LICENSE_FALLBACK_URL}." + ) + self.license_file_missing_msg_box = wx.MessageBox( + license_text, "License file missing", wx.OK | wx.ICON_WARNING + ) + self.Bind(wx.EVT_BUTTON, self.license_file_missing_msg_box) + return license_text + + def get_readme_text(self): + """returns the text of the README or a default one.""" + if self.readme_file: + readme_text = self.readme_file.read_text() + else: + readme_text = "# foxBMS 2 GUI" + return readme_text diff --git a/tools/gui/log_parser.py b/tools/gui/log_parser.py index 5e42a10a..212e3e8a 100644 --- a/tools/gui/log_parser.py +++ b/tools/gui/log_parser.py @@ -42,12 +42,24 @@ """ import os +import webbrowser import cantools import wx import pandas import matplotlib.pyplot as plt -__version__ = "0.0.1" +import fgui +from info_dialog import FoxbmsInfoDialog + +__version__ = fgui.__version__ +__appname__ = fgui.__appname__ +__author__ = fgui.__author__ +__copyright__ = fgui.__copyright__ +__author__ = fgui.__author__ +__email__ = fgui.__email__ + +BASE_URL = "https://iisb-foxbms.iisb.fraunhofer.de/" +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) class LogParserFrame(wx.Frame): # pylint: disable=too-many-ancestors @@ -78,10 +90,19 @@ def basic_gui(self): menu_bar.Append(file_menu, "File") menu_bar.Append(help_menu, "Help") - self.SetMenuBar(menu_bar) + help_menu = wx.Menu() + show_info_item = help_menu.Append(wx.Window.NewControlId(), "Info", "Info") + open_documentation_item = help_menu.Append( + wx.Window.NewControlId(), "Documentation", "Documentation" + ) + menu_bar.Append(help_menu, "?") + self.Bind(wx.EVT_MENU, self.cb_show_info, show_info_item) + self.Bind(wx.EVT_MENU, self.cb_open_documentation, open_documentation_item) self.Bind(wx.EVT_MENU, self.cb_quit, file_menu_exit) self.Bind(wx.EVT_MENU, self.cb_help, help_menu_help) + self.SetMenuBar(menu_bar) + # Set up dbc file selector box wx.StaticBox( # pylint: disable=unused-variable panel, wx.ID_ANY, "Select a database-file", size=(485, 130), pos=(5, 120) @@ -164,6 +185,24 @@ def basic_gui(self): self.Show(True) + @classmethod + def cb_open_documentation(cls, event): + """Shows the foxBMS documentation from local source if it exists, from + web if it does not""" + doc = os.path.join( + SCRIPT_DIR, "..", "..", "build", "docs", "tools", "log-parser.html" + ) + if not os.path.isfile(doc): + doc = f"{BASE_URL}foxbms/gen2/docs/html/latest/tools/log-parser.html" + webbrowser.open(doc) + + @classmethod + def cb_show_info(cls, event): + """Shows the program information""" + about_dialog = FoxbmsInfoDialog(None, title="About foxBMS 2") + about_dialog.ShowModal() + about_dialog.Destroy() + def open_dialog(self, window_name, only_files): """Wrapper for the FileDialog class""" open_file_dialog = wx.FileDialog( @@ -233,7 +272,7 @@ def get_id_name(self, checked_signal): # pylint: disable=no-self-use id_signal = id_signal.upper() return id_signal, signal_name - def get_muxid(self, id_signal, signal_name, mdb): # pylint: disable=no-self-use + def get_mux_id(self, id_signal, signal_name, mdb): # pylint: disable=no-self-use """Get multiplexer ID of checked signal""" msg = mdb.get_message_by_frame_id(int(id_signal, 16)) unit = "" @@ -249,7 +288,7 @@ def get_muxid(self, id_signal, signal_name, mdb): # pylint: disable=no-self-use break return unit, mux_id, msg - def append_plotdf(self, signal_timestamp, signal_val, signal_name, unit): + def append_plot_df(self, signal_timestamp, signal_val, signal_name, unit): """Append the signal values to the plot data frame""" if len(signal_timestamp) > 0 and len(signal_val) > 0: plot_df = pandas.DataFrame() @@ -272,7 +311,7 @@ def read_pcan_log_v1(self): # pylint: disable=too-many-locals id_signal, signal_name = self.get_id_name(checked_signal) # get mux id and unit - unit, mux_id, msg = self.get_muxid(id_signal, signal_name, mdb) + unit, mux_id, msg = self.get_mux_id(id_signal, signal_name, mdb) units.append(unit) # get lines with right signal @@ -315,7 +354,7 @@ def read_pcan_log_v1(self): # pylint: disable=too-many-locals signal_val.append(decoded_sig_val) # append plot_df with new plot data - self.append_plotdf(signal_timestamp, signal_val, signal_name, unit) + self.append_plot_df(signal_timestamp, signal_val, signal_name, unit) trace_template.seek(0) self.plot_selected_signals(units) @@ -333,7 +372,7 @@ def read_pcan_log_v2(self): # pylint: disable=too-many-locals id_signal, signal_name = self.get_id_name(checked_signal) # get mux id and unit - unit, mux_id, msg = self.get_muxid(id_signal, signal_name, mdb) + unit, mux_id, msg = self.get_mux_id(id_signal, signal_name, mdb) units.append(unit) cor_signal_lines = [] @@ -375,7 +414,7 @@ def read_pcan_log_v2(self): # pylint: disable=too-many-locals signal_val.append(decoded_sig_val) # append plot_df with new plot data - self.append_plotdf(signal_timestamp, signal_val, signal_name, unit) + self.append_plot_df(signal_timestamp, signal_val, signal_name, unit) trace_template.seek(0) self.plot_selected_signals(units) @@ -393,7 +432,7 @@ def read_can_log(self): # pylint: disable=too-many-locals id_signal, signal_name = self.get_id_name(checked_signal) # get mux id and unit - unit, mux_id, msg = self.get_muxid(id_signal, signal_name, mdb) + unit, mux_id, msg = self.get_mux_id(id_signal, signal_name, mdb) units.append(unit) cor_signal_lines = [] @@ -436,7 +475,7 @@ def read_can_log(self): # pylint: disable=too-many-locals signal_val.append(decoded_sig_val) # append plot_df with new plot data - self.append_plotdf(signal_timestamp, signal_val, signal_name, unit) + self.append_plot_df(signal_timestamp, signal_val, signal_name, unit) trace_template.seek(0) self.plot_selected_signals(units) diff --git a/tools/ide/vscode/README.md b/tools/ide/vscode/README.md index 7c596e44..1553dc35 100644 --- a/tools/ide/vscode/README.md +++ b/tools/ide/vscode/README.md @@ -1 +1,7 @@ -# VS Code +# VS Code Setting Configuration + +The files in this directory contain *configuration* files for VS Code settings. +These files get properly configured when running ``waf.bat configure`` or +``waf.sh configure`` in the root of the repository. +Please note that doing so, will overwrite the contents of `.vscode/` in +the root of the repository with these templates. diff --git a/tools/ide/vscode/cspell.json.jinja2 b/tools/ide/vscode/cspell.json.jinja2 index 68c26a9b..24bf5f08 100644 --- a/tools/ide/vscode/cspell.json.jinja2 +++ b/tools/ide/vscode/cspell.json.jinja2 @@ -24,7 +24,9 @@ "phosphane", "prepending", "recurse", + "readmes", "roadmap", + "semihosting", "strippable", "substate", "substates", @@ -32,6 +34,7 @@ "supercapacitors", "throughs", "toolchain", + "toolchains", "toolset", "undervoltage", "unversioned", @@ -53,8 +56,10 @@ "Altium", "GitHub", "GitLab", + "Mictor", // user name in the documentatn "vulpes", + "fgui", // Windows related "USERPROFILE", "LOCALAPPDATA", @@ -334,6 +339,10 @@ "epcos", "vishay", "ntcalug", // temperature sensor form vishay + "preinc", + "dashserver", + "localbuild", + "noauth", // asm keywords "endasmfunc", // third party software, tools, configuration files etc. @@ -546,6 +555,7 @@ "docs/doxygen*.*", "docs/general/team-ad-sc.rst", "docs/general/team-dev.rst", + "docs/general/team-former.rst", "docs/spelling_wordlist.txt", "docs/software/configuration/fstartup.c-check.txt", "docs/general/licenses-packages-conda-env.csv", diff --git a/tools/ide/vscode/settings.json.jinja2 b/tools/ide/vscode/settings.json.jinja2 index eb6ead40..b9ba37e4 100644 --- a/tools/ide/vscode/settings.json.jinja2 +++ b/tools/ide/vscode/settings.json.jinja2 @@ -64,7 +64,6 @@ "editor.rulers": [ 79 ], - "files.eol": "\r\n", "[shellscript]": { "files.eol": "\n", }, diff --git a/tools/utils/README.md b/tools/utils/README.md index 019b1540..d382619c 100644 --- a/tools/utils/README.md +++ b/tools/utils/README.md @@ -1,10 +1,15 @@ -# Copy of HALCoGen generated HAL files +# Utils -The script ``copy_halcogen_files.py`` copies all necessary HAL files generated -by the HALCoGen project from ``conf/hcg`` to to the ``src/hal`` directory. +This directory and its subdirectories contain batch and shellscript helper +scripts. The ``bash`` +directory contains bash scripts while ``cmd`` scripts contains batch scripts. -- It copies all ``*.c``, ``*.h`` and ``*.asm`` files. -- It does **not** copy the linker scripts ``*.cmd``. -- It does **not** copy the FreeRTOS sources (``*.c`` and ``*.h`` files. Instead -it parses ``src/os/freertos/include/FreeRTOSConfig.h`` and sets the correct -value for the define ``configCPU_CLOCK_HZ``. +| Script | Purpose | +|:----------------------------------|:------------------------------------------------------------------------------| +| ``bash/find_base_conda.sh`` | Searches for the base conda installation in common installation directories. | +| ``bash/run-python-script.sh`` | Runs a python script by passing all arguments verbatim to python. | +| ``cmd/find_base_conda.bat`` | Searches for the base conda installation in common installation directories. | +| ``cmd/find_git.bat`` | Searches for a git installation in common installation directories. | +| ``cmd/run-python.bat`` | Opens an interactive python shell (no arguments get passed to python). | +| ``cmd/run-python-coverage.bat`` | Runs the coverage tool (no arguments get passed to the tool). | +| ``cmd/run-python-script.bat`` | Runs a python script by passing all arguments verbatim to python. | diff --git a/tools/utils/bash/find_base_conda.sh b/tools/utils/bash/find_base_conda.sh old mode 100644 new mode 100755 index 1a65910e..c7a19d97 --- a/tools/utils/bash/find_base_conda.sh +++ b/tools/utils/bash/find_base_conda.sh @@ -83,6 +83,14 @@ function _win32_get_vars() { DEVEL_ENV_FOUND="$base_env" fi done + + if [ -z "${DEVEL_ENV_FOUND}" ]; then + echo "Could not find conda development environment directories [${BASE_ENVS_FOUND}]" + echo "Run '$SCRIPTDIR/../conda-update-env.bat'" + echo "Exiting..." + exit 1 + fi + CONDA_BASE_ENVIRONMENT_INCLUDING_DEVELOPMENT_ENVIRONMENT=$DEVEL_ENV_FOUND CONDA_BASE_ENVIRONMENT_ACTIVATE_SCRIPT=$DEVEL_ENV_FOUND$ACTIVATE_SCRIPT CONDA_DEVELOPMENT_ENVIRONMENT_NAME=$CONDA_DEVELOPMENT_ENVIRONMENT_NAME diff --git a/tools/utils/bash/run-python-script.sh b/tools/utils/bash/run-python-script.sh old mode 100644 new mode 100755 diff --git a/tools/utils/cmd/run-python-coverage.bat b/tools/utils/cmd/run-python-coverage.bat index 33e0ffa6..7e555c82 100644 --- a/tools/utils/cmd/run-python-coverage.bat +++ b/tools/utils/cmd/run-python-coverage.bat @@ -54,10 +54,11 @@ @CALL %CONDA_BASE_ENVIRONMENT_ACTIVATE_SCRIPT% %CONDA_DEVELOPMENT_ENVIRONMENT_NAME% -@SET PYEXE=coverage -@WHERE %PYEXE% 1>NUL 2>NUL +@SET PROGRAM=coverage +@WHERE %PROGRAM% 1>NUL 2>NUL @IF %ERRORLEVEL% NEQ 0 ( @EXIT /b %ERRORLEVEL% ) ELSE ( - @%PYEXE% %* + @%PROGRAM% %* ) +@EXIT /b %ERRORLEVEL% diff --git a/tools/waf-tools/f_bootstrap_library_project.py b/tools/waf-tools/f_bootstrap_library_project.py index b5d4ae7c..a9756124 100644 --- a/tools/waf-tools/f_bootstrap_library_project.py +++ b/tools/waf-tools/f_bootstrap_library_project.py @@ -96,7 +96,7 @@ def bootstrap_library_project(ctx): hcg_tool_line = re.compile(r"load\(.*\"f_hcg\"") for line in compiler_tool_txt.splitlines(): if not hcg_tool_line.search(line): - compiler_tool_txt_new += line + "\n" + compiler_tool_txt_new += line + os.linesep compiler_tool_txt_new = re.sub( r'\s{0,}(,)?\s{0,}"hcg_compiler"\s{0,}(,)?\s{0,}', "", compiler_tool_txt_new ) diff --git a/tools/waf-tools/f_guidelines.py b/tools/waf-tools/f_guidelines.py index b5ffa9a1..e7fe3c50 100644 --- a/tools/waf-tools/f_guidelines.py +++ b/tools/waf-tools/f_guidelines.py @@ -435,7 +435,7 @@ def test(txt): error = GuidelineViolations.NO_VIOLATION if not txt == "": - if not txt.endswith("\n"): + if not txt.endswith(os.linesep): error = GuidelineViolations.GENERAL_EOF_NO_EMPTY_NEWLINE if txt and txt.splitlines()[-1] == "": error = GuidelineViolations.GENERAL_EOF_TOO_MANY_EMPTY_NEWLINES @@ -950,7 +950,7 @@ def test(txt, section_strings): for j, comment_string in enumerate(section_strings): if comment_string == line: found_section.append((j, i, previous_line)) - previous_line = line.rstrip("\n") + previous_line = line.rstrip(os.linesep) found_section_bool = [False] * len(section_strings) previous_section_index = -1 diff --git a/tools/waf-tools/f_miniconda_env.py b/tools/waf-tools/f_miniconda_env.py index b95eb63a..23b4803b 100644 --- a/tools/waf-tools/f_miniconda_env.py +++ b/tools/waf-tools/f_miniconda_env.py @@ -172,7 +172,7 @@ def configure(conf): # pylint: disable=too-many-statements,too-many-branches ).split() try: std = conf.cmd_and_log( - cmd, output=Context.BOTH, quiet=Context.BOTH, input="\n".encode() + cmd, output=Context.BOTH, quiet=Context.BOTH, input=os.linesep.encode() ) except Errors.WafError as env_export: Logs.error(env_export.msg.strip()) diff --git a/tools/waf-tools/f_ti_arm_cgt.py b/tools/waf-tools/f_ti_arm_cgt.py index fd2b3bc1..1f7e5eeb 100644 --- a/tools/waf-tools/f_ti_arm_cgt.py +++ b/tools/waf-tools/f_ti_arm_cgt.py @@ -126,7 +126,7 @@ def colorize(txt): lines.append(Logs.colors.RED + line + Logs.colors.NORMAL) else: lines.append(line) - return "\n".join(lines) + return os.linesep.join(lines) def options(opt): @@ -621,11 +621,11 @@ def exec_command(self, cmd, **kw): # pylint: disable=arguments-differ std[0], ) if Logs.verbose: - Logs.info("\n".join(hits)) + Logs.info(os.linesep.join(hits)) if errors: Logs.error( "Removing binary as the following errors occurred after linkage:\n" - + "\n".join(errors) + + os.linesep.join(errors) ) # remove output since the binary was not linked as desired for i in self.outputs: @@ -1196,28 +1196,38 @@ def run(self): ) self.outputs[0].write( - '#include "version_cfg.h"\r\n' - "#pragma RETAIN(f_version_info)\r\n" - "const VERSION_s f_version_info = {\r\n" - f" .under_version_control = {is_git_repo},\r\n" - f" .is_dirty = {is_dirty},\r\n" - f' .version = "{version}",\r\n' - f' .git_remote = "{git_remote}",\r\n' - "};\r\n", + os.linesep.join( + [ + '#include "version_cfg.h"', + "#pragma RETAIN(f_version_info)", + "const VERSION_s f_version_info = {", + f" .under_version_control = {is_git_repo},", + f" .is_dirty = {is_dirty},", + f' .version = "{version}",', + f' .git_remote = "{git_remote}",', + "};", + ] + ) + + os.linesep, encoding="utf-8", ) self.outputs[1].write( - f"#ifndef {define_guard}\r\n" - f"#define {define_guard}\r\n" - '#include "general.h"\r\n' - "typedef struct VERSION {\r\n" - " bool under_version_control;\r\n" - " bool is_dirty;\r\n" - f" char version[{len(version)}u];\r\n" - f" char git_remote[{len(git_remote)}u];\r\n" - "} VERSION_s;\r\n" - f"extern const VERSION_s f_version_info;\r\n" - f"#endif /* {define_guard} */\r\n", + os.linesep.join( + [ + f"#ifndef {define_guard}", + f"#define {define_guard}", + '#include "general.h"', + "typedef struct VERSION {", + " bool under_version_control;", + " bool is_dirty;", + f" char version[{len(version)}u];", + f" char git_remote[{len(git_remote)}u];", + "} VERSION_s;", + "extern const VERSION_s f_version_info;", + f"#endif /* {define_guard} */", + ] + ) + + os.linesep, encoding="utf-8", ) @@ -1316,7 +1326,7 @@ def run(self): {"file:": self.inputs[0].relpath(), "functions": swi_functions}, indent=4, ) - self.outputs[0].write(info + "\r\n") + self.outputs[0].write(info + os.linesep) def keyword(self): """displayed keyword when this check is run""" @@ -1371,7 +1381,7 @@ def run(self): all_swi_functions, indent=4, ) - self.outputs[0].write(all_info + "\r\n") + self.outputs[0].write(all_info + os.linesep) @TaskGen.feature("swi-check") diff --git a/tools/waf-tools/f_vscode.py b/tools/waf-tools/f_vscode.py index 2af1abc6..cf3cdbd8 100644 --- a/tools/waf-tools/f_vscode.py +++ b/tools/waf-tools/f_vscode.py @@ -57,7 +57,10 @@ def fix_jinja(txt): """appends empty line to file, if missing""" - return "\n".join([s for s in txt.splitlines() if not s.strip() == ""]) + "\n" + return ( + os.linesep.join([s for s in txt.splitlines() if not s.strip() == ""]) + + os.linesep + ) def configure(conf): # pylint: disable=too-many-statements,too-many-branches diff --git a/waf.sh b/waf.sh old mode 100644 new mode 100755 index b39dd1e0..5bddeeb8 --- a/waf.sh +++ b/waf.sh @@ -65,7 +65,16 @@ elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ] || [ "$(expr substr $ PATHS_TO_ADD=`echo $PATHS_TO_ADD | awk '{gsub("C:", "/c", $0); print}'` PATHS_TO_ADD=$(echo "${PATHS_TO_ADD#?}" | tr '\\' '/') export PATH=$PATHS_TO_ADD:$PATH - CONDA_VARS=$($SCRIPTDIR/tools/utils/bash/find_base_conda.sh) + # call find_base_conda and make sure that we do not exit by printing + # the exit code to CONDA_VARS (otherwise we would exit with set -e, here + # we will not as echo returns exit code 0) + CONDA_VARS=$($SCRIPTDIR/tools/utils/bash/find_base_conda.sh || echo $?) + if [ "${CONDA_VARS: -1}" == "1" ]; then + # strip the exit code that we have printed to CONDA_VARS and + # print the rest + echo "${CONDA_VARS: : -1}" + exit 1 + fi CONDA_VARS_ARRAY=($CONDA_VARS) CONDA_BASE_ENVIRONMENT_INCLUDING_DEVELOPMENT_ENVIRONMENT=${CONDA_VARS_ARRAY[0]} CONDA_BASE_ENVIRONMENT_ACTIVATE_SCRIPT=${CONDA_VARS_ARRAY[1]} diff --git a/wscript b/wscript index 0c82b736..a41436c7 100644 --- a/wscript +++ b/wscript @@ -72,8 +72,6 @@ from waflib.Build import BuildContext, CleanContext, ListContext, StepContext Context.Context.line_just = 50 Configure.autoconfig = 1 -sys_platform = Utils.unversioned_sys_platform() # pylint:disable=invalid-name - out = "build" # pylint:disable=invalid-name """output directory""" top = "." # pylint:disable=invalid-name @@ -82,7 +80,7 @@ top = "." # pylint:disable=invalid-name APPNAME = "foxBMS" """name of the application. This is used in various waf functions""" -VERSION = "1.0.1" +VERSION = "1.0.2" """version of the application. This is used in various waf functions. This version must match the version number defined in ``macros.txt``. Otherwise a configuration error is thrown.""" @@ -122,15 +120,15 @@ for target_type, target_val in ALL_VARIANTS.items(): variant = var -bld_variants = [] # pylint:disable=invalid-name -cln_variants = [] # pylint:disable=invalid-name +BLD_VARIANTS = [] +CLN_VARIANTS = [] # build and clean variants exist for all commands for target_type, target_val in ALL_VARIANTS.items(): for var in target_val: - bld_variants.append(f"build_{var}") - cln_variants.append(f"clean_{var}") + BLD_VARIANTS.append(f"build_{var}") + CLN_VARIANTS.append(f"clean_{var}") -dist_exclude = ( # pylint:disable=invalid-name +DIST_EXCLUDE = ( f"{out}/** **/.git **/.gitignore .gitlab/** **/.gitattributes " "**/*.tar.bz2 **/*.tar.gz **/*.pyc __pycache__ " "tools/waf*.*.**-* .lock-* " @@ -142,27 +140,42 @@ dist_exclude = ( # pylint:disable=invalid-name def version_consistency_checker(ctx): """checks that all version strings in the repository are synced""" doc_dir = "docs" + changelog_file = ctx.path.find_node( + os.path.join(doc_dir, "general", "changelog.rst") + ) + changelog_txt = changelog_file.read(encoding="utf-8") m_file = ctx.path.find_node(os.path.join(doc_dir, "macros.txt")) m_file_txt = m_file.read(encoding="utf-8") gs_file = ctx.path.find_node( os.path.join(doc_dir, "getting-started", "software-installation.rst") ) gs_file_txt = gs_file.read() - if m_file_txt.find(f".. |version_foxbms| replace:: ``{str(VERSION)}``") < 0: + if m_file_txt.find(f".. |version_foxbms| replace:: ``{VERSION}``") < 0: ctx.fatal( f"The version information in {m_file} is different from the " - f"specified version {str(VERSION)}." + f"specified version {VERSION}." + ) + if changelog_txt.find(f"[{VERSION}]") < 0: + ctx.fatal( + f"The version information in {changelog_file} is different " + f"from the specified version {VERSION}." ) repo_url = "https://github.com/foxBMS/foxbms-2" must_include_version = [ - f"curl -Ss -L -o foxbms-2-v{str(VERSION)}.zip {repo_url}/archive/v{str(VERSION)}.zip", - f"tar -x -f foxbms-2-v{str(VERSION)}.zip", + f"curl -Ss -L -o foxbms-2-v{VERSION}.zip {repo_url}/archive/v{VERSION}.zip", + f"tar -x -f foxbms-2-v{VERSION}.zip", + f"ren foxbms-2-{VERSION} foxbms-2", ] if not all([gs_file_txt.find(i) > 0 for i in must_include_version]): ctx.fatal( f"The version information in {gs_file} is different from the " - f"specified version {str(VERSION)}" + f"specified version {VERSION}" ) + pys = [ + ctx.path.find_node(os.path.join("tools", "gui", "fgui", "__init__.py")), + ] + if not all([i.read().find(f'__version__ = "{VERSION}"') > 0 for i in pys]): + ctx.fatal(f"Version information in {pys} is not correct.") def options(opt): @@ -217,6 +230,12 @@ def options(opt): help="Use a configuration cache", ) + opt.add_option( + "--skip-doxygen", + action="store_true", + help="Builds the documentation without the Doxygen documentation", + ) + opt.add_option("--vscshell", default="bash", choices=["bash", "cmd"]) opt.load("f_miniconda_env", tooldir=TOOLDIR) opt.load("f_lauterbach", tooldir=TOOLDIR) @@ -394,7 +413,7 @@ def build(bld): # pylint: disable=too-many-branches,too-many-statements if not bld.variant: bld.fatal( f"A {bld.cmd} variant must be specified. The build variants are: " - f"{', '.join(bld_variants)}.\nFor more details run 'python " + f"{', '.join(BLD_VARIANTS)}.\nFor more details run 'python " f"tools{os.sep}waf --help'" ) @@ -615,17 +634,17 @@ def build(bld): # pylint: disable=too-many-branches,too-many-statements addon_pattern = " {}" cppcheck_root = root_pattern.format(pathlib.Path(bld.path.abspath()).as_posix()) - cppcheck_paths = "\n".join( + cppcheck_paths = os.linesep.join( [dir_pattern.format(pathlib.Path(i.abspath()).as_posix()) for i in paths] ) - cppcheck_exclude = "\n".join( + cppcheck_exclude = os.linesep.join( [ dir_pattern.format(pathlib.Path(i.abspath()).as_posix() + "/") for i in exclude ] ) addons = ["threadsafety", "y2038", "cert", "misra"] - cppcheck_addon = "\n".join([addon_pattern.format(i) for i in addons]) + cppcheck_addon = os.linesep.join([addon_pattern.format(i) for i in addons]) bld( features="subst", source=source, @@ -766,8 +785,9 @@ def build(bld): # pylint: disable=too-many-branches,too-many-statements bld.set_group("doxygen") doxy_conf_src = bld.path.get_bld().find_or_declare("doxygen_src.conf") doxy_conf_tests = bld.path.get_bld().find_or_declare("doxygen_tests.conf") - bld(features="doxygen", doxygen_conf=doxy_conf_src) - bld(features="doxygen", doxygen_conf=doxy_conf_tests) + if not bld.options.skip_doxygen: + bld(features="doxygen", doxygen_conf=doxy_conf_src) + bld(features="doxygen", doxygen_conf=doxy_conf_tests) bld.set_group("sphinx") # fmt: off @@ -789,6 +809,7 @@ def build(bld): # pylint: disable=too-many-branches,too-many-statements os.path.join(doc_dir, "general", "team.rst"), os.path.join(doc_dir, "general", "team-ad-sc.rst"), os.path.join(doc_dir, "general", "team-dev.rst"), + os.path.join(doc_dir, "general", "team-former.rst"), os.path.join(doc_dir, "introduction", "abbreviations-definitions.rst"), os.path.join(doc_dir, "introduction", "bms-overview.rst"), os.path.join(doc_dir, "getting-started", "getting-started.rst"), @@ -914,8 +935,7 @@ def build(bld): # pylint: disable=too-many-branches,too-many-statements config = bld.path.find_node(os.path.join("docs", "conf.py")) bld( features="sphinx", - # builders="html linkcheck spelling", - builders="html", + builders="html linkcheck spelling", outdir=".", source=source, confpy=config, @@ -926,13 +946,13 @@ def build(bld): # pylint: disable=too-many-branches,too-many-statements def build_all(ctx): # pylint: disable=unused-argument """shortcut to build all variants""" - for bld_var in bld_variants: + for bld_var in BLD_VARIANTS: Options.commands.insert(0, bld_var) def clean_all(ctx): # pylint: disable=unused-argument """shortcut to clean all variants""" - for cln_var in cln_variants: + for cln_var in CLN_VARIANTS: Options.commands.insert(0, cln_var) @@ -940,7 +960,7 @@ def dist(conf): """creates a archive based on the current repository state""" conf.base_name = APPNAME.lower() conf.algo = "tar.gz" - conf.excl = dist_exclude + conf.excl = DIST_EXCLUDE def distcheck_cmd(self): # pylint: disable=unused-argument,missing-function-docstring @@ -991,7 +1011,7 @@ def distcheck(conf): Scripting.DistCheck.make_distcheck_cmd = distcheck_cmd Scripting.DistCheck.check = check_cmd conf.base_name = APPNAME.lower() - conf.excl = dist_exclude + conf.excl = DIST_EXCLUDE class DistCheckBin(Scripting.DistCheck): @@ -1008,7 +1028,7 @@ def distcheck_bin(conf): Scripting.DistCheck.make_distcheck_cmd = distcheck_cmd Scripting.DistCheck.check = check_cmd conf.base_name = APPNAME.lower() - conf.excl = dist_exclude + conf.excl = DIST_EXCLUDE def check_filenames(ctx):