Compare commits

...

16 Commits

Author SHA1 Message Date
4022f12289 Deleting old files, updating ignore 2026-01-17 22:19:25 -05:00
812fec9f08 Updating for new server setup 2026-01-17 22:15:41 -05:00
8cb27adcaa Periodic Config Updates 2026-01-17 22:15:02 -05:00
581c91162b Initial Calibre Commit 2026-01-17 22:13:39 -05:00
7c2277786d Update README.md 2026-01-18 03:03:45 +00:00
d601c65254 Update README.md 2026-01-18 02:59:46 +00:00
418ce7b583 Include configuration yml files 2025-12-22 08:23:00 -05:00
97679cd03b Include configuration yml files 2025-12-22 08:20:53 -05:00
dcb11b9925 Added ingress for Calibre 2025-12-19 09:31:15 -05:00
2fae519a45 Added ingress for Calibre 2025-12-19 09:30:10 -05:00
05989271ef UFW Rules documentation 2025-12-19 08:35:35 -05:00
9c0d7e0466 Updating Docs 2025-12-18 14:31:36 -05:00
49c1a58566 Updating Docs 2025-12-18 14:29:37 -05:00
167b5af2bf Obsolete 2025-12-15 16:05:53 -05:00
b541866027 Updating Docs 2025-12-15 16:03:46 -05:00
6d9afb1571 Docker socket 2025-12-15 13:46:50 -05:00
37 changed files with 43121 additions and 1026 deletions

6
.gitignore vendored
View File

@@ -4,6 +4,12 @@
.env.*
### Container data (DO NOT VERSION)
/cloudflared
/dashy
/gitea
/homarr
/nginx
/codeserver
/portainer/config
/portainer/config/*
**/data/

View File

@@ -1,31 +1,25 @@
# Cloud Server Docker Contianers
### Device -- Raspberry Pi 4
## Device -- Raspberry Pi 4
### Information
## Information
This folder contains all of the services running on the Pi
### Contents:
## Contents:
**`~/Docker`**
├── **`cloudflared/`**
├── **`dashy/`**
├── **`calibre/`** -- Inactive
├── **`codeserver/`** -- Inactive
├── **`glances/`**
├── **`homarr/`**
├── **`ha/`**
├── **`nextcloud/`**
├── **`nginx/`**
├── **`portainer/`**
├── **`README.md`**
└── **`syncthing/`**
### Current Ports:
- **`81`** --> nginx proxy manager web ui
- **`2222`** --> gitea ssh
- **`3000`** --> gitea web ui
- **`7575`** --> homarr
## Current Ports:
- **`8000`** --> portainer
- **`8080`** --> nextcloud web ui
- **`8123`** --> home assistant web ui
- **`8181`** --> dashy
- **`8282`** --> ha bridge web ui
- **`8384`** --> syncthing web ui
- **`9443`** --> portainer web ui
@@ -33,17 +27,34 @@ This folder contains all of the services running on the Pi
- **`50000`** --> ha bridge
- **`61208`** --> glances web ui
### Current Web Paths:
- **`szumko.net`** --> dashy
- **`szumko.net/data`** --> glances
- **`pihole.szumko.net`** --> Pihole
- **`git.szumko.net`** --> Gitea
- **`cloud.szumko.net`** --> nextcloud
## Adding Subdomains:
1. Go to cloudflare account and add a dns record for the subdomain
2. Go to **`~/docker/cloudflared/config.yml`** and add the ingress pointing to NPM
3. Create a proxy host in NPM pointing to container_name:port (must be on **`homelab`** internal network)
## UFW Settings
```
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip
## Adding Paths:
1. Add path in NPM (must be on **`homelab`**)
To Action From
-- ------ ----
22 ALLOW IN 192.168.0.0/24 # LAN SSH
22 on tailscale0 ALLOW IN Anywhere # Tailscale SSH
80,443/tcp on tailscale0 ALLOW IN Anywhere # Tailscale HTTP/HTTPS
80,443/udp on tailscale0 ALLOW IN Anywhere # Tailscale HTTP/HTTPS
Anywhere ALLOW IN 192.168.0.0/24 # LAN General Access
8080 on tailscale0 ALLOW IN Anywhere # Tailscale Nextcloud
8123 on tailscale0 ALLOW IN Anywhere # Tailscale Homeassistant
8384 on tailscale0 ALLOW IN Anywhere # Tailscale Syncthing
9443 on tailscale0 ALLOW IN Anywhere # Tailscale Portainer
22000 on tailscale0 ALLOW IN Anywhere # Tailscale Syncthing
61208 on tailscale0 ALLOW IN Anywhere # Tailscale Glances
22 (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale SSH
80,443/tcp (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale HTTP/HTTPS
80,443/udp (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale HTTP/HTTPS
8080 (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale Nextcloud
8123 (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale Homeassistant
8384 (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale Syncthing
9443 (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale Portainer
22000 (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale Syncthing
61208 (v6) on tailscale0 ALLOW IN Anywhere (v6) # Tailscale Glances
```

26
calibre/.gitignore vendored Normal file
View File

@@ -0,0 +1,26 @@
# Ignore the environment file containing sensitive data
.env
# Ignore the config directory which may contain persistent data (e.g., Calibre database, metadata)
/app-config
/web-config
/calibre-lib
config/
# Ignore the Docker container image and build files
*.log
*.pid
docker-compose.override.yml
# Ignore any other temporary or autogenerated files
*.swp
*.bak
*.tmp
# Ignore Docker-related metadata
.docker/
# Ignore system files created by editors
.DS_Store
Thumbs.db

0
calibre/README.md Normal file
View File

View File

@@ -0,0 +1,48 @@
services:
app:
image: lscr.io/linuxserver/calibre:latest
container_name: calibre
#security_opt:
#- seccomp:unconfined #optional
environment:
- PUID=1000
- PGID=1000
- TZ=America/Detroit
#- PASSWORD=${PASSWORD}
- CLI_ARGS='--disable-web-password'
volumes:
- ./app-config:/config
- ./calibre-lib:/calibre
ports:
- 9000:8080 # Calibre desktop gui (only for reverse proxy access)
- 9001:8181 # Calibre desktop gui HTTPS
- 9002:8081 # Calibre webserver gui (needs to be enabled in gui settings first)
shm_size: "1gb"
restart: unless-stopped
web:
image: lscr.io/linuxserver/calibre-web:latest
container_name: calibre-web
environment:
- PUID=1000
- PGID=1000
- TZ=America/Detroit
- WEB_USER=${USERNAME}
- WEB_PASSWORD=${PASSWORD}
#- DOCKER_MODS=linuxserver/mods:universal-calibre #optional
#- OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional
volumes:
- ./web-config:/config
- ./calibre-lib:/books
ports:
- 9004:8083
networks:
- 'homelab'
- 'default'
restart: unless-stopped
networks:
homelab:
external: true

View File

@@ -1,20 +0,0 @@
# Ignore sensitive files
cloudflared/*.json
# Ignore all JSON files-> ignores <tunnel_id>.json
cert.pem
config.yml
.env
# Ignore docker-compose override files (local configurations)
docker-compose.override.yml
# Ignore log files
*.log
# Ignore backup or swap files created by editors
*.bak
*.swp
# Ignore any temporary files or directories created during runtime
tmp/
*.pid

View File

@@ -1,41 +0,0 @@
# Cloudflare Tunnel Info
## Instructions:
- Make sure config.yml is updated with changes from config.git.yml
## Contents:
**`cloudflared`**
│ ├── **`<tunnel_id>.json`**
│ ├── **`cert.pem`**
│ ├── **`config.git.yml`**
│ ├── **`config.yml`**
│ ├── **`docker-compose.yml`**
│ ├── **`.env`**
│ ├── **`.gitignore`**
│ └── **`README.md`**
### File Descriptions:
- **`<tunnel_id>.json`**: Cloudflare tunnel credentials file
- **`cert.pem`**: Cloudflare certificate file
- **`config.git.yml`**: Version-controlled template for `config.yml`
- **`config.yml`**: Configuration file for Cloudflare tunnel ingress methods
- **`docker-compose.yml`**: Docker Compose file for running the Cloudflare tunnel
- **`.env`**: Environment variables, including the tunnel ID
- **`.gitignore`**: Git ignore file
- **`README.md`**: Documentation
### Environment Variables:
- **`tunnel_id`**: Cloudflare tunnel ID (stored in `.env`).
### Ignored Files:
- **`<tunnel_id>.json`**: Sensitive file containing the Cloudflare tunnel credentials
- **`cert.pem`**: Cloudflare certificate file
- **`config.yml`**: Configuration file with sensitive data
- **`.env`**: Environment file containing sensitive data
### Current Ingress Methods:
- **szumko.net** --> dashy dashboard
- **cloud.szumko.net** --> nextcloud
- **git.szumko.net** --> Gitea
- **ha.szumko.net** --> Home Assistant
- **pihole.szumko.net**

View File

@@ -1,15 +0,0 @@
tunnel: <tunnel_id> # your tunnel ID
credentials-file: /etc/cloudflared/<tunnel_id>.json
ingress:
- hostname: szumko.net
service: http://nginx-app-1:80
- hostname: pihole.szumko.net
service: http://nginx-app-1:80
- hostname: git.szumko.net
service: http://nginx-app-1:80
- hostname: cloud.szumko.net
service: http://nginx-app-1:80
- hostname: ha.szumko.net
service: http://nginx-app-1:80
- service: http_status:404

View File

@@ -1,17 +0,0 @@
services:
cloudflared:
image: cloudflare/cloudflared:latest
restart: unless-stopped
networks:
- 'default'
- 'tunnel'
volumes:
- ./config.yml:/etc/cloudflared/config.yml
- ./${TUNNEL_ID}.json:/etc/cloudflared/${TUNNEL_ID}.json # Use environment variable for tunnel ID
command: tunnel --no-autoupdate --config /etc/cloudflared/config.yml run
env_file:
- .env # Reference the .env file to inject environment variables
networks:
tunnel:
external: true

10
dashy/.gitignore vendored
View File

@@ -1,10 +0,0 @@
# Ignore sensitive data
.env # Environment variables file (contains sensitive info)
# Ignore temporary or log files
*.log # Log files
*.bak # Backup files
*.swp # Swap files (e.g., from text editors)
# Ignore any local overrides or extra Docker Compose files
docker-compose.override.yml # Local override for docker-compose (optional)

View File

@@ -1,33 +0,0 @@
# Dashy Info
## Instructions:
- Access WebUI on port 8181
- Use conf.yml to edit page
## Contents:
**`dashy/`**
├── **`config/`**
│   ├── **`conf.yml`**
│   └── **`item-icons/`**
├── **`docker-compose.yml`**
├── **`.env`**
├── **`.gitignore`**
└── **`README.md`**
## File Descrptions:
- **`config/`**: Configuration data
* **`conf.yml`**: COnfiguration file
* **`item-icons/`**: Icons
- **`docker-compose.yml`**: Docker compose file
- **`.env`**: Environment Variables
- **`.gitignore`**: Git ignore file
- **`README.md`**: Documentation
## Environmet Variables:
- None
## Ignored Files:
- **`.env`**: Environment VariablesDashy Info

View File

@@ -1,107 +0,0 @@
pageInfo:
title: Pi Server
description: ''
navLinks:
- title: GitHub
path: https://github.com/Lissy93/dashy
target: newtab
- title: Documentation
path: https://dashy.to/docs
target: newtab
appConfig:
theme: dracula
layout: auto
iconSize: large
sections:
- name: Services
displayData:
sortBy: default
cols: 4
collapsed: false
hideForGuests: false
rows: 1
items:
- title: Pi-Hole
description: Network Ad Block
url: https://pihole.szumko.net
target: newtab
id: 0_836_pihole
- title: Gitea
description: Git Repos
url: https://git.szumko.net
target: newtab
id: 1_836_gitea
- title: Portainer
description: Docker Management
url: https://192.168.0.152:9443
target: newtab
id: 2_836_portainer
- title: Cloud
url: https://cloud.szumko.net
target: newtab
id: 3_836_cloud
- name: CPU
displayData:
cols: 1
sortBy: default
rows: 4
collapsed: false
hideForGuests: false
widgets:
- type: gl-cpu-temp
options:
hostname: https://szumko.net/data
untits: F
id: 0_232_glcputemp
- type: gl-current-cpu
options:
hostname: https://szumko.net/data
id: 1_232_glcurrentcpu
- type: gl-current-cores
options:
hostname: https://szumko.net/data
id: 2_232_glcurrentcores
- type: gl-cpu-history
options:
hostname: https://szumko.net/data
id: 3_232_glcpuhistory
- name: Memory
widgets:
- type: gl-current-mem
options:
hostname: https://szumko.net/data
id: 0_633_glcurrentmem
- type: gl-mem-history
options:
hostname: https://szumko.net/data
id: 1_633_glmemhistory
- name: Disk
widgets:
- type: gl-disk-space
options:
hostname: https://szumko.net/data
id: 0_395_gldiskspace
- type: gl-disk-io
options:
hostname: https://szumko.net/data
id: 1_395_gldiskio
- name: System Load
widgets:
- type: gl-system-load
options:
hostname: https://szumko.net/data
id: 0_1061_glsystemload
- type: gl-load-history
options:
hostname: https://szumko.net/data
id: 1_1061_glloadhistory
- name: Network
widgets:
- type: gl-network-interfaces
options:
hostname: https://szumko.net/data
id: 0_746_glnetworkinterfaces
- type: gl-network-traffic
options:
hostname: https://szumko.net/data
id: 1_746_glnetworktraffic

View File

@@ -1,39 +0,0 @@
# Welcome to Dashy! To get started, run `docker compose up -d`
# You can configure your container here, by modifying this file
version: "3.8"
services:
dashy:
container_name: Dashy
# Pull latest image from DockerHub
image: lissy93/dashy
# To build from source, replace 'image: lissy93/dashy' with 'build: .'
# build: .
# You can also use an image with a different tag, or pull from a different registry, e.g:
# image: ghcr.io/lissy93/dashy or image: lissy93/dashy:3.0.0
# Pass in your config file below, by specifying the path on your host machine
volumes:
- /home/szumkoal/docker/dashy/config/conf.yml:/app/user-data/conf.yml
- /home/szumkoal/docker/dashy/config/item-icons:/app/user-data/item-icons/
# Set port that web service will be served on. Keep container port as 8080
ports:
- 8181:8080
networks:
- 'homelab'
# Set any environmental variables
environment:
- NODE_ENV=production
# Specify your user ID and group ID. You can find this by running `id -u` and `id -g`
- UID=1000
- GID=1000
# Specify restart policy
restart: unless-stopped
networks:
homelab:
external: true

27
gitea/.gitignore vendored
View File

@@ -1,27 +0,0 @@
# Ignore environment file that contains sensitive information
.env
# Ignore any log files that may be generated by services
*.log
# Ignore temporary or backup files that might be created by editors
*.bak
*.swp
# Ignore docker-compose override files (local configurations, not meant to be versioned)
docker-compose.override.yml
# Ignore any database files that are mapped as volumes (persistent data)
config/
data/
mysql/
# Ignore any tmp or pid files that might be created during runtime
tmp/
*.pid
# Ignore any SQLite database files (if applicable)
*.sqlite
# Ignore any generated Nextcloud data files (if they're stored here instead of in volumes)
*.db

View File

@@ -1,38 +0,0 @@
services:
server:
image: docker.gitea.com/gitea:latest-rootless
environment:
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=db:3306
- GITEA__database__NAME=gitea
- GITEA__database__USER=${GITEA__database__USER}
- GITEA__database__PASSWD=${GITEA__database__PASSWD}
restart: always
volumes:
- ./data:/var/lib/gitea
- ./config:/etc/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:2222"
networks:
- 'default'
- 'homelab'
depends_on:
- db
db:
image: docker.io/library/mysql:8
restart: always
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
volumes:
- ./mysql:/var/lib/MySQL
networks:
homelab:
external: true

View File

@@ -23,3 +23,13 @@
## Ignored Files:
- **`.env`**: Environment Variables
## NPM Configurations
- ```
location /data/ {
proxy_pass http://glances:61208/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Access-Control-Allow-Origin *;
}

3
ha/.gitignore vendored
View File

@@ -2,6 +2,9 @@
*.env
ha_config/
bridge_config/
!ha_config/configuration.yml
!ha_config/automations.yml
!ha_config/scripts.yml
# Ignore system generated logs

View File

@@ -6,6 +6,7 @@ services:
- ./ha_config:/config
- /etc/localtime:/etc/localtime:ro
- /run/dbus:/run/dbus:ro
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
privileged: false
ports:

View File

@@ -0,0 +1,65 @@
- id: '1766178088964'
alias: Morning Weather
description: ''
triggers:
- trigger: time
at: 07:00:00
weekday:
- sun
- mon
- tue
- wed
- thu
- fri
- sat
conditions: []
actions:
- variables:
high: '{{ state_attr(''sensor.daily_forecast'', ''temperature_2m_max'')[0] }}'
low: '{{ state_attr(''sensor.daily_forecast'', ''temperature_2m_min'')[0] }}'
temp_unit: '{{ state_attr(''sensor.units'', ''temperature_2m'') }}'
loc: '{{ state_attr(''sensor.alexs_iphone_2_geocoded_location'', ''Locality'')
}}, {{ state_attr(''sensor.alexs_iphone_2_geocoded_location'', ''Administrative
Area'') }}'
condition: "{% set code = state_attr('sensor.daily_forecast', 'weather_code')[0]
| int %} {% set mapper = {\n 0: \"Clear sky\",\n 1: \"Mainly clear\",\n
\ 2: \"Partly cloudy\",\n 3: \"Overcast\",\n 45: \"Fog\",\n 48: \"Depositing
rime fog\",\n 51: \"Drizzle - Light intensity\",\n 53: \"Drizzle - Moderate
intensity\",\n 55: \"Drizzle - Dense intensity\",\n 56: \"Freezing Drizzle
- Light intensity\",\n 57: \"Freezing Drizzle - Dense intensity\",\n 61:
\"Rain - Slight intensity\",\n 63: \"Rain - Moderate intensity\",\n 65:
\"Rain - Heavy intensity\",\n 66: \"Freezing Rain - Light intensity\",\n
\ 67: \"Freezing Rain - Heavy intensity\",\n 71: \"Snow fall - Slight intensity\",\n
\ 73: \"Snow fall - Moderate intensity\",\n 75: \"Snow fall - Heavy intensity\",\n
\ 77: \"Snow grains\",\n 80: \"Rain showers - Slight intensity\",\n 81:
\"Rain showers - Moderate intensity\",\n 82: \"Rain showers - Violent intensity\",\n
\ 85: \"Snow showers - Slight intensity\",\n 86: \"Snow showers - Heavy intensity\",\n
\ 95: \"Thunderstorm - Slight intensity\",\n 96: \"Thunderstorm with slight
hail\",\n 99: \"Thunderstorm with heavy hail\"\n } %}\n {{ mapper.get(code,
\"Not Availible\") }}\n"
- action: script.general_notificatioon
data:
message: 'Good Morning!
Here is the weather for today for {{loc}}:
High: {{high}} {{temp_unit}}
Low: {{low}} {{temp_unit}}
Conditions: {{condition}}'
title: Morning Report
mode: single
- id: '1766182515375'
alias: Dash Test
description: ''
triggers: []
conditions: []
actions:
- action: script.phone_weather
metadata: {}
data: {}
response_variable: weather
- variables:
max_temp: '{{weather.content.daily.temperature_2m_max[0]}}'
mode: single

View File

@@ -0,0 +1,66 @@
# Loads default set of integrations. Do not remove.
default_config:
# Load frontend themes from the themes folder
frontend:
themes: !include_dir_merge_named themes
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
http:
use_x_forwarded_for: true
trusted_proxies:
#- 172.19.0.2 # Add the IP address of the proxy server
- 172.0.0.0/8 # You may also provide the subnet mask
- 192.168.0.56
rest_command: # This api shows: Daily code, max/min temp, apperent max/min temp, sunrise/sunset/daylight, UV, percip sum/hours/probability
get_phone_weather: # All in US units for 3 days out
url: >
{% set lat = state_attr('device_tracker.alexs_phone','latitude') %}
{% set lon = state_attr('device_tracker.alexs_phone','longitude') %}
https://api.open-meteo.com/v1/forecast?latitude={{lat}}&longitude={{lon}}&daily=weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,sunrise,daylight_duration,sunset,uv_index_max,precipitation_sum,precipitation_hours,precipitation_probability_max&timezone=America%2FNew_York&forecast_days=3&wind_speed_unit=mph&temperature_unit=fahrenheit&precipitation_unit=inch
method: GET
rest: !include_dir_merge_list rest/
monitor_docker:
- name: Docker
containers:
- glances
- habridge
- homeassistant
- nextcloud-app-1
- nextcloud-db-1
- nextcloud-redis-1
- portainer
- syncthing
rename:
glances: 'Glances'
habridge: 'Home Assistant Bridge'
homeassistant: 'Home Assistant'
nextcloud-app-1: 'Nextcloud Server'
nextcloud-db-1: 'Nextcloud Database'
nextcloud-redis-1: 'Nextcloud Redis'
portainer: 'Portainer'
syncthing: 'Syncthing'
monitored_conditions:
- version
- containers_running
- containers_paused
- containers_stopped
- containers_total
- containers_memory_percentage
- images
- state
- status
- health
- uptime
- image
- 1cpu_percentage
- memory
- memory_percentage
scan_interval: 60

139
ha/ha_config/scripts.yaml Normal file
View File

@@ -0,0 +1,139 @@
phone_weather:
sequence:
- action: rest_command.get_phone_weather
data: {}
response_variable: weather_data
- variables:
max_temp: '{{ weather_data.content.daily.temperature_2m_max[0] }}'
- action: script.general_notificatioon
metadata: {}
data:
message: 'Good morning!
The high for today is {{ max_temp }}
'
title: Morning Weather
alias: Phone Weather
description: ''
general_notificatioon:
sequence:
- action: notify.mobile_app_alexs_iphone_2
metadata: {}
data:
message: '{{ message }}'
title: '{{ title }}'
- action: notify.persistent_notification
metadata: {}
data:
message: '{{ message }}'
title: '{{ title }}'
fields:
title:
selector:
text:
name: Title
required: true
message:
selector:
text:
name: Message
required: true
alias: General Notification
description: ''
icon: mdi:bell-badge
get_cal_data:
sequence:
- action: calendar.get_events
metadata: {}
data:
duration:
hours: 96
minutes: 0
seconds: 0
response_variable: Events
target:
entity_id: calendar.szumkoal_gmail_com
alias: Get Cal Data
description: ''
parse_morning_weather:
sequence:
- variables:
high: '{{ state_attr(''sensor.daily_forecast'', ''temperature_2m_max'')[0] }}'
low: '{{ state_attr(''sensor.daily_forecast'', ''temperature_2m_min'')[0] }}'
temp_unit: '{{ state_attr(''sensor.units'', ''temperature_2m'') }}'
condition: "{% set code = state_attr('sensor.daily_forecast', 'weather_code')[0]
| int %} {% set mapper = {\n 0: \"Clear sky\",\n 1: \"Mainly clear\",\n
\ 2: \"Partly cloudy\",\n 3: \"Overcast\",\n 45: \"Fog\",\n 48: \"Depositing
rime fog\",\n 51: \"Drizzle - Light intensity\",\n 53: \"Drizzle - Moderate
intensity\",\n 55: \"Drizzle - Dense intensity\",\n 56: \"Freezing Drizzle
- Light intensity\",\n 57: \"Freezing Drizzle - Dense intensity\",\n 61:
\"Rain - Slight intensity\",\n 63: \"Rain - Moderate intensity\",\n 65:
\"Rain - Heavy intensity\",\n 66: \"Freezing Rain - Light intensity\",\n
\ 67: \"Freezing Rain - Heavy intensity\",\n 71: \"Snow fall - Slight intensity\",\n
\ 73: \"Snow fall - Moderate intensity\",\n 75: \"Snow fall - Heavy intensity\",\n
\ 77: \"Snow grains\",\n 80: \"Rain showers - Slight intensity\",\n 81:
\"Rain showers - Moderate intensity\",\n 82: \"Rain showers - Violent intensity\",\n
\ 85: \"Snow showers - Slight intensity\",\n 86: \"Snow showers - Heavy intensity\",\n
\ 95: \"Thunderstorm - Slight intensity\",\n 96: \"Thunderstorm with slight
hail\",\n 99: \"Thunderstorm with heavy hail\"\n } %}\n {{ mapper.get(code,
\"Not Availible\") }}\n"
current_temp: '{{ state_attr(''sensor.current_weather'', ''apparent_temperature'')
}}'
alias: Parse_Morning_Weather
description: ''
parse_current_weather:
sequence:
- variables:
time: '{{ state_attr(''sensor.current_weather'', ''time'') | as_timestamp()
| timestamp_custom(''%B %d, %Y, %I:%M %p'') }}'
temp: '{{ state_attr(''sensor.current_weather'', ''temperature_2m'') }}'
apparent_temp: '{{ state_attr(''sensor.current_weather'', ''apparent_temperature'')
}}'
precip: '{{ state_attr(''sensor.current_weather'', ''precipitation'') }}'
weather_code: "{% set code = state_attr('sensor.current_weather', 'weather_code')
| int %} {% set mapper = {\n 0: \"Clear sky\",\n 1: \"Mainly clear\",\n
\ 2: \"Partly cloudy\",\n 3: \"Overcast\",\n 45: \"Fog\",\n 48: \"Depositing
rime fog\",\n 51: \"Drizzle - Light intensity\",\n 53: \"Drizzle - Moderate
intensity\",\n 55: \"Drizzle - Dense intensity\",\n 56: \"Freezing Drizzle
- Light intensity\",\n 57: \"Freezing Drizzle - Dense intensity\",\n 61:
\"Rain - Slight intensity\",\n 63: \"Rain - Moderate intensity\",\n 65:
\"Rain - Heavy intensity\",\n 66: \"Freezing Rain - Light intensity\",\n
\ 67: \"Freezing Rain - Heavy intensity\",\n 71: \"Snow fall - Slight intensity\",\n
\ 73: \"Snow fall - Moderate intensity\",\n 75: \"Snow fall - Heavy intensity\",\n
\ 77: \"Snow grains\",\n 80: \"Rain showers - Slight intensity\",\n 81:
\"Rain showers - Moderate intensity\",\n 82: \"Rain showers - Violent intensity\",\n
\ 85: \"Snow showers - Slight intensity\",\n 86: \"Snow showers - Heavy intensity\",\n
\ 95: \"Thunderstorm - Slight intensity\",\n 96: \"Thunderstorm with slight
hail\",\n 99: \"Thunderstorm with heavy hail\"\n } %}\n {{ mapper.get(code,
\"Not Availible\") }}\n"
daytime: '{{ state_attr(''sensor.current_weather'', ''is_day'') }}'
alias: Parse Current Weather
description: ''
parse_hourly_weather:
sequence:
- variables:
iso_time: '{{ state_attr(''sensor.hourly_forecast'', ''time'') }}'
temp: '{{ state_attr(''sensor.hourly_forecast'', ''temperature_2m'') }}'
precip_prob: '{{ state_attr(''sensor.hourly_forecast'', ''precipitation_probability'')
}}'
weather_code: '{{ state_attr(''sensor.hourly_forecast'', ''weather_code'') }}'
precip: '{{ state_attr(''sensor.hourly_forecast'', ''precipitation'') }}'
count: 0
formatted_time: []
- variables:
test: '{% set count = count +1 %}'
formatted_time: "\n{% set result = [] %} \n{% for i in range(iso_time | length)
%}\n {% set formatted = iso_time[i] | as_timestamp() | timestamp_custom('%B
%d, %Y, %I:%M %p') %}\n {% set result = result + [iso_time[i] | as_timestamp()
| timestamp_custom('%B %d, %Y, %I:%M %p')] %}\n{% endfor %} \n{{ result }}\n
\ \n"
- action: notify.persistent_notification
metadata: {}
data:
title: test
message: '{{iso_time}}
{{ formatted_time }}'
alias: Parse Hourly Weather
description: ''

1
homarr/.gitignore vendored
View File

@@ -1 +0,0 @@
.env

View File

@@ -1,2 +0,0 @@
# Homarr Info
# Testing only right now

View File

@@ -1,18 +0,0 @@
services:
homarr:
container_name: homarr
image: ghcr.io/homarr-labs/homarr:latest
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration
- ./appdata:/appdata
environment:
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
ports:
- '7575:7575'
networks:
- 'homelab'
networks:
homelab:
external: true

View File

@@ -35,9 +35,9 @@ services:
- MYSQL_USER=${MYSQL_USER}
- MYSQL_HOST=db
- REDIS_HOST=redis
- OVERWRITECLIURL=${OVERWRITECLIURL}
- OVERWRITEPROTOCOL=${OVERWRITEPROTOCOL}
- OVERWRITEHOST=${OVERWRITEHOST}
# - OVERWRITECLIURL=${OVERWRITECLIURL}
# - OVERWRITEPROTOCOL=${OVERWRITEPROTOCOL}
# - OVERWRITEHOST=${OVERWRITEHOST}
depends_on:
- db
- redis

14
nginx/.gitignore vendored
View File

@@ -1,14 +0,0 @@
# Ignore sensitive data
.env # Environment variables file (contains sensitive info)
# Ignore directories with persistent or sensitive data
data/ # Contains persistent data (e.g., databases, configuration files)
letsencrypt/ # Contains SSL certificates (do not track in Git)
# Ignore temporary or log files
*.log # Log files
*.bak # Backup files
*.swp # Swap files (e.g., from text editors)
# Ignore any local overrides or extra Docker Compose files
docker-compose.override.yml # Local override for docker-compose (optional)

View File

@@ -1,32 +0,0 @@
# Nginx Proxy Manager Info
## Instructions:
- Use for controlling paths/subdomains in cloudflare tunnel
- Access WebUI on port 81
## Contents:
**`nginx/`**
├── **`data/`**
├── **`docker-compose.yml`**
├── **`.env`**
├── **`.gitignore`**
├── **`letsencrypt/`**
└── **`README.md`**
## File Descrptions:
- **`data/`**: Nginx Data
- **`docker-compose.yml`**: Compose file
- **`.env`**: Environment Variables
- **`.gitignore`**: Git Ignore file
- **`letsencrypt/`**: Letsencrypt Data
- **`README.md`**: Documentation
## Environmet Variables:
- None
## Ignored Files:
- **`data/`**: Persistant Data
- **`.env`**: Environment Variables
- **`letsencrypt/`**: Potentially sensitive data

View File

@@ -1,20 +0,0 @@
services:
app:
image: 'docker.io/jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# - '80:80'
- '81:81'
# - '443:443'
networks:
- 'homelab'
- 'tunnel'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
homelab:
external: true
tunnel:
external: true

View File

@@ -14,8 +14,8 @@ def get_data(filename):
y.append(float(data[1]))
return x, y
x_meas, y_meas = get_data('Plotting\Base\Measured.txt')
x_sim, y_sim = get_data("Plotting\Base\Simulated.txt")
x_meas, y_meas = get_data('Base\Measured.txt')
x_sim, y_sim = get_data("Base\Simulated.txt")
#print(min(x_meas),min(x_sim))

View File

@@ -0,0 +1,240 @@
import numpy as np
import matplotlib.pyplot as plt
def get_data(filename):
file = open(filename)
lines = file.readlines()
x = []
y = []
for i in range(len(lines)):
if i % 2 == 0:
lines[i].strip()
data = lines[i].split()
x.append(float(data[0]))
y.append(float(data[1]))
return x, y
time, load_power = get_data('Drone Comparison Data for Dan/ME481_load_power.txt')
time1, engine_power = get_data('Drone Comparison Data for Dan/ME481_engine_power.txt')
time2, elec_power = get_data('Drone Comparison Data for Dan/ME481_elec_power.txt')
time3, soc_small = get_data('Drone Comparison Data for Dan/ME481_soc.txt')
time4, mft_load_power = get_data('Drone Comparison Data for Dan/required_power.txt')
time5, mft_engine_power = get_data('Drone Comparison Data for Dan/engine_power.txt')
time6, mft_elec_power = get_data('Drone Comparison Data for Dan/hybrid_battery_power.txt')
time7, mft_battery_only = get_data('Drone Comparison Data for Dan/battery_only_power.txt')
soc =[]
for data in soc_small:
soc.append(data*100)
# Basic Styling
plt.rcParams.update({
'font.family': 'Courier New', # monospace font
'font.size': 20, # Fonts
'axes.titlesize': 20, # |
'axes.labelsize': 15, # V
'xtick.labelsize': 15,
'ytick.labelsize': 15,
'legend.fontsize': 15,
'figure.titlesize': 20,
'figure.figsize': [10,10] # Figure Size
})
# Figure Setup
fig, ax = plt.subplots(3, 1, gridspec_kw={'height_ratios': [2, 1, 2]})
title = 'Power Output vs Time' # Title
# fig.suptitle(title, y=0.95) #pad controls distance to plot
### Figure 1 (top) ###
x_1_title = 'Jetfire Hybrid System Power Output'
ax[0].set_title(x_1_title)
x_1_lab = 'Time [min]' # X Label
y_1_lab = 'Power [kW]' # Y Label
ax[0].set_xlabel(x_1_lab)
ax[0].set_ylabel(y_1_lab)
ax[0].spines['top'].set_visible(False) # Controls non axis borders
ax[0].spines['right'].set_visible(False)
ax[0].spines['bottom'].set_visible(False)
### Figure 2 (middle) ###
x_2_title = 'Jetfire Hybrid System State of charge'
ax[1].set_title(x_2_title)
x_2_lab = 'Time [min]' # X Label
y_2_lab = 'Charge [%]' # Y Label
ax[1].set_xlabel(x_2_lab)
ax[1].set_ylabel(y_2_lab)
ax[1].spines['top'].set_visible(False) # Controls non axis borders
ax[1].spines['right'].set_visible(False)
### Figure 3 (middle) ###
x_3_title = 'Maximum Flight Time Test'
ax[2].set_title(x_3_title)
x_3_lab = 'Time [min]' # X Label
y_3_lab = 'Power [kW]' # Y Label
ax[2].set_xlabel(x_3_lab,labelpad=-15)
ax[2].set_ylabel(y_3_lab)
ax[2].spines['top'].set_visible(False) # Controls non axis borders
ax[2].spines['right'].set_visible(False)
ax[2].spines['bottom'].set_visible(False)
### axis is the same for both graphs ###
### x displays on bottom graph only ###
x_1_min = 0 # Axis Limits and Ticks
x_1_max = 31
x_1_step_maj = 5 #steps not division
x_1_step_min = 1
ax[0].set_xlim(x_1_min,x_1_max) # X limits
ax[0].set_xticks(np.arange(x_1_min,x_1_max,x_1_step_maj)) # X Major Ticks
# ax[0].set_xticks([17.45],[''], minor=True)
# ax[1].set_xticks([-180,-90,0,90,180], minor=True) # X Minor Ticks
x_2_min = 0 # Axis Limits and Ticks
x_2_max = 31
x_2_step_maj = 5 #steps not division
x_2_step_min = 1
ax[1].set_xlim(x_2_min,x_2_max) # X limits
ax[1].set_xticks(np.arange(x_2_min,x_2_max,x_2_step_maj)) # X Major Ticks
# ax[1].set_xticks([-180,-90,0,90,180], minor=True) # X Minor Ticks
x_3_min = 0 # Axis Limits and Ticks
x_3_max = 95
x_3_step_maj = 10 #steps not division
x_3_step_min = 1
ax[2].set_xlim(x_3_min,x_3_max) # X limits
ax[2].set_xticks(np.arange(x_3_min,x_3_max,x_3_step_maj),['0','','20','','40','','60','','80','']) # X Major Ticks
ax[2].set_xticks([28.5,71.5,92.97],['28.53','Fuel Runs\nOut','92.97'], minor=True)
# ax[2].set_xticks([0,9.17,10,20,30,40,50,60,70,71.5,80,90,92.97],['0','Electric only ])
# ax[1].set_xticks([-180,-90,0,90,180], minor=True) # X Minor Ticks
### Figure 1 (top) ###
y_1_min = -5
y_1_max = 17
y_1_step_maj = 5
y_1_step_min = 1
ax[0].set_ylim(y_1_min,y_1_max) # Y limits
ax[0].set_yticks(np.arange(y_1_min,y_1_max,y_1_step_maj)) # Y Major Ticks
# ax.set_yticks(np.arange(y_min,y_max,y_step_min),minor=True) # Y Minor Ticks
ax[0].grid(True, which='major',alpha=0.5) # Turn On Major Grid
# ax[0].grid(True, which='minor',alpha=1,color='black',linestyle='--') # Turn on Minor Grid
# alpha controls transparency
ax[0].text(0.45,0.26,'Payload\ndelivery\n <--',transform=ax[0].transAxes, fontsize=13)
ax[0].text(0.575,0.26,'Return\nflight\n -->',transform=ax[0].transAxes, fontsize=13)
### Figure 2 (bottom) ###
y_2_min = 80
y_2_max = 105
y_2_step_maj = 10
y_2_step_min = 1
ax[1].set_ylim(y_2_min,y_2_max) # Y limits
ax[1].set_yticks(np.arange(y_2_min,y_2_max,y_2_step_maj)) # Y Major Ticks
# ax[1].set_yticks(np.arange(y_2_min,y_2_max,y_2_step_min),minor=True) # Y Minor Ticks
ax[1].grid(True, which='major',alpha=0.5) # Turn On Major Grid
# ax[1].grid(True, which='minor',alpha=0.2) # Turn on Minor Grid
# alpha controls transparency
y_3_min = -5
y_3_max = 17
y_3_step_maj = 5
y_3_step_min = 1
ax[2].set_ylim(y_3_min,y_3_max) # Y limits
ax[2].set_yticks(np.arange(y_3_min,y_3_max,y_3_step_maj)) # Y Major Ticks
# ax[1].set_yticks(np.arange(y_2_min,y_2_max,y_2_step_min),minor=True) # Y Minor Ticks
ax[2].grid(True, which='major',alpha=0.5) # Turn On Major Grid
# ax[2].grid(True, which='minor',alpha=1, linestyle='--', linewidth=1, color='black') # Turn on Minor Grid
ax[2].tick_params(axis='x', which='minor', length=10)
# alpha controls transparency
###################### Single Line ######################
'''
# x = []
# y = []
ax.plot(x,y,color='black',linestyle='-',linewidth='1')
# Basic Line Styles: -, --, :, -.
# Basic Colors: red, blue, green, purple, cyan, magenta, black, brown, etc
# Can Specify Hex code for colors
# ax.scatter(x,y,color='black',marker='o',size=20)
# # Many Markers: circle-'o', square-'s', triangle-'^',star-'*', x-'x'
# plt.show()
'''
###################### Stacked Line ######################
x1 = [[0,31],[17.4,17.4],time,time1,time2] # List of Lists
y1 = [[0,0],[-5,15.5],load_power,engine_power,elec_power] # List of Lists
dl1 = ['','','Required Output','Jetfire Engine','Electric Motor'] # Data Labels (list)
lc1 = ['black','black',"#A30F48","#1db9be","#0C53AF"] # Line Color |
ls1 = ['-','--','-','-','-'] # Line Style |
lw1 = [1,1,2,2,2] # Line Width V
a1 = [1,1,1,1,1] # Transparency
for i in range(len(x1)):
ax[0].plot(x1[i],y1[i],label=dl1[i],color=lc1[i],linestyle=ls1[i],linewidth=lw1[i], alpha=a1[i])
ax[0].legend(loc='center', bbox_to_anchor=(0.85,0.8), ncol=1, frameon=True,edgecolor='white',framealpha=1, labelspacing=0.2, columnspacing=0.75,handlelength=0.9, handletextpad=0.3)
# anchor loc is based on the plot area, 0.5 is half the width, 1.01 is just above the top
# labelspacing is for vertical spacing, column is for horizontal, handel is for line length, textpad is for handl eto text
x2 = [time3] # List of Lists
y2 = [soc] # List of Lists
dl2 = ['State of Charge'] # Data Labels (list)
lc2 = ['#008349'] # Line Color |
ls2 = ['-'] # Line Style |
lw2 = [2] # Line Width V
a2 = [1] # Transparency
for i in range(len(x2)):
ax[1].plot(x2[i],y2[i],label=dl2[i],color=lc2[i],linestyle=ls2[i],linewidth=lw2[i], alpha=a2[i])
# ax[1].fill_between(x_temp,y_temp,hatch='///', alpha=0)
# ax[1].legend(loc='center', bbox_to_anchor=(0.8,0.8), ncol=1, frameon=True,edgecolor='white',framealpha=1, labelspacing=0.2, columnspacing=0.75,handlelength=0.9, handletextpad=0.3)
# anchor loc is based on the plot area, 0.5 is half the width, 1.01 is just above the top
# labelspacing is for vertical spacing, column is for horizontal, handel is for line length, textpad is for handl eto text
x3 = [[0,95],[28.5,28.5],[71.5,71.5],[92.97,92.97],time4,time6,time5,time7] # List of Lists
y3 = [[0,0],[-5,0],[-5,0],[-5,6.34],mft_load_power,mft_elec_power,mft_engine_power,mft_battery_only] # List of Lists
dl3 = ['','','','','Hybrid Total Output', 'Electric Motor','Jetfire Engine','Fully Electric'] # Data Labels (list)
lc3 = ['black','black','black','black',"black","#667dc9","#45afd6","#04942F"] # Line Color |
ls3 = ['-','--','--','--','-','-','-','-'] # Line Style |
lw3 = [1,1,1,1,2,2,2,2] # Line Width V
a3 = [1,1,1,1,1,1,1,1] # Transparency
for i in range(len(x3)):
ax[2].plot(x3[i],y3[i],label=dl3[i],color=lc3[i],linestyle=ls3[i],linewidth=lw3[i], alpha=a3[i])
ax[2].legend(loc='center', bbox_to_anchor=(0.65,0.8), ncol=2, frameon=True,edgecolor='white',framealpha=1, labelspacing=0.2, columnspacing=0.75,handlelength=0.9, handletextpad=0.3)
plt.tight_layout()
plt.show()

View File

@@ -98,8 +98,8 @@ ax[0].set_xticks(np.arange(x_1_min,x_1_max,x_1_step_maj)) # X Maj
# ax[1].set_xticks([-180,-90,0,90,180], minor=True) # X Minor Ticks
x_2_min = 0 # Axis Limits and Ticks
x_2_max = 9.5
x_2_step_maj = 1 #steps not division
x_2_max = 29
x_2_step_maj = 2 #steps not division
x_2_step_min = 1
ax[1].set_xlim(x_2_min,x_2_max) # X limits