Skip to content

Commit cb91f7e

Browse files
authored
Update README and MQTT security settings to support updated Sling protocol (#909)
* Update existing README formatting * Add guide for setting up local MQTT environment * Allow 'monitor' topics in IoT deployment config
1 parent b25ebce commit cb91f7e

File tree

2 files changed

+72
-22
lines changed

2 files changed

+72
-22
lines changed

README.md

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@
77

88
Cadet is the web application powering Source Academy.
99

10-
* `master` is the main development branch, and may be broken, buggy, unstable,
11-
etc. It may not work with the frontend, if there are frontend changes that
12-
have not yet been merged.
13-
* `stable` is the stable branch and should work with the stable branch of the
14-
frontend. Note that `stable` may not have stable history!
10+
- `master` is the main development branch, and may be broken, buggy, unstable, etc. It may not work with the frontend, if there are frontend changes that have not yet been merged.
11+
- `stable` is the stable branch and should work with the stable branch of the frontend. Note that `stable` may not have stable history!
1512

1613
## Developer setup
1714

@@ -21,9 +18,7 @@ Cadet is the web application powering Source Academy.
2118
2. Erlang/OTP 23.2.1
2219
3. PostgreSQL 13 or 14
2320

24-
It is probably okay to use a different version of PostgreSQL or Erlang/OTP, but
25-
using a different version of Elixir may result in differences in e.g. `mix
26-
format`.
21+
It is probably okay to use a different version of PostgreSQL or Erlang/OTP, but using a different version of Elixir may result in differences in e.g. `mix format`.
2722

2823
### Setting up your local development environment
2924

@@ -34,9 +29,7 @@ format`.
3429
$ vim config/dev.secrets.exs
3530
```
3631

37-
- To use NUSNET authentication, specify the NUS ADFS OAuth2 URL. (Ask for it.)
38-
Note that the frontend will supply the ADFS client ID and redirect URL (so
39-
you will need that too, but not here).
32+
- To use NUSNET authentication, specify the NUS ADFS OAuth2 URL. (Ask for it.) Note that the frontend will supply the ADFS client ID and redirect URL (so you will need that too, but not here).
4033

4134
2. Install Elixir dependencies
4235

@@ -56,14 +49,69 @@ format`.
5649
$ mix phx.server
5750
```
5851

59-
5. You may now make API calls to the server locally via `localhost:4000`. The
60-
API documentation can also be accessed at http://localhost:4000/swagger.
52+
5. You may now make API calls to the server locally via `localhost:4000`. The API documentation can also be accessed at http://localhost:4000/swagger.
6153

54+
If you don't need to test MQTT connections for remote execution using [Sling](source-academy/sling), you can stop here. Otherwise, continue to [set up the local development environment with MQTT](#setting-up-a-local-development-environment-with-mqtt-support).
55+
56+
### Setting up a local development environment with MQTT support
57+
58+
In addition to performing the steps [above](#setting-up-your-local-development-environment), you will need to do the following:
59+
60+
1. Set up a local MQTT server.
61+
One cross-platform solution is Mosquitto. Follow their [instructions](https://mosquitto.org/download/) on how to install it for your system.
62+
63+
2. Update Mosquitto configurations
64+
We will require two listeners on two different ports: one for listening to the WebSockets connection from Source Academy Frontend, and one to listen for the regular MQTT connection from the EV3. Locate your `mosquitto.conf` file, and add the following lines:
65+
66+
```conf
67+
# Default listener
68+
listener 1883
69+
protocol mqtt
70+
allow_anonymous true
71+
72+
# MQTT over WebSockets
73+
listener 9001
74+
protocol websockets
75+
allow_anonymous true
76+
```
77+
78+
If necessary, you can change the default port numbers, but it is generally best to stick to the default MQQT/WS ports.
79+
80+
3. Restart the Mosquitto service to apply configuration changes
81+
82+
4. Manually update `lib/cadet/devices/devices.ex` to use our local MQTT server
83+
The MQTT endpoints are hardcoded to use AWS. For local development, change (but **do not commit**) the following functions:
84+
85+
- `get_device_ws_endpoint` returns the address the frontend should connect to. Take not that the port number should match what you have defined earlier in `mosquitto.conf`. Assuming your backend, frontend and MQTT server are hosted on the same computer, edit the function body as follows:
86+
87+
```elixir
88+
def get_device_ws_endpoint(%Device{id: device_id}, %User{id: user_id}, opts) do
89+
{:ok,
90+
%{
91+
endpoint: "ws://localhost:9001/",
92+
thing_name: get_thing_name(device_id),
93+
client_name_prefix: get_ws_client_prefix(user_id)
94+
}}
95+
end
96+
```
97+
98+
- `get_endpoint_address` gives the address the EV3 should connect to (under normal operations). The address should be the local IP address of the computer hosting the MQTT server. Again, take note of the port number.
99+
<details><summary>Sidenote on connecting from the EV3</summary>
100+
101+
We will not actually use this return value for anything, so the actual value. We just need to hardcode something to return (and stop the backend from trying to connect to AWS). Also, it is good practice to assume that the value is going to be used anyway:
102+
</details>
103+
104+
```elixir
105+
def get_endpoint_address do
106+
{:ok, "192.168.139.10:1883"} # This won't actually be used (for now -- see sidenote)
107+
end
108+
```
109+
110+
Your backend is now all set up for remote execution using a local MQTT server. To see how to configure the EV3 to use a local MQTT server, check out the [EV3-Source](https://github.com/source-academy/ev3-source) repository.
62111

63112
### Obtaining `access_token` in dev environment
64113

65-
You can obtain an `access_token` JWT for a user with a given role by simply
66-
running:
114+
You can obtain an `access_token` JWT for a user with a given role by simply running:
67115

68116
```bash
69117
$ mix cadet.token <role>
@@ -77,11 +125,9 @@ $ mix help cadet.token
77125

78126
### Style Guide
79127

80-
We follow this style guide: https://github.com/lexmag/elixir-style-guide and
81-
https://github.com/christopheradams/elixir_style_guide
128+
We follow this style guide: https://github.com/lexmag/elixir-style-guide and https://github.com/christopheradams/elixir_style_guide
82129

83-
Where there is a conflict between the two, the first one (lexmag) shall be the
84-
one followed.
130+
Where there is a conflict between the two, the first one (lexmag) shall be the one followed.
85131

86132
## Entity-Relationship Diagram
87133

@@ -92,6 +138,7 @@ Generated with [DBeaver](https://dbeaver.io/) on 03 June 2022
92138
## License
93139

94140
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
141+
95142
All sources in this repository are licensed under the [Apache License Version 2][apache2].
96143

97144
[apache2]: https://www.apache.org/licenses/LICENSE-2.0.txt

deployment/terraform/iot.tf

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ data "aws_iam_policy_document" "iot_sling" {
1919
"arn:aws:iot:${local.region}:${local.account_id}:topicfilter/$${iot:ClientId}/run",
2020
"arn:aws:iot:${local.region}:${local.account_id}:topicfilter/$${iot:ClientId}/stop",
2121
"arn:aws:iot:${local.region}:${local.account_id}:topicfilter/$${iot:ClientId}/ping",
22-
"arn:aws:iot:${local.region}:${local.account_id}:topicfilter/$${iot:ClientId}/input"
22+
"arn:aws:iot:${local.region}:${local.account_id}:topicfilter/$${iot:ClientId}/input",
23+
"arn:aws:iot:${local.region}:${local.account_id}:topicfilter/$${iot:ClientId}/monitor"
2324
]
2425
}
2526

@@ -32,7 +33,8 @@ data "aws_iam_policy_document" "iot_sling" {
3233
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/run",
3334
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/stop",
3435
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/ping",
35-
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/input"
36+
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/input",
37+
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/monitor"
3638
]
3739
}
3840

@@ -42,7 +44,8 @@ data "aws_iam_policy_document" "iot_sling" {
4244
resources = [
4345
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/status",
4446
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/display",
45-
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/hello"
47+
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/hello",
48+
"arn:aws:iot:${local.region}:${local.account_id}:topic/$${iot:ClientId}/monitor"
4649
]
4750
}
4851
}

0 commit comments

Comments
 (0)