mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-20 00:51:41 +00:00
Status LEDs (#104)
* Don't start metrics thread if not on linux * Add statusLED support * [Hardware] Add status LED support * [Hardware] Invalid LED port checks * [Hardware] Check if statusLED exists in config
This commit is contained in:
@@ -34,6 +34,7 @@ public class HardwareConfig {
|
||||
public final int ledPWMFrequency;
|
||||
public final String ledDimCommand;
|
||||
public final String ledBlinkCommand;
|
||||
public final ArrayList<Integer> statusRGBPins;
|
||||
|
||||
// Metrics
|
||||
public final String cpuTempCommand;
|
||||
@@ -55,6 +56,7 @@ public class HardwareConfig {
|
||||
ledSetCommand = "";
|
||||
ledsCanDim = false;
|
||||
ledPWMRange = new ArrayList<>();
|
||||
statusRGBPins = new ArrayList<>();
|
||||
ledPWMFrequency = 0;
|
||||
ledPWMSetRange = "";
|
||||
ledDimCommand = "";
|
||||
@@ -79,11 +81,12 @@ public class HardwareConfig {
|
||||
ArrayList<Integer> ledPins,
|
||||
String ledSetCommand,
|
||||
boolean ledsCanDim,
|
||||
ArrayList<Integer> ledPWMRange,
|
||||
ArrayList<Integer> statusRGBPins,
|
||||
String ledPWMSetRange,
|
||||
int ledPWMFrequency,
|
||||
String ledDimCommand,
|
||||
String ledBlinkCommand,
|
||||
ArrayList<Integer> ledPWMRange,
|
||||
String cpuTempCommand,
|
||||
String cpuMemoryCommand,
|
||||
String cpuUtilCommand,
|
||||
@@ -103,6 +106,7 @@ public class HardwareConfig {
|
||||
this.ledPWMFrequency = ledPWMFrequency;
|
||||
this.ledDimCommand = ledDimCommand;
|
||||
this.ledBlinkCommand = ledBlinkCommand;
|
||||
this.statusRGBPins = statusRGBPins;
|
||||
this.cpuTempCommand = cpuTempCommand;
|
||||
this.cpuMemoryCommand = cpuMemoryCommand;
|
||||
this.cpuUtilCommand = cpuUtilCommand;
|
||||
|
||||
@@ -34,48 +34,59 @@ public class CustomGPIO extends GPIOBase {
|
||||
|
||||
@Override
|
||||
public void togglePin() {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(!currentState))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = !currentState;
|
||||
if (this.port != -1) {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(!currentState))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = !currentState;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLow() {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(false))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = false;
|
||||
if (this.port != -1) {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(false))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHigh() {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(true))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = true;
|
||||
if (this.port != -1) {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(true))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(boolean state) {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(state))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = state;
|
||||
if (this.port != -1) {
|
||||
execute(
|
||||
commands
|
||||
.get("setState")
|
||||
.replace("{s}", String.valueOf(state))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
currentState = state;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shutdown() {
|
||||
execute(commands.get("shutdown"));
|
||||
return true;
|
||||
if (this.port != -1) {
|
||||
execute(commands.get("shutdown"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,13 +96,15 @@ public class CustomGPIO extends GPIOBase {
|
||||
|
||||
@Override
|
||||
public void setPwmRange(List<Integer> range) {
|
||||
execute(
|
||||
commands
|
||||
.get("setRange")
|
||||
.replace("{lower_range}", String.valueOf(range.get(0)))
|
||||
.replace("{upper_range}", String.valueOf(range.get(1)))
|
||||
.replace("{p}", String.valueOf(port)));
|
||||
pwmRange = range;
|
||||
if (this.port != -1) {
|
||||
execute(
|
||||
commands
|
||||
.get("setRange")
|
||||
.replace("{lower_range}", String.valueOf(range.get(0)))
|
||||
.replace("{upper_range}", String.valueOf(range.get(1)))
|
||||
.replace("{p}", String.valueOf(port)));
|
||||
pwmRange = range;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,23 +114,27 @@ public class CustomGPIO extends GPIOBase {
|
||||
|
||||
@Override
|
||||
public void blink(int pulseTimeMillis, int blinks) {
|
||||
execute(
|
||||
commands
|
||||
.get("blink")
|
||||
.replace("{pulseTime}", String.valueOf(pulseTimeMillis))
|
||||
.replace("{blinks}", String.valueOf(blinks))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
if (this.port != -1) {
|
||||
execute(
|
||||
commands
|
||||
.get("blink")
|
||||
.replace("{pulseTime}", String.valueOf(pulseTimeMillis))
|
||||
.replace("{blinks}", String.valueOf(blinks))
|
||||
.replace("{p}", String.valueOf(this.port)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dimLED(int dimValue) {
|
||||
// Check to see if dimValue is within the range
|
||||
if (dimValue < pwmRange.get(0) || dimValue > pwmRange.get(1)) return;
|
||||
execute(
|
||||
commands
|
||||
.get("dim")
|
||||
.replace("{p}", String.valueOf(port))
|
||||
.replace("{v}", String.valueOf(dimValue)));
|
||||
if (this.port != -1) {
|
||||
// Check to see if dimValue is within the range
|
||||
if (dimValue < pwmRange.get(0) || dimValue > pwmRange.get(1)) return;
|
||||
execute(
|
||||
commands
|
||||
.get("dim")
|
||||
.replace("{p}", String.valueOf(port))
|
||||
.replace("{v}", String.valueOf(dimValue)));
|
||||
}
|
||||
}
|
||||
|
||||
public static void setConfig(HardwareConfig config) {
|
||||
|
||||
@@ -29,128 +29,151 @@ import org.photonvision.common.logging.Logger;
|
||||
public class PiGPIO extends GPIOBase {
|
||||
private static final Logger logger = new Logger(PiGPIO.class, LogGroup.General);
|
||||
private final ArrayList<Pulse> pulses = new ArrayList<>();
|
||||
private final int pin;
|
||||
private final int port;
|
||||
|
||||
public static JPigpio getPigpioDaemon() {
|
||||
return Singleton.INSTANCE;
|
||||
}
|
||||
|
||||
public PiGPIO(int address, int frequency, int range) {
|
||||
this.pin = address;
|
||||
this.port = address;
|
||||
try {
|
||||
getPigpioDaemon().setPWMFrequency(this.pin, frequency);
|
||||
getPigpioDaemon().setPWMRange(this.pin, range);
|
||||
getPigpioDaemon().setPWMFrequency(this.port, frequency);
|
||||
getPigpioDaemon().setPWMRange(this.port, range);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set PWM settings on port " + this.pin);
|
||||
logger.error("Could not set PWM settings on port " + this.port);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void togglePin() {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.pin, !getPigpioDaemon().gpioRead(this.pin));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not toggle on pin " + this.pin);
|
||||
e.printStackTrace();
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.port, !getPigpioDaemon().gpioRead(this.port));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not toggle on pin " + this.port);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLow() {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.pin, false);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set pin low on port " + this.pin);
|
||||
e.printStackTrace();
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.port, false);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set pin low on port " + this.port);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHigh() {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.pin, true);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set pin high on port " + this.pin);
|
||||
e.printStackTrace();
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.port, true);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set pin high on port " + this.port);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(boolean state) {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.pin, state);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set pin state on port " + this.pin);
|
||||
e.printStackTrace();
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
getPigpioDaemon().gpioWrite(this.port, state);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set pin state on port " + this.port);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shutdown() {
|
||||
try {
|
||||
getPigpioDaemon().gpioTerminate();
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not terminate GPIO instance");
|
||||
e.printStackTrace();
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
getPigpioDaemon().gpioTerminate();
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not terminate GPIO instance");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getState() {
|
||||
try {
|
||||
return getPigpioDaemon().gpioRead(this.pin);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not read pin on port " + this.pin);
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
return getPigpioDaemon().gpioRead(this.port);
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not read pin on port " + this.port);
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPwmRange(List<Integer> range) {
|
||||
try {
|
||||
getPigpioDaemon().setPWMRange(this.pin, range.get(0));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set PWM range on port " + this.pin);
|
||||
e.printStackTrace();
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
getPigpioDaemon().setPWMRange(this.port, range.get(0));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not set PWM range on port " + this.port);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getPwmRange() {
|
||||
try {
|
||||
return List.of(0, getPigpioDaemon().getPWMRange(this.pin));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not get PWM range on port " + this.pin);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
return List.of(0, getPigpioDaemon().getPWMRange(this.port));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not get PWM range on port " + this.port);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blink(int pulseTimeMillis, int blinks) {
|
||||
try {
|
||||
pulses.clear();
|
||||
for (int i = 0; i < blinks; i++) {
|
||||
pulses.add(new Pulse(1 << this.pin, 0, pulseTimeMillis * 100));
|
||||
pulses.add(new Pulse(0, 1 << this.pin, pulseTimeMillis * 100));
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
pulses.clear();
|
||||
for (int i = 0; i < blinks; i++) {
|
||||
pulses.add(new Pulse(1 << this.port, 0, pulseTimeMillis * 100));
|
||||
pulses.add(new Pulse(0, 1 << this.port, pulseTimeMillis * 100));
|
||||
}
|
||||
getPigpioDaemon().waveAddGeneric(this.pulses);
|
||||
getPigpioDaemon().waveSendOnce(getPigpioDaemon().waveCreate());
|
||||
} catch (PigpioException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
getPigpioDaemon().waveAddGeneric(this.pulses);
|
||||
getPigpioDaemon().waveSendOnce(getPigpioDaemon().waveCreate());
|
||||
} catch (PigpioException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dimLED(int dimPercentage) {
|
||||
try {
|
||||
getPigpioDaemon().setPWMDutycycle(this.pin, getPwmRange().get(1) * (dimPercentage / 100));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not dim PWM on port " + this.pin);
|
||||
e.printStackTrace();
|
||||
if (this.port != -1) {
|
||||
try {
|
||||
getPigpioDaemon().setPWMDutycycle(this.port, getPwmRange().get(1) * (dimPercentage / 100));
|
||||
} catch (PigpioException e) {
|
||||
logger.error("Could not dim PWM on port " + this.port);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,30 @@ public class HardwareManager {
|
||||
LEDs.values().forEach(GPIOBase::shutdown);
|
||||
}
|
||||
|
||||
public GPIOBase redStatusLED() {
|
||||
try {
|
||||
return LEDs.get(hardwareConfig.statusRGBPins.get(0));
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return LEDs.get(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public GPIOBase greenStatusLED() {
|
||||
try {
|
||||
return LEDs.get(hardwareConfig.statusRGBPins.get(1));
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return LEDs.get(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public GPIOBase blueStatusLED() {
|
||||
try {
|
||||
return LEDs.get(hardwareConfig.statusRGBPins.get(2));
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return LEDs.get(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean restartDevice() {
|
||||
try {
|
||||
return shellExec.executeBashCommand(hardwareConfig.restartHardwareCommand) == 0;
|
||||
|
||||
Reference in New Issue
Block a user