Skip to content

Commit

Permalink
Merge pull request #179 from DCC-EX:fresh-view
Browse files Browse the repository at this point in the history
Fresh-view
  • Loading branch information
peteGSX authored Jul 7, 2024
2 parents c4e3377 + f8dedf5 commit ecc2e18
Show file tree
Hide file tree
Showing 30 changed files with 1,215 additions and 250 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@v3
- name: Requirements
run: |
pip3 install -r requirements-sphinx.txt
pip3 install -r requirements.txt
sudo apt-get install doxygen
- name: Build docs
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,4 @@ file_version.txt

# macOS build app directory (not required)
dist/EX-Installer-macOS.app/
.DS_Store
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ Binaries will be made available to allow EX-Installer to be run on:
- Linux graphical environments
- macOS

It is possible that it will also be able to run on Raspberry Pi.

## What's in this repository?

This repository includes all source code of EX-Installer, along with related documentation and screen captures of the initial design ideas.

The binaries are kept in the /dist directory of the repository, and will also be hosted on the [DCC-EX website](https://dcc-ex.com).

### EX-Installer-Configs repository

In addition to this EX-Installer repository, there is a separate repository [EX-Installer-Configs](https://github.com/DCC-EX/EX-Installer-Configs) which contains various configuration information that EX-Installer relies on.

This enables product and device configuration information to be updated without necessarily needing to build a new release of EX-Installer binaries.

## Operating principles and modules

EX-Installer operates within the confines of the user's home directory and temp directory only, with no files or folders outside of these directories being touched.
Expand Down Expand Up @@ -44,8 +48,6 @@ Initially, EX-Installer will be focused on basic configuration and installation
Once stable, it will be expanded to be able to configure and install all of our Arduino based products including:

- EX-CommandStation
- EX-DCCInspector
- EX-FastClock
- EX-IOExpander
- EX-Turntable

Expand Down
Binary file modified dist/EX-Installer-Linux64
Binary file not shown.
Binary file modified dist/EX-Installer-Win32.exe
Binary file not shown.
Binary file modified dist/EX-Installer-Win64.exe
Binary file not shown.
Binary file modified dist/EX-Installer-macOS
Binary file not shown.
1 change: 1 addition & 0 deletions ex_installer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Initialisation module
© 2024, Peter Cole.
© 2023, Peter Cole.
All rights reserved.
Expand Down
20 changes: 17 additions & 3 deletions ex_installer/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Main application controller
© 2024, Peter Cole.
© 2023, Peter Cole.
© 2023, Harald Barth.
All rights reserved.
Expand Down Expand Up @@ -33,9 +34,13 @@
from ex_installer.file_manager import FileManager as fm


def main(debug):
def main(debug, fake):
"""
Main function to start the application
Main method to start the application.
Arguments:
debug (boolean) - Accept command line option -D|--debug to enable debug logging
fake (boolean) - Accept command line option -F|--fake to enable a fake Arduino USB device for testing/demo
"""

# Set up logger
Expand Down Expand Up @@ -91,6 +96,8 @@ def main(debug):
customtkinter.set_window_scaling(scaling)
# switch to first view _after_ the scaling because of a bug in Linux that would unhide all hidden buttons
app.switch_view("welcome")
if fake is True:
app.enable_fake_device()
app.mainloop()
_log.debug("EX-Installer closed")

Expand All @@ -99,6 +106,7 @@ def main(debug):
# Setup command line parser with debug argument
parser = argparse.ArgumentParser()
parser.add_argument("-D", "--debug", action="store_true", help="Set debug log level")
parser.add_argument("-F", "--fake", action="store_true", help="Enable fake Arduino device for demo purposes")

# Read arguments
args = parser.parse_args()
Expand All @@ -109,5 +117,11 @@ def main(debug):
else:
debug = False

# If fake supplied, pass it also
if args.fake:
fake = True
else:
fake = False

# Start the app
main(debug)
main(debug, fake)
1 change: 1 addition & 0 deletions ex_installer/advanced_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
2) If user chooses "Advanced Config" on the product configuration page
3) by backing up from Compile_Upload (only if reached from this view)
© 2024, Peter Cole.
© 2023, M Steve Todd. All rights reserved.
This file is part of EX-Installer.
Expand Down
152 changes: 130 additions & 22 deletions ex_installer/arduino_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
This module uses threads and queues
© 2023, Peter Cole. All rights reserved.
© 2024, Peter Cole.
© 2023, Peter Cole.
All rights reserved.
This file is part of EX-Installer.
Expand Down Expand Up @@ -33,6 +35,7 @@
from collections import namedtuple
import logging
from datetime import datetime, timedelta
import shutil

from .file_manager import ThreadedDownloader, ThreadedExtractor

Expand Down Expand Up @@ -164,6 +167,7 @@ def run(self, *args, **kwargs):
else:
status = "error"
self.log.error(data)
self.log.debug(f"Thread output, status: {status}\ntopic: {topic}\ndata: {data}\nparams: {self.params}")
self.queue.put(
QueueMessage(status, topic, data)
)
Expand All @@ -181,46 +185,123 @@ class ArduinoCLI:
- get_platforms() - gets the list of installed platforms
- download_cli() - downloads the appropriate CLI for the operating system, returns the file path
- install_cli() - extracts the CLI to the specified file path from download file path
- delete_cli() - deletes the CLI, returns True|False
- initialise_config() - adds additional URLs to the CLI config
- update_index() - performs the core update-index and initial board list
- get_package_list() - gets the list of platform packages to install
- install_package() - installs the provided packages
- upgrade_platforms() - performs the core upgrade to ensure all are up to date
- list_boards() - lists all connected boards, returns list of dictionaries for boards
- upload_sketch() - compiles and uploads the provided sketch to the provided device
- compile_sketch() - compiles the sketch in the provided directory ready for upload
- upload_sketch() - uploads the sketch in the provided directory to the provided device
"""

# Dictionary of Arduino CLI archives for the appropriate platform
# Currently force usage of 0.35.3 due to changes in 1.0.x output that have not been fully tested yet.
urlbase = "https://github.com/arduino/arduino-cli/releases/download/v0.35.3/arduino-cli_0.35.3_"
arduino_downloads = {
"Linux32": "https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_32bit.tar.gz",
"Linux64": "https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_64bit.tar.gz",
"Darwin64": "https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_macOS_64bit.tar.gz",
"Windows32": "https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_32bit.zip",
"Windows64": "https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.zip"
"Linux64": urlbase + "Linux_64bit.tar.gz",
"Darwin64": urlbase + "macOS_64bit.tar.gz",
"Windows32": urlbase + "Windows_32bit.zip",
"Windows64": urlbase + "Windows_64bit.zip"
}

# Dictionary for additional board/platform support for the Arduino CLI
"""
Expose the currently supported version of the Arduino CLI to use.
"""
arduino_cli_version = "0.35.3"

"""
Dictionary for the base board/platform support for the Arduino CLI.
This should really just be Arduino AVR, and must specify the version.
Note this used to be defined in the manage_arduino_cli module but is now centralised here.
This format is consistent with extra_platforms, but without the URL.
base_platforms = {
"Platform Name": {
"platform_id": "<packager>:<arch>",
"version": "<version>"
}
}
"""
base_platforms = {
"Arduino AVR": {
"platform_id": "arduino:avr",
"version": "1.8.6"
}
}

"""
Dictionary for additional board/platform support for the Arduino CLI.
These must be tied to a specific version to avoid future unknown issues:
extra_platforms = {
"Platform Name": {
"platform_id": "<packager>:<arch>",
"version": "<version>",
"url": "<url>"
}
}
- ESP32 locked to 2.0.17 as 3.x causes compile errors for EX-CommandStation
- STM32 locked to 2.7.1 because 2.8.0 introduces new output that needs logic to deal with
"""
extra_platforms = {
"Espressif ESP32": {
"platform_id": "esp32:esp32",
"version": "2.0.17",
"url": "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json"
},
"STMicroelectronics Nucleo/STM32": {
"platform_id": "STMicroelectronics:stm32",
"version": "2.7.1",
"url": "https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json"
}
}

# Dictionary of devices supported with EX-Installer to enable selection when detecting unknown devices
"""
Dictionary of required Arduino libraries to be installed.
These must be tied to a specific version to avoid future unknown issues:
arduino_libraries = {
"<library name>": "<version>"
}
Note that these were previously an attribute of a product in the product_details module but are now here.
"""
arduino_libraries = {
"Ethernet": "2.0.2"
}

"""
Dictionary of devices supported with EX-Installer to enable selection when detecting unknown devices.
"""
supported_devices = {
"Arduino Mega or Mega 2560": "arduino:avr:mega",
"Arduino Uno": "arduino:avr:uno",
"Arduino Nano": "arduino:avr:nano",
"DCC-EX EX-CSB1": "esp32:esp32:esp32",
"ESP32 Dev Kit": "esp32:esp32:esp32",
"STMicroelectronics Nucleo F411RE": "STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_F411RE",
"STMicroelectronics Nucleo F446RE": "STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_F446RE"
}

"""
Dictionary of DCC-EX specific devices, used to preselect or exclude motor driver definitions.
While this isn't ideal, it makes it easier with the current implementation to control what users can and
can't select for motor drivers.
Future additions must start with "DCC-EX" in order to be used for this purpose.
"""
dccex_devices = {
"DCC-EX EX-CSB1": "EXCSB1"
}

def __init__(self, selected_device=None):
"""
Initialise the Arduino CLI instance
Expand All @@ -229,6 +310,7 @@ def __init__(self, selected_device=None):
"""
self.selected_device = selected_device
self.detected_devices = []
self.dccex_device = None

# Set up logger
self.log = logging.getLogger(__name__)
Expand Down Expand Up @@ -314,6 +396,22 @@ def get_platforms(self, file_path, queue):
)
self.log.debug("Arduino CLI not installed")

def get_libraries(self, file_path, queue):
"""
Function to retrieve the current libraries installed with the Arduino CLI
If successful, the list will be in the queue's "data" field
"""
if self.is_installed(file_path):
params = ["lib", "list", "--format", "jsonmini"]
acli = ThreadedArduinoCLI(file_path, params, queue)
acli.start()
else:
queue.put(
QueueMessage("error", "Arduino CLI is not installed", "Arduino CLI is not installed")
)
self.log.debug("Arduino CLI not installed")

def download_cli(self, queue):
"""
Download the Arduino CLI
Expand Down Expand Up @@ -365,11 +463,27 @@ def install_cli(self, download_file, file_path, queue):
extract = ThreadedExtractor(download_file, cli_directory, queue)
extract.start()

def delete_cli(self):
"""
Deletes all files in the provided directory.
This is required to remove an unsupported version of the Arduino CLI.
"""
_result = False
cli_directory = os.path.dirname(self.cli_file_path())
if os.path.isdir(cli_directory):
try:
shutil.rmtree(cli_directory)
_result = True
except Exception as e:
self.log.error(f"Unable to delete {cli_directory}: {e}")
return _result

def initialise_config(self, file_path, queue):
"""
Initialises the Arduino CLI configuration with the provided additional boards
Initialises the Arduino CLI configuration with the provided additional boards.
Overwrites existing configuration options
Overwrites existing configuration options.
"""
params = ["config", "init", "--format", "jsonmini", "--overwrite"]
if len(self.extra_platforms) > 0:
Expand All @@ -389,20 +503,12 @@ def update_index(self, file_path, queue):
acli = ThreadedArduinoCLI(file_path, params, queue)
acli.start()

def get_package_list(self, file_path, queue):
"""
Get list of Arduino packages to install
"""
params = ["core", "list", "--format", "jsonmini"]
acli = ThreadedArduinoCLI(file_path, params, queue)
acli.start()

def install_package(self, file_path, package, queue):
"""
Install packages for the listed Arduino platforms
"""
params = ["core", "install", package, "--format", "jsonmini"]
acli = ThreadedArduinoCLI(file_path, params, queue)
acli = ThreadedArduinoCLI(file_path, params, queue, 600)
acli.start()

def upgrade_platforms(self, file_path, queue):
Expand Down Expand Up @@ -431,9 +537,11 @@ def list_boards(self, file_path, queue):

def upload_sketch(self, file_path, fqbn, port, sketch_dir, queue):
"""
Compiles and uploads the sketch in the specified directory to the provided board/port
Compiles and uploads the sketch in the specified directory to the provided board/port.
"""
params = ["upload", "-v", "-t", "-b", fqbn, "-p", port, sketch_dir, "--format", "jsonmini"]
if fqbn.startswith('esp32:esp32'):
params = params + ["--board-options", "UploadSpeed=115200"]
acli = ThreadedArduinoCLI(file_path, params, queue)
acli.start()

Expand Down
3 changes: 2 additions & 1 deletion ex_installer/common_fonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
Every view should include this module and base the layout on WindowLayout
© 2024, Peter Cole. All rights reserved.
© 2024, Peter Cole.
All rights reserved.
This file is part of EX-Installer.
Expand Down
Loading

0 comments on commit ecc2e18

Please sign in to comment.