Introduction of Room assignments

This commit is contained in:
Ziver Koc 2023-01-06 23:54:53 +01:00
parent b5ac492414
commit 7a90189927
21 changed files with 707 additions and 130 deletions

View file

@ -1,6 +1,39 @@
{ {
"components": { "components": {
"schemas": { "schemas": {
"eventClass": {
"type": "object",
"properties": {
"data": {
"type": "object",
"$ref": "#/components/schemas/dataClass"
},
"name": {"type": "string"},
"id": {"type": "integer"},
"map": {
"type": "object",
"$ref": "#/components/schemas/mapClass"
},
"user": {"type": "string"},
"config": {
"type": "object",
"$ref": "#/components/schemas/configClass"
}
}
},
"roomClass": {
"type": "object",
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"},
"map": {
"type": "object",
"$ref": "#/components/schemas/mapClass"
}
}
},
"sensorClass": { "sensorClass": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10,8 +43,10 @@
}, },
"name": {"type": "string"}, "name": {"type": "string"},
"id": {"type": "integer"}, "id": {"type": "integer"},
"map_x": {"type": "number"}, "map": {
"map_y": {"type": "number"}, "type": "object",
"$ref": "#/components/schemas/mapClass"
},
"user": {"type": "string"}, "user": {"type": "string"},
"config": { "config": {
"type": "object", "type": "object",
@ -36,24 +71,6 @@
} }
} }
}, },
"eventClass": {
"type": "object",
"properties": {
"data": {
"type": "object",
"$ref": "#/components/schemas/dataClass"
},
"name": {"type": "string"},
"id": {"type": "integer"},
"map_x": {"type": "number"},
"map_y": {"type": "number"},
"user": {"type": "string"},
"config": {
"type": "object",
"$ref": "#/components/schemas/configClass"
}
}
},
"configClass": { "configClass": {
"type": "object", "type": "object",
@ -62,6 +79,7 @@
"typeData": {"type": "string"} "typeData": {"type": "string"}
} }
}, },
"dataClass": { "dataClass": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -69,16 +87,29 @@
"value": {"type": "number"}, "value": {"type": "number"},
"timestamp": {"type": "integer"} "timestamp": {"type": "integer"}
} }
} },
"mapClass": {
"type": "object",
"properties": {
"x": {"type": "number"},
"y": {"type": "number"},
"width": {"type": "number"},
"height": {"type": "number"}
}
},
} }
}, },
"servers": [ "servers": [
{ {
"description": "Hal Server", "description": "Hal Server",
"url": "/api" "url": "/api"
} }
], ],
"openapi": "3.0.1", "openapi": "3.0.1",
"paths": { "paths": {
"/event": { "/event": {
"get": { "get": {
@ -123,6 +154,35 @@
] ]
} }
}, },
"/room": {
"get": {
"responses": {
"200": {
"description": "A successful response.",
"content": {
"application/json": {
"schema": {
"type": "object",
"$ref": "#/components/schemas/roomClass"
}
}
}
}
},
"parameters": [
{
"schema": {
"type": "integer"
},
"in": "query",
"name": "id",
"required": false
}
]
}
},
"/sensor": { "/sensor": {
"get": { "get": {
"responses": { "responses": {

View file

@ -35,6 +35,7 @@
data-target="#eventModal" data-target="#eventModal"
data-action="modify_local_event" data-action="modify_local_event"
data-id="{{.getId()}}" data-id="{{.getId()}}"
data-room-id="{{.getRoom().getId()}}"
data-name="{{.getName()}}" data-name="{{.getName()}}"
data-type="{{.getType()}}" data-type="{{.getType()}}"
{{#.getDeviceConfigurator().getConfiguration()}} {{#.getDeviceConfigurator().getConfiguration()}}
@ -125,6 +126,16 @@
<div class="modal-body"> <div class="modal-body">
<input type="hidden" id="action" name="action"> <input type="hidden" id="action" name="action">
<input type="hidden" id="id" name="id"> <input type="hidden" id="id" name="id">
<div class="form-group">
<label class="control-label">Located in room:</label>
<select class="form-control" name="room-id">
<option value=""></option>
{{#rooms}}
<option value="{{.getId()}}">{{.getName()}} (id: {{.getId()}})</option>
{{/rooms}}
</select>
</div>
<div class="form-group"> <div class="form-group">
<label class="control-label">Name:</label> <label class="control-label">Name:</label>
<input type="text" class="form-control" name="name"> <input type="text" class="form-control" name="name">

View file

@ -167,26 +167,24 @@ function initDynamicModalForm(modalId, formTemplateId = null, templateID = null)
var button = $(event.relatedTarget); var button = $(event.relatedTarget);
var modal = $(this); var modal = $(this);
// Reset all inputs modal.find(" input, select").val('').change(); // Reset all inputs
if (formTemplateId != null)
modal.find("#" + formTemplateId).empty(); // clear form div
// set dynamic form data // Set dynamic form data
$.each(button.attr(), function(fieldName, value) { $.each(button.attr(), function(fieldName, value) {
if(fieldName.startsWith("data-")) { if(fieldName.startsWith("data-")) {
fieldName = fieldName.substring(5); // remove prefix data- fieldName = fieldName.substring(5); // remove prefix data-
// case insensitive search // Case-insensitive search
var input = modal.find("input, select").filter(function() { var input = modal.find("input, select").filter(function() {
if (this.name.toLowerCase() == fieldName) { if (this.name.toLowerCase() == fieldName) {
if (this.type == "hidden" && modal.find("input[type=checkbox][name=" + fieldName + "]") != null) if (this.type == "hidden" && modal.find("input[type=checkbox][name=" + fieldName + "]").length > 0)
return false; // Workaround for the default(false) boolean input return false; // Workaround for the default(false) boolean input
return true; return true;
} }
return false; return false;
}); });
if (input != null) { if (input.length > 0) {
if (input.prop("type") == "checkbox") { // special handling for checkboxes if (input.prop("type") == "checkbox") { // special handling for checkboxes
input.prop("value", "true"); input.prop("value", "true");
input.prop("checked", value == "true"); input.prop("checked", value == "true");
@ -196,10 +194,7 @@ function initDynamicModalForm(modalId, formTemplateId = null, templateID = null)
input.parent().prepend("<input type='hidden' name='" + input.prop("name") + "' value='false' />"); input.parent().prepend("<input type='hidden' name='" + input.prop("name") + "' value='false' />");
} }
} else { } else {
input.val(value); input.val(value).change();
if (input.prop("tagName") == "SELECT")
input.change(); // required for select elements to update properly
} }
} }
} }

View file

@ -0,0 +1,86 @@
<h1 class="page-header">Room Configuration</h1>
<div class="col-md-12">
<div class="panel panel-default drop-shadow">
<div class="panel-heading">Rooms</div>
<div class="panel-body">
<p>This is a list of all configured rooms.</p>
<table class="table table-hover table-condensed">
<thead>
<th style="width: 50px;">#</th>
<th>Name</th>
<th>
<button class="btn btn-default btn-xs pull-right" data-toggle="modal"
data-target="#roomModal"
data-action="create_room">
<span class="glyphicon glyphicon-plus"></span>
</button>
</th>
</thead>
{{#rooms}}
<tr>
<td>{{.getId()}}</td>
<td>{{.getName()}}</td>
<td>
<form method="POST">
<input type="hidden" name="id" value="{{.getId()}}">
<div class="btn-toolbar pull-right">
<button type="button" class="btn btn-default btn-xs" data-toggle="modal"
data-target="#roomModal"
data-action="modify_room"
data-id="{{.getId()}}"
data-name="{{.getName()}}"
>
<span class="glyphicon glyphicon-pencil"></span>
</button>
<button type="submit" class="btn btn-danger btn-xs" name="action" value="remove_room">
<span class="glyphicon glyphicon-trash"></span>
</button>
</div>
</form>
</td>
</tr>
{{/rooms}}
</table>
</div>
</div>
</div>
<!------------- MODALS --------------->
<script>
$(function(){
initDynamicModalForm("roomModal");
});
</script>
<div class="modal fade" id="roomModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
<h4 class="modal-title">Room</h4>
</div>
<form method="POST">
<div class="modal-body">
<input type="hidden" id="action" name="action">
<input type="hidden" id="id" name="id">
<div class="form-group">
<label class="control-label">Name:</label>
<input type="text" class="form-control" name="name">
</div>
</div>
<div class="modal-footer">
<button type="reset" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>

View file

@ -34,7 +34,8 @@
<div class="btn-toolbar pull-right"> <div class="btn-toolbar pull-right">
<button type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#sensorModal" <button type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#sensorModal"
data-action="modify_local_sensor" data-action="modify_local_sensor"
data-id="{{.getId()}}" data-sensor-id="{{.getId()}}"
data-room-id="{{.getRoom().getId()}}"
data-name="{{.getName()}}" data-name="{{.getName()}}"
data-type="{{.getType()}}" data-type="{{.getType()}}"
data-sync="{{.isSynced()}}" data-sync="{{.isSynced()}}"
@ -140,7 +141,7 @@
<div class="btn-toolbar pull-right"> <div class="btn-toolbar pull-right">
<button type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#userModal" <button type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#userModal"
data-action="modify_external_user" data-action="modify_external_user"
data-id="{{.getId()}}" data-user-id="{{.getId()}}"
data-hostname="{{.getHostname()}}" data-hostname="{{.getHostname()}}"
data-port="{{.getPort()}}"> data-port="{{.getPort()}}">
<span class="glyphicon glyphicon-pencil"></span> <span class="glyphicon glyphicon-pencil"></span>
@ -225,11 +226,27 @@
<form method="POST"> <form method="POST">
<div class="modal-body"> <div class="modal-body">
<input type="hidden" id="action" name="action" value=""> <input type="hidden" id="action" name="action" value="">
<input type="hidden" id="id" name="id"> <input type="hidden" id="sensor-id" name="sensor-id">
<div class="form-group">
<label class="control-label">Located in room:</label>
<select class="form-control" name="room-id">
<option value=""></option>
{{#rooms}}
<option value="{{.getId()}}">{{.getName()}} (id: {{.getId()}})</option>
{{/rooms}}
</select>
</div>
<div class="form-group"> <div class="form-group">
<label class="control-label">Name:</label> <label class="control-label">Name:</label>
<input type="text" class="form-control" name="name"> <input type="text" class="form-control" name="name">
</div> </div>
<div class="checkbox">
<label>
<input type="checkbox" name="sync" value="true">
Public
</label>
</div>
<div class="form-group"> <div class="form-group">
<label class="control-label">Type:</label> <label class="control-label">Type:</label>
<select class="form-control" name="type"> <select class="form-control" name="type">
@ -238,13 +255,6 @@
{{/availableSensorConfigClasses}} {{/availableSensorConfigClasses}}
</select> </select>
</div> </div>
<div class="checkbox">
<label>
<input type="checkbox" name="sync" value="true">
Public
</label>
</div>
<hr> <hr>
<div id="sensor-data-conf"> <div id="sensor-data-conf">
@ -290,7 +300,7 @@
<form method="POST"> <form method="POST">
<div class="modal-body"> <div class="modal-body">
<input type="hidden" name="action" value=""> <input type="hidden" name="action" value="">
<input type="hidden" name="id"> <input type="hidden" name="user-id">
<div class="form-group"> <div class="form-group">
<label class="control-label">Hostname/IP:</label> <label class="control-label">Hostname/IP:</label>
<input type="text" class="form-control" name="hostname"> <input type="text" class="form-control" name="hostname">

View file

@ -13,7 +13,7 @@ import java.util.logging.Logger;
public class HalCoreDatabaseUpgrader extends HalDatabaseUpgrader { public class HalCoreDatabaseUpgrader extends HalDatabaseUpgrader {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private static final int REFERENCE_DB_VERSION = 16; private static final int REFERENCE_DB_VERSION = 17;
private static final String REFERENCE_DB_PATH = HalContext.RESOURCE_ROOT + "/resource/hal-core-reference.db"; private static final String REFERENCE_DB_PATH = HalContext.RESOURCE_ROOT + "/resource/hal-core-reference.db";
private static final int CLEAR_INTERNAL_AGGR_DATA_DB_VERSION = 11; private static final int CLEAR_INTERNAL_AGGR_DATA_DB_VERSION = 11;

View file

@ -1,6 +1,7 @@
package se.hal.intf; package se.hal.intf;
import se.hal.HalContext; import se.hal.HalContext;
import se.hal.struct.Room;
import se.hal.struct.User; import se.hal.struct.User;
import se.hal.util.HalDeviceChangeListener; import se.hal.util.HalDeviceChangeListener;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -41,11 +42,14 @@ public abstract class HalAbstractDevice<V extends HalAbstractDevice, C extends H
@DBColumn("user_id") @DBColumn("user_id")
private User user; private User user;
@DBColumn("room_id")
private Room room;
// UI variables // UI variables
@DBColumn("map_x") @DBColumn("map_x")
private double x; private double mapX = 0;
@DBColumn("map_y") @DBColumn("map_y")
private double y; private double mapY = 0;
protected transient List<HalDeviceReportListener> deviceListeners = new LinkedList<>(); protected transient List<HalDeviceReportListener> deviceListeners = new LinkedList<>();
@ -186,6 +190,9 @@ public abstract class HalAbstractDevice<V extends HalAbstractDevice, C extends H
} }
} }
/**
* @return the owner of this device.
*/
public User getUser() { public User getUser() {
return user; return user;
} }
@ -193,17 +200,31 @@ public abstract class HalAbstractDevice<V extends HalAbstractDevice, C extends H
this.user = user; this.user = user;
} }
public double getX() { /**
return x; * @return the room that this device is located in.
*/
public Room getRoom() {
return room;
} }
public void setX(double x) { public void setRoom(Room room) {
this.x = x; this.room = room;
} }
public double getY() {
return y; /**
* @return the X coordinate of this device on the floor map
*/
public double getMapX() {
return mapX;
} }
public void setY(double y) { /**
this.y = y; * @return the Y coordinate of this device on the floor map
*/
public double getMapY() {
return mapY;
}
public void setMapCoordinates(double x, double y) {
this.mapX = x;
this.mapY = y;
} }
public void addReportListener(HalDeviceReportListener listener) { public void addReportListener(HalDeviceReportListener listener) {
@ -224,8 +245,10 @@ public abstract class HalAbstractDevice<V extends HalAbstractDevice, C extends H
deviceNode.set("id", getId()); deviceNode.set("id", getId());
deviceNode.set("name", getName()); deviceNode.set("name", getName());
deviceNode.set("user", getUser().getUsername()); deviceNode.set("user", getUser().getUsername());
deviceNode.set("map_x", getX());
deviceNode.set("map_y", getY()); DataNode mapNode = deviceNode.set("map", DataNode.DataType.Map);
mapNode.set("x", getMapX());
mapNode.set("y", getMapY());
if (getDeviceConfig() != null) { if (getDeviceConfig() != null) {
DataNode configNode = deviceNode.set("config", DataNode.DataType.Map); DataNode configNode = deviceNode.set("config", DataNode.DataType.Map);

View file

@ -6,9 +6,11 @@ import se.hal.intf.HalAbstractController;
import se.hal.intf.HalAbstractControllerManager; import se.hal.intf.HalAbstractControllerManager;
import se.hal.intf.HalScannableController; import se.hal.intf.HalScannableController;
import se.hal.intf.HalWebPage; import se.hal.intf.HalWebPage;
import se.hal.struct.Room;
import se.hal.util.ClassConfigurationFacade; import se.hal.util.ClassConfigurationFacade;
import se.hal.struct.Event; import se.hal.struct.Event;
import se.hal.struct.User; import se.hal.struct.User;
import se.hal.util.RoomValueProvider;
import zutil.ObjectUtil; import zutil.ObjectUtil;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
@ -43,7 +45,7 @@ public class EventConfigWebPage extends HalWebPage {
Map<String, Object> session, Map<String, Object> session,
Map<String, String> cookie, Map<String, String> cookie,
Map<String, String> request) Map<String, String> request)
throws Exception{ throws Exception {
DBConnection db = HalContext.getDB(); DBConnection db = HalContext.getDB();
User localUser = User.getLocalUser(db); User localUser = User.getLocalUser(db);
@ -51,12 +53,27 @@ public class EventConfigWebPage extends HalWebPage {
// Save new input // Save new input
if (request.containsKey("action")) { if (request.containsKey("action")) {
int id = (ObjectUtil.isEmpty(request.get("id")) ? -1 : Integer.parseInt(request.get("id"))); int id = (ObjectUtil.isEmpty(request.get("id")) ? -1 : Integer.parseInt(request.get("id")));
Event event; int roomId = (ObjectUtil.isEmpty(request.get("room-id")) ? -1 : Integer.parseInt(request.get("room-id")));
Event event = null;
Room room = (roomId >= 0 ? Room.getRoom(db, roomId) : null);
if (id >= 0) {
// Read in requested id
event = Event.getEvent(db, id);
if (event == null) {
logger.warning("Unknown event id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown event id: " + id, MessageTTL.ONE_VIEW));
}
}
switch(request.get("action")) { switch(request.get("action")) {
case "create_local_event": case "create_local_event":
logger.info("Creating new event: " + request.get("name")); logger.info("Creating new event: " + request.get("name"));
event = new Event(); event = new Event();
event.setRoom(room);
event.setName(request.get("name")); event.setName(request.get("name"));
event.setType(request.get("type")); event.setType(request.get("type"));
event.setUser(localUser); event.setUser(localUser);
@ -69,9 +86,9 @@ public class EventConfigWebPage extends HalWebPage {
break; break;
case "modify_local_event": case "modify_local_event":
event = Event.getEvent(db, id);
if (event != null) { if (event != null) {
logger.info("Modifying event: " + event.getName()); logger.info("Modifying event(id: " + event.getId() + "): " + event.getName());
event.setRoom(room);
event.setName(request.get("name")); event.setName(request.get("name"));
event.setType(request.get("type")); event.setType(request.get("type"));
event.setUser(localUser); event.setUser(localUser);
@ -80,26 +97,17 @@ public class EventConfigWebPage extends HalWebPage {
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully saved event: "+event.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully saved event: "+event.getName(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown event id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown event id: " + id, MessageTTL.ONE_VIEW));
} }
break; break;
case "remove_local_event": case "remove_local_event":
event = Event.getEvent(db, id);
if (event != null) { if (event != null) {
logger.info("Removing event: " + event.getName()); logger.info("Removing event(id: " + event.getId() + "): " + event.getName());
EventControllerManager.getInstance().deregister(event); EventControllerManager.getInstance().deregister(event);
event.delete(db); event.delete(db);
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully removed event: "+event.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully removed event: "+event.getName(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown event id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown event id: "+id, MessageTTL.ONE_VIEW));
} }
break; break;
@ -132,6 +140,7 @@ public class EventConfigWebPage extends HalWebPage {
// Output // Output
Templator tmpl = new Templator(FileUtil.find(TEMPLATE)); Templator tmpl = new Templator(FileUtil.find(TEMPLATE));
tmpl.set("user", localUser); tmpl.set("user", localUser);
tmpl.set("rooms", Room.getRooms(db));
tmpl.set("scanning", scanning); tmpl.set("scanning", scanning);
tmpl.set("localEvents", Event.getLocalEvents(db)); tmpl.set("localEvents", Event.getLocalEvents(db));
tmpl.set("detectedEvents", EventControllerManager.getInstance().getDetectedDevices()); tmpl.set("detectedEvents", EventControllerManager.getInstance().getDetectedDevices());

View file

@ -0,0 +1,118 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal.page;
import se.hal.HalContext;
import se.hal.intf.HalWebPage;
import se.hal.struct.Room;
import se.hal.struct.User;
import se.hal.util.ClassConfigurationFacade;
import zutil.ObjectUtil;
import zutil.db.DBConnection;
import zutil.io.file.FileUtil;
import zutil.log.LogUtil;
import zutil.parser.Templator;
import java.util.Map;
import java.util.logging.Logger;
import static zutil.ui.UserMessageManager.*;
public class RoomConfigWebPage extends HalWebPage {
private static final Logger logger = LogUtil.getLogger();
private static final String TEMPLATE = HalContext.RESOURCE_WEB_ROOT + "/room_config.tmpl";
private ClassConfigurationFacade roomConfiguration = new ClassConfigurationFacade(Room.class);
public RoomConfigWebPage() {
super("room_config");
super.getRootNav().createSubNav("Settings").createSubNav(this.getId(), "Room Settings").setWeight(200);
}
@Override
public Templator httpRespond(
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request)
throws Exception {
DBConnection db = HalContext.getDB();
// Save new input
if (request.containsKey("action")){
int id = (ObjectUtil.isEmpty(request.get("id")) ? -1 : Integer.parseInt(request.get("id")));
Room room = null;
if (id >= 0) {
// Read in requested id
room = Room.getRoom(db, id);
if (room == null) {
logger.warning("Unknown room id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown room id: " + id, MessageTTL.ONE_VIEW));
}
}
switch(request.get("action")) {
case "create_room":
logger.info("Creating new room: " + request.get("name"));
room = new Room();
/* FALLTHROUGH */
case "modify_room":
if (room != null) {
logger.info("Modifying room(id: " + room.getId() + "): " + room.getName());
room.setName(request.get("name"));
room.save(db);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully updated room: " + room.getName(), MessageTTL.ONE_VIEW));
}
break;
case "remove_room":
if (room != null) {
logger.info("Removing room(id: " + room.getId() + "): " + room.getName());
room.delete(db);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully removed room: " + room.getName(), MessageTTL.ONE_VIEW));
}
break;
}
}
// Output
Templator tmpl = new Templator(FileUtil.find(TEMPLATE));
tmpl.set("rooms", Room.getRooms(db));
tmpl.set("roomConfiguration", roomConfiguration);
return tmpl;
}
}

View file

@ -6,9 +6,11 @@ import se.hal.intf.HalAbstractController;
import se.hal.intf.HalAbstractControllerManager; import se.hal.intf.HalAbstractControllerManager;
import se.hal.intf.HalScannableController; import se.hal.intf.HalScannableController;
import se.hal.intf.HalWebPage; import se.hal.intf.HalWebPage;
import se.hal.struct.Room;
import se.hal.util.ClassConfigurationFacade; import se.hal.util.ClassConfigurationFacade;
import se.hal.struct.Sensor; import se.hal.struct.Sensor;
import se.hal.struct.User; import se.hal.struct.User;
import se.hal.util.RoomValueProvider;
import zutil.ObjectUtil; import zutil.ObjectUtil;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
@ -43,16 +45,42 @@ public class SensorConfigWebPage extends HalWebPage {
Map<String, Object> session, Map<String, Object> session,
Map<String, String> cookie, Map<String, String> cookie,
Map<String, String> request) Map<String, String> request)
throws Exception{ throws Exception {
DBConnection db = HalContext.getDB(); DBConnection db = HalContext.getDB();
User localUser = User.getLocalUser(db); User localUser = User.getLocalUser(db);
// Save new input // Save new input
if (request.containsKey("action")) { if (request.containsKey("action")) {
int id = (ObjectUtil.isEmpty(request.get("id")) ? -1 : Integer.parseInt(request.get("id"))); int sensorId = (ObjectUtil.isEmpty(request.get("sensor-id")) ? -1 : Integer.parseInt(request.get("sensor-id")));
Sensor sensor; int userId = (ObjectUtil.isEmpty(request.get("user-id")) ? -1 : Integer.parseInt(request.get("user-id")));
User user; int roomId = (ObjectUtil.isEmpty(request.get("room-id")) ? -1 : Integer.parseInt(request.get("room-id")));
Sensor sensor = null;
User user = null;
Room room = (roomId >= 0 ? Room.getRoom(db, roomId) : null);
if (sensorId >= 0) {
// Read in requested id
sensor = Sensor.getSensor(db, sensorId);
if (sensor == null) {
logger.warning("Unknown sensor id: " + sensorId);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown sensor id: " + sensorId, MessageTTL.ONE_VIEW));
}
}
if (userId >= 0) {
// Read in requested id
user = User.getUser(db, userId);
if (user == null) {
logger.warning("Unknown user id: " + userId);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown user id: " + userId, MessageTTL.ONE_VIEW));
}
}
switch(request.get("action")) { switch(request.get("action")) {
// ---------------------------------------- // ----------------------------------------
@ -62,6 +90,7 @@ public class SensorConfigWebPage extends HalWebPage {
case "create_local_sensor": case "create_local_sensor":
logger.info("Creating sensor: " + request.get("name")); logger.info("Creating sensor: " + request.get("name"));
sensor = new Sensor(); sensor = new Sensor();
sensor.setRoom(room);
sensor.setName(request.get("name")); sensor.setName(request.get("name"));
sensor.setType(request.get("type")); sensor.setType(request.get("type"));
sensor.setSynced(Boolean.parseBoolean(request.get("sync"))); sensor.setSynced(Boolean.parseBoolean(request.get("sync")));
@ -71,13 +100,13 @@ public class SensorConfigWebPage extends HalWebPage {
SensorControllerManager.getInstance().register(sensor); SensorControllerManager.getInstance().register(sensor);
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully created new sensor: "+sensor.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully created new sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
break; break;
case "modify_local_sensor": case "modify_local_sensor":
sensor = Sensor.getSensor(db, id);
if (sensor != null) { if (sensor != null) {
logger.info("Modifying sensor: " + sensor.getName()); logger.info("Modifying sensor(id: " + sensor.getId() + "): " + sensor.getName());
sensor.setRoom(room);
sensor.setName(request.get("name")); sensor.setName(request.get("name"));
sensor.setType(request.get("type")); sensor.setType(request.get("type"));
sensor.setSynced(Boolean.parseBoolean(request.get("sync"))); sensor.setSynced(Boolean.parseBoolean(request.get("sync")));
@ -85,27 +114,18 @@ public class SensorConfigWebPage extends HalWebPage {
sensor.save(db); sensor.save(db);
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully saved sensor: "+sensor.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully saved sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown sensor id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown sensor id: " + id, MessageTTL.ONE_VIEW));
} }
break; break;
case "remove_local_sensor": case "remove_local_sensor":
sensor = Sensor.getSensor(db, id);
if (sensor != null) { if (sensor != null) {
logger.warning("Removing sensor: " + sensor.getName()); logger.warning("Removing sensor(id: " + sensor.getId() + "): " + sensor.getName());
SensorControllerManager.getInstance().deregister(sensor); SensorControllerManager.getInstance().deregister(sensor);
sensor.delete(db); sensor.delete(db);
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully removed sensor: "+sensor.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully removed sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown sensor id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown sensor id: " + id, MessageTTL.ONE_VIEW));
} }
break; break;
@ -141,7 +161,6 @@ public class SensorConfigWebPage extends HalWebPage {
break; break;
case "modify_external_user": case "modify_external_user":
user = User.getUser(db, id);
if (user != null) { if (user != null) {
logger.info("Modifying external user: " + user.getHostname()); logger.info("Modifying external user: " + user.getHostname());
user.setHostname(request.get("hostname")); user.setHostname(request.get("hostname"));
@ -150,24 +169,15 @@ public class SensorConfigWebPage extends HalWebPage {
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully saved external user with host: "+user.getHostname(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully saved external user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown user id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown user id: " + id, MessageTTL.ONE_VIEW));
} }
break; break;
case "remove_external_user": case "remove_external_user":
user = User.getUser(db, id);
if (user != null) { if (user != null) {
logger.info("Removing external user: " + user.getHostname()); logger.info("Removing external user: " + user.getHostname());
user.delete(db); user.delete(db);
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully removed user with host: "+user.getHostname(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully removed user with host: "+user.getHostname(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown user id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown user id: "+id, MessageTTL.ONE_VIEW));
} }
break; break;
@ -176,18 +186,13 @@ public class SensorConfigWebPage extends HalWebPage {
// ---------------------------------------- // ----------------------------------------
case "modify_external_sensor": case "modify_external_sensor":
sensor = Sensor.getSensor(db, id);
if (sensor != null) { if (sensor != null) {
logger.warning("Modifying external sensor: " + sensor.getName()); logger.warning("Modifying external sensor: " + sensor.getName());
sensor.setSynced(Boolean.parseBoolean(request.get("sync"))); sensor.setSynced(Boolean.parseBoolean(request.get("sync")));
sensor.save(db); sensor.save(db);
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully saved external sensor: "+sensor.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully saved external sensor: " + sensor.getName(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown user id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown sensor id: "+id, MessageTTL.ONE_VIEW));
} }
break; break;
} }
@ -205,6 +210,7 @@ public class SensorConfigWebPage extends HalWebPage {
// Output // Output
Templator tmpl = new Templator(FileUtil.find(TEMPLATE)); Templator tmpl = new Templator(FileUtil.find(TEMPLATE));
tmpl.set("user", localUser); tmpl.set("user", localUser);
tmpl.set("rooms", Room.getRooms(db));
tmpl.set("scanning", scanning); tmpl.set("scanning", scanning);
tmpl.set("localSensors", Sensor.getLocalSensors(db)); tmpl.set("localSensors", Sensor.getLocalSensors(db));
tmpl.set("detectedSensors", SensorControllerManager.getInstance().getDetectedDevices()); tmpl.set("detectedSensors", SensorControllerManager.getInstance().getDetectedDevices());

View file

@ -46,8 +46,7 @@ public class MapApiEndpoint extends HalApiEndpoint {
else if ("event".equals(request.get("type"))) else if ("event".equals(request.get("type")))
device = Event.getEvent(db, id); device = Event.getEvent(db, id);
device.setX(Float.parseFloat(request.get("x"))); device.setMapCoordinates(Float.parseFloat(request.get("x")), Float.parseFloat(request.get("y")));
device.setY(Float.parseFloat(request.get("y")));
device.save(db); device.save(db);
} }
return root; return root;
@ -78,8 +77,8 @@ public class MapApiEndpoint extends HalApiEndpoint {
DataNode deviceNode = new DataNode(DataNode.DataType.Map); DataNode deviceNode = new DataNode(DataNode.DataType.Map);
deviceNode.set("id", device.getId()); deviceNode.set("id", device.getId());
deviceNode.set("name", device.getName()); deviceNode.set("name", device.getName());
deviceNode.set("x", device.getX()); deviceNode.set("x", device.getMapX());
deviceNode.set("y", device.getY()); deviceNode.set("y", device.getMapY());
return deviceNode; return deviceNode;
} }

View file

@ -0,0 +1,73 @@
package se.hal.page.api;
import se.hal.HalContext;
import se.hal.intf.HalApiEndpoint;
import se.hal.struct.Room;
import zutil.ArrayUtil;
import zutil.ObjectUtil;
import zutil.db.DBConnection;
import zutil.log.LogUtil;
import zutil.parser.DataNode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
* REST service to fetch event device information.
*/
public class RoomApiEndpoint extends HalApiEndpoint {
private static final Logger logger = LogUtil.getLogger();
public RoomApiEndpoint() {
super("api/room");
}
@Override
public DataNode jsonRespond(
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request) throws Exception{
DBConnection db = HalContext.getDB();
DataNode root = new DataNode(DataNode.DataType.List);
// --------------------------------------
// Get Action
// --------------------------------------
String[] req_ids = new String[0];
if (request.get("id") != null)
req_ids = request.get("id").split(",");
// Filter devices
List<Room> rooms = new ArrayList<>();
for (Room room : Room.getRooms(db)) {
boolean filter_match = true;
// id filtering
if (!ObjectUtil.isEmpty(req_ids) && !ArrayUtil.contains(req_ids, "" + room.getId())) {
filter_match = false;
}
// Check the filter
if (filter_match) {
rooms.add(room);
}
}
// --------------------------------------
// Generate DataNode
// --------------------------------------
for (Room room : rooms) {
DataNode deviceNode = room.getDataNode();
root.add(deviceNode);
}
return root;
}
}

View file

@ -14,17 +14,19 @@
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.EventApiEndpoint"}, {"se.hal.intf.HalApiEndpoint": "se.hal.page.api.EventApiEndpoint"},
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.MapApiEndpoint"}, {"se.hal.intf.HalApiEndpoint": "se.hal.page.api.MapApiEndpoint"},
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.RoomApiEndpoint"},
{"se.hal.intf.HalApiEndpoint": "se.hal.page.api.SensorApiEndpoint"}, {"se.hal.intf.HalApiEndpoint": "se.hal.page.api.SensorApiEndpoint"},
{"se.hal.intf.HalWebPage": "se.hal.page.MapWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.SensorOverviewWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.SensorConfigWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.EventOverviewWebPage"}, {"se.hal.intf.HalWebPage": "se.hal.page.EventOverviewWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.EventConfigWebPage"}, {"se.hal.intf.HalWebPage": "se.hal.page.EventConfigWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.TriggerWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.UserConfigWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.PropertyConfigWebPage"}, {"se.hal.intf.HalWebPage": "se.hal.page.PropertyConfigWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.PluginConfigWebPage"}, {"se.hal.intf.HalWebPage": "se.hal.page.PluginConfigWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.MapWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.RoomConfigWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.SensorOverviewWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.SensorConfigWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.TriggerWebPage"},
{"se.hal.intf.HalWebPage": "se.hal.page.UserConfigWebPage"},
{"se.hal.intf.HalTrigger": "se.hal.trigger.DateTimeTrigger"}, {"se.hal.intf.HalTrigger": "se.hal.trigger.DateTimeTrigger"},

View file

@ -0,0 +1,92 @@
package se.hal.struct;
import zutil.db.DBConnection;
import zutil.db.bean.DBBean;
import zutil.db.bean.DBBeanSQLResultHandler;
import zutil.parser.DataNode;
import zutil.ui.UserMessageManager.UserMessage;
import zutil.ui.conf.Configurator;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
/**
* Class represents a physical room.
*/
public class Room extends DBBean {
private transient UserMessage roomAlert;
private String name = "";
@DBColumn("map_x")
private double mapX = 0;
@DBColumn("map_y")
private double mapY = 0;
@DBColumn("map_width")
private double mapWidth = 10.0;
@DBColumn("map_height")
private double mapHeight = 10.0;
public static List<Room> getRooms(DBConnection db) throws SQLException {
PreparedStatement stmt = db.getPreparedStatement( "SELECT * FROM room" );
return DBConnection.exec(stmt, DBBeanSQLResultHandler.createList(Room.class, db) );
}
public static Room getRoom(DBConnection db, int id) throws SQLException {
return DBBean.load(db, Room.class, id);
}
public UserMessage getRoomAlert() {
return roomAlert;
}
public void clearRoomAlert() {
setRoomAlert(null);
}
public void setRoomAlert(UserMessage roomAlert) {
this.roomAlert = roomAlert;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMapX() {
return mapX;
}
public double getMapY() {
return mapY;
}
public double getMapWidth() {
return mapWidth;
}
public double getMapHeight() {
return mapHeight;
}
public void setMapCoordinates(double x, double y, double width, double height) {
this.mapX = x;
this.mapY = y;
this.mapWidth = width;
this.mapHeight = height;
}
public DataNode getDataNode() {
DataNode deviceNode = new DataNode(DataNode.DataType.Map);
deviceNode.set("id", getId());
deviceNode.set("name", getName());
DataNode mapNode = deviceNode.set("map", DataNode.DataType.Map);
mapNode.set("x", getMapX());
mapNode.set("y", getMapY());
mapNode.set("width", getMapWidth());
mapNode.set("height", getMapHeight());
return deviceNode;
}
}

View file

@ -24,8 +24,11 @@ public class Sensor extends HalAbstractDevice<Sensor, HalSensorConfig, HalSensor
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private long external_id = -1; private long external_id = -1;
/** local sensor= if sensor should be public. external sensor= if sensor should be requested from host **/ /** The value of this field represents different things depending on if it is a local device or not:
* - local sensor: if sensor should be public to external users.
* - external sensor: if sensor should be requested from host **/
private boolean sync = false; private boolean sync = false;
/** Indicates how far a sync has proceeded, is used to be able to do differential sync. */
private long aggr_version; private long aggr_version;

View file

@ -0,0 +1,70 @@
package se.hal.util;
import se.hal.HalContext;
import se.hal.struct.Room;
import zutil.Timer;
import zutil.db.DBConnection;
import zutil.log.LogUtil;
import zutil.ui.conf.Configurator;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A value provider that will give all Rooms as selection option
*/
public class RoomValueProvider implements Configurator.ConfigValueProvider<Room> {
private static final Logger logger = LogUtil.getLogger();
private static int REFRESH_TIME_IN_SECONDS = 3;
private Map<String, Room> rooms = new HashMap<>();
private Timer updateTimer = new Timer(REFRESH_TIME_IN_SECONDS * 1000);
public RoomValueProvider() {
refreshEventMap();
}
private void refreshEventMap() {
if (!updateTimer.hasTimedOut())
return;
try {
DBConnection db = HalContext.getDB();
for (Room room : Room.getRooms(db)) {
rooms.put(getValue(room), room);
}
updateTimer.start();
} catch (SQLException e) {
logger.log(Level.SEVERE, "Unable to retrieve rooms.", e);
}
}
@Override
public String getValue(Room room) {
return (room != null ?
room.getName() + " (id: " + room.getId() + ")" :
null);
}
@Override
public List<String> getPossibleValues() {
refreshEventMap();
return new ArrayList<>(rooms.keySet());
}
@Override
public Room getObject(String value) {
return rooms.get(value);
}
}

View file

@ -4,7 +4,7 @@
<div class="panel panel-default drop-shadow"> <div class="panel panel-default drop-shadow">
<div class="panel-heading">Cameras</div> <div class="panel-heading">Cameras</div>
<div class="panel-body"> <div class="panel-body">
<p>This is a list of cameras connected to this node.</p> <p>This is a list of all cameras connected to this server.</p>
<table class="table table-hover table-condensed"> <table class="table table-hover table-condensed">
<thead> <thead>
@ -33,6 +33,7 @@
data-target="#cameraModal" data-target="#cameraModal"
data-action="modify_camera" data-action="modify_camera"
data-id="{{.getId()}}" data-id="{{.getId()}}"
data-room-id="{{.getRoom().getId()}}"
data-name="{{.getName()}}" data-name="{{.getName()}}"
data-type="{{.getType()}}" data-type="{{.getType()}}"
{{#.getDeviceConfigurator().getConfiguration()}} {{#.getDeviceConfigurator().getConfiguration()}}
@ -75,6 +76,16 @@
<div class="modal-body"> <div class="modal-body">
<input type="hidden" id="action" name="action"> <input type="hidden" id="action" name="action">
<input type="hidden" id="id" name="id"> <input type="hidden" id="id" name="id">
<div class="form-group">
<label class="control-label">Located in room:</label>
<select class="form-control" name="room-id">
<option value=""></option>
{{#rooms}}
<option value="{{.getId()}}">{{.getName()}} (id: {{.getId()}})</option>
{{/rooms}}
</select>
</div>
<div class="form-group"> <div class="form-group">
<label class="control-label">Name:</label> <label class="control-label">Name:</label>
<input type="text" class="form-control" name="name"> <input type="text" class="form-control" name="name">

View file

@ -7,7 +7,7 @@ import se.hal.intf.HalDatabaseUpgrader;
* The DB upgrade class for Hal-NVR plugin * The DB upgrade class for Hal-NVR plugin
*/ */
public class NVRDatabaseUpgrader extends HalDatabaseUpgrader { public class NVRDatabaseUpgrader extends HalDatabaseUpgrader {
private static final int REFERENCE_DB_VERSION = 1; private static final int REFERENCE_DB_VERSION = 2;
private static final String REFERENCE_DB_PATH = HalContext.RESOURCE_ROOT + "/resource/hal-nvr-reference.db"; private static final String REFERENCE_DB_PATH = HalContext.RESOURCE_ROOT + "/resource/hal-nvr-reference.db";

View file

@ -30,8 +30,10 @@ import se.hal.intf.HalWebPage;
import se.hal.page.HalAlertManager; import se.hal.page.HalAlertManager;
import se.hal.plugin.nvr.CameraControllerManager; import se.hal.plugin.nvr.CameraControllerManager;
import se.hal.plugin.nvr.struct.Camera; import se.hal.plugin.nvr.struct.Camera;
import se.hal.struct.Room;
import se.hal.util.ClassConfigurationFacade; import se.hal.util.ClassConfigurationFacade;
import se.hal.struct.User; import se.hal.struct.User;
import se.hal.util.RoomValueProvider;
import zutil.ObjectUtil; import zutil.ObjectUtil;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
@ -73,12 +75,27 @@ public class CameraConfigWebPage extends HalWebPage {
// Save new input // Save new input
if (request.containsKey("action")){ if (request.containsKey("action")){
int id = (ObjectUtil.isEmpty(request.get("id")) ? -1 : Integer.parseInt(request.get("id"))); int id = (ObjectUtil.isEmpty(request.get("id")) ? -1 : Integer.parseInt(request.get("id")));
Camera camera; int roomId = (ObjectUtil.isEmpty(request.get("room-id")) ? -1 : Integer.parseInt(request.get("room-id")));
Camera camera = null;
Room room = (roomId >= 0 ? Room.getRoom(db, roomId) : null);
if (id >= 0) {
// Read in requested id
camera = Camera.getCamera(db, id);
if (camera == null) {
logger.warning("Unknown camera id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown camera id: " + id, MessageTTL.ONE_VIEW));
}
}
switch(request.get("action")) { switch(request.get("action")) {
case "create_camera": case "create_camera":
logger.info("Creating new camera: " + request.get("name")); logger.info("Creating new camera: " + request.get("name"));
camera = new Camera(); camera = new Camera();
camera.setRoom(room);
camera.setName(request.get("name")); camera.setName(request.get("name"));
camera.setType(request.get("type")); camera.setType(request.get("type"));
camera.setUser(localUser); camera.setUser(localUser);
@ -91,9 +108,9 @@ public class CameraConfigWebPage extends HalWebPage {
break; break;
case "modify_camera": case "modify_camera":
camera = Camera.getCamera(db, id);
if (camera != null) { if (camera != null) {
logger.info("Modifying camera: " + camera.getName()); logger.info("Modifying camera(id: " + camera.getId() + "): " + camera.getName());
camera.setRoom(room);
camera.setName(request.get("name")); camera.setName(request.get("name"));
camera.setType(request.get("type")); camera.setType(request.get("type"));
camera.setUser(localUser); camera.setUser(localUser);
@ -102,26 +119,17 @@ public class CameraConfigWebPage extends HalWebPage {
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully saved camera: " + camera.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully saved camera: " + camera.getName(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown camera id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown camera id: " + id, MessageTTL.ONE_VIEW));
} }
break; break;
case "remove_camera": case "remove_camera":
camera = Camera.getCamera(db, id);
if (camera != null) { if (camera != null) {
logger.info("Removing camera: " + camera.getName()); logger.info("Removing camera(id: " + camera.getId() + "): " + camera.getName());
CameraControllerManager.getInstance().deregister(camera); CameraControllerManager.getInstance().deregister(camera);
camera.delete(db); camera.delete(db);
HalAlertManager.getInstance().addAlert(new UserMessage( HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.SUCCESS, "Successfully removed camera: " + camera.getName(), MessageTTL.ONE_VIEW)); MessageLevel.SUCCESS, "Successfully removed camera: " + camera.getName(), MessageTTL.ONE_VIEW));
} else {
logger.warning("Unknown camera id: " + id);
HalAlertManager.getInstance().addAlert(new UserMessage(
MessageLevel.ERROR, "Unknown camera id: " + id, MessageTTL.ONE_VIEW));
} }
break; break;
} }
@ -129,6 +137,7 @@ public class CameraConfigWebPage extends HalWebPage {
// Output // Output
Templator tmpl = new Templator(FileUtil.find(TEMPLATE)); Templator tmpl = new Templator(FileUtil.find(TEMPLATE));
tmpl.set("rooms", Room.getRooms(db));
tmpl.set("cameras", Camera.getCameras(db)); tmpl.set("cameras", Camera.getCameras(db));
tmpl.set("availableCameraConfigClasses", CameraControllerManager.getInstance().getAvailableDeviceConfigs()); tmpl.set("availableCameraConfigClasses", CameraControllerManager.getInstance().getAvailableDeviceConfigs());
tmpl.set("availableCameraObjectConfig", cameraConfigurations); tmpl.set("availableCameraObjectConfig", cameraConfigurations);