# Project export: TruckrZzz

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: An all-in-one smart solution for early drowsiness detection amongst truck drivers, providing smart solutions.
- Devpost: https://devpost.com/software/truckrzzz
- GitHub: https://github.com/pnavab/TruckrZzz
- Demo: https://github.com/banyar-shin/TruckrZzz-iOS-App
- Video: https://www.youtube.com/embed/ROCqNnT--EI?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Result: winner (Reflex: Best Use of Reflex ($2k Cash); TerraAPI: Most Commercially Viable Hack (weekly 1v1 product sessions))
- Team: 3 GitHub contributor(s) — pnavab (23 commits), Marcus Cheung (14 commits), sarah (11 commits)

## Devpost submission (written by the team)

### Inspiration

News frequently reports on vehicle crashes and accidents, with one statistic highlighting the prevalence of heavy truck accidents caused by driver fatigue. Truck drivers endure long hours on the road, delivering shipments nationwide, contributing to the tiredness that can lead to accidents. According to the National Transportation Safety Board, nearly 40% of heavy truck accidents originate from fatigue. In response, we pushed to develop a system capable of monitoring both facial expressions and heartbeats to detect early signs of fatigue among drivers.

### What it does

Our web app boasts two features aimed at improving driver safety: one harnesses computer vision technology to track the driver's face, effectively detecting signs of drowsiness, while the other streams the driver's heartbeat in real-time, providing an additional layer of drowsiness detection. Accessible through our web app is a dedicated page for viewing the webcam feed, which ideally can be monitored via personal devices like smartphones. Should the webcam detect the driver falling asleep, it triggers an alert with flashing lights and a sound to awaken the driver. Additionally, our dashboard feature enables managers to monitor their drivers and their respective drowsiness levels. We've incorporated a graphing feature within the dashboard that dynamically turns red when a selected driver's drowsiness level drops below the acceptable threshold, providing a clear visual indication of potential fatigue.

### How we built it

By combining Reflex and TerraAPI, as well as a companion mobile app in Swift, we were able to create a solution all within our ecosystem. The TerraAPI provided the crucial heartrate data in real time, which we livestreamed through a webhook that our Reflex website could read. The Reflex website also contains a manager-style dashboard for viewing several truckers and collect their unique data all at the same time. As a demo for future mobile usage, we also included a facial recognition and landmarking model to detect drowsiness and alert the user if they are falling asleep. The Swift app also provided additional information such as the heartrate in real time and establishing the connection to the webhook from the wearable device.

### Challenges we ran into

In order to construct the complex data flow of our project, we had to learn several new technologies along the way. It started with developing on a new wearable device with limited documentation and support only through a Swift iOS app, which none of us had experience with. With Reflex, we also encountered some bugs, which all had workarounds, and the difficulties that come with developing any website.

### Accomplishments we're proud of

We're proud of being able to integrate such complex technologies and orchestrate them in a seamless way. At times, we were afraid that our product wouldn't come together since all the components depended on each other and we needed to complete all of them. However, our team made everything work in the end.

### What we learned

Many of the technologies we worked with during TreeHacks were new and had a large learning curve in order to build our end goal. Along this journey, our team picked up valuable skills in Swift, Python, computer vision, web development, and how to work on 2 hours of sleep.

### What's next

We hope to broaden our target audience and not only apply these technologies for truck drivers, but also every day drivers that might need some extra assistance staying awake on the road.

## README (from the GitHub repository)

# TruckrZzz
### Our TreeHacks2024 project

An all in one smart solution for early drowsiness detection in truck drivers by using real time body data and computer vision to alert the drivers before it is too late. 

Built using Reflex for the web framework, TerraAPI for livestreaming heartrate data, Swift for the iOS companion app, and a complex backend to handle and process all the data

Link to companion iOS app repo: https://github.com/banyar-shin/TruckrZzz-iOS-App


## Detected evidence (automated analysis)

Indexed codebase: 36 recognized source files, 119 KB.
- CSS (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- Swift (language) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (50 of 50)

```
.gitignore
.web/.gitignore
.web/bun.lockb
.web/components/reflex/chakra_color_mode_provider.js
.web/components/reflex/radix_themes_color_mode_provider.js
.web/env.json
.web/jsconfig.json
.web/next.config.js
.web/package.json
.web/pages/_app.js
.web/pages/_document.js
.web/pages/404.js
.web/pages/dashboard.js
.web/pages/graphs/[id].js
.web/pages/index.js
.web/pages/webcam.js
.web/postcss.config.js
.web/reflex.install_frontend_packages.cached
.web/reflex.json
.web/styles/styles.css
.web/styles/tailwind.css
.web/tailwind.config.js
.web/utils/client_side_routing.js
.web/utils/components.js
.web/utils/context.js
.web/utils/helpers/dataeditor.js
.web/utils/helpers/range.js
.web/utils/state.js
.web/utils/stateful_components.js
.web/utils/theme.js
alembic.ini
alembic/env.py
alembic/README
alembic/script.py.mako
README.md
reflex.db
requirements.txt
rxconfig.py
TruckrZzz/__init__.py
TruckrZzz/components/__init__.py
TruckrZzz/components/footer.py
TruckrZzz/components/navbar.py
TruckrZzz/dashboard.py
TruckrZzz/fetchai.py
TruckrZzz/graphs.py
TruckrZzz/landmark.py
TruckrZzz/shape_predictor_68_face_landmarks.dat
TruckrZzz/styles.py
TruckrZzz/TruckrZzz.py
TruckrZzz/webcam.py
```

### Dependencies

- .web/package.json: @chakra-ui/react@2.6.1, @chakra-ui/system@2.5.7, @emotion/react@^11.11.1, @radix-ui/react-form@^0.0.3, @radix-ui/themes@^2.0.0, autoprefixer@10.4.14, axios@1.4.0, framer-motion@10.16.4, json5@2.2.3, lucide-react@0.314.0, next@14.0.1, next-sitemap@4.1.8, next-themes@0.2.0, postcss@8.4.31, react@18.2.0, react-dom@18.2.0, react-player@2.12.0, recharts@2.8.0, silly@^0.2.0, socket.io-client@4.6.1, tailwindcss@3.3.2, universal-cookie@4.0.4
- requirements.txt: reflex@==0.4.0

### Recent commits (newest first)

- Update README.md
- Create README.md
- changes
- changes
- add stuff
- changed heading color
- fix graphs
- graphs
- Merge branch 'main' of https://github.com/pnavab/TruckrZzz
- added to splash
- bugfix
- bugfix
- bugfix
- Merge branch 'main' of https://github.com/pnavab/TruckrZzz into main
- tune_hyper_params
- api for heart rate
- Merge branch 'main' of https://github.com/pnavab/TruckrZzz
- fixed dash theme
- Merge branch 'main' of https://github.com/pnavab/TruckrZzz into main
- tune_hyper_params

## Key source files (fetched from GitHub, selected and truncated for size)

### requirements.txt

```
reflex==0.4.0

```

### .web/package.json

```
{
  "name": "reflex",
  "scripts": {
    "dev": "next dev",
    "export": "next build",
    "export-sitemap": "next build && next-sitemap",
    "prod": "next start"
  },
  "dependencies": {
    "@chakra-ui/react": "2.6.1",
    "@chakra-ui/system": "2.5.7",
    "@emotion/react": "^11.11.1",
    "@radix-ui/react-form": "^0.0.3",
    "@radix-ui/themes": "^2.0.0",
    "axios": "1.4.0",
    "framer-motion": "10.16.4",
    "json5": "2.2.3",
    "lucide-react": "0.314.0",
    "next": "14.0.1",
    "next-sitemap": "4.1.8",
    "next-themes": "0.2.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-player": "2.12.0",
    "recharts": "2.8.0",
    "silly": "^0.2.0",
    "socket.io-client": "4.6.1",
    "universal-cookie": "4.0.4"
  },
  "devDependencies": {
    "autoprefixer": "10.4.14",
    "postcss": "8.4.31",
    "tailwindcss": "3.3.2"
  }
}
```

### .web/pages/index.js

```javascript
/** @jsxImportSource @emotion/react */


import { Fragment, useContext } from "react"
import { EventLoopContext, StateContexts } from "/utils/context"
import { Event, getBackendURL, isTrue } from "/utils/state"
import { Box as RadixThemesBox, Dialog as RadixThemesDialog, Flex as RadixThemesFlex, Heading as RadixThemesHeading, Link as RadixThemesLink, ScrollArea as RadixThemesScrollArea, Text as RadixThemesText } from "@radix-ui/themes"
import env from "/env.json"
import dynamic from "next/dynamic"
import NextLink from "next/link"
import NextHead from "next/head"

const ReactPlayer = dynamic(() => import('react-player'), { ssr: false });


export function Nextlink_04e84d65253ae2f5e88f7285b980b20d () {
  const state__navbar_state = useContext(StateContexts.state__navbar_state)


  return (
    <NextLink css={{"padding": "1em", "borderRadius": "0.5em", "color": isTrue(((state__navbar_state.selected_tab) === (""))) ? `#ffffff` : `black`, "backgroundColor": isTrue(((state__navbar_state.selected_tab) === (""))) ? `#3e5c76` : `transparent`, "textDecoration": isTrue(((state__navbar_state.selected_tab) === (""))) ? `underline` : `none`, "&:hover": {"textDecoration": "underline"}}} href={`/`} passHref={true}>
  {`Home`}
</NextLink>
  )
}

export function Nextlink_e63d737be7802d6043c88ba5b017461d () {
  const state__navbar_state = useContext(StateContexts.state__navbar_state)


  return (
    <NextLink css={{"padding": "1em", "borderRadius": "0.5em", "color": isTrue(((state__navbar_state.selected_tab) === ("webcam"))) ? `#ffffff` : `black`, "backgroundColor": isTrue(((state__navbar_state.selected_tab) === ("webcam"))) ? `#3e5c76` : `transparent`, "textDecoration": isTrue(((state__navbar_state.selected_tab) === ("webcam"))) ? `underline` : `none`, "&:hover": {"textDecoration": "underline"}}} href={`/webcam`} passHref={true}>
  {`Webcam`}
</NextLink>
  )
}

export function Fragment_1762bb90abdb81b879b2a22edbbe01a1 () {
  const [addEvents, connectError] = useContext(EventLoopContext);


  return (
    <Fragment>
  {isTrue(connectError !== null) ? (
  <Fragment>
  <RadixThemesDialog.Root open={connectError !== null}>
  <RadixThemesDialog.Content>
  <RadixThemesDialog.Title>
  {`Connection Error`}
</RadixThemesDialog.Title>
  <RadixThemesText as={`p`}>
  {`Cannot connect to server: `}
  {(connectError !== null) ? connectError.message : ''}
  {`. Check if server is reachable at `}
  {getBackendURL(env.EVENT).href}
</RadixThemesText>
</RadixThemesDialog.Content>
</RadixThemesDialog.Root>
</Fragment>
) : (
  <Fragment/>
)}
</Fragment>
  )
}

export function Nextlink_3667c1e2fcc00ab30d42e8b29b5b05be () {
  const state__navbar_state = useContext(StateContexts.state__navbar_state)


  return (
    <NextLink css={{"padding": "1em", "borderRadius": "0.5em", "color": isTrue(((state__navbar_state.selected_tab) === ("dashboard"))) ? `#ffffff` : `black`, "backgroundColor": isTrue(((state__navbar_state.selected_tab) === ("dashboard"))) ? `#3e5c76` : `transparent`, "textDecoration": isTrue(((state__navbar_state.selected_tab) === ("dashboard"))) ? `underline` : `none`, "&:hover": {"textDecoration": "underline"}}} href={`/dashboard`} passHref={true}>
  {`Dashboard`}
</NextLink>
  )
}

export function Nextlink_7b60baf52fd3d49dbf1f60abe53e5691 () {
  const state__navbar_state = useContext(StateContexts.state__navbar_state)


  return (
    <NextLink css={{"padding": "1em", "borderRadius": "0.5em", "color": isTrue(((state__navbar_state.selected_tab) === ("graphs"))) ? `#ffffff` : `black`, "backgroundColor": isTrue(((state__navbar_state.selected_tab) === ("graphs"))) ? `#3e5c76` : `transparent`, "textDecoration": isTrue(((state__navbar_state.selected_tab) === ("graphs"))) ? `underline` : `none`, "&:hover": {"textDecoration": "underline"}}} href={`/graphs/6`} passHref={true}>
  {`Graph`}
</NextLink>
  )
}

export default function Component() {

  return (
    <Fragment>
  <Fragment_1762bb90abdb81b879b2a22edbbe01a1/>
  <RadixThemesFlex align={`start`} css={{"width": "100%", "height": "100vh", "alignItems": "center", "flexDirection": "column"}} gap={`2`}>
  <ReactPlayer controls={true} playing={true} url={`/truck-honk.mp3`}/>
  <RadixThemesFlex align={`start`} css={{"width": "100%", "padding": "1em", "backgroundColor": "#f0ebd8", "height": "15%", "borderRadius": "0 0 10px 10px", "borderBottom": "1px solid #F4F3F6", "flexDirection": "row"}} gap={`2`}>
  <RadixThemesLink asChild={true}>
  <NextLink css={{"transition": "transform 0.2s ease-in-out", "&:hover": {"textDecor": "none", "transform": "scale(1.1)"}}} href={`/`} passHref={true}>
  <RadixThemesHeading css={{"color": "#1d2d44"}} size={`9`}>
  {`TruckrZzz`}
</RadixThemesHeading>
</NextLink>
</RadixThemesLink>
  <RadixThemesFlex css={{"flex": 1, "justifySelf": "stretch", "alignSelf": "stretch"}}/>
  <RadixThemesFlex css={{"display": "flex", "alignItems": "center", "justifyContent": "center"}} gap={`4`}>
  <RadixThemesLink asChild={true}>
  <Nextlink_04e84d65253ae2f5e88f7285b980b20d/>
</RadixThemesLink>
  <RadixThemesFlex css={{"width": "20px", "flex": 1, "justifySelf": "stretch", "alignSelf": "stretch"}}/>
  <RadixThemesLink asChild={true}>
  <Nextlink_3667c1e2fcc00ab30d42e8b29b5b05be/>
</RadixThemesLink>
  <RadixThemesFlex css={{"width": "20px", "flex": 1, "justifySelf": "stretch", "alignSelf": "stretch"}}/>
  <RadixThemesLink asChild={true}>
  <Nextlink_7b60baf52fd3d49dbf1f60abe53e5691/>
</RadixThemesLink>
  <RadixThemesFlex css={{"width": "20px", "flex": 1, "justifySelf": "stretch", "alignSelf": "stretch"}}/>
  <RadixThemesLink asChild={true}>
  <Nextlink_e63d737be7802d6043c88ba5b017461d/>
</RadixThemesLink>
</RadixThemesFlex>
  <RadixThemesFlex css={{"flex": 1, "justifySelf": "stretch", "alignSelf": "stretch"}}/>
  <RadixThemesLink asChild={true}>
  <NextLink css={{"&:hover": {"background": "#F5EFFE"}, "boxShadow": "0px 0px 0px 1px rgba(84, 82, 95, 0.14)", "background": "transparent", "borderRadius": "0.375rem"}} href={`https://github.com/reflex-dev/reflex`} passHref={tr
[truncated — 8571 more characters]
```

### rxconfig.py

```python
import reflex as rx

config = rx.Config(
    app_name="TruckrZzz",
)
```

### TruckrZzz/__init__.py

```python
from .graphs import graphs
```

### .web/postcss.config.js

```javascript
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

```

### .web/next.config.js

```javascript
module.exports = {basePath: "", compress: true, reactStrictMode: true, trailingSlash: true};

```

### .web/tailwind.config.js

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
	content: ["./pages/**/*.{js,ts,jsx,tsx}", "./utils/**/*.{js,ts,jsx,tsx}"],
	theme: null,
	plugins: [
	],
};
```

### TruckrZzz/fetchai.py

```python
from typing import List
import numpy as np

from uagents import Context, Model, Protocol, Agent


class FramePackage(Model):
    ret: bool
    frame: np.ndarray

class PreprocessFrameRequest(Model):
    frame: np.ndarray
    visualize: bool

query_proto = Protocol()

@query_proto.on_message(model=PreprocessFrameRequest, replies=FramePackage)
async def handle_query_request(ctx: Context, sender: str, msg: PreprocessFrameRequest):
    # Preprocess
    

class Preprocess(Model):
    pass

class PreprocessReturnFrame(Model):
    frame: np.ndarray

class Process(Model):
    pass

class ProcessRequest(Model):
    frame: np.ndarray
    visualize: bool


class ProcessReturn(Model):
    drowsy: bool
    annotated_frame:Optional[np.ndarray]


query_proto = Protocol()

```

### TruckrZzz/styles.py

```python
"""Styles for the app."""

import reflex as rx

border_radius = "0.375rem"
box_shadow = "0px 0px 0px 1px rgba(84, 82, 95, 0.14)"
border = "1px solid #F4F3F6"
text_color = "black"
accent_text_color = "#1A1060"
accent_color = "#F5EFFE"
hover_accent_color = {"_hover": {"color": accent_color}}
hover_accent_bg = {"_hover": {"bg": accent_color}}
content_width_vw = "90vw"
sidebar_width = "20em"

template_page_style = {"padding_top": "5em", "padding_x": ["auto", "2em"], "flex": "1"}

template_content_style = {
    "align_items": "flex-start",
    "box_shadow": box_shadow,
    "border_radius": border_radius,
    "padding": "1em",
    "margin_bottom": "2em",
}

link_style = {
    "color": text_color,
    "text_decoration": "none",
    **hover_accent_color,
}

overlapping_button_style = {
    "background_color": "white",
    "border": border,
    "border_radius": border_radius,
}

# base_style = {
#     rx.menu: {
#         "width": "3em",
#         "height": "3em",
#         **overlapping_button_style,
#     },
#     rx.MenuItem: hover_accent_bg,
# }

markdown_style = {
    "code": lambda text: rx.code(text, color="#1F1944", bg="#EAE4FD"),
    "a": lambda text, **props: rx.link(
        text,
        **props,
        font_weight="bold",
        color="#03030B",
        text_decoration="underline",
        text_decoration_color="#AD9BF8",
        _hover={
            "color": "#AD9BF8",
            "text_decoration": "underline",
            "text_decoration_color": "#03030B",
        },
    ),
}

```

[27 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]