mirror of
https://github.com/zyphlar/LanternPowerMonitor.git
synced 2024-03-08 14:07:47 +00:00
Add a rules engine so I can be notified when I forget to close my garage door.
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
package com.lanternsoftware.rules;
|
||||
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.CurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.currentmonitor.MongoCurrentMonitorDao;
|
||||
import com.lanternsoftware.dataaccess.rules.MongoRulesDataAccess;
|
||||
import com.lanternsoftware.dataaccess.rules.RulesDataAccess;
|
||||
import com.lanternsoftware.datamodel.currentmonitor.Account;
|
||||
import com.lanternsoftware.datamodel.rules.Action;
|
||||
import com.lanternsoftware.datamodel.rules.ActionType;
|
||||
import com.lanternsoftware.datamodel.rules.Criteria;
|
||||
import com.lanternsoftware.datamodel.rules.Event;
|
||||
import com.lanternsoftware.datamodel.rules.EventId;
|
||||
import com.lanternsoftware.datamodel.rules.EventType;
|
||||
import com.lanternsoftware.datamodel.rules.Rule;
|
||||
import com.lanternsoftware.rules.actions.ActionImpl;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class RulesEngine {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(RulesEngine.class);
|
||||
|
||||
private static RulesEngine INSTANCE;
|
||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
private final RulesDataAccess dao;
|
||||
private final CurrentMonitorDao cmDao;
|
||||
private final Map<ActionType, ActionImpl> actions = new HashMap<>();
|
||||
private final Map<Integer, EventTimeTask> timeTasks = new HashMap<>();
|
||||
private Timer timer;
|
||||
|
||||
|
||||
public static RulesEngine instance() {
|
||||
if (INSTANCE == null)
|
||||
INSTANCE = new RulesEngine();
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public RulesEngine() {
|
||||
ServiceLoader.load(ActionImpl.class).forEach(_action->actions.put(_action.getType(), _action));
|
||||
dao = new MongoRulesDataAccess(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
cmDao = new MongoCurrentMonitorDao(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
timer = new Timer("RulesEngine Timer");
|
||||
}
|
||||
|
||||
public void start() {
|
||||
for (String id : cmDao.getProxy().queryForField(Account.class, null, "_id")) {
|
||||
scheduleNextTimeEventForAccount(DaoSerializer.toInteger(id));
|
||||
}
|
||||
}
|
||||
|
||||
public RulesDataAccess dao() {
|
||||
return dao;
|
||||
}
|
||||
|
||||
public void fireEvent(Event _event) {
|
||||
if (_event.getType() != EventType.TIME)
|
||||
dao.putEvent(_event);
|
||||
executor.submit(()->{
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago"); //TODO: Get from the current monitor account
|
||||
List<Rule> rules = CollectionUtils.filter(dao.getRulesForAccount(_event.getAccountId()), _r->_r.triggers(_event));
|
||||
if (!rules.isEmpty()) {
|
||||
for (Rule rule : rules) {
|
||||
List<Event> events = CollectionUtils.asArrayList(_event);
|
||||
List<Criteria> critNeedingData = rule.getCriteriaNeedingData(_event);
|
||||
if (!critNeedingData.isEmpty()) {
|
||||
Set<EventId> eventsToGet = CollectionUtils.transformToSet(critNeedingData, Criteria::toEventId);
|
||||
for (EventId id : eventsToGet) {
|
||||
Event event = dao.getMostRecentEvent(_event.getAccountId(), id.getType(), id.getSourceId());
|
||||
if (event != null)
|
||||
events.add(event);
|
||||
}
|
||||
}
|
||||
if (rule.isMet(events, tz)) {
|
||||
for (Action action : CollectionUtils.makeNotNull(rule.getActions())) {
|
||||
ActionImpl impl = actions.get(action.getType());
|
||||
impl.invoke(rule, events, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void scheduleNextTimeEventForAccount(int _accountId) {
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago"); //TODO: Get from the current monitor account
|
||||
EventTimeTask nextTask = timeTasks.remove(_accountId);
|
||||
if (nextTask != null)
|
||||
nextTask.cancel();
|
||||
List<Rule> rules = CollectionUtils.filter(dao.getRulesForAccount(_accountId), _r->CollectionUtils.anyQualify(_r.getAllCriteria(), _c->_c.getType() == EventType.TIME));
|
||||
if (rules.isEmpty())
|
||||
return;
|
||||
Collection<Date> dates = CollectionUtils.aggregate(rules, _r->CollectionUtils.transform(_r.getAllCriteria(), _c->_c.getNextTriggerDate(tz)));
|
||||
Date nextDate = CollectionUtils.getSmallest(dates);
|
||||
LOG.info("Scheduling next time event for account {} at {}", _accountId, DateUtils.format("MM/dd/yyyy HH:mm:ss", nextDate));
|
||||
nextTask = new EventTimeTask(_accountId, nextDate);
|
||||
timer.schedule(nextTask, nextDate);
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
if (INSTANCE == null)
|
||||
return;
|
||||
INSTANCE.executor.shutdown();
|
||||
INSTANCE.dao.shutdown();
|
||||
INSTANCE.cmDao.shutdown();
|
||||
INSTANCE.timer.cancel();
|
||||
INSTANCE.timer = null;
|
||||
INSTANCE = null;
|
||||
}
|
||||
|
||||
private class EventTimeTask extends TimerTask {
|
||||
private final int accountId;
|
||||
private final Date eventTime;
|
||||
|
||||
EventTimeTask(int _accountId, Date _eventTime) {
|
||||
accountId = _accountId;
|
||||
eventTime = _eventTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.info("Firing time event for account {}", accountId);
|
||||
Event event = new Event();
|
||||
event.setAccountId(accountId);
|
||||
event.setTime(eventTime);
|
||||
event.setType(EventType.TIME);
|
||||
fireEvent(event);
|
||||
scheduleNextTimeEventForAccount(accountId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.lanternsoftware.rules.actions;
|
||||
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.firebase.FirebaseApp;
|
||||
import com.google.firebase.FirebaseOptions;
|
||||
import com.google.firebase.messaging.AndroidConfig;
|
||||
import com.google.firebase.messaging.FirebaseMessaging;
|
||||
import com.google.firebase.messaging.Message;
|
||||
import com.lanternsoftware.datamodel.rules.Alert;
|
||||
import com.lanternsoftware.datamodel.rules.FcmDevice;
|
||||
import com.lanternsoftware.datamodel.rules.Rule;
|
||||
import com.lanternsoftware.rules.RulesEngine;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractAlertAction implements ActionImpl {
|
||||
protected static final Logger logger = LoggerFactory.getLogger(AbstractAlertAction.class);
|
||||
protected static final FirebaseMessaging messaging;
|
||||
static {
|
||||
FirebaseMessaging m = null;
|
||||
try {
|
||||
FileInputStream is = new FileInputStream(LanternFiles.OPS_PATH + "google_account_key.json");
|
||||
FirebaseOptions options = FirebaseOptions.builder().setCredentials(GoogleCredentials.fromStream(is)).build();
|
||||
m = FirebaseMessaging.getInstance(FirebaseApp.initializeApp(options));
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
catch (Exception _e) {
|
||||
logger.error("Failed to load google credentials", _e);
|
||||
}
|
||||
messaging = m;
|
||||
}
|
||||
|
||||
protected void sendAlert(Rule _rule, Alert _alert) {
|
||||
List<FcmDevice> devices = RulesEngine.instance().dao().getFcmDevicesForAccount(_rule.getAccountId());
|
||||
if (devices.isEmpty())
|
||||
return;
|
||||
for (FcmDevice device : devices) {
|
||||
Message msg = Message.builder().setToken(device.getToken()).putData("payload", DaoSerializer.toBase64ZipBson(_alert)).putData("payloadClass", Alert.class.getCanonicalName()).setAndroidConfig(AndroidConfig.builder().setPriority(AndroidConfig.Priority.HIGH).setDirectBootOk(true).build()).build();
|
||||
try {
|
||||
messaging.send(msg);
|
||||
} catch (Exception _e) {
|
||||
logger.error("Failed to send message to account {}, device {}", _rule.getAccountId(), device.getName(), _e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.lanternsoftware.rules.actions;
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.Action;
|
||||
import com.lanternsoftware.datamodel.rules.ActionType;
|
||||
import com.lanternsoftware.datamodel.rules.Event;
|
||||
import com.lanternsoftware.datamodel.rules.Rule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ActionImpl {
|
||||
ActionType getType();
|
||||
void invoke(Rule _rule, List<Event> _event, Action _action);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.lanternsoftware.rules.actions;
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.Action;
|
||||
import com.lanternsoftware.datamodel.rules.ActionType;
|
||||
import com.lanternsoftware.datamodel.rules.Alert;
|
||||
import com.lanternsoftware.datamodel.rules.Event;
|
||||
import com.lanternsoftware.datamodel.rules.Rule;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MobileAlertAction extends AbstractAlertAction {
|
||||
@Override
|
||||
public ActionType getType() {
|
||||
return ActionType.MOBILE_ALERT_EVENT_DESCRIPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(Rule _rule, List<Event> _event, Action _action) {
|
||||
sendAlert(_rule, new Alert(CollectionUtils.transformToCommaSeparated(_event, Event::getEventDescription)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.lanternsoftware.rules.actions;
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.Action;
|
||||
import com.lanternsoftware.datamodel.rules.ActionType;
|
||||
import com.lanternsoftware.datamodel.rules.Alert;
|
||||
import com.lanternsoftware.datamodel.rules.Event;
|
||||
import com.lanternsoftware.datamodel.rules.Rule;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MobileAlertStatic extends AbstractAlertAction {
|
||||
@Override
|
||||
public ActionType getType() {
|
||||
return ActionType.MOBILE_ALERT_STATIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(Rule _rule, List<Event> _event, Action _action) {
|
||||
sendAlert(_rule, new Alert(_action.getDescription()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lanternsoftware.rules.servlet;
|
||||
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.Event;
|
||||
import com.lanternsoftware.rules.RulesEngine;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/event")
|
||||
public class EventServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
Event event = getRequestPayload(_req, Event.class);
|
||||
if (event == null) {
|
||||
_rep.setStatus(400);
|
||||
return;
|
||||
}
|
||||
event.setAccountId(_authCode.getAccountId());
|
||||
RulesEngine.instance().fireEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lanternsoftware.rules.servlet;
|
||||
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.FcmDevice;
|
||||
import com.lanternsoftware.rules.RulesEngine;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet("/fcm")
|
||||
public class FcmServlet extends SecureServlet {
|
||||
@Override
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
FcmDevice device = getRequestPayload(_req, FcmDevice.class);
|
||||
if (device == null) {
|
||||
_rep.setStatus(400);
|
||||
return;
|
||||
}
|
||||
device.setAccountId(_authCode.getAccountId());
|
||||
RulesEngine.instance().dao().putFcmDevice(device);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.lanternsoftware.rules.servlet;
|
||||
|
||||
import com.lanternsoftware.util.cryptography.AESTool;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.auth.AuthCode;
|
||||
import com.lanternsoftware.util.servlet.LanternServlet;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public abstract class SecureServlet extends LanternServlet {
|
||||
private static final AESTool aes = AESTool.authTool();
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = DaoSerializer.fromZipBson(aes.decryptFromBase64(_req.getHeader("auth_code")), AuthCode.class);
|
||||
if (authCode == null) {
|
||||
_rep.setStatus(401);
|
||||
return;
|
||||
}
|
||||
get(authCode, _req, _rep);
|
||||
}
|
||||
|
||||
protected void get(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
AuthCode authCode = DaoSerializer.fromZipBson(aes.decryptFromBase64(_req.getHeader("auth_code")), AuthCode.class);
|
||||
if (authCode == null) {
|
||||
_rep.setStatus(401);
|
||||
return;
|
||||
}
|
||||
post(authCode, _req, _rep);
|
||||
}
|
||||
|
||||
protected void post(AuthCode _authCode, HttpServletRequest _req, HttpServletResponse _rep) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
com.lanternsoftware.rules.actions.MobileAlertAction
|
||||
com.lanternsoftware.rules.actions.MobileAlertStatic
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.lanternsoftware;
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.Action;
|
||||
import com.lanternsoftware.datamodel.rules.ActionType;
|
||||
import com.lanternsoftware.datamodel.rules.Criteria;
|
||||
import com.lanternsoftware.datamodel.rules.EventType;
|
||||
import com.lanternsoftware.datamodel.rules.Operator;
|
||||
import com.lanternsoftware.datamodel.rules.Rule;
|
||||
import com.lanternsoftware.rules.RulesEngine;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
public class CreateRules {
|
||||
public static void main(String[] args) {
|
||||
for (Rule r : RulesEngine.instance().dao().getRulesForAccount(100)) {
|
||||
RulesEngine.instance().dao().deleteRule(r.getId());
|
||||
}
|
||||
Rule r1 = new Rule();
|
||||
r1.setAccountId(100);
|
||||
Criteria c1 = new Criteria();
|
||||
c1.setType(EventType.SWITCH_LEVEL);
|
||||
c1.setSourceId("203");
|
||||
c1.setOperator(Operator.EQUAL);
|
||||
c1.setValue(1);
|
||||
r1.setCriteria(CollectionUtils.asArrayList(c1));
|
||||
Action a1 = new Action();
|
||||
a1.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a1.setDescription("Garage Door 1 opened");
|
||||
a1.setDestinationId("*");
|
||||
r1.setActions(CollectionUtils.asArrayList(a1));
|
||||
RulesEngine.instance().dao().putRule(r1);
|
||||
|
||||
Rule r2 = new Rule();
|
||||
r2.setAccountId(100);
|
||||
Criteria c2 = new Criteria();
|
||||
c2.setType(EventType.SWITCH_LEVEL);
|
||||
c2.setSourceId("203");
|
||||
c2.setOperator(Operator.EQUAL);
|
||||
c2.setValue(0);
|
||||
r2.setCriteria(CollectionUtils.asArrayList(c2));
|
||||
Action a2 = new Action();
|
||||
a2.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a2.setDescription("Garage Door 1 closed");
|
||||
a2.setDestinationId("*");
|
||||
r2.setActions(CollectionUtils.asArrayList(a2));
|
||||
RulesEngine.instance().dao().putRule(r2);
|
||||
|
||||
Rule r3 = new Rule();
|
||||
r3.setAccountId(100);
|
||||
Criteria c3 = new Criteria();
|
||||
c3.setType(EventType.SWITCH_LEVEL);
|
||||
c3.setSourceId("204");
|
||||
c3.setOperator(Operator.EQUAL);
|
||||
c3.setValue(1);
|
||||
r3.setCriteria(CollectionUtils.asArrayList(c3));
|
||||
Action a3 = new Action();
|
||||
a3.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a3.setDescription("Garage Door 2 opened");
|
||||
a3.setDestinationId("*");
|
||||
r3.setActions(CollectionUtils.asArrayList(a3));
|
||||
RulesEngine.instance().dao().putRule(r3);
|
||||
|
||||
Rule r4 = new Rule();
|
||||
r4.setAccountId(100);
|
||||
Criteria c4 = new Criteria();
|
||||
c4.setType(EventType.SWITCH_LEVEL);
|
||||
c4.setSourceId("204");
|
||||
c4.setOperator(Operator.EQUAL);
|
||||
c4.setValue(0);
|
||||
r4.setCriteria(CollectionUtils.asArrayList(c4));
|
||||
Action a4 = new Action();
|
||||
a4.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a4.setDescription("Garage Door 2 closed");
|
||||
a4.setDestinationId("*");
|
||||
r4.setActions(CollectionUtils.asArrayList(a4));
|
||||
RulesEngine.instance().dao().putRule(r4);
|
||||
|
||||
Rule r5 = new Rule();
|
||||
r5.setAccountId(100);
|
||||
Criteria c5 = new Criteria();
|
||||
c5.setType(EventType.SWITCH_LEVEL);
|
||||
c5.setSourceId("205");
|
||||
c5.setOperator(Operator.EQUAL);
|
||||
c5.setValue(1);
|
||||
r5.setCriteria(CollectionUtils.asArrayList(c5));
|
||||
Action a5 = new Action();
|
||||
a5.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a5.setDescription("Garage Door 3 opened");
|
||||
a5.setDestinationId("*");
|
||||
r5.setActions(CollectionUtils.asArrayList(a5));
|
||||
RulesEngine.instance().dao().putRule(r5);
|
||||
|
||||
Rule r6 = new Rule();
|
||||
r6.setAccountId(100);
|
||||
Criteria c6 = new Criteria();
|
||||
c6.setType(EventType.SWITCH_LEVEL);
|
||||
c6.setSourceId("205");
|
||||
c6.setOperator(Operator.EQUAL);
|
||||
c6.setValue(0);
|
||||
r6.setCriteria(CollectionUtils.asArrayList(c6));
|
||||
Action a6 = new Action();
|
||||
a6.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a6.setDescription("Garage Door 3 closed");
|
||||
a6.setDestinationId("*");
|
||||
r6.setActions(CollectionUtils.asArrayList(a6));
|
||||
RulesEngine.instance().dao().putRule(r6);
|
||||
|
||||
Rule r7 = new Rule();
|
||||
r7.setAccountId(100);
|
||||
Criteria c7 = new Criteria();
|
||||
c7.setType(EventType.SWITCH_LEVEL);
|
||||
c7.setSourceId("203");
|
||||
c7.setOperator(Operator.EQUAL);
|
||||
c7.setValue(1);
|
||||
Criteria c7_2 = new Criteria();
|
||||
c7_2.setType(EventType.TIME);
|
||||
c7_2.setValue(79200);
|
||||
// c7_2.setValue(74400);
|
||||
r7.setCriteria(CollectionUtils.asArrayList(c7, c7_2));
|
||||
Action a7 = new Action();
|
||||
a7.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a7.setDescription("Garage Door 1 is still open");
|
||||
a7.setDestinationId("*");
|
||||
r7.setActions(CollectionUtils.asArrayList(a7));
|
||||
RulesEngine.instance().dao().putRule(r7);
|
||||
|
||||
Rule r8 = new Rule();
|
||||
r8.setAccountId(100);
|
||||
Criteria c8 = new Criteria();
|
||||
c8.setType(EventType.SWITCH_LEVEL);
|
||||
c8.setSourceId("204");
|
||||
c8.setOperator(Operator.EQUAL);
|
||||
c8.setValue(1);
|
||||
Criteria c8_2 = new Criteria();
|
||||
c8_2.setType(EventType.TIME);
|
||||
c8_2.setValue(79200);
|
||||
// c8_2.setValue(74400);
|
||||
r8.setCriteria(CollectionUtils.asArrayList(c8, c8_2));
|
||||
Action a8 = new Action();
|
||||
a8.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a8.setDescription("Garage Door 2 is still open");
|
||||
a8.setDestinationId("*");
|
||||
r8.setActions(CollectionUtils.asArrayList(a8));
|
||||
RulesEngine.instance().dao().putRule(r8);
|
||||
|
||||
Rule r9 = new Rule();
|
||||
r9.setAccountId(100);
|
||||
Criteria c9 = new Criteria();
|
||||
c9.setType(EventType.SWITCH_LEVEL);
|
||||
c9.setSourceId("205");
|
||||
c9.setOperator(Operator.EQUAL);
|
||||
c9.setValue(1);
|
||||
Criteria c9_2 = new Criteria();
|
||||
c9_2.setType(EventType.TIME);
|
||||
c9_2.setValue(79200);
|
||||
// c9_2.setValue(74400);
|
||||
r9.setCriteria(CollectionUtils.asArrayList(c9, c9_2));
|
||||
Action a9 = new Action();
|
||||
a9.setType(ActionType.MOBILE_ALERT_STATIC);
|
||||
a9.setDescription("Garage Door 3 is still open");
|
||||
a9.setDestinationId("*");
|
||||
r9.setActions(CollectionUtils.asArrayList(a9));
|
||||
RulesEngine.instance().dao().putRule(r9);
|
||||
RulesEngine.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.lanternsoftware;
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.EventType;
|
||||
import com.lanternsoftware.datamodel.rules.Rule;
|
||||
import com.lanternsoftware.rules.RulesEngine;
|
||||
import com.lanternsoftware.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class TestRuleSchedule {
|
||||
public static void main(String[] args) {
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Chicago"); //TODO: Get from the current monitor account
|
||||
List<Rule> rules = CollectionUtils.filter(RulesEngine.instance().dao().getRulesForAccount(100), _r->CollectionUtils.anyQualify(_r.getAllCriteria(), _c->_c.getType() == EventType.TIME));
|
||||
if (rules.isEmpty())
|
||||
return;
|
||||
Collection<Date> dates = CollectionUtils.aggregate(rules, _r->CollectionUtils.transform(_r.getAllCriteria(), _c->_c.getNextTriggerDate(tz), true));
|
||||
Date nextDate = CollectionUtils.getSmallest(dates);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.lanternsoftware;
|
||||
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.firebase.FirebaseApp;
|
||||
import com.google.firebase.FirebaseOptions;
|
||||
import com.google.firebase.messaging.FirebaseMessaging;
|
||||
import com.google.firebase.messaging.Message;
|
||||
import com.lanternsoftware.dataaccess.rules.MongoRulesDataAccess;
|
||||
import com.lanternsoftware.dataaccess.rules.RulesDataAccess;
|
||||
import com.lanternsoftware.datamodel.rules.Alert;
|
||||
import com.lanternsoftware.datamodel.rules.FcmDevice;
|
||||
import com.lanternsoftware.util.LanternFiles;
|
||||
import com.lanternsoftware.util.dao.DaoSerializer;
|
||||
import com.lanternsoftware.util.dao.mongo.MongoConfig;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
|
||||
public class TestSendAlert {
|
||||
public static void main(String[] args) {
|
||||
RulesDataAccess dao = new MongoRulesDataAccess(MongoConfig.fromDisk(LanternFiles.OPS_PATH + "mongo.cfg"));
|
||||
for (FcmDevice d : dao.getFcmDevicesForAccount(100)) {
|
||||
Alert alert = new Alert();
|
||||
alert.setMessage("Test Alert");
|
||||
Message msg = Message.builder().setToken(d.getToken()).putData("payload", DaoSerializer.toBase64ZipBson(alert)).putData("payloadClass", Alert.class.getCanonicalName()).build();
|
||||
try {
|
||||
FileInputStream is = new FileInputStream("d:\\zwave\\firebase\\account_key.json");
|
||||
FirebaseOptions options = FirebaseOptions.builder().setCredentials(GoogleCredentials.fromStream(is)).build();
|
||||
FirebaseMessaging.getInstance(FirebaseApp.initializeApp(options)).send(msg);
|
||||
IOUtils.closeQuietly(is);
|
||||
} catch (Exception _e) {
|
||||
_e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.lanternsoftware;
|
||||
|
||||
import com.lanternsoftware.datamodel.rules.Event;
|
||||
import com.lanternsoftware.datamodel.rules.EventType;
|
||||
import com.lanternsoftware.rules.RulesEngine;
|
||||
import com.lanternsoftware.util.DateUtils;
|
||||
import com.lanternsoftware.util.concurrency.ConcurrencyUtils;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class TestTimeRule {
|
||||
public static void main(String[] args) {
|
||||
Event event = new Event();
|
||||
event.setAccountId(100);
|
||||
event.setTime(DateUtils.date(7, 15, 2021, 18, 30, 0, 0, TimeZone.getTimeZone("America/Chicago")));
|
||||
event.setType(EventType.TIME);
|
||||
RulesEngine.instance().fireEvent(event);
|
||||
ConcurrencyUtils.sleep(200000);
|
||||
RulesEngine.shutdown();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user