2019-09-21 16:04:58 +03:00
|
|
|
package com.chameleonvision.web;
|
|
|
|
|
|
2019-10-14 21:22:43 +03:00
|
|
|
import com.chameleonvision.settings.GeneralSettings;
|
2019-10-14 22:36:56 +03:00
|
|
|
import com.chameleonvision.vision.*;
|
2019-10-14 21:22:43 +03:00
|
|
|
import com.chameleonvision.vision.camera.Camera;
|
2019-10-04 15:55:45 -04:00
|
|
|
import com.chameleonvision.vision.camera.CameraException;
|
2019-09-21 16:04:58 +03:00
|
|
|
import com.chameleonvision.settings.SettingsManager;
|
|
|
|
|
import com.chameleonvision.vision.camera.CameraManager;
|
2019-10-14 11:21:20 +03:00
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
2019-10-13 21:58:34 +03:00
|
|
|
import edu.wpi.cscore.VideoException;
|
2019-10-11 02:25:25 +03:00
|
|
|
import io.javalin.websocket.*;
|
2019-10-14 11:21:20 +03:00
|
|
|
|
2019-10-11 02:25:25 +03:00
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
2019-10-14 11:21:20 +03:00
|
|
|
import org.msgpack.jackson.dataformat.MessagePackFactory;
|
2019-10-14 21:22:43 +03:00
|
|
|
import org.springframework.beans.BeanUtils;
|
2019-10-13 22:59:36 +03:00
|
|
|
|
2019-10-14 11:21:20 +03:00
|
|
|
import java.io.IOException;
|
2019-09-21 16:04:58 +03:00
|
|
|
import java.lang.reflect.Field;
|
2019-10-14 23:35:29 +03:00
|
|
|
import java.lang.reflect.ParameterizedType;
|
2019-10-14 11:21:20 +03:00
|
|
|
import java.nio.ByteBuffer;
|
2019-10-11 02:25:25 +03:00
|
|
|
import java.util.*;
|
2019-09-21 16:04:58 +03:00
|
|
|
|
2019-10-12 03:38:42 +03:00
|
|
|
|
2019-09-21 16:04:58 +03:00
|
|
|
public class ServerHandler {
|
|
|
|
|
|
|
|
|
|
private static List<WsContext> users;
|
2019-10-14 11:21:20 +03:00
|
|
|
private static ObjectMapper objectMapper;
|
2019-09-21 16:04:58 +03:00
|
|
|
|
2019-09-21 13:05:00 -04:00
|
|
|
ServerHandler() {
|
|
|
|
|
users = new ArrayList<>();
|
2019-10-14 11:21:20 +03:00
|
|
|
objectMapper = new ObjectMapper(new MessagePackFactory());
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
|
2019-09-21 13:05:00 -04:00
|
|
|
void onConnect(WsConnectContext context) {
|
2019-09-21 16:04:58 +03:00
|
|
|
users.add(context);
|
|
|
|
|
sendFullSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onClose(WsCloseContext context) {
|
|
|
|
|
users.remove(context);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-14 22:24:37 +03:00
|
|
|
void onBinaryMessage(WsBinaryMessageContext context) throws Exception {
|
|
|
|
|
Map<String, Object> deserialized = objectMapper.readValue(ArrayUtils.toPrimitive(context.data()), new TypeReference<Map<String,Object>>(){});
|
2019-10-14 11:21:20 +03:00
|
|
|
for (Map.Entry<String,Object> entry: deserialized.entrySet()) {
|
2019-10-13 21:58:34 +03:00
|
|
|
try {
|
2019-10-14 11:21:20 +03:00
|
|
|
switch (entry.getKey()) {
|
2019-10-13 22:59:36 +03:00
|
|
|
case "generalSettings": {
|
2019-10-15 21:00:18 +03:00
|
|
|
for (HashMap.Entry<String,Object> e : ((HashMap<String,Object>)entry.getValue()).entrySet()){
|
|
|
|
|
setField(SettingsManager.GeneralSettings,e.getKey(),e.getValue());
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "cameraSettings": {
|
2019-10-16 08:10:06 +03:00
|
|
|
HashMap camSettings = (HashMap)entry.getValue();
|
2019-10-16 14:13:12 +03:00
|
|
|
CameraManager.getCurrentCamera().setFOV((Number)camSettings.get("fov"));
|
2019-10-16 08:10:06 +03:00
|
|
|
CameraManager.getCurrentCamera().setStreamDivisor((Integer) camSettings.get("streamDivisor"));
|
|
|
|
|
CameraManager.getCurrentCamera().setCamVideoMode((Integer) camSettings.get("resolution"),true);
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-19 17:45:40 +03:00
|
|
|
case "changeCameraName":{
|
|
|
|
|
// needs to be implemented
|
|
|
|
|
}
|
|
|
|
|
case "changePipelineName":{
|
|
|
|
|
// needs to be implemented
|
|
|
|
|
}
|
|
|
|
|
case "duplicatePipeline":{
|
|
|
|
|
// needs to be implemented
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
case "command": {
|
2019-10-19 16:58:10 +03:00
|
|
|
switch ((String) entry.getValue()){
|
|
|
|
|
case "addNewPipeline":
|
|
|
|
|
CameraManager.getCurrentCamera().addPipeline();
|
|
|
|
|
break;
|
|
|
|
|
case "deleteCurrentPipeline":
|
|
|
|
|
var cam = CameraManager.getCurrentCamera();
|
|
|
|
|
CameraManager.getCurrentCamera().deleteCurrentPipeline();
|
|
|
|
|
CameraManager.getCurrentCamera().setCurrentPipelineIndex(cam.getCurrentPipelineIndex() -1);
|
|
|
|
|
sendFullSettings();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
// used to define all incoming commands
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "currentCamera": {
|
2019-10-14 21:22:43 +03:00
|
|
|
CameraManager.setCurrentCamera((String) entry.getValue());
|
|
|
|
|
HashMap<String,Object> tmp = new HashMap<>();
|
|
|
|
|
tmp.put("pipeline",CameraManager.getCurrentCamera().getCurrentPipeline());
|
2019-10-16 08:10:06 +03:00
|
|
|
tmp.put("port", CameraManager.getCurrentCamera().getStreamPort());
|
|
|
|
|
tmp.put("resolutionList",CameraManager.getResolutionList());
|
2019-10-14 21:22:43 +03:00
|
|
|
broadcastMessage(tmp);
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "currentPipeline": {
|
2019-10-14 21:22:43 +03:00
|
|
|
CameraManager.getCurrentCamera().setCurrentPipelineIndex((Integer) entry.getValue());
|
|
|
|
|
HashMap<String,Object> tmp = new HashMap<>();
|
2019-10-14 23:35:29 +03:00
|
|
|
tmp.put("pipeline",getOrdinalPipeline());
|
2019-10-14 21:22:43 +03:00
|
|
|
broadcastMessage(tmp);
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
default: {
|
|
|
|
|
setField(CameraManager.getCurrentCamera().getCurrentPipeline(),entry.getKey(),entry.getValue());
|
2019-10-14 23:35:29 +03:00
|
|
|
switch (entry.getKey()){
|
|
|
|
|
case "exposure":{
|
2019-10-16 14:13:12 +03:00
|
|
|
try{
|
|
|
|
|
CameraManager.getCurrentCamera().setExposure((Integer) entry.getValue());
|
|
|
|
|
} catch (Exception e){
|
|
|
|
|
System.err.println("Camera Does not support exposure change");
|
|
|
|
|
}
|
2019-10-14 23:35:29 +03:00
|
|
|
}
|
|
|
|
|
case "brightness":{
|
|
|
|
|
CameraManager.getCurrentCamera().setBrightness((Integer) entry.getValue());
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
2019-10-13 21:58:34 +03:00
|
|
|
}
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
} catch (Exception e) {
|
2019-10-19 16:58:10 +03:00
|
|
|
System.err.println(e.getMessage());
|
2019-10-13 21:58:34 +03:00
|
|
|
}
|
2019-10-14 22:24:37 +03:00
|
|
|
broadcastMessage(deserialized,context);
|
2019-10-12 03:38:42 +03:00
|
|
|
}
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
private void setField(Object obj, String fieldName, Object value) {
|
2019-09-21 16:04:58 +03:00
|
|
|
try {
|
2019-10-14 21:22:43 +03:00
|
|
|
Field field = obj.getClass().getField(fieldName);
|
|
|
|
|
if (BeanUtils.isSimpleValueType(field.getType())){
|
2019-10-14 22:24:37 +03:00
|
|
|
if (field.getType().isEnum()){
|
|
|
|
|
field.set(obj,field.getType().getEnumConstants()[(Integer) value]);
|
|
|
|
|
}else{
|
|
|
|
|
field.set(obj,value);
|
|
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
} else if(field.getType() == List.class){
|
2019-10-14 23:35:29 +03:00
|
|
|
// if(((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0] == Double.class){
|
|
|
|
|
field.set(obj,value);
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
} catch (NoSuchFieldException | IllegalAccessException ex) {
|
|
|
|
|
ex.printStackTrace();
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-12 03:38:42 +03:00
|
|
|
private static void broadcastMessage(Object obj, WsContext userToSkip) {
|
|
|
|
|
if (users != null)
|
|
|
|
|
for (var user : users) {
|
|
|
|
|
if (userToSkip != null && user.getSessionId().equals(userToSkip.getSessionId())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-10-14 11:21:20 +03:00
|
|
|
try{
|
|
|
|
|
ByteBuffer b = ByteBuffer.wrap(objectMapper.writeValueAsBytes(obj));
|
|
|
|
|
user.send(b);
|
|
|
|
|
} catch (JsonProcessingException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
2019-10-12 03:38:42 +03:00
|
|
|
}
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
|
2019-10-16 14:13:12 +03:00
|
|
|
public static void broadcastMessage(Object obj) {
|
2019-10-11 02:25:25 +03:00
|
|
|
broadcastMessage(obj, null);//Broadcasts the message to every user
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
|
2019-10-15 21:00:18 +03:00
|
|
|
private static HashMap<String,Object> getOrdinalPipeline() throws CameraException, IllegalAccessException {
|
2019-10-14 22:36:56 +03:00
|
|
|
HashMap<String,Object> tmp = new HashMap<>();
|
|
|
|
|
for (Field f : Pipeline.class.getFields()){
|
|
|
|
|
if (!f.getType().isEnum()){
|
|
|
|
|
tmp.put(f.getName(),f.get(CameraManager.getCurrentCamera().getCurrentPipeline()));
|
|
|
|
|
} else{
|
|
|
|
|
var i = (Enum) f.get(CameraManager.getCurrentCamera().getCurrentPipeline());
|
|
|
|
|
tmp.put(f.getName(),i.ordinal());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
2019-10-16 14:13:12 +03:00
|
|
|
private static HashMap<String,Object> getOrdinalSettings(){
|
2019-10-15 21:00:18 +03:00
|
|
|
HashMap<String,Object> tmp = new HashMap<>();
|
|
|
|
|
tmp.put("teamNumber",SettingsManager.GeneralSettings.teamNumber);
|
|
|
|
|
tmp.put("connectionType",SettingsManager.GeneralSettings.connectionType.ordinal());
|
|
|
|
|
tmp.put("ip",SettingsManager.GeneralSettings.ip);
|
|
|
|
|
tmp.put("gateway",SettingsManager.GeneralSettings.gateway);
|
|
|
|
|
tmp.put("netmask",SettingsManager.GeneralSettings.netmask);
|
|
|
|
|
tmp.put("hostname",SettingsManager.GeneralSettings.hostname);
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
2019-10-16 14:13:12 +03:00
|
|
|
private static HashMap<String ,Object> getOrdinalCameraSettings(){
|
|
|
|
|
HashMap<String,Object> tmp = new HashMap<>();
|
|
|
|
|
try {
|
|
|
|
|
var currentCamera = CameraManager.getCurrentCamera();
|
|
|
|
|
tmp.put("fov",currentCamera.getFOV());
|
|
|
|
|
tmp.put("streamDivisor",currentCamera.getStreamDivisor().ordinal());
|
|
|
|
|
tmp.put("resolution",currentCamera.getVideoModeIndex());
|
|
|
|
|
} catch (CameraException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
2019-09-22 02:49:30 -04:00
|
|
|
public static void sendFullSettings() {
|
2019-09-21 16:04:58 +03:00
|
|
|
//General settings
|
2019-10-15 21:00:18 +03:00
|
|
|
Map<String, Object> fullSettings = new HashMap<>();
|
2019-09-21 16:04:58 +03:00
|
|
|
try {
|
2019-10-15 21:00:18 +03:00
|
|
|
fullSettings.put("settings", getOrdinalSettings());
|
2019-10-16 14:13:12 +03:00
|
|
|
fullSettings.put("cameraSettings",getOrdinalCameraSettings());
|
2019-10-15 21:00:18 +03:00
|
|
|
fullSettings.put("cameraList", CameraManager.getAllCamerasByName().keySet());
|
2019-09-21 16:04:58 +03:00
|
|
|
var currentCamera = CameraManager.getCurrentCamera();
|
2019-10-14 22:36:56 +03:00
|
|
|
fullSettings.put("pipeline", getOrdinalPipeline());
|
2019-09-21 16:04:58 +03:00
|
|
|
fullSettings.put("pipelineList", currentCamera.getPipelines().keySet());
|
|
|
|
|
fullSettings.put("resolutionList", CameraManager.getResolutionList());
|
2019-09-22 02:49:30 -04:00
|
|
|
fullSettings.put("port", currentCamera.getStreamPort());
|
2019-10-14 22:36:56 +03:00
|
|
|
} catch (CameraException | IllegalAccessException e) {
|
2019-09-21 16:04:58 +03:00
|
|
|
System.err.println("No camera found!");
|
|
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
broadcastMessage(fullSettings);
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
}
|