Skip to content

Commit

Permalink
Preparing to make the repo public (#15)
Browse files Browse the repository at this point in the history
* renamed in readme, moved to groundlight with github actions

* should only publish containers when pulled into main

* Changed name in MIT License

* removed unused components

* removed unused code, fixed docker-compose

* cleaned up dockerfiles

* renamed in package json

* renamed to monitoring-notification-server

fixed action step names

Co-authored-by: robotrapta <79607467+robotrapta@users.noreply.github.com>

* Update .github/workflows/test_building_containers.yaml

added useful comment

Co-authored-by: robotrapta <79607467+robotrapta@users.noreply.github.com>

* fixed opencv-python version, new version isn't built for aarch64 yet

* fixed opencv-headless version

---------

Co-authored-by: Max McKelvey <maxmckelvey@Maxs-MBP.positronix.local>
Co-authored-by: robotrapta <79607467+robotrapta@users.noreply.github.com>
  • Loading branch information
3 people committed Aug 9, 2023
1 parent 2c90ffe commit 1fefdef
Show file tree
Hide file tree
Showing 26 changed files with 204 additions and 478 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# This is a workflow to build images
name: Build Docker Images

on: [push, workflow_dispatch]
on:
push:
branches: [ "main" ]

jobs:
build-frontend:
Expand Down Expand Up @@ -36,7 +38,7 @@ jobs:
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/detector-builder-frontend:latest
tags: docker.io/groundlight/monitoring-notification-server-frontend:latest
platforms: linux/amd64,linux/arm64
file: ./frontend.Dockerfile
push: true
Expand Down Expand Up @@ -75,7 +77,7 @@ jobs:
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/detector-builder-frontend-armv7:latest
tags: docker.io/groundlight/monitoring-notification-server-frontend:armv7-latest
platforms: linux/arm/v7
file: ./frontend-armv7.Dockerfile
push: true
Expand Down Expand Up @@ -114,7 +116,7 @@ jobs:
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/detector-builder-backend:latest
tags: docker.io/groundlight/monitoring-notification-server-backend:latest
platforms: linux/amd64,linux/arm64
file: ./backend.Dockerfile
push: true
Expand Down Expand Up @@ -153,7 +155,7 @@ jobs:
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/maxatgroundlight/detector-builder-backend-armv7:latest
tags: docker.io/groundlight/monitoring-notification-server-backend:armv7-latest
platforms: linux/arm/v7
file: ./backend-armv7.Dockerfile
push: true
Expand Down
164 changes: 164 additions & 0 deletions .github/workflows/test_building_containers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# This is a workflow to build images
name: Build Docker Images

on: [push, workflow_dispatch]

jobs:
build-frontend:
# TODO: move these four repetitive jobs into a shared parameterized github action
name: Build Frontend Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to container registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
registry: docker.io

# So now you can use Actions' own caching!
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build Image to verify it works but don't push
uses: docker/build-push-action@v3
with:
tags: docker.io/groundlight/monitoring-notification-server-frontend:latest
platforms: linux/amd64,linux/arm64
file: ./frontend.Dockerfile
push: false
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

build-frontend-armv7:
name: Build Frontend armv7 Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to container registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
registry: docker.io

# So now you can use Actions' own caching!
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build Image to verify it works but don't push
uses: docker/build-push-action@v3
with:
tags: docker.io/groundlight/monitoring-notification-server-frontend:armv7-latest
platforms: linux/arm/v7
file: ./frontend-armv7.Dockerfile
push: false
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

build-backend:
name: Build Backend Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to container registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
registry: docker.io

# So now you can use Actions' own caching!
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build Image to verify it works but don't push
uses: docker/build-push-action@v3
with:
tags: docker.io/groundlight/monitoring-notification-server-backend:latest
platforms: linux/amd64,linux/arm64
file: ./backend.Dockerfile
push: false
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

build-backend-armv7:
name: Build Backend armv7 Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to container registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
registry: docker.io

# So now you can use Actions' own caching!
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build and Push Image
uses: docker/build-push-action@v3
with:
tags: docker.io/groundlight/monitoring-notification-server-backend:armv7-latest
platforms: linux/arm/v7
file: ./backend-armv7.Dockerfile
push: false
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
# go here (https://evilmartians.com/chronicles/build-images-on-github-actions-with-docker-layer-caching)
# if cache is overflowing and is breaking
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 Diego Valdez
Copyright (c) 2023 Groundlight AI

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<p align="center">
<a href="https://nextjs-fastapi-starter.vercel.app/">
<img src="https://avatars.githubusercontent.com/u/118213576?s=200&v=4" height="96">
<h3 align="center">Groundlight Detector Builder</h3>
<h3 align="center">Notification Server Example</h3>
</a>
</p>

<br/>

## What is the Groundlight Detector Builder?
## What is the Notification Server Example?

Groundlight Detector Builder is an app you can deploy anywhere to easily build Groundlight Detectors, and configure them to pull from custom image sources and post notifications.
Our Notification Server Example is a server you can deploy anywhere to easily build Groundlight Detectors, and configure them to pull from custom image sources and post notifications.

The Detector Builder has a simple web interface (depected below) that allows you to configure your detector, and a backend that runs on your device to pull images from your camera and post notifications.
The Notification Server Example has a simple web interface (depected below) that allows you to configure your detector, and a backend that runs on your device to pull images from your camera and post notifications.

### Intro Page

Expand All @@ -21,20 +21,20 @@ The Detector Builder has a simple web interface (depected below) that allows you

![Detector Dashboard](./images/Groundlight-Detector-Dashboard.png)

## Running from Docker
## Running with Docker

1. Create the file `docker-compose.yml` with the following contents:

```yaml
services:
frontend:
image: docker.io/maxatgroundlight/detector-builder-frontend:latest
image: docker.io/groundlight/monitoring-notification-server-frontend:latest
ports:
- "3000:3000"
depends_on:
- backend
backend:
image: docker.io/maxatgroundlight/detector-builder-backend:latest
image: docker.io/groundlight/monitoring-notification-server-backend:latest
ports:
- "8000:8000"
devices:
Expand All @@ -56,13 +56,13 @@ services:
```yaml
services:
frontend:
image: docker.io/maxatgroundlight/detector-builder-frontend-armv7:latest
image: docker.io/groundlight/monitoring-notification-server-frontend:armv7-latest
ports:
- "3000:3000"
depends_on:
- backend
backend:
image: docker.io/maxatgroundlight/detector-builder-backend-armv7:latest
image: docker.io/groundlight/monitoring-notification-server-backend:armv7-latest
ports:
- "8000:8000"
devices:
Expand All @@ -77,7 +77,7 @@ services:

2. Run `docker-compose up` in the same directory as the `docker-compose.yml` file.

## Running from Source
## Building from Source

1. Install [Node.js](https://nodejs.org/en/download/) and [Python 3.8+](https://www.python.org/downloads/).

Expand Down
3 changes: 0 additions & 3 deletions api/gl_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,12 @@ def push_label_result(api_key: str, endpoint: str, query_id: str, label: str):
def run_process(idx: int, logger, detector: dict, api_key: str, endpoint: str,
notify_queue: multiprocessing.Queue,
photo_queue: multiprocessing.Queue,
# websocket_img_queue: multiprocessing.Queue,
websocket_metadata_queue: multiprocessing.Queue,
websocket_cancel_queue: multiprocessing.Queue,
websocket_response_queue: multiprocessing.Queue):
# print("Starting process...")

trigger_type = detector["config"]["trigger_type"]

# delay = lambda: time.sleep(30)
poll_delay = 0.5
delay = lambda: time.sleep(poll_delay)
cycle_time = 30
Expand Down
50 changes: 5 additions & 45 deletions api/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,32 @@

def send_notifications(det_name: str, query: str, label: str, options: dict, image, logger):
if "condition" not in options:
# print("No condition provided")
logger.error("No condition provided")
return
condition = options["condition"].upper() # "PASS", "FAIL"
condition = options["condition"].upper() # "PASS" or "FAIL"
if label == "YES":
label = "PASS"
elif label == "NO":
label = "FAIL"

if "stacklight" in options:
# print("Sending stacklight")
logger.error("Sending stacklight")
logger.error("Sending to stacklight")
stacklight_options = options["stacklight"]
post_to_stacklight(det_name, query, label, stacklight_options)

if not ((condition == "PASS" and label == "PASS") or (condition == "FAIL" and label == "FAIL")):
# print("Condition not met")
logger.error("Condition not met")
return

if "email" in options:
# print("Sending email")
logger.error("Sending email")
email_options = options["email"]
send_email(det_name, query, image, label, email_options)
if "twilio" in options:
# print("Sending sms")
logger.error("Sending sms")
twilio_options = options["twilio"]
send_sms(det_name, query, label, twilio_options)
if "slack" in options:
# print("Sending slack")
logger.error("Sending slack")
slack_options = options["slack"]
send_slack(det_name, query, label, slack_options)
Expand Down Expand Up @@ -109,46 +103,12 @@ def send_slack(det_name: str, query: str, label: str, options: dict):
channel=options["channel_id"],
text=f"Your detector [{det_name}] returned a \"{label}\" result to the query [{query}]."
)
# assert response["message"]["text"] == f"Your detector [{det_name}] returned a \"{label}\" result."

def post_to_stacklight(det_name: str, query: str, label: str, options: dict):
if "ip" not in options:
return # TODO: Fix this (probably add usb stuff)

if "ip" not in options:
id = options["id"]
ap_name = "GL_STACKLIGHT_" + id
ap_password = "gl_stacklight_password_" + id
if "ssid" not in options or "password" not in options:
print("No ssid or password provided")
return
ssid = options["ssid"]
password = options["password"]
try:
wifi_networks = os.popen("nmcli -t -f ssid dev wifi list").read()
if ap_name not in wifi_networks:
return
os.popen(f"nmcli dev wifi connect {ap_name} password {ap_password}")

# push ssid and password to stacklight
res = requests.post(f"http://192.168.4.1:8080", json={"ssid": ssid, "password": password})
if res.status_code != 200:
print("Could not connect to stacklight")
return
res = requests.get(f"http://192.168.4.1:8080/ip")
if res.status_code != 200:
print("Could not connect to stacklight")
return
ip = res.text
except:
try:
os.popen(f"nmcli dev wifi connect {options['ssid']} password {options['password']}")
except:
print("Could not connect to wifi network")
return

else:
ip: str = options["ip"]
return

ip: str = options["ip"]

port = "8080"

Expand Down
Loading

0 comments on commit 1fefdef

Please sign in to comment.