Commit 3c3f8e65 authored by David's avatar David
Browse files

Making things work.

I have disabled the i2c stuff, because it wasn't working with pi4j, and
I'm kinda okay with that for now.
parent 001dcaca
Pipeline #707 failed with stage
in 10 seconds
......@@ -8,34 +8,18 @@ A GUI application for my raspberry PI to show my name and other cool stuff.
Be sure to install wiringpi: `sudo apt install wiringpi`
### Graphics
To install the embedded (egl) version of javafx, you need [the overlay](https://chriswhocodes.com/) for java 8.
Specifically the "OpenJFX 8 nightly for armv6hf with libbrcm fix" version
After updating or anythinging the JDK on that guy, go to the `/usr/lib/jvm/<your java>/` and extract the zip
to get the right things into your system.
https://docs.gluonhq.com/index.html#_javafx_on_embedded
### Systemd init script
Taking advantage of the Gluon DRM enabled thing that's free for non-commercial use.
Need to install some packages too:
I use the `/etc/default/deskscreen` to contain the environment variables to configure my application.
```
[Unit]
Description=Desk Screen Application
[Service]
EnvironmentFile=/etc/default/deskscreen
# Has to run as root to enable framebuffer and touch input stuff
User=root
WorkingDirectory=/opt/deskscreen/data
ExecStart=/opt/deskscreen/jfx
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
apt install libgl1-mesa-dri gldriver-test libgles2-mesa libgles2 libegl1
```
### jfx app script
```
......
......@@ -21,8 +21,9 @@ apply plugin: 'org.junit.platform.gradle.plugin'
mainClassName = "is.kow.deskscreen.DeskScreenKt"
javafx {
version = "11.0.2"
version = "15.0.1"
modules = [ 'javafx.controls', 'javafx.swing' ]
configuration = "compileOnly"
}
wrapper {
......@@ -116,17 +117,23 @@ dependencies {
//Using the snapshot version of pi4j, because it's the best
//Maybe I can get away without using the snapshot....
implementation 'com.pi4j:pi4j-core:1.4-SNAPSHOT'
implementation("io.dvlopt:linux-i2c:1.0.0")
//implementation 'com.pi4j:pi4j-core:1.4-SNAPSHOT'
//Pi4j 2 is hella immature, might have to figure out how to write some kind of rust wrapper to export local json or something
//implementation('com.pi4j:pi4j-plugin-raspberrypi:2.0-SNAPSHOT')
//Javafx dependencies
// implementation "org.openjfx:javafx-base:${javaFxVersion}:${platformClassifier}"
// implementation "org.openjfx:javafx-swing:${javaFxVersion}:${platformClassifier}"
// implementation "org.openjfx:javafx-controls:${javaFxVersion}:${platformClassifier}"
//Trying ikonili, because FontawesomeFX is being a pain
//TODO: update this to use a version variable
implementation 'org.kordamp.ikonli:ikonli-javafx:12.0.0'
implementation 'org.kordamp.ikonli:ikonli-fontawesome5-pack:12.0.0'
implementation 'org.kordamp.ikonli:ikonli-weathericons-pack:12.0.0'
implementation 'org.kordamp.ikonli:ikonli-javafx:12.2.0'
implementation 'org.kordamp.ikonli:ikonli-fontawesome5-pack:12.2.0'
implementation 'org.kordamp.ikonli:ikonli-weathericons-pack:12.2.0'
// implementation 'com.hierynomus:sshj:0.26.0',
// 'com.jcraft:jzlib:1.1.3'
......
......@@ -2,22 +2,17 @@
Description=Desk Screen Application
[Service]
Environment="DISPLAY=:0"
Environment=ENABLE_GLUON_COMMERCIAL_EXTENSIONS=true
User=root
WorkingDirectory=/opt/deskscreen/data
#ExecStart=/usr/bin/java \
# -Dembedded=monocle \
# -Dglass.platform=Monocle \
# -Dprism.verbose=true \
# --add-opens java.base/jdk.internal.misc=ALL-UNNAMED\
# -jar /opt/deskscreen/deskScreen-all.jar
ExecStart=/usr/bin/java \
--module-path=/opt/javafx-11-armv6hf \
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED \
-cp /opt/deskscreen/deskScreen-all.jar \
-Dembedded=monocle \
-Dglass.platform=Monocle \
-Dmonocle.platform=EGL \
-Djava.library.path=/opt/arm32fb-sdk/lib \
-Dmonocle.egl.lib=/opt/arm32fb-sdk/lib/libgluon_drm.so \
-Dprism.verbose=true \
--module-path=/opt/arm32fb-sdk \
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED \
--class-path /opt/arm32fb-sdk/lib/*:/opt/deskscreen/deskScreen-all.jar \
is.kow.deskscreen.DeskScreenKt
SuccessExitStatus=143
TimeoutStopSec=10
......
deviceIp = 10.10.220.80
deviceIp = 10.10.220.95
jiraBaseUrl = https://www.example.com
username = nope
password = nope
......@@ -7,3 +7,4 @@ redditUsername = nope
redditPassword = lol
redditClientId = huehuehueh
redditSecret = hahahaha
package is.kow.bme280;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/*
* Pressure, Altitude, Temperature, Humidity
* Adapted from https://github.com/adafruit/Adafruit_Python_BME280
*
* I acquired it from: https://github.com/OlivierLD/raspberry-pi4j-samples/blob/master/I2C.SPI/src/i2c/sensor/BME280.java
* I have a lot of reading to do to fully understand this....
*
* There's also this, which is interesting, It's for a BMP280, but it's operating modes might be interesting.
* https://github.com/whitestripes/BMP280/blob/master/BMP280/src/net/pateras/iot/BMP280/BMP280.java
*/
public class BME280 {
private final Logger logger = LoggerFactory.getLogger(BME280.class);
private final static EndianReaders.Endianness BME280_ENDIANNESS = EndianReaders.Endianness.LITTLE_ENDIAN;
/*
Prompt> sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77
*/
// This next addresses is returned by "sudo i2cdetect -y 1", see above.
public final static int BME280_I2CADDR = 0x76;
// Operating Modes
public final static int BME280_OSAMPLE_1 = 1;
public final static int BME280_OSAMPLE_2 = 2;
public final static int BME280_OSAMPLE_4 = 3;
public final static int BME280_OSAMPLE_8 = 4;
public final static int BME280_OSAMPLE_16 = 5;
// BME280 Registers
public final static int BME280_REGISTER_DIG_T1 = 0x88; // Trimming parameter registers
public final static int BME280_REGISTER_DIG_T2 = 0x8A;
public final static int BME280_REGISTER_DIG_T3 = 0x8C;
public final static int BME280_REGISTER_DIG_P1 = 0x8E;
public final static int BME280_REGISTER_DIG_P2 = 0x90;
public final static int BME280_REGISTER_DIG_P3 = 0x92;
public final static int BME280_REGISTER_DIG_P4 = 0x94;
public final static int BME280_REGISTER_DIG_P5 = 0x96;
public final static int BME280_REGISTER_DIG_P6 = 0x98;
public final static int BME280_REGISTER_DIG_P7 = 0x9A;
public final static int BME280_REGISTER_DIG_P8 = 0x9C;
public final static int BME280_REGISTER_DIG_P9 = 0x9E;
public final static int BME280_REGISTER_DIG_H1 = 0xA1;
public final static int BME280_REGISTER_DIG_H2 = 0xE1;
public final static int BME280_REGISTER_DIG_H3 = 0xE3;
public final static int BME280_REGISTER_DIG_H4 = 0xE4;
public final static int BME280_REGISTER_DIG_H5 = 0xE5;
public final static int BME280_REGISTER_DIG_H6 = 0xE6;
public final static int BME280_REGISTER_DIG_H7 = 0xE7;
public final static int BME280_REGISTER_CHIPID = 0xD0;
public final static int BME280_REGISTER_VERSION = 0xD1;
public final static int BME280_REGISTER_SOFTRESET = 0xE0;
public final static int BME280_REGISTER_CONTROL_HUM = 0xF2;
public final static int BME280_REGISTER_CONTROL = 0xF4;
public final static int BME280_REGISTER_CONFIG = 0xF5;
public final static int BME280_REGISTER_PRESSURE_DATA = 0xF7;
public final static int BME280_REGISTER_TEMP_DATA = 0xFA;
public final static int BME280_REGISTER_HUMIDITY_DATA = 0xFD;
private int dig_T1 = 0;
private int dig_T2 = 0;
private int dig_T3 = 0;
private int dig_P1 = 0;
private int dig_P2 = 0;
private int dig_P3 = 0;
private int dig_P4 = 0;
private int dig_P5 = 0;
private int dig_P6 = 0;
private int dig_P7 = 0;
private int dig_P8 = 0;
private int dig_P9 = 0;
private int dig_H1 = 0;
private int dig_H2 = 0;
private int dig_H3 = 0;
private int dig_H4 = 0;
private int dig_H5 = 0;
private int dig_H6 = 0;
private float tFine = 0F;
private I2CBus bus;
private I2CDevice bme280;
private int mode = BME280_OSAMPLE_8;
public BME280() throws I2CFactory.UnsupportedBusNumberException {
this(BME280_I2CADDR);
}
public BME280(int address) throws I2CFactory.UnsupportedBusNumberException {
try {
// Get i2c bus
bus = I2CFactory.getInstance(I2CBus.BUS_1); // Depends onthe RasPI version
logger.trace("Connected to bus. OK.");
// Get device itself
bme280 = bus.getDevice(address);
logger.trace("Connected to device. OK.");
try {
this.readCalibrationData();
} catch (Exception ex) {
ex.printStackTrace();
}
bme280.write(BME280_REGISTER_CONTROL, (byte) 0x3F);
tFine = 0.0f;
} catch (IOException e) {
logger.error("Unable to initialize BME280", e);
throw new RuntimeException(e);
}
}
private int readU8(int register) throws Exception {
return EndianReaders.readU8(this.bme280, BME280_I2CADDR, register, false);
}
private int readS8(int register) throws Exception {
return EndianReaders.readS8(this.bme280, BME280_I2CADDR, register, false);
}
private int readU16LE(int register) throws Exception {
return EndianReaders.readU16LE(this.bme280, BME280_I2CADDR, register, false);
}
private int readS16LE(int register) throws Exception {
return EndianReaders.readS16LE(this.bme280, BME280_I2CADDR, register, false);
}
public void readCalibrationData() throws Exception {
// Reads the calibration data from the IC
dig_T1 = readU16LE(BME280_REGISTER_DIG_T1);
dig_T2 = readS16LE(BME280_REGISTER_DIG_T2);
dig_T3 = readS16LE(BME280_REGISTER_DIG_T3);
dig_P1 = readU16LE(BME280_REGISTER_DIG_P1);
dig_P2 = readS16LE(BME280_REGISTER_DIG_P2);
dig_P3 = readS16LE(BME280_REGISTER_DIG_P3);
dig_P4 = readS16LE(BME280_REGISTER_DIG_P4);
dig_P5 = readS16LE(BME280_REGISTER_DIG_P5);
dig_P6 = readS16LE(BME280_REGISTER_DIG_P6);
dig_P7 = readS16LE(BME280_REGISTER_DIG_P7);
dig_P8 = readS16LE(BME280_REGISTER_DIG_P8);
dig_P9 = readS16LE(BME280_REGISTER_DIG_P9);
dig_H1 = readU8(BME280_REGISTER_DIG_H1);
dig_H2 = readS16LE(BME280_REGISTER_DIG_H2);
dig_H3 = readU8(BME280_REGISTER_DIG_H3);
dig_H6 = readS8(BME280_REGISTER_DIG_H7);
int h4 = readS8(BME280_REGISTER_DIG_H4);
h4 = (h4 << 24) >> 20;
dig_H4 = h4 | (readU8(BME280_REGISTER_DIG_H5) & 0x0F);
int h5 = readS8(BME280_REGISTER_DIG_H6);
h5 = (h5 << 24) >> 20;
dig_H5 = h5 | (readU8(BME280_REGISTER_DIG_H5) >> 4 & 0x0F);
if (logger.isTraceEnabled()) {
showCalibrationData();
}
}
private String displayRegister(int reg) {
return String.format("0x%s (%d)", Integer.toHexString(reg & 0xFFFF).toUpperCase(), 4);
}
private void showCalibrationData() {
// Displays the calibration values for debugging purposes
logger.trace("======================");
logger.trace("DBG: T1 = " + displayRegister(dig_T1));
logger.trace("DBG: T2 = " + displayRegister(dig_T2));
logger.trace("DBG: T3 = " + displayRegister(dig_T3));
logger.trace("----------------------");
logger.trace("DBG: P1 = " + displayRegister(dig_P1));
logger.trace("DBG: P2 = " + displayRegister(dig_P2));
logger.trace("DBG: P3 = " + displayRegister(dig_P3));
logger.trace("DBG: P4 = " + displayRegister(dig_P4));
logger.trace("DBG: P5 = " + displayRegister(dig_P5));
logger.trace("DBG: P6 = " + displayRegister(dig_P6));
logger.trace("DBG: P7 = " + displayRegister(dig_P7));
logger.trace("DBG: P8 = " + displayRegister(dig_P8));
logger.trace("DBG: P9 = " + displayRegister(dig_P9));
logger.trace("----------------------");
logger.trace("DBG: H1 = " + displayRegister(dig_H1));
logger.trace("DBG: H2 = " + displayRegister(dig_H2));
logger.trace("DBG: H3 = " + displayRegister(dig_H3));
logger.trace("DBG: H4 = " + displayRegister(dig_H4));
logger.trace("DBG: H5 = " + displayRegister(dig_H5));
logger.trace("DBG: H6 = " + displayRegister(dig_H6));
logger.trace("======================");
}
private int readRawTemp() throws Exception {
// Reads the raw (uncompensated) temperature from the sensor
int meas = mode;
logger.trace(String.format("readRawTemp: 1 - meas=%d", meas));
bme280.write(BME280_REGISTER_CONTROL_HUM, (byte) meas); // HUM ?
meas = mode << 5 | mode << 2 | 1;
logger.trace(String.format("readRawTemp: 2 - meas=%d", meas));
bme280.write(BME280_REGISTER_CONTROL, (byte) meas);
double sleepTime = 0.00125 + 0.0023 * (1 << mode);
sleepTime = sleepTime + 0.0023 * (1 << mode) + 0.000575;
sleepTime = sleepTime + 0.0023 * (1 << mode) + 0.000575;
Thread.sleep((long) (sleepTime * 1_000L));
int msb = readU8(BME280_REGISTER_TEMP_DATA);
int lsb = readU8(BME280_REGISTER_TEMP_DATA + 1);
int xlsb = readU8(BME280_REGISTER_TEMP_DATA + 2);
int raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4;
logger.trace("DBG: Raw Temp: " + (raw & 0xFFFF) + ", " + raw + String.format(", msb: 0x%04X lsb: 0x%04X xlsb: 0x%04X", msb, lsb, xlsb));
return raw;
}
private int readRawPressure() throws Exception {
// Reads the raw (uncompensated) pressure level from the sensor
int msb = readU8(BME280_REGISTER_PRESSURE_DATA);
int lsb = readU8(BME280_REGISTER_PRESSURE_DATA + 1);
int xlsb = readU8(BME280_REGISTER_PRESSURE_DATA + 2);
int raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4;
logger.trace("DBG: Raw Press: " + (raw & 0xFFFF) + ", " + raw + String.format(", msb: 0x%04X lsb: 0x%04X xlsb: 0x%04X", msb, lsb, xlsb));
return raw;
}
private int readRawHumidity() throws Exception {
int msb = readU8(BME280_REGISTER_HUMIDITY_DATA);
int lsb = readU8(BME280_REGISTER_HUMIDITY_DATA + 1);
int raw = (msb << 8) | lsb;
return raw;
}
public float readTemperature() throws Exception {
// Gets the compensated temperature in degrees celcius
float UT = readRawTemp();
float var1 = 0;
float var2 = 0;
float temp = 0.0f;
// Read raw temp before aligning it with the calibration values
var1 = (UT / 16_384.0f - dig_T1 / 1_024.0f) * (float) dig_T2;
var2 = ((UT / 131_072.0f - dig_T1 / 8_192.0f) * (UT / 131_072.0f - dig_T1 / 8_192.0f)) * (float) dig_T3;
tFine = (int) (var1 + var2);
temp = (var1 + var2) / 5_120.0f;
logger.trace("DBG: Calibrated temperature = " + temp + " C");
return temp;
}
public float readPressure() throws Exception {
// Gets the compensated pressure in pascal
int adc = readRawPressure();
logger.trace("ADC:" + adc + ", tFine:" + tFine);
float var1 = (tFine / 2.0f) - 64_000.0f;
float var2 = var1 * var1 * (dig_P6 / 32_768.0f);
var2 = var2 + var1 * dig_P5 * 2.0f;
var2 = (var2 / 4.0f) + (dig_P4 * 65_536.0f);
var1 = (dig_P3 * var1 * var1 / 524_288.0f + dig_P2 * var1) / 524_288.0f;
var1 = (1.0f + var1 / 32_768.0f) * dig_P1;
if (var1 == 0f) {
return 0f;
}
float p = 1_048_576.0f - adc;
p = ((p - var2 / 4_096.0f) * 6_250.0f) / var1;
var1 = dig_P9 * p * p / 2_147_483_648.0f;
var2 = p * dig_P8 / 32_768.0f;
p = p + (var1 + var2 + dig_P7) / 16.0f;
logger.trace("DBG: Pressure = " + p + " Pa");
return p;
}
public float readHumidity() throws Exception {
int adc = readRawHumidity();
float h = tFine - 76_800.0f;
h = (adc - (dig_H4 * 64.0f + dig_H5 / 16_384.8f * h)) *
(dig_H2 / 65_536.0f * (1.0f + dig_H6 / 67_108_864.0f * h * (1.0f + dig_H3 / 67_108_864.0f * h)));
h = h * (1.0f - dig_H1 * h / 524_288.0f);
if (h > 100) {
h = 100;
} else if (h < 0) {
h = 0;
}
logger.trace("DBG: Humidity = " + h);
return h;
}
private int standardSeaLevelPressure = 101_325;
public void setStandardSeaLevelPressure(int standardSeaLevelPressure) {
this.standardSeaLevelPressure = standardSeaLevelPressure;
}
public double readAltitude() throws Exception {
// "Calculates the altitude in meters"
double altitude = 0.0;
float pressure = readPressure();
altitude = 44_330.0 * (1.0 - Math.pow(pressure / standardSeaLevelPressure, 0.1903));
logger.trace("DBG: Altitude = " + altitude);
return altitude;
}
public static void main(String... args) throws Exception {
final NumberFormat NF = new DecimalFormat("##00.00");
BME280 sensor = new BME280();
float press = 0;
float temp = 0;
float hum = 0;
double alt = 0;
while (true) {
try {
temp = sensor.readTemperature();
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace();
}
try {
press = sensor.readPressure();
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace();
}
/*
sensor.setStandardSeaLevelPressure((int)press); // As we ARE at the sea level (in San Francisco).
try { alt = sensor.readAltitude(); }
catch (Exception ex)
{
System.err.println(ex.getMessage());
ex.printStackTrace();
}
*/
try {
hum = sensor.readHumidity();
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace();
}
System.out.println("Temperature: " + NF.format(temp) + " C");
System.out.println("Pressure : " + NF.format(press / 100) + " hPa");
// logger.trace("Altitude : " + NF.format(alt) + " m");
System.out.println("Humidity : " + NF.format(hum) + " %");
Thread.sleep(2000);
}
}
}
\ No newline at end of file
package is.kow.bme280;
import com.pi4j.io.i2c.I2CDevice;
import java.io.IOException;
public class EndianReaders {
public enum Endianness {
LITTLE_ENDIAN,
BIG_ENDIAN
}
/**
* Read an unsigned byte from the I2C device
*/
public static int readU8(I2CDevice device, int i2caddr, int reg, boolean verbose) throws IOException {
int result = 0;
result = device.read(reg);
if (verbose) {
System.out.println("I2C: Device " + i2caddr + " (0x" + Integer.toHexString(i2caddr) +
") returned " + result + " (0x" + Integer.toHexString(result) +
") from reg " + reg + " (0x" + Integer.toHexString(reg) + ")");
}
return result; // & 0xFF;
}
/**
* Read a signed byte from the I2C device
*/
public static int readS8(I2CDevice device, int i2caddr, int reg, boolean verbose) throws IOException {
int result = 0;
result = device.read(reg); // & 0x7F;
if (result > 127)
result -= 256;
if (verbose) {
System.out.println("I2C: Device " + i2caddr + " returned " + result + " from reg " + reg);
}
return result; // & 0xFF;
}
public static int readU16LE(I2CDevice device, int i2caddr, int register, boolean verbose) throws IOException {
return EndianReaders.readU16(device, i2caddr, register, Endianness.LITTLE_ENDIAN, verbose);
}
public static int readU16BE(I2CDevice device, int i2caddr, int register, boolean verbose) throws IOException {
return EndianReaders.readU16(device, i2caddr, register, Endianness.BIG_ENDIAN, verbose);
}
public static int readU16(I2CDevice device, int i2caddr, int register, Endianness endianness, boolean verbose) throws IOException {
int hi = EndianReaders.readU8(device, i2caddr, register, verbose);
int lo = EndianReaders.readU8(device, i2caddr, register + 1, verbose);
return ((endianness == Endianness.BIG_ENDIAN) ? (hi << 8) + lo : (lo << 8) + hi); // & 0xFFFF;
}
public static int readS16(I2CDevice device, int i2caddr, int register, Endianness endianness, boolean verbose) throws IOException {
int hi = 0, lo = 0;
if (endianness == Endianness.BIG_ENDIAN) {
hi = EndianReaders.readS8(device, i2caddr, register, verbose);
lo = EndianReaders.readU8(device, i2caddr, register + 1, verbose);
} else {
lo = EndianReaders.readU8(device, i2caddr, register, verbose);
hi = EndianReaders.readS8(device, i2caddr, register + 1, verbose);
}
return ((hi << 8) + lo); // & 0xFFFF;
}
public static int readS16LE(I2CDevice device, int i2caddr, int register, boolean verbose) throws IOException {
return EndianReaders.readS16(device, i2caddr, register, Endianness.LITTLE_ENDIAN, verbose);
}
public static int readS16BE(I2CDevice device, int i2caddr, int register, boolean verbose) throws IOException {
return EndianReaders.readS16(device, i2caddr, register, Endianness.BIG_ENDIAN, verbose);
}
}
\ No newline at end of file
......@@ -35,6 +35,7 @@ class DisplayController : Controller() {
}
.observeOn(Schedulers.io())
.filter {
//I do still need to know
mainController.isPi
}
.doOnNext {
......@@ -138,4 +139,4 @@ class DisplayController : Controller() {
return brightness.toInt()
}