2019-09-15 15:03:44 -04:00
package com.chameleonvision.web ;
2019-09-10 23:47:06 +03:00
2019-09-16 04:10:26 +03:00
import com.chameleonvision.NoCameraException ;
2019-09-15 15:03:44 -04:00
import com.chameleonvision.settings.SettingsManager ;
2019-09-16 04:10:26 +03:00
import com.chameleonvision.vision.GeneralSettings ;
2019-09-15 15:22:52 -04:00
import com.chameleonvision.vision.Pipeline ;
2019-09-16 04:10:26 +03:00
import com.google.gson.JsonObject ;
2019-09-10 23:47:06 +03:00
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 ;
2019-09-16 04:10:26 +03:00
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
2019-09-10 23:47:06 +03:00
public class Server {
2019-09-11 20:28:56 +03:00
private static List < WsContext > users = new ArrayList < WsContext > ( ) ;
2019-09-16 04:10:26 +03:00
2019-09-10 23:47:06 +03:00
public static void main ( int port ) {
2019-09-11 20:28:56 +03:00
Javalin app = Javalin . create ( ) ;
app . config . addStaticFiles ( " web " ) ;
2019-09-16 04:10:26 +03:00
app . ws ( " /websocket " , ws - > {
2019-09-11 20:28:56 +03:00
ws . onConnect ( ctx - > {
users . add ( ctx ) ;
System . out . println ( " Socket Connected " ) ;
2019-09-16 04:10:26 +03:00
sendFullSettings ( ) ;
2019-09-11 20:28:56 +03:00
} ) ;
ws . onClose ( ctx - > {
users . remove ( ctx ) ;
System . out . println ( " Socket Disconnected " ) ;
2019-09-14 12:45:00 +03:00
SettingsManager . getInstance ( ) . SaveSettings ( ) ;
2019-09-11 20:28:56 +03:00
} ) ;
ws . onMessage ( ctx - > {
2019-09-16 04:10:26 +03:00
// 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 ;
2019-09-17 02:12:53 -04:00
var jsonKeySetArray = jsonObject . keySet ( ) . toArray ( ) ;
2019-09-16 11:45:56 -04:00
try {
2019-09-17 02:12:53 -04:00
key = jsonKeySetArray [ 0 ] . toString ( ) ;
2019-09-16 11:45:56 -04:00
} catch ( Exception ex ) {
2019-09-17 02:12:53 -04:00
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 ) ;
2019-09-17 02:12:53 -04:00
// System.out.printf("Got websocket json data: [%s, %s]\n", key, value);
2019-09-16 04:10:26 +03:00
if ( ! setField ( SettingsManager . getInstance ( ) . GetCurrentPipeline ( ) , key , value ) ) {
//If field not in pipeline
switch ( key ) {
case " change_general_settings_values " :
JSONObject newSettings = ( JSONObject ) value ;
2019-09-17 02:12:53 -04:00
setFields ( SettingsManager . GeneralSettings , newSettings ) ;
2019-09-16 04:10:26 +03:00
break ;
case " curr_camera " :
2019-09-17 02:12:53 -04:00
String newCamera = ( String ) value ;
System . out . printf ( " Changing camera to %s \ n " , newCamera ) ;
SettingsManager . getInstance ( ) . SetCurrentCamera ( newCamera ) ;
2019-09-16 04:10:26 +03:00
//broadcastMessage((Map<String, Object>) new HashMap<String, Object>(){}.put("port",SettingsManager.CameraPorts.get(SettingsManager.GeneralSettings.curr_camera)));
2019-09-17 02:12:53 -04:00
//broadcastMessage(ctx, SettingsManager.getInstance().GetCurrentCamera()); //TODO CHECK JSON FOR CAMERA CHANGE
2019-09-16 04:10:26 +03:00
break ;
case " curr_pipeline " :
2019-09-17 02:12:53 -04:00
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 ) ;
2019-09-16 04:10:26 +03:00
break ;
case " resolution " :
2019-09-17 02:12:53 -04:00
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 ) ;
2019-09-16 04:10:26 +03:00
SettingsManager . getInstance ( ) . SaveSettings ( ) ;
break ;
case " fov " :
2019-09-17 02:12:53 -04:00
double newFov = ( double ) value ;
System . out . printf ( " Changing FOV to %d \ n " , newFov ) ;
SettingsManager . getInstance ( ) . GetCurrentCamera ( ) . FOV = newFov ;
2019-09-16 04:10:26 +03:00
SettingsManager . getInstance ( ) . SaveSettings ( ) ;
break ;
default :
2019-09-17 02:12:53 -04:00
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 ( ) ;
2019-09-16 04:10:26 +03:00
break ;
2019-09-15 01:55:29 +03:00
}
}
2019-09-11 20:28:56 +03:00
} ) ;
} ) ;
app . start ( port ) ;
}
2019-09-16 04:10:26 +03:00
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 ;
}
2019-09-16 18:50:00 +03:00
private static void broadcastMessage ( WsContext sendingUser , Object obj ) { //TODO chekc if session id is a good way to differentiate users
2019-09-16 04:10:26 +03:00
for ( var user : users ) {
2019-09-17 02:12:53 -04:00
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-10 23:47:06 +03:00
}
2019-09-11 20:28:56 +03:00
2019-09-16 04:10:26 +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-16 04:10:26 +03:00
}
2019-09-15 01:55:29 +03:00
2019-09-10 23:47:06 +03:00
}