Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions gcs/data/default_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
"mapStyle": {
"default": "hybrid",
"type": "option",
"options": ["satellite", "hybrid", "streets", "outdoor"],
"options": [
"satellite",
"hybrid",
"streets",
"outdoor"
],
"display": "Map Style"
},
"autoCheckForUpdates": {
Expand All @@ -21,14 +26,22 @@
"default": false,
"type": "boolean",
"display": "Sync Dashboard and Missions Map Viewstate"
},
"speechAnnouncements": {
"default": false,
"type": "boolean",
"display": "Speech Announcements"
}
},
"Dashboard": {
"maxAltitudeAlert": {
"description": "You'll be notified when the relative altitude of a drone exceeds this value.",
"default": 120,
"type": "number",
"range": [0, 100000],
"range": [
0,
100000
],
"display": "Maximum Altitude Alert",
"suffix": "m",
"group": "Altitude"
Expand All @@ -37,16 +50,26 @@
"description": "You'll be notified when the relative altitude of a drone goes below these values.",
"default": [],
"type": "extendableNumber",
"range": [0, 100000],
"range": [
0,
100000
],
"display": "Minimum Altitude Alerts",
"suffix": "m",
"group": "Altitude"
},
"batteryAlert": {
"description": "You'll be notified when the battery percentage falls below these values.",
"default": [10, 20, 50],
"default": [
10,
20,
50
],
"type": "extendableNumber",
"range": [0, 100],
"range": [
0,
100
],
"display": "Battery Alert",
"suffix": "%",
"group": "Battery"
Expand Down
Binary file added gcs/src/assets/sounds/flightmodechanged.mp3
Binary file not shown.
Binary file added gcs/src/assets/sounds/lowbattery.mp3
Binary file not shown.
Binary file added gcs/src/assets/sounds/waypointreached.mp3
Binary file not shown.
61 changes: 58 additions & 3 deletions gcs/src/dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ import {
selectHasSecondaryGps,
} from "./redux/slices/droneInfoSlice"
import { selectMessages } from "./redux/slices/statusTextSlice"
import { selectCurrentMission } from "./redux/slices/missionSlice"

import { useSettings } from "./helpers/settings"

// Helper javascript files
import { GPS_FIX_TYPES } from "./helpers/mavlinkConstants"
Expand All @@ -66,6 +69,9 @@ const tailwindColors = resolveConfig(tailwindConfig).theme.colors
// Sounds
import armSound from "./assets/sounds/armed.mp3"
import disarmSound from "./assets/sounds/disarmed.mp3"
import lowBatterySound from "./assets/sounds/lowbattery.mp3"
import waypointReachedSound from "./assets/sounds/waypointreached.mp3"
import flightModeChangedSound from "./assets/sounds/flightmodechanged.mp3"

export default function Dashboard() {
const dispatch = useDispatch()
Expand All @@ -83,6 +89,9 @@ export default function Dashboard() {
const hdopDisplay = hdop != null ? hdop.toFixed(2) : "0.00"

const connectedToDrone = useSelector(selectConnectedToDrone)
const currentMission = useSelector(selectCurrentMission)

const { getSetting } = useSettings()
const gps2 = useSelector(selectGPS2RawInt)
const hasSecondaryGps = useSelector(selectHasSecondaryGps)

Expand Down Expand Up @@ -122,14 +131,60 @@ export default function Dashboard() {
// Sounds
const [playArmed] = useSound(armSound, { volume: 0.1 })
const [playDisarmed] = useSound(disarmSound, { volume: 0.1 })
const [playLowBattery] = useSound(lowBatterySound, { volume: 0.1 })
const [playWaypointReached] = useSound(waypointReachedSound, { volume: 0.1 })
const [playFlightModeChanged] = useSound(flightModeChangedSound, {
volume: 0.1,
})

const currentMissionSeqRef = useRef(currentMission.seq)

// Play queued arming sounds
useEffect(() => {
if (armedNotification !== "") {
armedNotification === "armed" ? playArmed() : playDisarmed()
if (!getSetting("General.speechAnnouncements")) {
return
}
switch (armedNotification) {
case "armed":
playArmed()
break
case "disarmed":
playDisarmed()
break
case "mode_change":
playFlightModeChanged()
break
case "low_battery":
playLowBattery()
break
default:
break
}
dispatch(soundPlayed())
}, [
armedNotification,
playArmed,
playDisarmed,
playLowBattery,
dispatch,
getSetting("General.speechAnnouncements"),
])

useEffect(() => {
if (currentMission.seq > currentMissionSeqRef.current) {
if (!getSetting("General.speechAnnouncements")) {
return
}
playWaypointReached()
dispatch(soundPlayed())
currentMissionSeqRef.current = currentMission.seq
}
}, [armedNotification, playArmed, playDisarmed, dispatch])
}, [
currentMission.seq,
playWaypointReached,
dispatch,
getSetting("General.speechAnnouncements"),
])

// Following drone logic
useEffect(() => {
Expand Down
9 changes: 9 additions & 0 deletions gcs/src/redux/slices/droneInfoSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const droneInfoSlice = createSlice({
},
lastGraphResultsMessage: false,
},
lowBatteryAlerted: false,
},
reducers: {
setFlightSwVersion: (state, action) => {
Expand All @@ -127,6 +128,10 @@ const droneInfoSlice = createSlice({
state.notificationSound = "disarmed"
}
state.heartbeatData.baseMode = action.payload.base_mode

if (action.payload.custom_mode !== state.heartbeatData.customMode) {
state.notificationSound = "mode_change"
}
state.heartbeatData.customMode = action.payload.custom_mode
state.heartbeatData.systemStatus = action.payload.system_status
},
Expand All @@ -139,6 +144,10 @@ const droneInfoSlice = createSlice({
} else {
state.batteryData.push(action.payload)
}
if (action.payload.battery_remaining <= 20 && !state.lowBatteryAlerted) {
state.notificationSound = "low_battery"
state.lowBatteryAlerted = true
}
},
soundPlayed: (state) => {
state.notificationSound = ""
Expand Down