Files
PhotonVision/Main/src/main/java/com/chameleonvision/web/Server.java

195 lines
9.1 KiB
Java
Raw Normal View History

package com.chameleonvision.web;
import com.chameleonvision.NoCameraException;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.vision.GeneralSettings;
import com.chameleonvision.vision.Pipeline;
import com.google.gson.JsonObject;
import io.javalin.Javalin;
2019-09-11 20:28:56 +03:00
import io.javalin.websocket.WsContext;
2019-09-15 01:55:29 +03:00
import java.lang.reflect.Field;
import java.util.*;
2019-09-15 01:55:29 +03:00
import org.json.JSONArray;
2019-09-11 20:28:56 +03:00
import org.json.JSONObject;
2019-09-15 01:55:29 +03:00
import org.springframework.beans.BeanUtils;
2019-09-11 20:28:56 +03:00
public class Server {
2019-09-11 20:28:56 +03:00
private static List<WsContext> users = new ArrayList<WsContext>();
public static void main(int port) {
2019-09-11 20:28:56 +03:00
Javalin app = Javalin.create();
app.config.addStaticFiles("web");
app.ws("/websocket", ws -> {
2019-09-11 20:28:56 +03:00
ws.onConnect(ctx -> {
users.add(ctx);
System.out.println("Socket Connected");
sendFullSettings();
2019-09-11 20:28:56 +03:00
});
ws.onClose(ctx -> {
users.remove(ctx);
System.out.println("Socket Disconnected");
SettingsManager.getInstance().SaveSettings();
2019-09-11 20:28:56 +03:00
});
ws.onMessage(ctx -> {
// System.out.println(SettingsManager.getInstance().GetCurrentPipeline().);
2019-09-11 20:28:56 +03:00
broadcastMessage(ctx, ctx.message());
2019-09-15 01:55:29 +03:00
JSONObject jsonObject = new JSONObject(ctx.message());
2019-09-16 11:45:56 -04:00
String key = null;
var jsonKeySetArray = jsonObject.keySet().toArray();
2019-09-16 11:45:56 -04:00
try {
key = jsonKeySetArray[0].toString();
2019-09-16 11:45:56 -04:00
} catch (Exception ex) {
System.err.println("WebSocket JSON data was empty!");
2019-09-16 11:45:56 -04:00
}
if (key == null) return;
2019-09-15 01:55:29 +03:00
Object value = jsonObject.get(key);
// System.out.printf("Got websocket json data: [%s, %s]\n", key, value);
if (!setField(SettingsManager.getInstance().GetCurrentPipeline(), key, value)) {
//If field not in pipeline
switch (key) {
case "change_general_settings_values":
JSONObject newSettings = (JSONObject) value;
setFields(SettingsManager.GeneralSettings, newSettings);
break;
case "curr_camera":
String newCamera = (String) value;
System.out.printf("Changing camera to %s\n", newCamera);
SettingsManager.getInstance().SetCurrentCamera(newCamera);
//broadcastMessage((Map<String, Object>) new HashMap<String, Object>(){}.put("port",SettingsManager.CameraPorts.get(SettingsManager.GeneralSettings.curr_camera)));
//broadcastMessage(ctx, SettingsManager.getInstance().GetCurrentCamera()); //TODO CHECK JSON FOR CAMERA CHANGE
break;
case "curr_pipeline":
String newPipeline = (String) value;
System.out.printf("Changing pipeline to %s\n", newPipeline);
SettingsManager.getInstance().SetCurrentPipeline(newPipeline);
SettingsManager.CamerasCurrentPipeline.put(SettingsManager.GeneralSettings.curr_camera, newPipeline);
break;
case "resolution":
int newResolution = (int) value;
System.out.printf("Changing resolution mode to %d\n", newResolution);
SettingsManager.getInstance().GetCurrentCamera().resolution = newResolution;
SettingsManager.getInstance().SetCameraSettings(SettingsManager.GeneralSettings.curr_camera, "resolution", newResolution);
SettingsManager.getInstance().SaveSettings();
break;
case "fov":
double newFov = (double) value;
System.out.printf("Changing FOV to %d\n", newFov);
SettingsManager.getInstance().GetCurrentCamera().FOV = newFov;
SettingsManager.getInstance().SaveSettings();
break;
default:
System.out.printf("Unexpected value from websocket: [%s, %s]\n", key, value);
break;
}
} else { //
switch (key) {
case "exposure":
int newExposure = (int) value;
System.out.printf("Changing exposure to %d\n", newExposure);
SettingsManager.getInstance().GetCurrentPipeline().exposure = newExposure;
SettingsManager.getInstance().GetCurrentUsbCamera().setExposureManual(newExposure);
SettingsManager.getInstance().SaveSettings();
break;
case "brightness":
int newBrightness = (int) value;
System.out.printf("Changing brightness to %d\n", newBrightness);
SettingsManager.getInstance().GetCurrentPipeline().brightness = newBrightness;
SettingsManager.getInstance().GetCurrentUsbCamera().setBrightness(newBrightness);
SettingsManager.getInstance().SaveSettings();
break;
2019-09-15 01:55:29 +03:00
}
}
2019-09-11 20:28:56 +03:00
});
});
app.start(port);
}
public static boolean setField(Object obj, String fieldName, Object value) {
boolean successful = false;
try {
Field[] fields = obj.getClass().getFields();
for (Field f : fields) {
if (f.getName().equals(fieldName)) {
successful = true;
if (BeanUtils.isSimpleValueType(value.getClass())) {
f.set(obj, value);
} else if (value.getClass() == JSONArray.class) {
f.set(obj, ((JSONArray) value).toList());
}
}
}
} catch (IllegalAccessException e) {
return false;
}
return successful;
}
public static boolean setFields(Object obj, JSONObject data) {
boolean successful = false;
try {
Field[] fields = obj.getClass().getFields();
for (Field f : fields) {
if (data.has(f.getName())) {
Object value = data.get(f.getName());
if (BeanUtils.isSimpleValueType(value.getClass())) {
successful = true;
f.set(obj, value);
}
}
}
} catch (IllegalAccessException e) {
return false;
}
return successful;
}
public static void broadcastMessage(WsContext sendingUser, Object obj) {//TODO chekc if session id is a good way to differentiate users
for (var user : users) {
if (sendingUser!=null&& user.getSessionId().equals(sendingUser.getSessionId())) {
2019-09-16 18:50:00 +03:00
continue;
2019-09-11 20:28:56 +03:00
}
2019-09-16 18:50:00 +03:00
if (obj.getClass() == String.class)
user.send((String) obj);
else if (obj.getClass() == HashMap.class)
user.send(new JSONObject((HashMap<String, Object>) obj).toString());
else
user.send(new JSONObject(obj).toString());
2019-09-11 20:28:56 +03:00
}
}
2019-09-11 20:28:56 +03:00
private static void addAllFieldsToMap(Map<String, Object> map, Object obj) {
try {
Field[] fields = obj.getClass().getFields();
for (Field field : fields)
map.put(field.getName(), field.get(obj));
} catch (IllegalAccessException e) {
System.err.println("Illegal Access error:" + e.getStackTrace().toString());
}
}
private static void sendFullSettings() {
Map<String, Object> fullSettings = new HashMap<>();
//General settings
addAllFieldsToMap(fullSettings, SettingsManager.GeneralSettings);
fullSettings.put("cameraList", SettingsManager.Cameras.keySet());
try {
addAllFieldsToMap(fullSettings, SettingsManager.getInstance().GetCurrentPipeline());
fullSettings.put("pipelineList", SettingsManager.getInstance().GetCurrentCamera().pipelines.keySet());
fullSettings.put("resolutionList", SettingsManager.getInstance().GetResolutionList());
fullSettings.put("resolution", SettingsManager.getInstance().GetCurrentCamera().resolution);
fullSettings.put("FOV", SettingsManager.getInstance().GetCurrentCamera().FOV);
// fullSettings.put("port", SettingsManager.CameraPorts.get(SettingsManager.GeneralSettings.curr_camera));
} catch (NoCameraException e) {
System.err.println("No camera found!");
//TODO: add message to ui to inform that there are no cameras
}
2019-09-16 18:50:00 +03:00
broadcastMessage(null, fullSettings);
}
2019-09-15 01:55:29 +03:00
}