Compare commits

..

No commits in common. "main" and "1.1.1" have entirely different histories.
main ... 1.1.1

14 changed files with 43 additions and 193 deletions

Binary file not shown.

View File

@ -1,10 +0,0 @@
LCSC Part Number,Quantity
C2977589,1
C43846,1
C43840,1
C385441,2
C385449,1
C385460,1
C385498,1
C433508,1
C397337,16
1 LCSC Part Number Quantity
2 C2977589 1
3 C43846 1
4 C43840 1
5 C385441 2
6 C385449 1
7 C385460 1
8 C385498 1
9 C433508 1
10 C397337 16

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>lantern-currentmonitor</artifactId> <artifactId>lantern-currentmonitor</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.1.3</version> <version>1.1.1</version>
<name>lantern-currentmonitor</name> <name>lantern-currentmonitor</name>
<parent> <parent>

View File

@ -7,38 +7,27 @@ import com.lanternsoftware.currentmonitor.bluetooth.BleHelper;
import com.lanternsoftware.currentmonitor.bluetooth.BleService; import com.lanternsoftware.currentmonitor.bluetooth.BleService;
import com.lanternsoftware.datamodel.currentmonitor.HubConfigService; import com.lanternsoftware.datamodel.currentmonitor.HubConfigService;
import com.lanternsoftware.util.CollectionUtils; import com.lanternsoftware.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
public class BluetoothConfig { public class BluetoothConfig {
private static final Logger LOG = LoggerFactory.getLogger(BluetoothConfig.class);
private final BleApplication app; private final BleApplication app;
public BluetoothConfig(String _hubName, BleCharacteristicListener _listener) { public BluetoothConfig(String _hubName, BleCharacteristicListener _listener) {
BleApplication a = null; BleHelper.getAdapter().setPowered(true);
try { BleHelper.requestBusName("com.lanternsoftware");
BleHelper.getAdapter().setPowered(true); BleHelper.setBasePath("/com/lanternsoftware");
BleHelper.requestBusName("com.lanternsoftware"); HubConfigService service = new HubConfigService();
BleHelper.setBasePath("/com/lanternsoftware"); List<BleCharacteristic> chars = CollectionUtils.transform(service.getCharacteristics(), _c->new BleCharacteristic("HubConfig", _c.getUUID(), _c.name(), _c.getFlags()));
List<BleCharacteristic> chars = CollectionUtils.transform(HubConfigService.getCharacteristics(), _c -> new BleCharacteristic("HubConfig", _c.getUUID(), _c.name(), _c.getFlags())); chars.forEach(_c->_c.setListener(_listener));
chars.forEach(_c -> _c.setListener(_listener)); app = new BleApplication("Lantern", _hubName, new BleService("HubConfig", service.getServiceUUID(), chars));
a = new BleApplication("Lantern", _hubName, new BleService("HubConfig", HubConfigService.getServiceUUID(), chars));
}
catch (Throwable _t) {
LOG.error("Failed to initialize BLE service", _t);
}
app = a;
} }
public void start() { public void start() {
if (app != null) app.start();
app.start();
} }
public void stop() { public void stop() {
if (app != null) app.stop();
app.stop();
} }
} }

View File

@ -219,7 +219,7 @@ public class MonitorApp {
config = new MonitorConfig(); config = new MonitorConfig();
ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config)); ResourceLoader.writeFile(WORKING_DIR + "config.json", DaoSerializer.toJson(config));
} }
pool = HttpPool.builder().withValidateSSLCertificates(!config.isAcceptSelfSignedCertificates()).build(); pool = new HttpPool(10, 10, config.getSocketTimeout(), config.getConnectTimeout(), config.getSocketTimeout());
if (NullUtils.isNotEmpty(config.getHost())) if (NullUtils.isNotEmpty(config.getHost()))
host = NullUtils.terminateWith(config.getHost(), "/"); host = NullUtils.terminateWith(config.getHost(), "/");
monitor.setDebug(config.isDebug()); monitor.setDebug(config.isDebug());
@ -301,12 +301,10 @@ public class MonitorApp {
monitor.stop(); monitor.stop();
pool.shutdown(); pool.shutdown();
}, "Monitor Shutdown")); }, "Monitor Shutdown"));
synchronized (monitor) { try {
try { monitor.wait();
monitor.wait(); } catch (InterruptedException _e) {
} catch (InterruptedException _e) { LOG.error("Interrupted, shutting down", _e);
LOG.error("Interrupted, shutting down", _e);
}
} }
} }

View File

@ -19,7 +19,6 @@ public class MonitorConfig {
private int socketTimeout; private int socketTimeout;
private boolean postSamples = false; private boolean postSamples = false;
private boolean needsCalibration = true; private boolean needsCalibration = true;
private boolean acceptSelfSignedCertificates = false;
private String mqttBrokerUrl; private String mqttBrokerUrl;
private String mqttUserName; private String mqttUserName;
private String mqttPassword; private String mqttPassword;
@ -116,14 +115,6 @@ public class MonitorConfig {
needsCalibration = _needsCalibration; needsCalibration = _needsCalibration;
} }
public boolean isAcceptSelfSignedCertificates() {
return acceptSelfSignedCertificates;
}
public void setAcceptSelfSignedCertificates(boolean _acceptSelfSignedCertificates) {
acceptSelfSignedCertificates = _acceptSelfSignedCertificates;
}
public String getMqttBrokerUrl() { public String getMqttBrokerUrl() {
return mqttBrokerUrl; return mqttBrokerUrl;
} }

View File

@ -36,7 +36,6 @@ public class MonitorConfigSerializer extends AbstractDaoSerializer<MonitorConfig
d.put("socket_timeout", _o.getSocketTimeout()); d.put("socket_timeout", _o.getSocketTimeout());
d.put("post_samples", _o.isPostSamples()); d.put("post_samples", _o.isPostSamples());
d.put("needs_calibration", _o.isNeedsCalibration()); d.put("needs_calibration", _o.isNeedsCalibration());
d.put("accept_self_signed_certificates", _o.isAcceptSelfSignedCertificates());
d.put("mqtt_broker_url", _o.getMqttBrokerUrl()); d.put("mqtt_broker_url", _o.getMqttBrokerUrl());
d.put("mqtt_user_name", _o.getMqttUserName()); d.put("mqtt_user_name", _o.getMqttUserName());
d.put("mqtt_password", _o.getMqttPassword()); d.put("mqtt_password", _o.getMqttPassword());
@ -61,7 +60,6 @@ public class MonitorConfigSerializer extends AbstractDaoSerializer<MonitorConfig
o.setSocketTimeout(DaoSerializer.getInteger(_d, "socket_timeout")); o.setSocketTimeout(DaoSerializer.getInteger(_d, "socket_timeout"));
o.setPostSamples(DaoSerializer.getBoolean(_d, "post_samples")); o.setPostSamples(DaoSerializer.getBoolean(_d, "post_samples"));
o.setNeedsCalibration(DaoSerializer.getBoolean(_d, "needs_calibration")); o.setNeedsCalibration(DaoSerializer.getBoolean(_d, "needs_calibration"));
o.setAcceptSelfSignedCertificates(DaoSerializer.getBoolean(_d, "accept_self_signed_certificates"));
o.setMqttBrokerUrl(DaoSerializer.getString(_d, "mqtt_broker_url")); o.setMqttBrokerUrl(DaoSerializer.getString(_d, "mqtt_broker_url"));
o.setMqttUserName(DaoSerializer.getString(_d, "mqtt_user_name")); o.setMqttUserName(DaoSerializer.getString(_d, "mqtt_user_name"));
o.setMqttPassword(DaoSerializer.getString(_d, "mqtt_password")); o.setMqttPassword(DaoSerializer.getString(_d, "mqtt_password"));

View File

@ -662,7 +662,7 @@ public class MongoCurrentMonitorDao implements CurrentMonitorDao {
if (NullUtils.isEmpty(_username) || NullUtils.isEmpty(_password)) if (NullUtils.isEmpty(_username) || NullUtils.isEmpty(_password))
return null; return null;
Account acct = proxy.queryOne(Account.class, new DaoQuery("username", _username.toLowerCase().trim())); Account acct = proxy.queryOne(Account.class, new DaoQuery("username", _username.toLowerCase().trim()));
if ((acct == null) || !BCrypt.checkpw(_password, NullUtils.makeNotNull(acct.getPassword()))) if ((acct == null) || !BCrypt.checkpw(_password, acct.getPassword()))
return null; return null;
return toAuthCode(acct.getId(), acct.getAuxiliaryAccountIds()); return toAuthCode(acct.getId(), acct.getAuxiliaryAccountIds());
} }

View File

@ -8,7 +8,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
public abstract class HubConfigService { public class HubConfigService {
public static final UUIDFormatter uuidFormat = new UUIDFormatter("c5650001-d50f-49af-b906-cada0dc17937"); public static final UUIDFormatter uuidFormat = new UUIDFormatter("c5650001-d50f-49af-b906-cada0dc17937");
private static final AESTool aes = new AESTool(37320708309265127L,-8068168662055796771L,-4867793276337148572L,4425609941731230765L); private static final AESTool aes = new AESTool(37320708309265127L,-8068168662055796771L,-4867793276337148572L,4425609941731230765L);
private static final UUID serviceUUID = uuidFormat.format(1); private static final UUID serviceUUID = uuidFormat.format(1);
@ -20,7 +20,7 @@ public abstract class HubConfigService {
return serviceUUID; return serviceUUID;
} }
public static List<HubConfigCharacteristic> getCharacteristics() { public List<HubConfigCharacteristic> getCharacteristics() {
return Arrays.asList(HubConfigCharacteristic.values()); return Arrays.asList(HubConfigCharacteristic.values());
} }

View File

@ -28,7 +28,7 @@ public class AppleSSO {
private final String audience; private final String audience;
public AppleSSO(String _credentialsPath) { public AppleSSO(String _credentialsPath) {
audience = NullUtils.trim(ResourceLoader.loadFileAsString(_credentialsPath)); audience = ResourceLoader.loadFileAsString(_credentialsPath).trim();
} }
public String getEmailFromIdToken(String _idToken) { public String getEmailFromIdToken(String _idToken) {

View File

@ -1,36 +1,27 @@
package com.lanternsoftware.util.http; package com.lanternsoftware.util.http;
import com.lanternsoftware.util.NullUtils; import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.CookieStore; import org.apache.http.client.CookieStore;
import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import com.lanternsoftware.util.NullUtils;
import java.io.InputStream;
import java.security.KeyStore;
public class HttpPool { public class HttpPool {
private static final Logger LOG = LoggerFactory.getLogger(HttpPool.class); private static final Logger LOG = LoggerFactory.getLogger(HttpPool.class);
@ -41,43 +32,17 @@ public class HttpPool {
private final PoolingHttpClientConnectionManager connectionManager; private final PoolingHttpClientConnectionManager connectionManager;
public HttpPool(int _maxTotalConnections, int _maxPerRoute) { public HttpPool(int _maxTotalConnections, int _maxPerRoute) {
this(_maxTotalConnections, _maxPerRoute, null, null); this(_maxTotalConnections, _maxPerRoute, 10000, 5000, 10000);
}
public HttpPool(int _maxTotalConnections, int _maxPerRoute, KeyStore _keystore, String _keystorePassword) {
this(_maxTotalConnections, _maxPerRoute, 10000, 5000, 10000, _keystore, _keystorePassword, true);
} }
public HttpPool(int _maxTotalConnections, int _maxPerRoute, int _socketTimeoutMs, int _connectTimeoutMs, int _connectionRequestTimeoutMs) { public HttpPool(int _maxTotalConnections, int _maxPerRoute, int _socketTimeoutMs, int _connectTimeoutMs, int _connectionRequestTimeoutMs) {
this(_maxTotalConnections, _maxPerRoute, _socketTimeoutMs, _connectTimeoutMs, _connectionRequestTimeoutMs, null, null, true);
}
public HttpPool(int _maxTotalConnections, int _maxPerRoute, int _socketTimeoutMs, int _connectTimeoutMs, int _connectionRequestTimeoutMs, KeyStore _keystore, String _keystorePassword, boolean _validateSSLCertificates) {
requestConfig = RequestConfig.custom().setSocketTimeout(_socketTimeoutMs).setConnectTimeout(_connectTimeoutMs).setConnectionRequestTimeout(_connectionRequestTimeoutMs).setCookieSpec(CookieSpecs.STANDARD).build(); requestConfig = RequestConfig.custom().setSocketTimeout(_socketTimeoutMs).setConnectTimeout(_connectTimeoutMs).setConnectionRequestTimeout(_connectionRequestTimeoutMs).setCookieSpec(CookieSpecs.STANDARD).build();
keepAliveStrategy = (HttpResponse response, HttpContext context) -> 0; keepAliveStrategy = (HttpResponse response, HttpContext context) -> 0;
Registry<ConnectionSocketFactory> registry = null; connectionManager = new PoolingHttpClientConnectionManager();
if ((_keystore != null) || !_validateSSLCertificates) {
try {
SSLContextBuilder contextBuilder = SSLContexts.custom();
if (_keystore != null)
contextBuilder.loadKeyMaterial(_keystore, _keystorePassword.toCharArray());
if (!_validateSSLCertificates)
contextBuilder.loadTrustMaterial(null, (x509CertChain, authType) -> true);
SSLConnectionSocketFactory socketFactory = _validateSSLCertificates ? new SSLConnectionSocketFactory(contextBuilder.build()) : new SSLConnectionSocketFactory(contextBuilder.build(), NoopHostnameVerifier.INSTANCE);
registry = RegistryBuilder.<ConnectionSocketFactory>create().register("https", socketFactory).register("http", new PlainConnectionSocketFactory()).build();
} catch (Exception _e) {
LOG.error("Failed to load SSL keystore", _e);
}
}
connectionManager = registry != null ? new PoolingHttpClientConnectionManager(registry) : new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(_maxTotalConnections); connectionManager.setMaxTotal(_maxTotalConnections);
connectionManager.setDefaultMaxPerRoute(_maxPerRoute); connectionManager.setDefaultMaxPerRoute(_maxPerRoute);
} }
public static Builder builder() {
return new Builder();
}
public void shutdown() { public void shutdown() {
connectionManager.shutdown(); connectionManager.shutdown();
} }
@ -111,28 +76,26 @@ public class HttpPool {
} }
public byte[] executeToByteArray(HttpUriRequest _request) { public byte[] executeToByteArray(HttpUriRequest _request) {
return executeToPayload(_request).getPayload();
}
public HttpResponsePayload executeToPayload(HttpUriRequest _request) {
InputStream is = null; InputStream is = null;
CloseableHttpResponse resp = null; CloseableHttpResponse resp = null;
try { try {
resp = execute(_request); resp = execute(_request);
if (resp == null) if (resp == null)
return new HttpResponsePayload(HttpStatus.SC_INTERNAL_SERVER_ERROR, null); return null;
if ((resp.getStatusLine().getStatusCode() < 200) || (resp.getStatusLine().getStatusCode() >= 300)) if ((resp.getStatusLine().getStatusCode() < 200) || (resp.getStatusLine().getStatusCode() >= 300)) {
LOG.error("Failed to make http request to " + _request.getURI().toString() + ". Status code: " + resp.getStatusLine().getStatusCode()); LOG.error("Failed to make http request to " + _request.getURI().toString() + ". Status code: " + resp.getStatusLine().getStatusCode());
return null;
}
HttpEntity entity = resp.getEntity(); HttpEntity entity = resp.getEntity();
if (entity != null) { if (entity != null) {
is = entity.getContent(); is = entity.getContent();
return new HttpResponsePayload(resp.getStatusLine().getStatusCode(), IOUtils.toByteArray(is)); return IOUtils.toByteArray(is);
} }
return new HttpResponsePayload(resp.getStatusLine().getStatusCode(), null); return null;
} }
catch (Exception _e) { catch (Exception _e) {
LOG.error("Failed to make http request to " + _request.getURI().toString(), _e); LOG.error("Failed to make http request to " + _request.getURI().toString(), _e);
return new HttpResponsePayload(HttpStatus.SC_INTERNAL_SERVER_ERROR, null); return null;
} }
finally { finally {
IOUtils.closeQuietly(is); IOUtils.closeQuietly(is);
@ -143,57 +106,4 @@ public class HttpPool {
public static void addBasicAuthHeader(HttpUriRequest _request, String _username, String _password) { public static void addBasicAuthHeader(HttpUriRequest _request, String _username, String _password) {
_request.addHeader("Authorization", "Basic " + Base64.encodeBase64String(NullUtils.toByteArray(_username + ":" + _password))); _request.addHeader("Authorization", "Basic " + Base64.encodeBase64String(NullUtils.toByteArray(_username + ":" + _password)));
} }
public static final class Builder {
private int maxTotalConnections = 10;
private int maxPerRoute = 10;
private int socketTimeoutMs = 10000;
private int connectTimeoutMs = 5000;
private int connectionRequestTimeoutMs = 10000;
private KeyStore keystore;
private String keystorePassword;
private boolean validateSSLCertificates = true;
private Builder() {
}
public Builder withMaxTotalConnections(int val) {
maxTotalConnections = val;
return this;
}
public Builder withMaxPerRoute(int val) {
maxPerRoute = val;
return this;
}
public Builder withSocketTimeoutMs(int val) {
socketTimeoutMs = val;
return this;
}
public Builder withConnectTimeoutMs(int val) {
connectTimeoutMs = val;
return this;
}
public Builder withConnectionRequestTimeoutMs(int val) {
connectionRequestTimeoutMs = val;
return this;
}
public Builder withKeystore(KeyStore _keystore, String _password) {
keystore = _keystore;
keystorePassword = _password;
return this;
}
public Builder withValidateSSLCertificates(boolean val) {
validateSSLCertificates = val;
return this;
}
public HttpPool build() {
return new HttpPool(maxTotalConnections, maxPerRoute, socketTimeoutMs, connectTimeoutMs, connectionRequestTimeoutMs, keystore, keystorePassword, validateSSLCertificates);
}
}
} }

View File

@ -1,29 +0,0 @@
package com.lanternsoftware.util.http;
import com.lanternsoftware.util.NullUtils;
public class HttpResponsePayload {
private final int status;
private final byte[] payload;
public HttpResponsePayload(int _status, byte[] _payload) {
status = _status;
payload = _payload;
}
public int getStatus() {
return status;
}
public byte[] getPayload() {
return payload;
}
public boolean isSuccess() {
return (status >= 200) && (status < 300);
}
public String asString() {
return NullUtils.toString(payload);
}
}

View File

@ -76,6 +76,7 @@ public class ZWaveApp {
private HttpPool pool; private HttpPool pool;
private SwitchScheduleTask nextScheduleTask; private SwitchScheduleTask nextScheduleTask;
private final Map<Integer, Double> sensors = new HashMap<>(); private final Map<Integer, Double> sensors = new HashMap<>();
private final Object ZWAVE_MUTEX = new Object();
private ExecutorService executor = null; private ExecutorService executor = null;
public void start() { public void start() {
@ -558,15 +559,17 @@ public class ZWaveApp {
if (_sw.isSourceUrlValid()) if (_sw.isSourceUrlValid())
return DaoSerializer.getDouble(DaoSerializer.parse(pool.executeToString(new HttpGet(_sw.getSourceUrl()))), "temp"); return DaoSerializer.getDouble(DaoSerializer.parse(pool.executeToString(new HttpGet(_sw.getSourceUrl()))), "temp");
else if (_sw.isZWaveThermostat() && config.isMySwitch(_sw)) { else if (_sw.isZWaveThermostat() && config.isMySwitch(_sw)) {
synchronized (sensors) { synchronized (ZWAVE_MUTEX) {
controller.send(new MultilevelSensorGetRequest((byte) _sw.getNodeId())); synchronized (sensors) {
try { controller.send(new MultilevelSensorGetRequest((byte) _sw.getNodeId()));
sensors.wait(3000); try {
} catch (InterruptedException _e) { sensors.wait(3000);
_e.printStackTrace(); } catch (InterruptedException _e) {
_e.printStackTrace();
}
Double temp = sensors.get(_sw.getNodeId());
return (temp == null) ? 0.0 : temp;
} }
Double temp = sensors.get(_sw.getNodeId());
return (temp == null) ? 0.0 : temp;
} }
} }
return 0.0; return 0.0;