diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..fece05e --- /dev/null +++ b/.envrc @@ -0,0 +1,22 @@ +if test -e env/bin/activate +then + . ./env/bin/activate +fi + +if test -f pyproject.toml; then + backend=$(sed -nr 's/^build-backend *= *\"([a-z]+).*/\1/p' pyproject.toml) + case $backend in + poetry|pdm|hatchling) + backend_command=${backend%ling} + if ! command -v $backend_command >/dev/null 2>&1; then + echo WARNING: $backend_command is not installed, the Python environment will not be loaded >/dev/stderr + else + while IFS= read -r -d $'\0' pair; do + export "$pair" + done < <($backend_command run env -0) + fi + ;; + ,*) + echo "WARNING: Unsupported build backend '$backend', the Python environment will not be loaded" >/dev/stderr + esac +fi diff --git a/20240709212004-tonberry_humidifier.org b/20240709212004-tonberry_humidifier.org new file mode 100644 index 0000000..ecaf761 --- /dev/null +++ b/20240709212004-tonberry_humidifier.org @@ -0,0 +1,21 @@ +:PROPERTIES: +:ID: 2e1170d1-a6a4-44ca-abe9-47ffe687960f +:END: +#+title: Tonberry Humidifier + +Project to build a humidifier in the form of a Final Fantasy Tonberry. +* Salvaged parts +** USB Humidifier +*** Energy requirements +- Input :: DC 5V, 300mA USB +- Idle :: 35mA (50mA) +- With humidifier :: 160mA (200mA) + +The board includes three RGB LEDs that I don't have a plan to use, so that +reduces the total power requirements. +** Bluetooth speaker +* Power +| | Voltage | Current | +|------------+---------+---------| +| ESP-8266 | 5 | 100 | +| Humidifier | 5 | 300 | diff --git a/20240721133048-pto.org b/20240721133048-pto.org new file mode 100644 index 0000000..5b59536 --- /dev/null +++ b/20240721133048-pto.org @@ -0,0 +1,210 @@ +:PROPERTIES: +:ID: c21a443b-2311-497b-afcb-52cf866230d2 +:END: +#+title: PTO + +* AWeber +** PTO Accrual +#+caption: Employee Handbook v6 +#+begin_quote +Effective on your anniversary date, and each year thereafter, you earn PTO based +on your years of service per the timeline below: +#+end_quote + +| Years of Service | Yearly Vacation Accrual | Per Pay Period Accrual | +|-------------------+-------------------------+---------------------------------------------------| +| Less than 3 year | 15 days | 0.5775 x hours worked (max at 4.62 hrs per pay) | +| 3 but less than 5 | 20 days | 0.76875 x hours worked (max at 6.15 hrs per pay) | +| 5 but less than 7 | 25 days | 0.96125 x hours worked (max at 7.69 hrs per pay) | +| 7 or more | 30 days | 0.115385 x hours worked (max at 9.23 hrs per day) | + +- Hire Date :: October 23, 2017 +- Initial End Date :: July 22, 2022 +- Rehire Date :: August 28th, 2023 +- Adjusted Seniority Date :: December 1, 2018 + +#+begin_src python :exports none + import datetime + + hired = datetime.date(2017, 10, 23) + left = datetime.date(2022, 7, 22) + rehired = datetime.date(2023, 8, 18) + adjusted_start = datetime.date(2018, 12, 1) + today = datetime.date(2024, 7, 21) + + return [ + ["Actual days employed", ((left - hired) + (today - rehired)).days], + ["Adjusted days employed", (today - adjusted_start).days], + ] +#+end_src + +#+RESULTS: +| Actual days employed | 2071 | +| Adjusted days employed | 2059 | + +** Full History + +#+name: paylocity-pto-history +| Trans Date | Begin Date | Type | Trans Type | Subtype | Hours/Days | Avail Hours/Days | +|------------+------------+------+-------------------+-----------------------+--------------+------------------| +| 07/12/2024 | 07/12/2024 | PTO | Earned | Ongoing | 4.62 Hours | 7.85 Hours | +| 07/12/2024 | 07/12/2024 | PTO | Used | | 8.00 Hours | 3.23 Hours | +| 06/28/2024 | 06/28/2024 | PTO | Earned | Ongoing | 4.62 Hours | 11.23 Hours | +| 06/14/2024 | 06/14/2024 | PTO | Earned | Ongoing | 4.62 Hours | 6.62 Hours | +| 05/31/2024 | 05/31/2024 | PTO | Earned | Ongoing | 4.62 Hours | 2.00 Hours | +| 05/31/2024 | 05/31/2024 | PTO | Used | | 8.00 Hours | -2.61 Hours | +| 05/17/2024 | 05/17/2024 | PTO | Earned | Ongoing | 4.62 Hours | 5.39 Hours | +| 05/03/2024 | 05/03/2024 | PTO | Earned | Ongoing | 4.62 Hours | 0.77 Hours | +| 05/03/2024 | 05/03/2024 | PTO | Used | | 8.00 Hours | -3.85 Hours | +| 04/19/2024 | 04/19/2024 | PTO | Earned | Ongoing | 4.62 Hours | 4.15 Hours | +| 04/05/2024 | 04/05/2024 | PTO | Earned | Ongoing | 4.62 Hours | -0.46 Hours | +| 03/22/2024 | 03/22/2024 | PTO | Earned | Ongoing | 4.62 Hours | -5.08 Hours | +| 03/08/2024 | 03/08/2024 | PTO | Earned | Ongoing | 4.62 Hours | -9.69 Hours | +| 02/23/2024 | 02/23/2024 | PTO | Earned | Ongoing | 4.62 Hours | -14.31 Hours | +| 02/23/2024 | 02/23/2024 | PTO | Used | | 8.00 Hours | -18.92 Hours | +| 02/09/2024 | 02/09/2024 | PTO | Earned | Ongoing | 4.62 Hours | -10.92 Hours | +| 01/26/2024 | 01/26/2024 | PTO | Earned | Ongoing | 4.62 Hours | -15.54 Hours | +| 01/26/2024 | 01/26/2024 | PTO | Used | | 16.00 Hours | -20.15 Hours | +| 01/12/2024 | 01/12/2024 | PTO | Earned | Ongoing | 4.62 Hours | -4.15 Hours | +| 01/12/2024 | 01/12/2024 | VOL | Earned | Ongoing | 0.00 Hours | 16.00 Hours | +| 01/12/2024 | 01/12/2024 | FLEX | Earned | Ongoing | 0.00 Hours | 8.00 Hours | +| 12/29/2023 | 12/29/2023 | PTO | Earned | Ongoing | 4.62 Hours | -8.77 Hours | +| 12/15/2023 | 12/15/2023 | PTO | Earned | Ongoing | 4.62 Hours | -13.38 Hours | +| 12/01/2023 | 12/01/2023 | PTO | Earned | Ongoing | 4.62 Hours | -18.00 Hours | +| 11/17/2023 | 11/17/2023 | PTO | Earned | Ongoing | 4.62 Hours | -22.62 Hours | +| 11/03/2023 | 11/03/2023 | PTO | Earned | Ongoing | 4.62 Hours | -27.23 Hours | +| 11/03/2023 | 11/03/2023 | PTO | Used | | 8.00 Hours | -31.85 Hours | +| 10/20/2023 | 10/20/2023 | PTO | Earned | Ongoing | 4.62 Hours | -23.85 Hours | +| 10/06/2023 | 10/06/2023 | PTO | Earned | Ongoing | 4.62 Hours | -28.46 Hours | +| 10/06/2023 | 10/06/2023 | FLEX | Earned | Above maximum balance | -8.00 Hours | 8.00 Hours | +| 10/06/2023 | 10/06/2023 | FLEX | Initial | | 8.00 Hours | 16.00 Hours | +| 10/06/2023 | 10/06/2023 | PTO | Used | | 16.00 Hours | -33.08 Hours | +| 09/22/2023 | 09/22/2023 | PTO | Earned | Ongoing | 4.62 Hours | -17.08 Hours | +| 09/22/2023 | 09/22/2023 | PTO | Used | | 24.00 Hours | -21.69 Hours | +| 09/08/2023 | 09/08/2023 | PTO | Earned | Ongoing | 2.31 Hours | 2.31 Hours | +| 09/08/2023 | 09/08/2023 | VOL | Earned | Above maximum balance | -16.00 Hours | 16.00 Hours | +| 09/08/2023 | 09/08/2023 | VOL | Initial | | 16.00 Hours | 32.00 Hours | +| 08/29/2023 | 08/29/2023 | PTO | Manual Adjustment | Adjustment | 142.15 Hours | 0.00 Hours | +| 07/29/2022 | 07/29/2022 | PTO | Earned | Ongoing | 6.15 Hours | 6.16 Hours | +| 07/29/2022 | 07/09/2022 | PTO | Used | | 38.15 Hours | 0.00 Hours | +| 07/15/2022 | 07/15/2022 | PTO | Earned | Ongoing | 6.15 Hours | 38.15 Hours | +| 07/01/2022 | 07/01/2022 | PTO | Earned | Ongoing | 6.15 Hours | 32.00 Hours | +| 07/01/2022 | 07/01/2022 | PTO | Used | | 16.00 Hours | 25.85 Hours | +| 06/17/2022 | 06/17/2022 | PTO | Earned | Ongoing | 6.15 Hours | 41.85 Hours | +| 06/03/2022 | 06/03/2022 | PTO | Earned | Ongoing | 6.15 Hours | 35.69 Hours | +| 05/20/2022 | 05/20/2022 | PTO | Earned | Ongoing | 6.15 Hours | 29.54 Hours | +| 05/20/2022 | 05/20/2022 | PTO | Used | | 16.00 Hours | 23.38 Hours | +| 05/06/2022 | 05/06/2022 | PTO | Earned | Ongoing | 6.15 Hours | 39.38 Hours | +| 05/06/2022 | 05/06/2022 | PTO | Used | | 40.00 Hours | 33.23 Hours | +| 04/22/2022 | 04/22/2022 | PTO | Earned | Ongoing | 6.15 Hours | 73.23 Hours | +| 04/08/2022 | 04/08/2022 | PTO | Earned | Ongoing | 6.15 Hours | 67.08 Hours | +| 03/25/2022 | 03/25/2022 | PTO | Earned | Ongoing | 6.15 Hours | 60.92 Hours | +| 03/11/2022 | 03/11/2022 | PTO | Earned | Ongoing | 6.15 Hours | 54.77 Hours | +| 03/11/2022 | 03/11/2022 | PTO | Used | | 16.00 Hours | 48.61 Hours | +| 02/25/2022 | 02/25/2022 | PTO | Earned | Ongoing | 6.15 Hours | 64.61 Hours | +| 02/11/2022 | 02/11/2022 | PTO | Earned | Ongoing | 6.15 Hours | 58.46 Hours | +| 01/28/2022 | 01/28/2022 | PTO | Earned | Ongoing | 6.15 Hours | 52.31 Hours | +| 01/14/2022 | 01/14/2022 | PTO | Earned | Ongoing | 6.15 Hours | 46.15 Hours | +| 01/14/2022 | 01/14/2022 | FLEX | Earned | Ongoing | 8.00 Hours | 8.00 Hours | +| 01/14/2022 | 01/14/2022 | VOL | Earned | Ongoing | 0.00 Hours | 16.00 Hours | +| 01/14/2022 | 01/14/2022 | PTO | Used | | 8.00 Hours | 40.00 Hours | +| 12/30/2021 | 12/30/2021 | PTO | Earned | Ongoing | 6.15 Hours | 48.00 Hours | +| 12/30/2021 | 12/30/2021 | PTO | Used | | 8.00 Hours | 41.84 Hours | +| 12/30/2021 | 12/30/2021 | FLEX | Used | | 8.00 Hours | 0.00 Hours | +| 12/17/2021 | 12/17/2021 | PTO | Earned | Ongoing | 6.15 Hours | 49.84 Hours | +| 12/03/2021 | 12/03/2021 | PTO | Earned | Ongoing | 6.15 Hours | 43.69 Hours | +| 11/19/2021 | 11/19/2021 | PTO | Earned | Ongoing | 6.15 Hours | 37.54 Hours | +| 11/05/2021 | 11/05/2021 | PTO | Earned | Ongoing | 6.15 Hours | 31.38 Hours | +| 11/05/2021 | 11/05/2021 | SAB | Earned | Ongoing | 0.00 Hours | 0.00 Hours | +| 11/05/2021 | 11/05/2021 | SAB | Cleared | | 0.00 Hours | 0.00 Hours | +| 11/05/2021 | 11/05/2021 | PTO | Cleared | | 0.00 Hours | 25.23 Hours | +| 11/05/2021 | 11/05/2021 | PTO | Used | | 12.00 Hours | 25.23 Hours | +| 10/22/2021 | 10/22/2021 | PTO | Earned | Ongoing | 6.15 Hours | 37.23 Hours | +| 10/08/2021 | 10/08/2021 | PTO | Earned | Ongoing | 6.15 Hours | 31.07 Hours | +| 09/24/2021 | 09/24/2021 | PTO | Earned | Ongoing | 6.15 Hours | 24.92 Hours | +| 09/24/2021 | 09/24/2021 | PTO | Used | | 32.00 Hours | 18.77 Hours | +| 09/10/2021 | 09/10/2021 | PTO | Earned | Ongoing | 6.15 Hours | 50.77 Hours | +| 08/27/2021 | 08/27/2021 | PTO | Earned | Ongoing | 6.15 Hours | 44.61 Hours | +| 08/27/2021 | 08/27/2021 | PTO | Used | | 8.00 Hours | 38.46 Hours | +| 08/13/2021 | 08/13/2021 | PTO | Earned | Ongoing | 6.15 Hours | 46.46 Hours | +| 07/30/2021 | 07/30/2021 | PTO | Earned | Ongoing | 6.15 Hours | 40.30 Hours | +| 07/16/2021 | 07/16/2021 | PTO | Earned | Ongoing | 6.15 Hours | 34.15 Hours | +| 07/02/2021 | 07/02/2021 | PTO | Earned | Ongoing | 6.15 Hours | 28.00 Hours | +| 07/02/2021 | 07/02/2021 | PTO | Used | | 8.00 Hours | 21.84 Hours | +| 06/18/2021 | 06/18/2021 | PTO | Earned | Ongoing | 6.15 Hours | 29.84 Hours | +| 06/18/2021 | 06/18/2021 | PTO | Used | | 32.00 Hours | 23.69 Hours | +| 06/04/2021 | 06/04/2021 | PTO | Earned | Ongoing | 6.15 Hours | 55.69 Hours | +| 06/04/2021 | 06/04/2021 | PTO | Used | | 4.00 Hours | 49.54 Hours | +| 05/21/2021 | 05/21/2021 | PTO | Earned | Ongoing | 6.15 Hours | 53.54 Hours | +| 05/21/2021 | 05/21/2021 | PTO | Used | | 8.00 Hours | 47.38 Hours | +| 05/07/2021 | 05/07/2021 | PTO | Earned | Ongoing | 6.15 Hours | 55.38 Hours | +| 04/23/2021 | 04/23/2021 | PTO | Earned | Ongoing | 6.15 Hours | 49.23 Hours | +| 04/23/2021 | 04/23/2021 | PTO | Used | | 8.00 Hours | 43.07 Hours | +| 04/09/2021 | 04/09/2021 | PTO | Earned | Ongoing | 6.15 Hours | 51.07 Hours | +| 03/26/2021 | 03/26/2021 | PTO | Earned | Ongoing | 6.15 Hours | 44.92 Hours | +| 03/12/2021 | 03/12/2021 | PTO | Earned | Ongoing | 6.15 Hours | 38.77 Hours | +| 02/26/2021 | 02/26/2021 | PTO | Earned | Ongoing | 6.15 Hours | 32.61 Hours | +| 02/26/2021 | 02/26/2021 | PTO | Used | | 8.00 Hours | 26.46 Hours | +| 02/12/2021 | 02/12/2021 | PTO | Earned | Ongoing | 6.15 Hours | 34.46 Hours | +| 01/29/2021 | 01/29/2021 | PTO | Earned | Ongoing | 6.15 Hours | 28.30 Hours | +| 01/15/2021 | 01/15/2021 | PTO | Earned | Ongoing | 6.15 Hours | | +| 01/15/2021 | 01/15/2021 | FLEX | Earned | Ongoing | 8.00 Hours | 8.00 Hours | +| 01/15/2021 | 01/15/2021 | VOL | Earned | Ongoing | 16.00 Hours | 16.00 Hours | + +** Discrepancy since December 1st, 2023 (5-year anniversary) + +Since my rehire date, I should have been accruing PTO at the 3-5 year rate up +until the 5th annivesary of my adjusted seniority date, following which it +should have been accruing at the 5-7 year rate. It has instead been accruing at +the 0-3 year rate the entire time. + +#+name: pto-earned-discrepency +#+begin_src python :var data=paylocity-pto-history :var filename="pto-aweber-2024-discrepency.png" :results file :exports results + from datetime import datetime, date + + import pandas as pd + + + def from_hours(text) -> float | None: + try: + return float(text.split()[0]) + except (ValueError, IndexError): + return None + + + data = [ + { + "date": datetime.strptime(tdate, "%m/%d/%Y").date(), + "PTO Type": ptype, + "Trans Type": ttype, + "hours": from_hours(hours), + "available": from_hours(available), + } + for tdate, bdate, ptype, ttype, stype, hours, available in data + ] + data = pd.DataFrame(data) + pto = data[data["PTO Type"] == "PTO"] + pto = pto[(pto["Trans Type"] =="Earned") | (pto["Trans Type"] == "Used")] + pto = pto[pto["date"] > date(2022, 9, 1)] + pto = pto.pivot(index="date", columns="Trans Type", values="hours").fillna(0) + pto["Expected Earned"] = pto["Earned"] + pto.loc[pto.index == date(2023, 9, 8), "Expected Earned"] = 3.08 # (2.31 / 4.62) * 6.15 + pto.loc[pto.index > date(2023, 9, 8), "Expected Earned"] = 6.15 + pto.loc[pto.index > date(2023, 12, 1), "Expected Earned"] = 7.69 + pto["change"] = pto["Earned"] - pto["Used"] + pto["expected change"] = pto["Expected Earned"] - pto["Used"] + pto["Actual"] = pto["change"].cumsum() + pto["Expected"] = pto["expected change"].cumsum() + plot = pto[["Actual", "Expected"]].plot(title="PTO Accrual Discrepancy", xlabel="Date", ylabel="Hours") + last = pto.iloc[-1] + plot.get_legend().set_title("") + plot.text(last.name, last["Actual"], f" {last.Actual:.2f}") + plot.text(last.name, last["Expected"], f" {last.Expected:.2f}") + fig = plot.get_figure() + fig.autofmt_xdate() + fig.savefig(filename) + return filename +#+end_src + +#+RESULTS: pto-earned-discrepency +[[file:pto-aweber-2024-discrepency.png]] diff --git a/20240811193938-sailmaker_ldap.org b/20240811193938-sailmaker_ldap.org new file mode 100644 index 0000000..8bbdd7f --- /dev/null +++ b/20240811193938-sailmaker_ldap.org @@ -0,0 +1,14 @@ +:PROPERTIES: +:ID: 97f839e2-7a1a-4fba-9da8-f98801cd67cb +:END: +#+title: Sailmaker LDAP + +Handles authentication for services across the [[id:e83c1ece-35f6-414d-986f-59533fb3d6a9][Sailmaker Network]]. + +LDAP is provided using [[https://github.com/lldap/lldap][LLDAP]], a lightweight LDAP implementation with a simple UI +for configuring users and groups. +* Configuration +- URL :: http://reason.sailmaker:17170/ +- LDAP Port (plain) :: =3890= +- Base DN :: =dc=sailmaker,dc=local= +- Example DN :: =uid=correlr,ou=people,dc=sailmaker,dc=local= diff --git a/20240822235459-sailmaker_network_services.org b/20240822235459-sailmaker_network_services.org new file mode 100644 index 0000000..8e16223 --- /dev/null +++ b/20240822235459-sailmaker_network_services.org @@ -0,0 +1,36 @@ +:PROPERTIES: +:ID: 20aff805-8eab-4f77-9077-004e1fc2d5bc +:END: +#+title: Sailmaker Network Services + +Services running on the [[id:e83c1ece-35f6-414d-986f-59533fb3d6a9][Sailmaker Network]]. + +| Server | Service | Hostname | IP Address | Web UI Port | Proxy Host | Proxy Port | +|---------------+---------------------+----------+--------------+-------------+--------------------------+------------| +| PiHole | PiHole | pi.hole | 192.168.1.2 | 80 | | | +| PiHole | Uptime Kuma | pi.hole | 192.168.1.2 | 3001 | | | +| HomeAssistant | Home Assistant | | 192.168.1.13 | 8123 | home-assistant.sailmaker | 80 | +| HomeAssistant | Nginx Proxy Manager | | 192.168.1.13 | 81 | | | +| HomeAssistant | Mosquitto | | 192.168.1.13 | | | | +| Nomadix | PiHole | | 192.168.1.3 | 80 | | | +| Nomadix | Traefik | | 192.168.1.8 | 8080 | | | +| Nomadix | Wireguard | | 192.168.1.6 | 10086 | | | + +* Network Map + +- Primary services (.1 - .9) must be hosted on the Nomadix device +- Secondary services (.10 - .19) should be hosted on the Nomadix device or a standalone device +- Tertiary +| IP | Service | Role | +|--------------+-------------------+------------------------------| +| 192.168.1.1 | Internet Router | Routing | +| 192.168.1.2 | PiHole | (DNS / DHCP) | +| 192.168.1.3 | *reserved* | | +| 192.168.1.4 | *reserved* | | +| 192.168.1.5 | Proxmox (Nomadix) | Primary service host | +| 192.168.1.6 | Wireguard | VPN | +| 192.168.1.7 | LLDAP | Authentication | +| 192.168.1.8 | Proxy Manager | (inbound HTTP/HTTPS traffic) | +| 192.168.1.9 | | | +|--------------+-------------------+------------------------------| +| 192.168.1.13 | Home Assistant | Home automation | diff --git a/pto-aweber-2024-discrepency.png b/pto-aweber-2024-discrepency.png new file mode 100644 index 0000000..587925d Binary files /dev/null and b/pto-aweber-2024-discrepency.png differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..cba7206 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[tool.poetry] +name = "personal" +version = "0.1.0" +description = "" +authors = ["Correl Roush "] +package-mode = false + + +[tool.poetry.dependencies] +python = "^3.12" +pandas = "^2.2.2" +matplotlib = "^3.9.1" + +[tool.poetry.group.dev.dependencies] +black = "^24.4.2" +mypy = "^1.11.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api"