Skip to content

Commit

Permalink
Add config support for camera feed ips.
Browse files Browse the repository at this point in the history
  • Loading branch information
We-Gold committed Oct 17, 2023
1 parent d90de55 commit 787f627
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 72 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ Download the latest setup exe file from [github releases](https://github.com/FRC
2. Identify the path to the installed app. This path should be `C:\Users\[YOUR USERNAME HERE]\AppData\Local\Programs\Cougar-Dashboard\Cougar-Dashboard.exe`. If you can't find the app at that location, find the desktop shortcut to the dashboard app, right click and open properties, and you will find the path labelled **target**.
3. Edit the configuration file for the driver station app (this assumes the driver station app is already installed). See instructions here: [Official Instructions](https://docs.wpilib.org/en/stable/docs/software/driverstation/manually-setting-the-driver-station-to-start-custom-dashboard.html). When you replace the `DashboardCmdLine`, replace it with `""C:\Users\[YOUR USERNAME HERE]\AppData\Local\Programs\Cougar-Dashboard\Cougar-Dashboard.exe""`, or whichever path you identified in step 2.

### Changing Team Number
## Configuration

#### Changing Team Number

To change the team number, you need to edit the configuration file (or create one).

Expand All @@ -29,6 +31,15 @@ To change the team number, you need to edit the configuration file (or create on
}
```

#### Changing Camera Feeds

```json
{
"primary": "http://10.25.39.11:5800",
"secondary": "http://10.25.39.12:5800"
}
```

## Testing and Development

Development requires a local repo clone, [node.js](https://nodejs.org/en/), and `npm`.
Expand Down
73 changes: 37 additions & 36 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
{
"name": "Cougar-Dashboard",
"author": "FRC Team 2539",
"version": "0.3.3",
"main": "public/electron.js",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"electron-dev": "concurrently \"npm run dev\" \"electron .\"",
"electron-pack": "electron-builder",
"release": "vite build && electron-builder"
},
"dependencies": {
"@tailwindcss/forms": "^0.2.1",
"electron-is-dev": "^2.0.0",
"electron-store": "^8.0.1",
"preact": "^10.5.13"
},
"devDependencies": {
"@preact/preset-vite": "^2.0.0",
"autoprefixer": "^10.2.5",
"concurrently": "^6.2.0",
"electron": "^13.0.1",
"electron-builder": "^22.10.5",
"postcss": "^8.2.8",
"tailwindcss": "^2.0.3",
"vite": "^2.1.0"
},
"build": {
"files": [
"./build/**/*",
"./build/icon.*",
"./public/electron.js",
"./public/preload.js"
]
}
"name": "Cougar-Dashboard",
"author": "FRC Team 2539",
"version": "0.3.4",
"main": "public/electron.js",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"electron-dev": "concurrently \"npm run dev\" \"electron .\"",
"electron-pack": "electron-builder",
"release": "vite build && electron-builder"
},
"dependencies": {
"@tailwindcss/forms": "^0.2.1",
"electron-is-dev": "^2.0.0",
"electron-store": "^8.0.1",
"preact": "^10.5.13"
},
"devDependencies": {
"@preact/preset-vite": "^2.0.0",
"autoprefixer": "^10.2.5",
"concurrently": "^6.2.0",
"electron": "^13.0.1",
"electron-builder": "^22.10.5",
"postcss": "^8.2.8",
"tailwindcss": "^2.0.3",
"vite": "^2.1.0"
},
"build": {
"files": [
"./build/**/*",
"./build/icon.*",
"./public/electron.js",
"./public/preload.js"
]
}
}

17 changes: 17 additions & 0 deletions public/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ const Store = require("electron-store")
const schema = {
team: {
type: "string"
},
primary: {
type: "string"
},
secondary: {
type: "string"
}
}

Expand Down Expand Up @@ -71,6 +77,17 @@ function createWindow() {
win.setTitle(title)
})

ipcMain.handle("get-camera-ip", async (event, cameraKey) => {
switch (cameraKey) {
case "primary":
return await store.get("primary", "http://10.25.39.11:5800")
case "secondary":
return await store.get("secondary", "http://10.25.39.12:5800")
default:
return await store.get(cameraKey, "")
}
})

ipcMain.handle("get-team-number", async (event, args) => {
return await store.get("team", "2539")
})
Expand Down
1 change: 1 addition & 0 deletions public/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld("api", {
getTeamNumber: () => ipcRenderer.invoke("get-team-number"),
setWindowTitle: (title) => ipcRenderer.send("set-title", title),
getCameraIP: (cameraKey) => ipcRenderer.invoke("get-camera-ip", cameraKey),
handleConnect: (callback) => ipcRenderer.on("connect", (_, mode) => callback(mode))
})
28 changes: 14 additions & 14 deletions src/components/camerafeed.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { Component } from "preact"

export default class CameraFeed extends Component {
constructor(props) {
super(props)
constructor(props) {
super(props)

this.ip = this.props.cameraIP
this.isThumbnail = this.props.isThumbnail
}

this.isThumbnail = this.props.isThumbnail
}
render() {
let className =
"max-h-full m-auto " + (this.isThumbnail ? "" : "h-full")

render() {
let className = "max-h-full m-auto " + (this.isThumbnail ? "" : "h-full")
return (
<div className="h-full w-full relative">
<img className={className} src={this.props.cameraIP} />
</div>
)
}
}

return (
<div className="h-full w-full relative">
<img className={className} src={this.ip} />
</div>
)
}
}
77 changes: 56 additions & 21 deletions src/home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,60 @@ import ConfigurableAutos from "./components/configurable-autos"
import Pressure from "./components/pressure"

export default class Home extends Component {
constructor(props) {
super(props)
}
constructor(props) {
super(props)

// Create state to store loaded camera ips
this.state = {
hasFetchedCameraIPs: false,
}
}

componentDidMount() {
this.fetchCameraIPs()
}

fetchCameraIPs() {
if (!this.state.hasFetchedCameraIPs) {
Promise.all([
window.api.getCameraIP("primary"),
window.api.getCameraIP("secondary"),
]).then(([primaryIP, secondaryIP]) => {
this.setState({
hasFetchedCameraIPs: true,
primaryIP,
secondaryIP,
})
})
}
}

render() {
return (
<div className="grid grid-cols-12 w-full max-h-full h-full bg-gray text-black">
<div className="max-h-full col-span-3 grid grid-rows-8 grid-cols-1 p-3">
<Mechanisms nt={this.props.nt} />
<ConfigurableAutos
nt={this.props.nt}
ntMap={this.props.ntMap}
putValueNT={this.props.putValueNT}
/>
</div>
<div className="col-span-6 flex flex-row justify-around p-3">
<CameraFeed
cameraIP={this.state.primaryIP}
isThumbnail={false}
/>
</div>
<div className="col-span-3 flex flex-col justify-between p-3">
<CameraFeed
cameraIP={this.state.secondaryIP}
isThumbnail={true}
/>
<Pressure nt={this.props.nt} />
</div>
</div>
)
}
}

render() {
return (
<div className="grid grid-cols-12 w-full max-h-full h-full bg-gray text-black">
<div className="max-h-full col-span-3 grid grid-rows-8 grid-cols-1 p-3">
<Mechanisms nt={this.props.nt} />
<ConfigurableAutos nt={this.props.nt} ntMap={this.props.ntMap} putValueNT={this.props.putValueNT}/>
</div>
<div className="col-span-6 flex flex-row justify-around p-3">
<CameraFeed cameraIP={"http://10.25.39.11:5800"} isThumbnail={false}/>
</div>
<div className="col-span-3 flex flex-col justify-between p-3">
<CameraFeed cameraIP={"http://10.25.39.12:5800"} isThumbnail={true}/>
<Pressure nt={this.props.nt} />
</div>
</div>
)
}
}

0 comments on commit 787f627

Please sign in to comment.