From b3aea5dddae6195fdf3f1c953d81dbd35db4f840 Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Mon, 15 Dec 2025 10:50:18 -0500 Subject: [PATCH] feat: Initial commit. --- .gitattributes | 1 + Definitions.md | 18 ++++ README.md | 6 ++ footer.tex | 26 ++++++ head.tex | 74 ++++++++++++++++ justfile | 34 ++++++++ project/.gitignore | 6 ++ project/Airflow/.gitkeep | 0 project/README.md | 27 ++++++ project/Report.md | 172 ++++++++++++++++++++++++++++++++++++++ project/img/.gitkeep | 0 project/img/goals.png | 3 + project/img/logo.png | 3 + project/img/signature.png | 3 + project/justfile | 47 +++++++++++ project/vars.yml | 25 ++++++ project/vault.yml | 16 ++++ repo_vars/vars.yml | 44 ++++++++++ repo_vars/vault.yml | 14 ++++ 19 files changed, 519 insertions(+) create mode 100644 .gitattributes create mode 100644 Definitions.md create mode 100644 README.md create mode 100644 footer.tex create mode 100644 head.tex create mode 100644 justfile create mode 100644 project/.gitignore create mode 100644 project/Airflow/.gitkeep create mode 100644 project/README.md create mode 100644 project/Report.md create mode 100644 project/img/.gitkeep create mode 100644 project/img/goals.png create mode 100644 project/img/logo.png create mode 100644 project/img/signature.png create mode 100644 project/justfile create mode 100644 project/vars.yml create mode 100644 project/vault.yml create mode 100644 repo_vars/vars.yml create mode 100644 repo_vars/vault.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..24a8e87 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/Definitions.md b/Definitions.md new file mode 100644 index 0000000..e122fbe --- /dev/null +++ b/Definitions.md @@ -0,0 +1,18 @@ +# Definitions + + + +### IAQ {#iaq-definition} + +Stands for $I$ndoor $A$ir $Q$uality. We spend most of our time indoors, so having good indoor air +quality can help reduce illness and potentially improve the quality and longevity of life. + +### TESP {#tesp-definition} + +Stands for $T$otal $E$xternal $S$tatic $P$ressure, which is a metric used to determine how much +resistance the blower motor has to overcome for the airflow requirement of the system. + +### WC {#wc-definition} + +Stands for $W$ater $C$olumn, which is a unit of measurement for pressure. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c1d931 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Airflow Assessment Template + +This repository is a template used to generate an airflow assessment for clients. Using the +[swift-hpa](https://git.housh.dev/michael/swift-hpa.git) command line tool. + + diff --git a/footer.tex b/footer.tex new file mode 100644 index 0000000..1937ab9 --- /dev/null +++ b/footer.tex @@ -0,0 +1,26 @@ +% customize the footer +\usepackage{fancyhdr} +\pagestyle{fancy} +% clear all footers +\fancyfoot{} +% clear all headers +\fancyhead{} + +% change font size on footer. +\newcommand{\changefont}{ + \fontsize{8}{10}\selectfont +} +% NOTE: What is displayed in the footer of each page. +\fancyfoot[LE,LO]{ + \href{ {{ company.website }} } + {\changefont\textbf{ + {{ company.url_display_title }} + }} +} +\fancyfoot[RE,RO]{\textbf{ + \changefont{ + Phone: \href{tel:{{ company.phone }} }{ + \color{orange}{{ company.phone }} + } + } +}} diff --git a/head.tex b/head.tex new file mode 100644 index 0000000..a2f14f6 --- /dev/null +++ b/head.tex @@ -0,0 +1,74 @@ +% https://jdhao.github.io/2019/05/30/markdown2pdf_pandoc/#the-top +% These were adapted from the above, which was very helpful in getting this +% functional. + +% change style of quote, see also https://tex.stackexchange.com/a/436253/114857 +\usepackage[most]{tcolorbox} + +% change page margins +\usepackage[top=2cm, bottom=1.5cm, left=2cm, right=2cm]{geometry} + +% change the line spacing +\usepackage{setspace} +\setstretch{1.25} + +\usepackage[utf8]{inputenc} + +% NOTE: This needs to stay above hyperref otherwise internal links break. + +% start each section on new page and make section titles orange. +\usepackage{titlesec} +\titleformat{\section} +{\color{orange}\normalfont\Huge\bfseries} +\newcommand{\sectionbreak}{\clearpage} + +% custom colors +\definecolor{applegreen}{rgb}{0.55,0.71,0.0} + +% Remove figure from images +\usepackage[labelformat=empty]{caption} + +\usepackage{fancyvrb,newverbs} + +% see for different color codes https://rgbcolorcode.com/color/E6FFEA +\definecolor{linequote}{RGB}{224,215,188} +\definecolor{backquote}{RGB}{230,255,234} % background color of quotes +\definecolor{bordercolor}{RGB}{221,221,221} + +% change left border: https://tex.stackexchange.com/a/475716/114857 +% change left margin: https://tex.stackexchange.com/a/457936/114857 +\newtcolorbox{myquote}[1][]{% + enhanced, + breakable, + size=minimal, + left=10pt, + top=5pt, + bottom=5pt, + frame hidden, + boxrule=0pt, + sharp corners=all, + colback=backquote, + borderline west={4pt}{0pt}{bordercolor}, + #1 +} + +% redefine quote environment to use the myquote environment, see https://tex.stackexchange.com/a/337587/114857 +\renewenvironment{quote}{\begin{myquote}}{\end{myquote}} + +% remove the abstract title. +\usepackage{abstract} +\renewcommand{\abstractname}{} +\renewcommand{\absnamepos}{empty} + +\def\squarefoot{$ft^{\text{2}}$ } +\def\goalsimage{ +\begin{center} + +\hfill\break +\hfill\break + +\includegraphics[width=0.6\linewidth,height=\textheight,keepaspectratio]{img/goals.png} + +\end{center} + +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..4dbc84a --- /dev/null +++ b/justfile @@ -0,0 +1,34 @@ +playbook_dir := "${ANSIBLE_LOCAL}/ansible-hpa-playbook" +project_files := "project" + +[private] +default: + @just --list + +[group('template')] +edit-repo-vault: + @ansible-vault edit \ + --vault-id "consults@$SCRIPTS/vault-gopass-client" \ + ./repo_vars/vault.yml + +[group('template')] +create-repo-vault: + @ansible-vault create \ + --vault-id "consults@$SCRIPTS/vault-gopass-client" \ + ./repo_vars/vault.yml + +[group('template')] +edit-project-vault: + @ansible-vault edit \ + --vault-id "consults@$SCRIPTS/vault-gopass-client" \ + {{project_files}}/vault.yml + +[group('project')] +create-project dir *ARGS: + @ansible-playbook {{playbook_dir}}/main.yml \ + --inventory {{playbook_dir}}/inventory.ini \ + --vault-id "consults@$SCRIPTS/vault-gopass-client" \ + --tags setup-project \ + --extra-vars "project_dir={{dir}}" \ + --extra-vars "@{{justfile_directory()}}/repo_vars/vars.yml" \ + {{ARGS}} diff --git a/project/.gitignore b/project/.gitignore new file mode 100644 index 0000000..766ea87 --- /dev/null +++ b/project/.gitignore @@ -0,0 +1,6 @@ +.build/* +Report.pdf +Report.html +Report.tex +Airflow/*.pdf +ManJ/*.pdf diff --git a/project/Airflow/.gitkeep b/project/Airflow/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/project/README.md b/project/README.md new file mode 100644 index 0000000..9e71e96 --- /dev/null +++ b/project/README.md @@ -0,0 +1,27 @@ +# Home Performance Assessment + +This is a system airflow assessment project, where files are stored to generate the report. + +## TODO + +### While on site at customers home + +- [ ] Get equipment photos +- [ ] Perform TrueFlow report and static pressure analysis + - Store in `Airflow` folder + +### Post site visit + +- [ ] Generate TrueFlow forecast reports. + - Store in `Airflow` + - [ ] Need screen shots of report and forecast for report template. + - Store as `img/trueflow.png` and `img/truflow-forecast.png` +- [ ] Generate share / cloud storage for customer facing files / links needed in report + - Store final `Airflow` folder, `ManJ` folder, and `Report.pdf` + - [ ] Upload photos to cloud storage. +- [ ] Fill out `Report.md` template. + - [ ] Update `vars.yml` and `vault.yml` +- [ ] Generate `Report.pdf` from template. + - [ ] Review generated report. +- [ ] Upload final `Report.pdf` to cloud storage +- [ ] Send final `Report.pdf` to client diff --git a/project/Report.md b/project/Report.md new file mode 100644 index 0000000..95f4103 --- /dev/null +++ b/project/Report.md @@ -0,0 +1,172 @@ +--- +title: '{{ document_title }}' +author: '{{ author_name }}' +date: \today{} +mainfont: DejaVu Sans +documentclass: article +fontsize: 12pt +# NOTE: The applegreen is a custom color defined in resources/head.tex +linkcolor: applegreen +urlcolor: applegreen +abstract: | + **Prepared For:** + + {{ customer.name }} + + {{ customer.address.street }} + {{ customer.address.city }}, {{ customer.address.state }} {{ customer.address.zip }} + + ```{=latex} + \begin{center} + ``` + + \ + \ + \ + + [![logo]({{ links.images.logo }}){ width=30% }]({{ company.website }}) + + ```{=latex} + \end{center} + ``` +--- + + + +# Contents + +1. [Introduction](#introduction) +1. [Airflow Assessment](#airflow-assessment) + 1. [Your Static Measurements](#your-static-measurements) + 1. [Static Pressure Forecast](#static-measurements-forecast) +1. [Summary](#summary) +1. [Definitions](#definitions) + 1. [IAQ] + 1. [TESP] + 1. [WC][wc] + +## Introduction + +Thank you for having us to your home for a system airflow assessment. I hope that it was beneficial. We learned a lot +about your system during the brief visit. So, let’s jump in to some of the things discovered. + +Below is a summary of the system measurements and some recommendations. As part of the service we ran airflow test and +forecasting. + +Once you read the report you’ll have 3 options: do nothing, pick and choose upgrades, or do more planning for more +difficult goals or complex projects. These options are discussed at the end of the report as well as our leanings for +your home. + +\newpage + +## Airflow Assessment + +While on site, we also measured the total system airflow and static pressure of the system. Static pressure is +equivalent to the blood pressure of your system and gives us a better understanding of the overall ability for the +system to provide the proper amount of airflow, as well as how much it may struggle to do so. + +Static pressure is the amount of resistance that the blower has to work against in order to move air through the system. +Things that have an effect on the static pressure of the system include, air filters (size and type), duct sizes, amount +of ducts, length of ducts, duct fittings and transitions, as well as internal system components. Each component of the +system has a resistance associated with it that the blower has to overcome, by taking some key measurements we are able +to determine the [TESP] of the system. While there are several static pressures in the system, when we talk about static +pressure we are generally referring to [TESP]. + +Static pressure ([TESP]) has a range of _low_, _acceptable_, or _high_. While these numbers are specific to the actual +equipment, most manufacturers follow similar standards. For the sake of simplicity, 0.5" [wc] or under is an +_acceptable_ target, 0.8" [wc] is generally the max acceptable static pressure (although we like to stay well below this +if possible), and above 0.8" [wc] is considered _high_ and should be addressed. _Low_ is generally not common and is +rarely problematic, so it is not focused on much. + + + +\newpage + +### Your Static Measurements + +![True Flow Report](img/trueflow.png){height=50%} + + + +The above image is a snapshot of the static pressures recorded for your system. This shows that the static pressure of +your system is very high (1.114" [wc]). The primary culprits for the high static pressure are that the filter is +undersized for the airflow required and the return duct sizing is small. + +These measurements were taken in the heating mode because your system does not currently have air conditioning. +Currently the heating airflow is on the low side for what is required for your system (1200 CFM would be ideal). This +should be adjusted if possible during the install to get better performance and efficiency out of the system, given that +some static pressures can be improved during the project. + + + +\newpage + +### Static Measurements Forecast + +![True Flow Forecast](img/trueflow-forecast.png){height=50%} + + + +The above image is a snapshot is of a forecast of the static pressures after adding air conditioning. It should be noted +that these measurements are based solely on the airflow required for cooling mode, not for heating mode (in other words, +heating mode is going to be higher because the airflow requirement is higher). + +This shows that with an upgraded filter we can get the static pressure below the 0.8" [wc] max target while in cooling +mode. + +\newpage + +## Summary + +The purpose of the system airflow assessment is to help find the correct airflow or improvements +that are required to increase the system longevity and efficiency. + + + +Regards, + +![](img/signature.png){width=20%; float=left} + +\ +\ + +[Here is a link to all the documents][document-folder] + +> [!NOTE:] +> +> Documents are stored on our internal servers and links to your documents expire in approximately 30 days from the +> creation of your report, for security reasons. We recommend that you download any documents you would like to keep for +> your records. If you have troubles then we can send the documents via email or extend the expiration date of the +> provided document links. + + + + + +[IAQ]: #iaq-definition "IAQ" +[wc]: #wc-definition "wc" +[TESP]: #tesp-definition "TESP" + + + + + +[trueflow-image]: + +[trueflow-forecast-image]: + + + +[document-folder]: + + +``` + +``` diff --git a/project/img/.gitkeep b/project/img/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/project/img/goals.png b/project/img/goals.png new file mode 100644 index 0000000..556a46b --- /dev/null +++ b/project/img/goals.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f82b583a1714a599585902c6c2c375178468c3627bfdcffa91af276975741b8 +size 50802 diff --git a/project/img/logo.png b/project/img/logo.png new file mode 100644 index 0000000..9101f61 --- /dev/null +++ b/project/img/logo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ead2115764cfcdec32664aff6979b1394871aad6f11bc928a2f456368d8141b +size 26811 diff --git a/project/img/signature.png b/project/img/signature.png new file mode 100644 index 0000000..92a04c5 --- /dev/null +++ b/project/img/signature.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f43b3f74020149544783d417735bf85e779d688bbbbda717927b980790d091f +size 2502 diff --git a/project/justfile b/project/justfile new file mode 100644 index 0000000..f332e43 --- /dev/null +++ b/project/justfile @@ -0,0 +1,47 @@ +build_dir_name := ".build" +dir_name := `basename $PWD` +cloud_dir := "/mnt/customers" + +[private] +default: + just --list + +# Builds and fills the templates into the .build directory. +[group('build')] +build: + @gum spin --title="Building project..." -- bash -xc "hpa build &>/dev/null" + +# Build & generate an HTML report. +[group("generate")] +html: + @gum spin --title="Generating html..." -- bash -xc "hpa generate html &>/dev/null" + @xdg-open Report.html & + +# Build & generate a PDF report. +[group("generate")] +pdf: + @gum spin --title="Generating pdf..." -- bash -xc "hpa generate pdf &>/dev/null" + @pidof zathura &>/dev/null || xdg-open Report.pdf & + +# Copy files to cloud storage directory. +[group("generate")] +cloud-storage: + mkdir {{cloud_dir}}/{{dir_name}} &>/dev/null || true + cp -R Airflow {{cloud_dir}}/{{dir_name}} + cp -R ManJ {{cloud_dir}}/{{dir_name}} + [ -f Report.pdf ] && cp Report.pdf {{cloud_dir}}/{{dir_name}} + +# Build & generate a Latex file. +[group("generate")] +[group("debug")] +latex: + @gum spin --title="Generating latex..." -- baxh -xc "hpa generate latex &>/dev/null" + @xdg-open Report.tex & + +[group('utilities')] +edit-vault: + @hpa ansible-vault edit --vault-password /run/secrets/vault-pass vault.yml + +[group('utilities')] +clean: + @rm -rf {{build_dir_name}} diff --git a/project/vars.yml b/project/vars.yml new file mode 100644 index 0000000..5447bbc --- /dev/null +++ b/project/vars.yml @@ -0,0 +1,25 @@ +--- + +# Stores variables related to the template directory, which is used +# to setup projects and store commonly used files. +# +template: + path: /root/.local/share/hpa/template + +author_name: "{{ vault_author_name }}" + +company: "{{ vault_company }}" + +links: + images: + logo: "img/logo.png" + trueflow: "img/trueflow.png" + trueflow_forecast: "img/forecast.png" + +customer: "{{ vault_customer }}" + +# WARNING: Update these for the project. +home: + square_feet: "3,000" + cfm50: "3,000" + lair: "1:1" diff --git a/project/vault.yml b/project/vault.yml new file mode 100644 index 0000000..26f0e19 --- /dev/null +++ b/project/vault.yml @@ -0,0 +1,16 @@ +$ANSIBLE_VAULT;1.2;AES256;consults +36353833666438306363313239323865633538633061376534336139656536643034393564653964 +3665616466303038383663376136393463353361643461630a326530306330663130343639656630 +62623861376433333831326637303462636461366432386239323136323663343332613838346137 +3362616563353531650a323962356634316262343165616230346630386666313262333235303534 +63643430616430656233653936653263623937646333373339313430376131313435343464633136 +65333665396332393266383662336439616635383866616639313661613033393336363865633366 +33383935613962353831616235626166376336386235633130646461623939613131616265333730 +63343065313964353965343464396563313661633165363734636638313533653532623035346439 +36366536366438356162323264323862663265373931353338636235613764653966663964643739 +38356131306432646163323962333131343431336538373331646134333134326364613733356136 +65643466366635353038623335376435373030323265306362306239346130383662306537343733 +61323331656661653461373063353036383263626266663462353431313230363132303665613736 +33353564643938333832323061623132653532363939616238363537626537666233626335396136 +32346666363539306266313466303230646439646238656364653934366161313032626231646262 +366635313263326630303336366233366264 diff --git a/repo_vars/vars.yml b/repo_vars/vars.yml new file mode 100644 index 0000000..df7e616 --- /dev/null +++ b/repo_vars/vars.yml @@ -0,0 +1,44 @@ +--- + +document_title: "Home Performance Report" + +template: + #path: "{{ lookup('env', 'REPOS') }}/hhe-consult-template" + repo: + url: "https://git.housh.dev/hhe/consult-template.git" + version: "main" + +# Files to copy to the project directory when setting up a new consult project. +# +# These can be specified as a single item which is a path to the file +# to copy. Or a dict that includes the following: +# +# src: "/path/to/the/file" +# dest: "FileName" +# mode: '0600' # optional mode, defaults to 0600 +copy_directory_on_setup: + - "project" + +# Files to copy to the build directory when building a consult document. +# +# These can be specified as a single item which is a path to the file +# to copy. Or a dict that includes the following: +# +# src: "/path/to/the/file" +# dest: "Name" +# mode: '0600' # optional mode, defaults to 0600 +copy_on_build: + - "{{ template_dir }}/Definitions.md" + - "{{ template_dir }}/head.tex" + +# Files to fill with their template values and copy to the build directory. +# +# These can be specified as a single item which is a path to the file +# to copy. Or a dict that includes the following: +# +# src: "/path/to/the/file" +# dest: "Name" +# mode: '0600' # optional mode, defaults to 0600 +template_on_build: + - "{{ template_dir }}/footer.tex" + - "{{ project_dir }}/Report.md" diff --git a/repo_vars/vault.yml b/repo_vars/vault.yml new file mode 100644 index 0000000..354b11b --- /dev/null +++ b/repo_vars/vault.yml @@ -0,0 +1,14 @@ +$ANSIBLE_VAULT;1.2;AES256;consults +63633864356131333232633035373230306261383962313137343563313832316332313664656339 +6461373230646437653939323732626364333830373435350a323133636333326564333138626433 +61393365383036666231303031653534373630613164623836653534303965313932326266336537 +6430373836326237330a336434356664663235346435313339646662626430623464333737373531 +61626437643639333136633432653136663831313539313463656536326263383537623331316461 +34393931323536373239656162313539383835346162363665666630316266646137333365623037 +66323062396661333134363732303463373835323034303933656461323734653466363638343863 +62323938623131623034623562313838623263353163663964363265343437393035396331656435 +31326362323534653635306663366365316538313134343538646631663933636239326133363864 +39383333353932316435643665373337333134383535633133356136616134663535373932353238 +35306235633365393735323539396363383535313930316434306363636438633934373266313837 +63333764653566643435326533383836343365313932336336396665623062323530366266343139 +3738