diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3c20192..8c3bc19 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -45,6 +45,10 @@ jobs: run: | ./generate_static.py + - name: Generate example docs + run: | + ./generate.py + - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: diff --git a/.gitignore b/.gitignore index 01c74fb..0f99dc4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ _site/ +_gb_temp_/ build/ + .vscode/* .venv/ __pycache__/ diff --git a/documentation/PeliCalse1430.md b/documentation/PeliCalse1430.md new file mode 100644 index 0000000..d5e0900 --- /dev/null +++ b/documentation/PeliCalse1430.md @@ -0,0 +1,20 @@ +--- +PartData: + Specs: + Internal Dimensions: 360 x 162 x 295 mm + Internal Lid Depth: 50 mm + Internal Base Depth: 245 mm + External Dimensions: 430 x 244 x 341 mm + Weight Empty: 2.54 kg + Weight With Foam: 2.95 kg + IP rating: IP67 + Airline carry on size?: True + Suppliers: + Peli Products: + PartNo: 1430-001-110 + Link: https://peliproducts.co.uk/products/1430-protector-case +--- + +# Peli Case 1430 + +To print the nimble you will need a fused filament fabrication (FFF) 3D printer, sometimes called a FDM printer. Most FDM printers should do. \ No newline at end of file diff --git a/documentation/README.md b/documentation/README.md index 4921067..6ea8c4d 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -1,30 +1,5 @@ - +This directory contains fixed documentation for all nimble racks and the templates that will be used by our orchestration script to generate complete documentation for any custom rack. -# This project is documented with GitBuilding - -## What is GitBuilding - -GitBuilding is an OpenSource project for documenting hardware projects with minimal -effort, so you can stop writing and GitBuilding. GitBuilding is a python program that -works on Windows, Linux, and MacOS. More information on the GitBuilding project, or how -to install GitBuilding please see the [GitBuilding website](http://gitbuilding.io) - -## How do I edit the documentation? - -To edit the documentation you do not need to install anything, but you will need to -install something to build the final version of the documentation (such as a website). -The documentation files can be opened in a plain text editor such as Windows Notepad, -Notepad++, gedit, VS Code, etc. GitBuilding also comes with a browser-based editor that -displays has a live display of the final HTML documentation. - -If you have ever used [markdown](https://www.markdownguide.org/basic-syntax/) you will -notice that the files you are editing are markdown files. GitBuilding uses an extended -markdown syntax (that we call BuildUp). This allows you to keep track of parts in the -documentation. More detail on the documentation is available on the -[GitBuilding website](https://gitbuilding.io/syntax/). There is also additional -[syntax for configuration](https://gitbuilding.io/syntax/buildconfsyntax), and for -[part libraries](https://gitbuilding.io/syntax/builduplibrary/). +As these scripts are not yet complete please see our [example documentation repository](https://github.com/Wakoma/nimble-example-documentation). diff --git a/documentation/_templates/header.html.jinja b/documentation/_templates/header.html.jinja new file mode 100644 index 0000000..7e0af23 --- /dev/null +++ b/documentation/_templates/header.html.jinja @@ -0,0 +1,15 @@ +
+{% if title is not none %} + +

{{title}}

+{%endif %} +{% if subtitle is not none %} +

{{subtitle}}

+{%endif %} +{% if authors is not none %} +

by {{authors}}

+{%endif %} +{% if affiliation is not none %} +

{{affiliation}}

+{%endif %} +
diff --git a/documentation/assets/favicon-16x16.png b/documentation/assets/favicon-16x16.png new file mode 100644 index 0000000..6544b2f Binary files /dev/null and b/documentation/assets/favicon-16x16.png differ diff --git a/documentation/assets/favicon-32x32.png b/documentation/assets/favicon-32x32.png new file mode 100644 index 0000000..ebedb2e Binary files /dev/null and b/documentation/assets/favicon-32x32.png differ diff --git a/documentation/assets/favicon.ico b/documentation/assets/favicon.ico new file mode 100644 index 0000000..472665f Binary files /dev/null and b/documentation/assets/favicon.ico differ diff --git a/documentation/assets/style.css b/documentation/assets/style.css new file mode 100644 index 0000000..93978b4 --- /dev/null +++ b/documentation/assets/style.css @@ -0,0 +1,19 @@ + + +.wakoma-logo{ + width:60%; +} + +.wakoma-logo-link{ + line-height: 0.5; +} + +.site-title { + color: #424242; + font-size: 32px; + font-weight: 400; + line-height: 54px; + letter-spacing: -1px; + margin-bottom: 0; + display: flex; +} diff --git a/documentation/assets/wakoma-logo.png b/documentation/assets/wakoma-logo.png new file mode 100644 index 0000000..c7182e5 Binary files /dev/null and b/documentation/assets/wakoma-logo.png differ diff --git a/documentation/buildconf.yaml b/documentation/buildconf.yaml index dfbe156..8298523 100644 --- a/documentation/buildconf.yaml +++ b/documentation/buildconf.yaml @@ -1,31 +1,32 @@ - -Title: 'Nimble Rack' - -Authors: - - The Nimble team - -Affiliation: Wakoma - +AutoCompleteSubNav: true +CustomCategories: + consumable: + DisplayName: Comsumables + Reuse: false + mech: + DisplayName: Mechanical Components + Reuse: false + net: + DisplayName: Networking Compontents + Reuse: false + prev: + DisplayName: Previously Assembled + Reuse: false + printed: + DisplayName: 3D printed parts + Reuse: false +DefaultCategory: mech +HoverColor: '#555555' License: CERN-OHL-S-2.0 - -Email: info@wakoma.co - - -#Uncomment below to add custom categories -#CustomCategories: -# printedtool: -# Reuse: False -# DisplayName: Printed tools - -#Uncomment below to set a custom default category -#DefaultCategory: printedtool - -#Uncomment below to set the title for the bill of material on a page -#PageBOMTitle: '##For this step you will need' - - -#Uncomment below to set a custom Website root for static HTML builds -# WebsiteRoot: index.html - -#Uncomment below to disable fussy warnings -#Fussy: False +Navigation: + - Link: config.md + Title: Your Nimble Configuration + - Link: troubleshooting.md + Title: Troubleshooting + - Link: knowledgebase.md + Title: Knowledge Base +PageBOMTitle: '## For this page you will need' +PrimaryColor: '#2d3b46' +SecondaryColor: '#cccccc' +ExternalDirs: + project: ".." diff --git a/documentation/case.md b/documentation/case.md new file mode 100644 index 0000000..0c74cb8 --- /dev/null +++ b/documentation/case.md @@ -0,0 +1,38 @@ +--- +Make: + AP Mount Top: + template: printing.md + stl-file: ../Legacy/STLs/ap_mount_for_1430_top.stl + stlname: ap_mount_for_1430_top.stl + material: PLA + weight-qty: 40g + supports: "Yes" + AP Mount Bottom: + template: printing.md + stl-file: ../Legacy/STLs/ap_mount_for_1430_bottom.stl + stlname: ap_mount_for_1430_bottom.stl + material: PLA + weight-qty: 40g + supports: "Yes" +--- + +# Prepare the case + +{{BOM}} + +[M4x10mm countersunk screws]: parts/Hardware.yaml#CskScrew_M4x10mm_SS +[M4x10mm cap screws]: parts/Hardware.yaml#CapScrew_M4x10mm_SS + +## Construct the lid insert {pagestep} + +* Join [AP Mount Top]{make, qty:1,cat:printed} and [AP Mount Bottom]{make, qty:1,cat:printed} together using two [M4x10mm countersunk screws]{qty: 2,cat: mech} and a [3mm Allen key](parts/metric_allen_keys.md){qty: 1,cat: tool} +* Using three more [M4x10mm countersunk screws]{qty: 3,cat: mech} attach the brackets that came with your three UniFi Access Points to the holes just below the join between the two prints. + +## Attach to case{pagestep} + +* Get your [Peli Case][Peli Case 1430](PeliCalse1430.md){qty:1} and open the lid. +* Locate the mounting lugs on the Peli Case lid and align the lid insert with these lugs +* Use [M4x10mm cap screws]{qty: 2,cat: mech} to attach the inset into the Peli Case. + +>!! **TODO** +>!! Add images of this step diff --git a/documentation/components.md b/documentation/components.md deleted file mode 100644 index d5dff15..0000000 --- a/documentation/components.md +++ /dev/null @@ -1,28 +0,0 @@ - - -# Installing the components in trays - -{{BOM}} -![](svg/baseplate_beams_topplate.svg) - -For all of your components: - -* find the corresponding 3d printed tray -* install the tray on the rack -* mount the device on the tray - -Here are the devices and the trays - -* [Netgate SG-1100](DeviceParts.yaml#NetgateSG1100){Qty: 1} -* tray_NetgateSG1100.stl ([preview](models/tray_NetgateSG1100.stl){previewpage}, [download](models/tray_NetgateSG1100.stl)) -* [UniFi USW-Flex](DeviceParts.yaml#UniFiUSWFlex){Qty: 1} -* tray_UniFiUSWFlex.stl ([preview](models/tray_UniFiUSWFlex.stl){previewpage}, [download](models/tray_UniFiUSWFlex.stl)) -* [Intel NUC10i5FNH](DeviceParts.yaml#NUC10i5FNH){Qty: 1} -* tray_NUC10i5FNH.stl ([preview](models/tray_NUC10i5FNH.stl){previewpage}, [download](models/tray_NUC10i5FNH.stl)) -* [Raspberry Pi 4](DeviceParts.yaml#RPi4){Qty: 1} -* tray_RPi4.stl ([preview](models/tray_RPi4.stl){previewpage}, [download](models/tray_RPi4.stl)) -![](svg/trays.svg) diff --git a/documentation/config.md b/documentation/config.md new file mode 100644 index 0000000..d60b748 --- /dev/null +++ b/documentation/config.md @@ -0,0 +1,11 @@ +# Your Nimble Configuration + +The nimble is a modular rack-and-shelf system. The first part of construction is to 3D print the custom parts, and then to assemble the shelves. + +The shelves in your system are: + +{{listpages, tag:shelf}} + +Once you have assembled each shelf, you will [construct the rack](construction.md){step} and [prepare the case](case.md){step} before finally [wiring up the system](wiring.md){step} and [setting it up](setup.md){step}. + +Make sure you have [all the parts you need]{bom}, before you start assembly. \ No newline at end of file diff --git a/documentation/construction.md b/documentation/construction.md new file mode 100644 index 0000000..28737bb --- /dev/null +++ b/documentation/construction.md @@ -0,0 +1,66 @@ +--- +Make: + base plate: + template: printing.md + stl-file: ../build/printed_components/baseplate.stl + stlname: baseplate.stl + material: PLA + weight-qty: 50g + top plate: + template: printing.md + stl-file: ../build/printed_components/topplate.stl + stlname: topplate.stl + material: PLA + weight-qty: 50g + rack legs: + template: printing.md + stl-file: ../build/printed_components/beam.stl + stlname: beam.stl + material: PLA + weight-qty: 60g + stuff shelf: + template: printing.md + stl-file: models/Stuff_Shelf_1.0.stl + stlname: Stuff_Shelf_1.0.stl + material: PLA + weight-qty: 50g +--- + +# Construct and populate the rack + +{{BOM}} + +[M4x10mm countersunk screws]: parts/Hardware.yaml#CskScrew_M4x10mm_SS +[M4x10mm cap screws]: parts/Hardware.yaml#CapScrew_M4x10mm_SS + +## Attach the legs to the base plate {pagestep} + +* Get the [base plate]{make, qty:1, cat:printed} and the four [rack legs]{make, qty:4, cat:printed} that you printed earlier. +* Get a [3mm Allen key](parts/metric_allen_keys.md){qty:1, cat:tool} ready +* Use four [M4x10mm countersunk screws]{qty:4} to attach a leg to each corner of the bottom. + +>!! **TODO** +>!! Add images of this step + +## Add the broad shelves {pagestep} + +>!! **TODO** +>!! Each shelf that is broad should be added in this stage + + +## Mount the top plate {pagestep} + +* Take the [top plate]{make, qty:1, cat:printed} and place it on top of the rack. +* Use four [M4x10mm countersunk screws]{qty:4} to attach the shelf to the four legs of the rack + +>!! **TODO** +>!! Add images of this step + + +## Insert the remaining shelves {pagestep} + +>!! **TODO** +>!! Explain what order the assembled shelves are used. + + + diff --git a/documentation/fasteners.yaml b/documentation/fasteners.yaml deleted file mode 100644 index d4f968c..0000000 --- a/documentation/fasteners.yaml +++ /dev/null @@ -1,24 +0,0 @@ - -M4x10PanSteel: - Name: M4x10 Pan Head Steel - Specs: - Head: Pan - Length: 10 mm - Material: Stainless Steel - Pitch: 0.7 - Suppliers: - RS: - PartNo: 528-817 - Link: https://uk.rs-online.com/web/p/machine-screws/0528817/ - McMasterCarr: - PartNo: 90116A207 - Link: https://www.mcmaster.com/90116A207 - -M5x8_DIN7991: - Name: M5x8 DIN 7991 Counter Sunk Screw - Specs: - Head: Counter Sunk / Flat Head - Size: M5 - Length: 8 mm - Pitch: Standard / 0.8 - Material: Stainless Steel diff --git a/documentation/finalize.md b/documentation/finalize.md deleted file mode 100644 index e69de29..0000000 diff --git a/documentation/frame.md b/documentation/frame.md deleted file mode 100644 index 59286be..0000000 --- a/documentation/frame.md +++ /dev/null @@ -1,33 +0,0 @@ - - -[M5x8 screws]:fasteners.yaml#M5x8_DIN7991 -[Allen Key 3mm]:tools.yaml#Allen_3mm - -# Assembling the frame - -{{BOM}} - -## Start with the base plate {pagestep} - -* Start with the [3d printed base plate](3DPParts.yaml#baseplate){Qty: 1} - -![](svg/baseplate.svg) - -## Add beams {pagestep} - -* Add a [3d printed beam](3DPParts.yaml#beam){Qty: 4} at each corner -* Use [M5x8 screws]{Qty: 4} and screw them together - -![](svg/baseplate_beams.svg) - -## Add top plate {pagestep} - -* Add [3d printed top plate](3DPParts.yaml#topplate){Qty: 1} -* Use [M5x8 screws]{Qty: 4} and screw it on the beams - -![](svg/baseplate_beams_topplate.svg) - diff --git a/documentation/index.md b/documentation/index.md index 9f6d604..b42f0da 100644 --- a/documentation/index.md +++ b/documentation/index.md @@ -1,28 +1,31 @@ - -# Nimble Rack Assembly +## What is Nimble -The Nimble rack is built from 3d printed parts. There are some standard components, as well as custom trays for all the networking devices that you are using. +Nimble is an open source, rapidly deployable, wireless mesh network. -This is a [list of needed parts]{BOM} -As a first step you need to 3d print the needed parts +![](../assets/img/2-23.jpg) -[.](3dprintingparts.md){step} +Anyone connected to the nimble can video and voice chat, stream videos, share files, build and run eLearning courses and websites, create collaborative spreadsheets and documents, read e-books, play games, and so much more… completely offline. -Assembly starts with the frame: +If a single internet connection is available, it can be plugged into the nimble to provide free or paid internet access to anyone on the network. The offline services and content are always available to users, regardless of internet availability. -[.](frame.md){step} +Anyone in the world can build their own nimble with locally sourced hardware and 3D-printed components. -You then add the trays and the individual components to the frame: +You can find out more about Nimble on [our website](https://wakoma.co/nimble/). -[.](components.md){step} +## Customisation -The assembly is finished by doing the cabling and adding the battery +Nimble, as an open source project, is designed so that you can tailor it to your own needs and to the hardware that you have available. -[.](finalize.md){step} +![](../assets/img/Model_M/1.jpg) +We are [working on building an interface for customising your nimble](https://github.com/Wakoma/nimble/pull/23). In the mean time this is an example of the assembly instructions for a specific configuration. + +To customise your Nimble you can go to [our GitHub](https://github.com/Wakoma/nimble). If you aren't sure where to start, you can always ask for help by [opening an issue](https://github.com/Wakoma/nimble/issues) or [starting a discussion](https://github.com/Wakoma/nimble/discussions). + +## Building your Nimble + +In the next pages we will build [your nimble](config.md){step}. diff --git a/documentation/knowledgebase.md b/documentation/knowledgebase.md new file mode 100644 index 0000000..24d3119 --- /dev/null +++ b/documentation/knowledgebase.md @@ -0,0 +1,5 @@ +# Nimble Knowledge Base + +The following pages may help you understand your Nimble. + +{{listpages, tag:info}} \ No newline at end of file diff --git a/documentation/poe-explanation.md b/documentation/poe-explanation.md new file mode 100644 index 0000000..6145e91 --- /dev/null +++ b/documentation/poe-explanation.md @@ -0,0 +1,11 @@ +--- +Tags: info +--- + +# Power over Ethernet (PoE) + +Many of the devices in your Nimble are powered directly through the Ethernet cable. + +Power over Ethernet allows both data and power to be transmitted between devices using only a single cable. This really cuts down on excess cables. + +There is far more information on Power over Ethernet at [wikipedia](https://en.wikipedia.org/wiki/Power_over_Ethernet) \ No newline at end of file diff --git a/documentation/printing.md b/documentation/printing.md new file mode 100644 index 0000000..4560f63 --- /dev/null +++ b/documentation/printing.md @@ -0,0 +1,25 @@ +# 3D Printing + +{{BOM}} + +[PLA]:parts/filament.md "{cat:consumable}" + +## Print the custom components {pagestep} + + +Using the slicer that comes with your [3d printer](parts/3dprinter.md){qty:1, cat: tool}, slice the following parts, and then print them. + +Some parts require support. A brim is advised for all parts. + + +| Qty | Item | Material | File | Supports
Required?| +|-----|------|----------|------|----------------------| +{{foreachmakeitem: "| {{qty}} | {{id}} | {{weight-qty}} of [{{material}}]{qty:{{weight-qty}}} | [{{stlname}}]({{stl-file}}){previewpage}|{{supports, default: No}}|"}} + + +You can [download all of the STLs as a single zipfile](all-stls.zip){zip, pattern:"*.stl"} + + +## Remove the brim {pagestep} + +Remove the brim with a [utility knife](parts/utility_knife.md){qty:1, cat:tool} diff --git a/documentation/setup.md b/documentation/setup.md new file mode 100644 index 0000000..586296c --- /dev/null +++ b/documentation/setup.md @@ -0,0 +1,30 @@ +# Set up your Nimble + +>!! **TODO** +>!! +>!! * How do we power it on?! +>!! * Are there other set up steps!? + +{{BOM}} + + +## Mount the rack and access points {pagestep} + +* Take your wired Nimble rack and insert it into your Peli Case. + + +>!! **TODO** +>!! Add images of this step + +* Take the three [UniFi Access Points](parts/UniFiAccessPoints.md){qty:3, cat:net} and clip them onto the mounting brackets in the Peli Case lid. + + +>!! **TODO** +>!! Add images of this step + +## Power on the system + + +>!! **TODO** +>!! Add images of this step + diff --git a/documentation/tools.yaml b/documentation/tools.yaml deleted file mode 100644 index 68562c8..0000000 --- a/documentation/tools.yaml +++ /dev/null @@ -1,15 +0,0 @@ - -Screwdriver_Philips_No2: - Name: No. 2 Phillips screwdriver - Description: > - No2 Phillips screwdriver. This is the correct size - form an M4 pan head screw - Specs: - Drive Size: No. 2 - -Allen_3mm: - Name: Allen Key 3mm - Description: > - Allen Key 3mm - Specs: - Drive Size: 3mm diff --git a/documentation/troubleshooting.md b/documentation/troubleshooting.md new file mode 100644 index 0000000..a99dcd1 --- /dev/null +++ b/documentation/troubleshooting.md @@ -0,0 +1,3 @@ +# Troubleshooting and Support + +**Write me!!** \ No newline at end of file diff --git a/documentation/wiring.md b/documentation/wiring.md new file mode 100644 index 0000000..3682822 --- /dev/null +++ b/documentation/wiring.md @@ -0,0 +1,25 @@ +--- +Make: + Power Box: + template: printing.md + stl-file: ../Legacy/STLs/power_box.stl + stlname: power_box.stl + material: PLA + weight-qty: 60g +--- + +# Wiring the Nimble + +>!! **TODO** +>!! +>!! * Write the instructions +>!! * Be clear what passes through where +>!! * Add cables to the BOM.. what are they!? +>!! * Annotate images to be clear what we are looking at + +{{BOM}} + + +Once done must mention [Power Box]{make, qty:1,cat:printed} + + diff --git a/generate.md b/generate.md index 3d9339f..6e9f00b 100644 --- a/generate.md +++ b/generate.md @@ -46,7 +46,7 @@ To run this script, run the following command: This should create the `build` directory. Inside this the `printed_components` directory should contain a number of `stl` files that can be 3D printed. -The script also creates a simple web-page with an index of all of the files. +The script also creates a simple web-page with an index of all of the files. The final link to the "Partially complete automatically generated documentation" will be broken unless you also run `generate.py` (see below). It also creates a number of files that are used by the orchestration script. diff --git a/generate.py b/generate.py index 785aaf2..97fc2d6 100755 --- a/generate.py +++ b/generate.py @@ -26,6 +26,8 @@ def generate(selected_devices_ids): runner.generate_assembly(config.assembly_definition) + runner.generate_docs(config) + def generate_example_configuration(): """ diff --git a/generate_static.py b/generate_static.py index f95f7ef..6bf13df 100755 --- a/generate_static.py +++ b/generate_static.py @@ -150,7 +150,6 @@ def output_static_site(components): for hardware configuration. We call this "Smart Doc". For more details on Nimble see https://github.com/Wakoma/nimble

-

Smart Doc" is not yet finished, but the code already generates a number of nimble components @@ -164,6 +163,15 @@ def output_static_site(components): for component in components: f.write(f"

  • {component.name}
  • ") f.write("") + f.write( + """ +

    Example documentation:

    +

    + Partially complete automatically generated documentation + is also available. +

    + """) + f.write("") if __name__ == "__main__": diff --git a/mechanical/components/cadquery/tray_6in.py b/mechanical/components/cadquery/tray_6in.py index b5f20d2..4a90fe8 100644 --- a/mechanical/components/cadquery/tray_6in.py +++ b/mechanical/components/cadquery/tray_6in.py @@ -29,16 +29,11 @@ height_in_u = 2 -def create_6in_shelf(shelf_type, height_in_u) -> cad.Body: - """ - This is the top level function called when the script - is called. It uses the `shelf_type` string to decide - which of the defined shelf functions to call. - """ +def _shelf_functions(): # Dictionary of with key as shelf type and value as tuple # of (function, keyword-arguments) - shelf_functions = { + return { "generic": (generic_shelf, {}), "stuff": (stuff_shelf, {}), "stuff-thin": (stuff_shelf, {"thin":True}), @@ -69,11 +64,29 @@ def create_6in_shelf(shelf_type, height_in_u) -> cad.Body: "raspi": (raspi_shelf, {}) } - if shelf_type in shelf_functions: - shelf_func = shelf_functions[shelf_type][0] - kwargs = shelf_functions[shelf_type][1] - return shelf_func(height_in_u, **kwargs) - raise ValueError(f"Unknown shelf type: {shelf_type}") +def available_shelves(): + """ + Return a list of suported shelf-types. + """ + return list(_shelf_functions().keys) + +def create_6in_shelf(shelf_type, height_in_u) -> cad.Body: + """ + This is the top level function called when the script + is called. It uses the `shelf_type` string to decide + which of the defined shelf functions to call. + """ + + shelf_functions = _shelf_functions() + + if shelf_type not in shelf_functions: + print(f"Unknown shelf type: {shelf_type}, creating generic shelf") + shelf_type = "generic" + + shelf_func = shelf_functions[shelf_type][0] + kwargs = shelf_functions[shelf_type][1] + return shelf_func(height_in_u, **kwargs) + def generic_shelf(height_in_u) -> cad.Body: """ diff --git a/nimble_orchestration/components.py b/nimble_orchestration/components.py index f590496..f86b783 100644 --- a/nimble_orchestration/components.py +++ b/nimble_orchestration/components.py @@ -10,7 +10,7 @@ `MechanicalComponent` """ from copy import copy, deepcopy - +from nimble_orchestration.device import Device class MechanicalComponent: """ @@ -168,3 +168,38 @@ def color(self): The color of this component. """ return self._color + + +class Shelf: + """ + A class for all the orchestration information relating to a shelf + """ + def __init__(self, + assembled_shelf: AssembledComponent, + device: Device): + self._assembled_shelf = assembled_shelf + self._device = device + + @property + def assembled_shelf(self): + """ + Return the Object describing the assembled shelf (currently this in an empty + shelf in the correct location on the rack). + This is an AssembledComponent + """ + return self._assembled_shelf + + @property + def device(self): + """ + Return the Device object for the networking component that sits on this shelf + """ + return self._device + + @property + def md(self): + """ + Return the markdown (BuildUp) for the GitBuilding page for assembling this shelf + """ + + return f"# {self._device.name}\n\n This is a shelf for a {self._device.name}" diff --git a/nimble_orchestration/configuration.py b/nimble_orchestration/configuration.py index 0f4eaaf..92b9d1a 100644 --- a/nimble_orchestration/configuration.py +++ b/nimble_orchestration/configuration.py @@ -12,7 +12,9 @@ from nimble_builder import RackParameters from nimble_orchestration.assembly_def_generator import AssemblyDefGenerator -from nimble_orchestration.components import GeneratedMechanicalComponent, AssembledComponent +from nimble_orchestration.components import (GeneratedMechanicalComponent, + AssembledComponent, + Shelf) from nimble_orchestration.device import Device from nimble_orchestration.paths import MODULE_PATH, REL_MECH_DIR @@ -22,6 +24,7 @@ class NimbleConfiguration: """ _rack_params: RackParameters _devices: list + _shelves: list _components: list _assembled_components: list @@ -40,6 +43,7 @@ def find_device(device_id): selected_devices = [Device(find_device(x)) for x in selected_devices_ids] self._devices = deepcopy(selected_devices) + self._shelves = self._generate_shelf_list self._assembled_components = self._generate_assembled_components_list() self._components = [] for assembled_component in self._assembled_components: @@ -78,6 +82,16 @@ def assembled_components(self): """ return deepcopy(self._assembled_components) + @property + def shelves(self): + """ + Return a list of the shelves assembled in this nimble rack. + + Each object in the list is an instance of the Shelf object, this holds both the information on + the assembled shelf, and on the Device the shelf is for. + """ + return deepcopy(self._shelves) + @property def total_height_in_u(self): """ @@ -90,7 +104,7 @@ def _generate_assembled_components_list(self): # collect all needed parts and their parameters rack_components = self._legs + [self._baseplate, self._topplate] - return rack_components + self._trays + return rack_components + [i.assembled_shelf for i in self._shelves] @property def _legs(self): @@ -192,51 +206,51 @@ def _topplate(self): ) @property - def _trays(self): + def _generate_shelf_list(self): """ - Generate aseembled components for each tray. This function is a bit + Generate aseembled components for each shelf. This function is a bit long and messy! """ source = os.path.join(REL_MECH_DIR, "components/cadquery/tray_6in.py") source = posixpath.normpath(source) - trays = [] + shelves = [] z_offset = self._rack_params.bottom_tray_offet height_in_u = 0 for i, device in enumerate(self._devices): x_pos = 0 y_pos = -self._rack_params.rack_width / 2.0 z_pos = z_offset + height_in_u * self._rack_params.mounting_hole_spacing - tray_id = device.tray_id + shelf_key = device.shelf_key color = 'dodgerblue1' if i%2 == 0 else 'deepskyblue1' component = GeneratedMechanicalComponent( - key=tray_id, - name=f"{device.name} tray", - description="A tray for " + device.name, + key=shelf_key, + name=f"{device.name} shelf", + description="A shelf for " + device.name, output_files=[ - f"./printed_components/{tray_id}.step", - f"./printed_components/{tray_id}.stl", + f"./printed_components/{shelf_key}.step", + f"./printed_components/{shelf_key}.stl", ], source_files=[source], parameters={ "height_in_u": device.height_in_u, - "shelf_type": "generic", + "shelf_type": device.shelf_builder_id, }, application="cadquery" ) - trays.append( - AssembledComponent( - key=f"tray_{i}", - component=component, - position = (x_pos, y_pos, z_pos), - step=4, - color=color - ) + assm_component = AssembledComponent( + key=f"shelf_{i}", + component=component, + position = (x_pos, y_pos, z_pos), + step=4, + color=color ) + shelves.append(Shelf(assm_component, device)) + height_in_u += device.height_in_u - return trays + return shelves @property def assembly_definition(self): diff --git a/nimble_orchestration/device.py b/nimble_orchestration/device.py index 0f7aa8e..b77fc2b 100644 --- a/nimble_orchestration/device.py +++ b/nimble_orchestration/device.py @@ -2,6 +2,8 @@ Contains an object that represents the information of a device in the devices.json file. """ +import re + class Device: """ Represents a subset of the information for a device from the devices.json file @@ -48,12 +50,25 @@ def __init__(self, json_node): self.width = json_node['LengthMm'] self.depth = json_node['Depth'] self.shelf_id = json_node['ShelfId'] - # self.tray_type = json_node['TrayType'] self.shelf_type = json_node['Shelf'] @property - def tray_id(self): + def shelf_key(self): + """ + Return an key to identify the shelf. + """ + return f"shelf_h{self.height_in_u}_t{self.shelf_type.lower().replace(' ', '_')}" + + @property + def shelf_builder_id(self): """ - Return an identification for the shelf. + shelf_builder and devices.json don't use the same ids. devices.json seems + to use similar terms but appends -6 as the shelf is 6 inch, and optionally -s + and -t for tall and short versions. + These should be unified later """ - return f"tray_h{self.height_in_u}_t{self.shelf_type.lower().replace(' ', '_')}" + if self.shelf_id: + if match := re.match(r'^(.*)-6(?:-[st])?$', self.shelf_id): + #strip of -6 and optionally -s or -t + return match.group(1) + return "generic" diff --git a/nimble_orchestration/orchestration.py b/nimble_orchestration/orchestration.py index 4cf8544..80c1718 100644 --- a/nimble_orchestration/orchestration.py +++ b/nimble_orchestration/orchestration.py @@ -7,14 +7,15 @@ """ import os - +import shutil +import subprocess import exsource_tools import exsource_tools.cli import exsource_tools.tools from nimble_orchestration.exsource_def_generator import ExsourceDefGenerator -from nimble_orchestration.paths import BUILD_DIR, REL_MECH_DIR +from nimble_orchestration.paths import BUILD_DIR, REL_MECH_DIR, DOCS_DIR, DOCS_TMP_DIR class OrchestrationRunner: """ @@ -81,6 +82,35 @@ def generate_assembly(self, assembly_definition): exsource.save(exsource_path) self._run_exsource(exsource_path) + def generate_docs(self, configuration): + """ + Run GitBuilding to generate documentation + """ + if os.path.exists(DOCS_TMP_DIR): + shutil.rmtree(DOCS_TMP_DIR) + shutil.copytree(DOCS_DIR, DOCS_TMP_DIR) + + for shelf in configuration.shelves: + filename = os.path.join(DOCS_TMP_DIR, f"{shelf.device.id}_shelf.md") + with open(filename, 'w', encoding="utf-8") as gb_file: + gb_file.write(shelf.md) + + self._run_gitbuilding() + + def _run_gitbuilding(self): + cur_dir = os.getcwd() + os.chdir(DOCS_TMP_DIR) + subprocess.run( + ['gitbuilding', 'build-html'], + check=True, + capture_output=True + ) + os.chdir(cur_dir) + tmp_built_docs = os.path.join(DOCS_TMP_DIR, "_site") + built_docs = os.path.join(BUILD_DIR, "assembly-docs") + if os.path.exists(built_docs): + shutil.rmtree(built_docs) + shutil.copytree(tmp_built_docs, built_docs) def _run_exsource(self, exsource_path): diff --git a/nimble_orchestration/paths.py b/nimble_orchestration/paths.py index 2834c76..1e1d3d9 100644 --- a/nimble_orchestration/paths.py +++ b/nimble_orchestration/paths.py @@ -7,3 +7,5 @@ MODULE_PATH = os.path.normpath(os.path.join(os.path.split(__file__)[0], '..')) BUILD_DIR = os.path.join(MODULE_PATH, "build") REL_MECH_DIR = os.path.relpath(os.path.join(MODULE_PATH, "mechanical"), BUILD_DIR) +DOCS_DIR = os.path.join(MODULE_PATH, "documentation") +DOCS_TMP_DIR = os.path.join(MODULE_PATH, "_gb_temp_") diff --git a/setup.py b/setup.py index 2d79755..78841b8 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ 'cadscript>=0.5.2', 'exsource-tools', 'cq-cli @ git+https://github.com/CadQuery/cq-cli.git', - 'gitbuilding' + 'gitbuilding==0.15.0a2' ], extras_require={ 'dev': [