Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
slapos
Commits
3c2ed453
Commit
3c2ed453
authored
May 31, 2023
by
Léo-Paul Géneau
👾
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
software/js-drone: add frontend for subscriber
parent
fa8c3c27
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
386 additions
and
54 deletions
+386
-54
software/js-drone/buildout.hash.cfg
software/js-drone/buildout.hash.cfg
+18
-10
software/js-drone/drone-scripts/main.js.jinja
software/js-drone/drone-scripts/main.js.jinja
+0
-0
software/js-drone/drone-scripts/pubsub.js.jinja
software/js-drone/drone-scripts/pubsub.js.jinja
+0
-0
software/js-drone/drone-scripts/worker.js.jinja
software/js-drone/drone-scripts/worker.js.jinja
+0
-0
software/js-drone/instance-default.cfg.jinja
software/js-drone/instance-default.cfg.jinja
+46
-0
software/js-drone/instance-peer-input-schema.json
software/js-drone/instance-peer-input-schema.json
+0
-0
software/js-drone/instance-peer-output-schema.json
software/js-drone/instance-peer-output-schema.json
+0
-0
software/js-drone/instance-peer.cfg.jinja.in
software/js-drone/instance-peer.cfg.jinja.in
+42
-3
software/js-drone/instance.cfg.in
software/js-drone/instance.cfg.in
+29
-15
software/js-drone/software.cfg
software/js-drone/software.cfg
+21
-21
software/js-drone/software.cfg.json
software/js-drone/software.cfg.json
+5
-5
software/js-drone/test/test.py
software/js-drone/test/test.py
+10
-0
software/js-drone/web-gui/index.html.jinja
software/js-drone/web-gui/index.html.jinja
+120
-0
software/js-drone/web-gui/script.js.jinja
software/js-drone/web-gui/script.js.jinja
+95
-0
No files found.
software/js-drone/buildout.hash.cfg
View file @
3c2ed453
...
@@ -12,26 +12,34 @@
...
@@ -12,26 +12,34 @@
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
# not need these here).
[index-html]
_update_hash_filename_ = web-gui/index.html.jinja
md5sum = d652b1b4769bae17b0b8c92ed233144b
[instance-profile]
[instance-profile]
filename = instance.cfg
filename = instance.cfg
.in
md5sum = c
15e4e308d5669cd87258c841714244f
md5sum = c
7f9de7830c1a6a57ae8683a1d329977
[instance-default]
[instance-default]
filename = instance-default.cfg
filename = instance-default.cfg
.jinja
md5sum =
9a41a0902663fb87d52bc35a03dbcc49
md5sum =
0ed9aac3b3a61c41b8a7b61ab8067c77
[instance-
drone
]
[instance-
peer
]
filename = instance-
drone.cfg
filename = instance-
peer.cfg.jinja.in
md5sum =
b1910416ffa6f2b6a84fd13cca6109ce
md5sum =
8615afba84028f1a61ca922cb1c0dcc5
[main]
[main]
filename = main.js
_update_hash_filename_ = drone-scripts/main.js.jinja
md5sum = 8bc77ebd49e8e6fe060de507bccc44d5
md5sum = 8bc77ebd49e8e6fe060de507bccc44d5
[pubsub]
[pubsub]
filename = pubsub.js
_update_hash_filename_ = drone-scripts/pubsub.js.jinja
md5sum = 1555496ad591a31a845f33488d5c335d
md5sum = 1555496ad591a31a845f33488d5c335d
[script-js]
_update_hash_filename_ = web-gui/script.js.jinja
md5sum = 90bf6eaf67e2941d8a34e2cf2afdae2a
[worker]
[worker]
filename = worker.js
_update_hash_filename_ = drone-scripts/worker.js.jinja
md5sum = ccbdd75b2a58e8d92d7cb990f2565b37
md5sum = ccbdd75b2a58e8d92d7cb990f2565b37
software/js-drone/
main.js
→
software/js-drone/
drone-scripts/main.js.jinja
View file @
3c2ed453
File moved
software/js-drone/
pubsub.js
→
software/js-drone/
drone-scripts/pubsub.js.jinja
View file @
3c2ed453
File moved
software/js-drone/
worker.js
→
software/js-drone/
drone-scripts/worker.js.jinja
View file @
3c2ed453
File moved
software/js-drone/instance-default.cfg
→
software/js-drone/instance-default.cfg
.jinja
View file @
3c2ed453
{% set autopilot_ip = slapparameter_dict.get('autopilotIp', '192.168.27.1') -%}
{%- set parameter_dict = dict(default_parameter_dict, **parameter_dict) %}
{% set autopilot_port = slapparameter_dict.get('autopilotPort', 7909) -%}
{% set guid_list = parameter_dict['droneGuidList'] + parameter_dict['subscriberGuidList'] -%}
{% set flight_script = slapparameter_dict.get('flightScript', 'https://lab.nexedi.com/nexedi/flight-scripts/raw/master/default.js') -%}
{% set is_a_simulation = slapparameter_dict.get('isASimulation', False) -%}
{% set multicast_ip = slapparameter_dict.get('multicastIp', 'ff15::1111') -%}
{% set net_if = slapparameter_dict.get('netIf', 'eth0') -%}
{% set drone_guid_list = slapparameter_dict.get('droneGuidList', []) -%}
{% set subscriber_guid_list = slapparameter_dict.get('subscriberGuidList', []) -%}
{% set guid_list = drone_guid_list + subscriber_guid_list -%}
{% set drone_id_list = [] -%}
{% set drone_id_list = [] -%}
{% set subscriber_id_list = [] -%}
{% set subscriber_id_list = [] -%}
{% set part_list = ['publish-connection-information'] -%}
{% set part_list = ['publish-connection-information'] -%}
{% for id, guid in enumerate(guid_list) -%}
{% for id, guid in enumerate(guid_list) -%}
{% set request_
drone_section_title = 'request-drone
' ~ id -%}
{% set request_
peer_section_title = 'request-peer
' ~ id -%}
{% do part_list.append(request_
drone
_section_title) %}
{% do part_list.append(request_
peer
_section_title) %}
[{{ request_
drone
_section_title }}]
[{{ request_
peer
_section_title }}]
<= slap-connection
<= slap-connection
recipe = slapos.cookbook:request.serialised
recipe = slapos.cookbook:request.serialised
name =
Drone
{{ id }}
name =
Peer
{{ id }}
software-url = $
$
{:software-release-url}
software-url = ${:software-release-url}
software-type =
drone
software-type =
peer
return = instance-path
return = instance-path
sla-computer_guid = {{ guid }}
sla-computer_guid = {{ guid }}
config-autopilotIp = {{
autopilot_ip
}}
config-autopilotIp = {{
parameter_dict['autopilotIp']
}}
config-autopilotPort = {{ dumps(
autopilot_port
) }}
config-autopilotPort = {{ dumps(
parameter_dict['autopilotPort']
) }}
config-numberOfDrone = {{ dumps(len(
drone_guid_list
)) }}
config-numberOfDrone = {{ dumps(len(
parameter_dict['droneGuidList']
)) }}
config-numberOfSubscriber = {{ dumps(len(
subscriber_guid_list
)) }}
config-numberOfSubscriber = {{ dumps(len(
parameter_dict['subscriberGuidList']
)) }}
config-id = {{ dumps(id) }}
config-id = {{ dumps(id) }}
config-isASimulation = {{ dumps(
is_a_simulation
) }}
config-isASimulation = {{ dumps(
parameter_dict['isASimulation']
) }}
{% if id < len(
drone_guid_list
) -%}
{% if id < len(
parameter_dict['droneGuidList']
) -%}
{% do drone_id_list.append(id) %}
{% do drone_id_list.append(id) %}
config-isADrone = {{ dumps(True) }}
config-isADrone = {{ dumps(True) }}
config-flightScript = {{
flight_script
}}
config-flightScript = {{
parameter_dict['flightScript']
}}
{% else -%}
{% else -%}
{% do subscriber_id_list.append(id) %}
{% do subscriber_id_list.append(id) %}
config-isADrone = {{ dumps(False) }}
config-isADrone = {{ dumps(False) }}
config-flightScript = https://lab.nexedi.com/nexedi/flight-scripts/raw/api_update/subscribe.js
config-flightScript = https://lab.nexedi.com/nexedi/flight-scripts/raw/api_update/subscribe.js
{% endif -%}
{% endif -%}
config-multicastIp = {{
multicast_ip
}}
config-multicastIp = {{
parameter_dict['multicastIp']
}}
config-netIf = {{
net_if
}}
config-netIf = {{
parameter_dict['netIf']
}}
{% endfor %}
{% endfor %}
[publish-connection-information]
[publish-connection-information]
...
...
software/js-drone/instance-
drone
-input-schema.json
→
software/js-drone/instance-
peer
-input-schema.json
View file @
3c2ed453
File moved
software/js-drone/instance-
drone
-output-schema.json
→
software/js-drone/instance-
peer
-output-schema.json
View file @
3c2ed453
File moved
software/js-drone/instance-
drone.cfg
→
software/js-drone/instance-
peer.cfg.jinja.in
View file @
3c2ed453
...
@@ -6,16 +6,20 @@ parts =
...
@@ -6,16 +6,20 @@ parts =
[directory]
[directory]
recipe = slapos.cookbook:mkdirectory
recipe = slapos.cookbook:mkdirectory
home = $${buildout:directory}
home = $${buildout:directory}
bin = $${:home}/bin
bin = $${:home}/bin
etc = $${:home}/etc
etc = $${:home}/etc
srv = $${:home}/srv
var = $${:home}/var
var = $${:home}/var
log = $${:var}/log
log = $${:var}/log
public = $${:srv}/public
service = $${:etc}/service
[js-dynamic-template]
[js-dynamic-template]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
rendered = $${directory:etc}/$${:_buildout_section_name_}.js
rendered = $${directory:etc}/$${:_buildout_section_name_}.js
template = ${buildout:directory}/$${:_buildout_section_name_}.js
extra-context =
extra-context =
context =
context =
import json_module json
import json_module json
...
@@ -26,15 +30,18 @@ context =
...
@@ -26,15 +30,18 @@ context =
[main]
[main]
<= js-dynamic-template
<= js-dynamic-template
template = ${main:target}
extra-context =
extra-context =
key log_dir directory:log
key log_dir directory:log
key pubsub_script pubsub:rendered
key pubsub_script pubsub:rendered
key worker_script worker:rendered
key worker_script worker:rendered
[pubsub]
[pubsub]
template = ${pubsub:target}
<= js-dynamic-template
<= js-dynamic-template
[worker]
[worker]
template = ${worker:target}
<= js-dynamic-template
<= js-dynamic-template
[symlink-quickjs-binary]
[symlink-quickjs-binary]
...
@@ -46,9 +53,41 @@ init =
...
@@ -46,9 +53,41 @@ init =
if not os.path.exists(options['target']):
if not os.path.exists(options['target']):
os.symlink(options['binary-path'], options['target'])
os.symlink(options['binary-path'], options['target'])
[script-js]
recipe = slapos.recipe.template:jinja2
template = ${script-js:target}
rendered = $${directory:public}/script.js
websocket-url = [{{ ipv6 }}]:{{ websocket_port }}
context =
raw websocket_url $${:websocket-url}
[index-html]
recipe = slapos.recipe.template:jinja2
template = ${index-html:target}
rendered = $${directory:public}/index.html
context =
raw nb_drones {{ parameter_dict['numberOfDrone'] }}
[httpd-port]
recipe = slapos.cookbook:free_port
minimum = 8080
maximum = 8090
ip = {{ ipv6 }}
[httpd]
recipe = slapos.cookbook:simplehttpserver
host = {{ ipv6 }}
port = $${httpd-port:port}
base-path = $${directory:public}
wrapper = $${directory:service}/http-server
log-file = $${directory:log}/httpd.log
use-hash-url = false
depends = $${index-html:rendered}
[publish-connection-information]
[publish-connection-information]
recipe = slapos.cookbook:publish.serialised
recipe = slapos.cookbook:publish.serialised
instance-path = $${directory:home}
instance-path = $${directory:home}
{% if not is_a_drone -%}
{% if not parameter_dict['isADrone'] -%}
websocket-url = ws://[{{ websocket_ip }}]:{{ websocket_port }}
httpd-url = [$${httpd:host}]:$${httpd:port}
websocket-url = ws://$${script-js:websocket-url}
{% endif -%}
{% endif -%}
software/js-drone/instance.cfg
→
software/js-drone/instance.cfg
.in
View file @
3c2ed453
...
@@ -9,7 +9,7 @@ offline = true
...
@@ -9,7 +9,7 @@ offline = true
[switch-softwaretype]
[switch-softwaretype]
recipe = slapos.cookbook:switch-softwaretype
recipe = slapos.cookbook:switch-softwaretype
default = instance-default:output
default = instance-default:output
drone = instance-drone
:output
peer = instance-peer
:output
RootSoftwareInstance = $${:default}
RootSoftwareInstance = $${:default}
[slap-configuration]
[slap-configuration]
...
@@ -22,14 +22,28 @@ cert = $${slap_connection:cert_file}
...
@@ -22,14 +22,28 @@ cert = $${slap_connection:cert_file}
[dynamic-template-base]
[dynamic-template-base]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
url = ${buildout:directory}/$${:_buildout_section_name_}.cfg
output = $${buildout:directory}/$${:_buildout_section_name_}.cfg
output = $${buildout:directory}/$${:_buildout_section_name_}
extra-context =
context =
jsonkey default_parameter_dict :default-parameters
key parameter_dict slap-configuration:configuration
$${:extra-context}
default-parameters =
{
"autopilotIp": "192.168.27.1",
"autopilotPort": 7909,
"flightScript": "https://lab.nexedi.com/nexedi/flight-scripts/raw/master/default.js",
"isASimulation": false,
"multicastIp": "ff15::1111",
"netIf": "eth0",
"droneGuidList": [],
"subscriberGuidList":[]
}
[instance-default]
[instance-default]
<= dynamic-template-base
<= dynamic-template-base
url = ${instance-default:target}
extensions = jinja2.ext.do
extensions = jinja2.ext.do
context =
key slapparameter_dict slap-configuration:configuration
[directory]
[directory]
recipe = slapos.cookbook:mkdirectory
recipe = slapos.cookbook:mkdirectory
...
@@ -48,7 +62,7 @@ minimum = 6789
...
@@ -48,7 +62,7 @@ minimum = 6789
maximum = 6799
maximum = 6799
ip = $${slap-configuration:ipv6-random}
ip = $${slap-configuration:ipv6-random}
[
drone
-configuration]
[
peer
-configuration]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
output = $${directory:etc}/configuration.json
output = $${directory:etc}/configuration.json
extensions = jinja2.ext.do
extensions = jinja2.ext.do
...
@@ -56,17 +70,17 @@ context =
...
@@ -56,17 +70,17 @@ context =
import json_module json
import json_module json
key websocket_ip gwsocket-port:ip
key websocket_ip gwsocket-port:ip
key websocket_port gwsocket-port:port
key websocket_port gwsocket-port:port
key
slap
parameter_dict slap-configuration:configuration
key parameter_dict slap-configuration:configuration
inline =
inline =
{% do
slap
parameter_dict.__setitem__('websocketIp', websocket_ip) -%}
{% do parameter_dict.__setitem__('websocketIp', websocket_ip) -%}
{% do
slap
parameter_dict.__setitem__('websocketPort', websocket_port) -%}
{% do parameter_dict.__setitem__('websocketPort', websocket_port) -%}
{{ json_module.dumps(
slap
parameter_dict) }}
{{ json_module.dumps(parameter_dict) }}
[instance-
drone
]
[instance-
peer
]
<= dynamic-template-base
<= dynamic-template-base
url = ${instance-peer:output}
depends = $${user:recipe}
depends = $${user:recipe}
context =
extra-context =
key configuration drone-configuration:output
key configuration peer-configuration:output
key is_a_drone slap-configuration:configuration.isADrone
key ipv6 slap-configuration:ipv6-random
key websocket_ip gwsocket-port:ip
key websocket_port gwsocket-port:port
key websocket_port gwsocket-port:port
software/js-drone/software.cfg
View file @
3c2ed453
...
@@ -7,39 +7,39 @@ extends =
...
@@ -7,39 +7,39 @@ extends =
parts =
parts =
instance-profile
instance-profile
instance-default
instance-drone
main
pubsub
worker
slapos-cookbook
slapos-cookbook
[instance-
profile
]
[instance-
default
]
recipe = slapos.recipe.
template
recipe = slapos.recipe.
build:download
url = ${:_profile_base_location_}/${:filename}
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/template.cfg
[
jinja-
template-base]
[template-base]
recipe = slapos.recipe.template
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:_buildout_section_name_}.cfg
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:_buildout_section_name_}.cfg
[instance-default]
[instance-peer]
<= jinja-template-base
<= template-base
output = ${buildout:directory}/${:_buildout_section_name_}.cfg.jinja
[instance-drone]
[instance-profile]
<= jinja-template-base
<= template-base
output = ${buildout:directory}/template.cfg
[download
-file-base
]
[download]
recipe = slapos.recipe.build:download
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:filename}
url = ${:_profile_base_location_}/${:_update_hash_filename_}
destination = ${buildout:directory}/${:filename}
[index-html]
<= download
[main]
[main]
<= download
-file-base
<= download
[pubsub]
[pubsub]
<= download-file-base
<= download
[script-js]
<= download
[worker]
[worker]
<= download
-file-base
<= download
software/js-drone/software.cfg.json
View file @
3c2ed453
...
@@ -12,11 +12,11 @@
...
@@ -12,11 +12,11 @@
"index"
:
0
"index"
:
0
},
},
"drone"
:
{
"drone"
:
{
"title"
:
"
Drone
"
,
"title"
:
"
Peer
"
,
"software-type"
:
"
drone
"
,
"software-type"
:
"
peer
"
,
"description"
:
"
Drone
Instance"
,
"description"
:
"
Peer
Instance"
,
"request"
:
"instance-
drone
-input-schema.json"
,
"request"
:
"instance-
peer
-input-schema.json"
,
"response"
:
"instance-
drone
-output-schema.json"
,
"response"
:
"instance-
peer
-output-schema.json"
,
"index"
:
1
"index"
:
1
}
}
}
}
...
...
software/js-drone/test/test.py
View file @
3c2ed453
...
@@ -254,6 +254,16 @@ class JSDroneTestCase(SlapOSInstanceTestCase):
...
@@ -254,6 +254,16 @@ class JSDroneTestCase(SlapOSInstanceTestCase):
s
.
setsockopt
(
socket
.
IPPROTO_IP
,
socket
.
IP_MULTICAST_TTL
,
2
)
s
.
setsockopt
(
socket
.
IPPROTO_IP
,
socket
.
IP_MULTICAST_TTL
,
2
)
s
.
sendto
(
ua_message
,
(
'::1'
,
OPC_UA_PORT
))
s
.
sendto
(
ua_message
,
(
'::1'
,
OPC_UA_PORT
))
def
test_process
(
self
):
expected_process_name_list
=
[
'http-server-on-watch'
]
with
self
.
slap
.
instance_supervisor_rpc
as
supervisor
:
process_names
=
[
process
[
'name'
]
for
process
in
supervisor
.
getAllProcessInfo
()]
for
expected_process_name
in
expected_process_name_list
:
self
.
assertIn
(
expected_process_name
,
process_names
)
def
test_requested_instances
(
self
):
def
test_requested_instances
(
self
):
connection_parameter_dict
=
json
.
loads
(
connection_parameter_dict
=
json
.
loads
(
self
.
computer_partition
.
getConnectionParameterDict
()[
'_'
])
self
.
computer_partition
.
getConnectionParameterDict
()[
'_'
])
...
...
software/js-drone/web-gui/index.html.jinja
0 → 100644
View file @
3c2ed453
<!DOCTYPE html>
<html
lang=
"en-GB"
>
<head>
<meta
charset=
"utf-8"
>
<title>
JS-Drone GUI
</title>
<script
src=
"script.js"
></script>
<style>
button
{
padding
:
0.5%
;
font-size
:
24px
;
cursor
:
pointer
;
border
:
none
;
border-radius
:
10px
;
box-shadow
:
0
4px
#999
;
}
button
:active
{
box-shadow
:
0
2px
#666
;
transform
:
translateY
(
4px
);
}
div
>
*
{
margin
:
1%
}
label
{
margin
:
2%
}
table
{
width
:
30%
}
th
,
td
{
padding
:
1%
;
text-align
:
center
;
vertical-align
:
middle
;
}
.connected
{
color
:
green
}
.container
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.disconnected
{
color
:
red
}
.gray-button
{
background-color
:
lightgray
}
.gray-button
:hover
{
background-color
:
gray
}
.green-button
{
background-color
:
#4caf50
}
.green-button
:hover
{
background-color
:
#3e8e41
}
.red-button
{
background-color
:
red
}
.red-button
{
background-color
:
#e42828
}
</style>
</head>
<body>
<header
class=
"container"
>
<label
for=
"web-socket-status"
>
web socket status:
</label>
<output
class=
"disconnected"
id=
"web-socket-status"
>
Disconnected
</output>
</header>
<div
class=
"container"
>
<table>
<tr>
<th></th>
{% for i in range(int(nb_drones)) -%}
<th>
Drone {{ i }}
</th>
{% endfor %}
</tr>
<tr>
<th>
Flight state
</th>
{% for i in range(int(nb_drones)) -%}
<td
class=
"disconnected"
id=
"flight_state_{{ i }}"
>
Unknown
</td>
{% endfor %}
</tr>
<tr>
<th>
Latitude (°)
</th>
{% for i in range(int(nb_drones)) -%}
<td
id=
"latitude_{{ i }}"
></td>
{% endfor %}
</tr>
<tr>
<th>
Longitude (°)
</th>
{% for i in range(int(nb_drones)) -%}
<td
id=
"longitude_{{ i }}"
></td>
{% endfor %}
</tr>
<tr>
<th>
Altitude (m)
</th>
{% for i in range(int(nb_drones)) -%}
<td
id=
"altitude_{{ i }}"
></td>
{% endfor %}
</tr>
<tr>
<th>
Yaw (°)
</th>
{% for i in range(int(nb_drones)) -%}
<td
id=
"yaw_{{ i }}"
></td>
{% endfor %}
</tr>
<tr>
<th>
Air speed (m/s)
</th>
{% for i in range(int(nb_drones)) -%}
<td
id=
"airspeed_{{ i }}"
></td>
{% endfor %}
</tr>
<tr>
<th>
Climb rate (m/s)
</th>
{% for i in range(int(nb_drones)) -%}
<td
id=
"climb_rate_{{ i }}"
></td>
{% endfor %}
</tr>
</table>
</div>
<div
class=
"container"
>
<button
id=
"flight-btn"
class=
"green-button"
type=
"button"
>
Start
</button>
<button
id=
"switch-btn"
class=
"gray-button"
type=
"button"
>
Switch
</button>
<button
id=
"quit-btn"
class=
"red-button"
type=
"button"
>
Quit
</button>
</div>
</body>
</html>
software/js-drone/web-gui/script.js.jinja
0 → 100644
View file @
3c2ed453
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
(function () {
"use strict";
var ALTITUDE_BASE_ID = "altitude_",
AIRSPEED_BASE_ID = "airspeed_",
CONNECTED_CLASS_NAME = "connected",
CLIMB_RATE_BASE_ID = "climb_rate_",
DISCONNECTED_CLASS_NAME = "disconnected",
FLIGHT_BTN_ID = "flight-btn",
FLIGHT_STATUS_BASE_ID = "flight_state_",
GREEN_BTN_CLASS_NAME = "green-button",
LATITUDE_BASE_ID = "latitude_",
LONGITUDE_BASE_ID = "longitude_",
QUIT_BTN_ID = "quit-btn",
RED_BTN_CLASS_NAME = "red-button",
SWITCH_BTN_ID = "switch-btn",
WEB_SOCKET_STATUS_OUTPUT_ID = "web-socket-status",
YAW_BASE_ID = "yaw_",
socket;
function updateConnexionClass(element, status) {
element.classList.remove(status ? DISCONNECTED_CLASS_NAME : CONNECTED_CLASS_NAME);
element.classList.add(status ? CONNECTED_CLASS_NAME : DISCONNECTED_CLASS_NAME);
}
function setWebSocketStatus(connected, status) {
var status_output = document.getElementById(WEB_SOCKET_STATUS_OUTPUT_ID);
updateConnexionClass(status_output, connected);
status_output.value = status;
}
function stopFlight(event) {
socket.send("stop");
event.target.removeEventListener('click', stopFlight);
}
function startFlight(event) {
var button = event.target;
socket.send("start");
button.removeEventListener('click', startFlight);
button.innerHTML = "Stop";
button.classList.remove(GREEN_BTN_CLASS_NAME);
button.classList.add(RED_BTN_CLASS_NAME);
button.addEventListener('click', stopFlight);
}
socket = new WebSocket('ws://{{ websocket_url }}');
socket.onopen = function(event) {
setWebSocketStatus(true, "Connected");
};
socket.onmessage = function(event) {
var message = JSON.parse(event.data),
flight_state_cell;
if (message.hasOwnProperty("drone_dict")) {
Object.entries(message["drone_dict"]).forEach(function ([id, drone]) {
document.getElementById(LATITUDE_BASE_ID + id).innerHTML = drone["latitude"];
document.getElementById(LONGITUDE_BASE_ID + id).innerHTML = drone["longitude"];
document.getElementById(ALTITUDE_BASE_ID + id).innerHTML = drone["altitude"];
document.getElementById(YAW_BASE_ID + id).innerHTML = drone["yaw"];
document.getElementById(AIRSPEED_BASE_ID + id).innerHTML = drone["speed"];
document.getElementById(CLIMB_RATE_BASE_ID + id).innerHTML = drone["climbRate"];
});
} else if (message.hasOwnProperty("state") && message.hasOwnProperty("id")) {
flight_state_cell = document.getElementById(FLIGHT_STATUS_BASE_ID + message['id']);
flight_state_cell.innerHTML = message['state'];
updateConnexionClass(flight_state_cell, message['inAir']);
} else {
console.info(message);
}
};
socket.onclose = function(event) {
setWebSocketStatus(false, "Closed");
};
socket.onerror = function(event) {
console.error(event.reason);
};
document.addEventListener("DOMContentLoaded", () => {
document.getElementById(FLIGHT_BTN_ID).addEventListener('click', startFlight);
document.getElementById(SWITCH_BTN_ID).addEventListener('click', event => {
socket.send("switch");
});
document.getElementById(QUIT_BTN_ID).addEventListener('click', event => {
socket.send("quit");
});
});
}());
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment