diff --git a/themes/simple_white/simple_white.org b/themes/simple_white/simple_white.org new file mode 100644 index 0000000..c803c84 --- /dev/null +++ b/themes/simple_white/simple_white.org @@ -0,0 +1,132 @@ +#+SETUPFILE: ~/.emacs.d/org-styles/html/simple_white.theme +#+TITLE: Simple White +#+AUTHOR: Unknown +#+EMAIL: mail@blablub.nil +#+OPTIONS: ^:nil p:t + +* Simple White +Includes: +- [X] CSS +- [ ] JAVASCRIPT + +Available as: +- [ ] CSS FILE +- [ ] JS FILE +- [X] SETUPFILE + +* Lists +** Todo List +*** TODO First todo +*** DONE First Done with Date +CLOSED: [2021-02-18 Thu 10:12] +*** TODO Scheduled +SCHEDULED: <2021-02-18 Thu> +*** TODO Deadline +DEADLINE: <2021-02-18 Thu> +*** TODO Date +<2021-02-18 Thu> + +** Simple list +- List item +- List item +- List item +- List item + +** Sorted List +1. List item +2. List item +3. List item +4. List item + +** Checkbox +- [ ] List item +- [X] List item +- [ ] List item +- [X] List item + + +* H1 +H1 Text +** H2 +H2 Text +*** H3 +H3 Text +**** H4 +H4 Text +***** H5 +H5 Text +****** H6 +H6 Text +******* H7 +H7 Text + + + +* Table + +| a | b | c | d | e | f | +|----+----+----+----+----+----| +| 0 | 1 | 2 | 3 | 4 | 5 | +| 6 | 7 | 8 | 9 | 10 | 11 | +| 12 | 13 | 14 | 15 | 16 | 17 | +| 18 | 19 | 20 | 21 | 22 | 23 | +| 24 | 25 | 26 | 27 | 28 | 29 | + + +* Blocks +** Center +#+begin_center +This is a center block +#+end_center + +** Comment +#+begin_comment +This is a comment block +#+end_comment + +** Example +#+begin_example +This is an example block +#+end_example + +** Quote +#+begin_quote +This is a quote block +#+end_quote + +** Verse +#+begin_verse +This is a verse block +#+end_verse + + +** Source Blocks +*** Python +#+begin_src python :results output :exports both +for i in range(10): + print(i) +#+end_src + +#+RESULTS: +#+begin_example +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +#+end_example + +*** Elisp +#+begin_src emacs-lisp :exports both +(car '(a b c d)) +#+end_src + +#+RESULTS: +: a + + diff --git a/themes/simple_white/simple_white.theme b/themes/simple_white/simple_white.theme new file mode 100644 index 0000000..4006edd --- /dev/null +++ b/themes/simple_white/simple_white.theme @@ -0,0 +1,3 @@ +#+OPTIONS: org-html-head-include-default-style:nil + +#+HTML_HEAD: diff --git a/todo.org b/todo.org new file mode 100644 index 0000000..9ef29c8 --- /dev/null +++ b/todo.org @@ -0,0 +1,255 @@ +:PROPERTIES: +:LOGGING: PROGRESS(!) DONE(!) CANCELED(!) +:END: + +#+SETUPFILE: ~/src/org-themes/src/white_clean/white_clean.theme +#+TITLE: E-Bike-Tracker + +* Requirements + +** PROGRESS [#A] Device components +- State "PROGRESS" from "TODO" [2022-05-27 Fri 00:42] + +Components needed to develop a PoC: +- BMS +- GSM (SIM800L is the cheapest and most reliable, i.e. best value for + money, but only supports GPRS) +- GPS module +- BLE module +- Accelerometer +- Flash for storing local device data (no need for more than 4M?) + +Esp32 has most of these, is pretty cheap and compact and easy to +develop on. + +Choose Rust ... + +** PROGRESS [#A] BMS +- State "PROGRESS" from "TODO" [2022-05-27 Fri 00:44] +Find a BMS that will do good for the battery, measure all cells and +give out data needed for various measurments. + +*** TODO [#A] Measure bike battery level + +** TODO [#A] GPS module +Find a minimal GPS chip and read from it, test stability and tolerance. + +** PROGRESS [#A] SIM module (GPRS/3G/4G/LTE) +- State "PROGRESS" from "TODO" [2022-05-26 Thu 23:57] +Find a minimal GSM chip and try to communicate with it. +- [[https://www.aliexpress.com/item/4000830117417.html?spm=a2g0o.productlist.0.0.6f9ad49ffLG35d&algo_pvid=594a04bb-8a80-4596-8025-9486269f0923&algo_exp_id=594a04bb-8a80-4596-8025-9486269f0923-28&pdp_ext_f=%7B%22sku_id%22%3A%2210000008680354389%22%7D&pdp_npi=2%40dis%21RSD%21%21288.56%21%21%21%21%21%40210318c916529073178195889e0edd%2110000008680354389%21sea][SIM800L]] - GPRS only, no 3G or 4G ([[https://github.com/lesha108/sim800_ups_monitor/blob/main/src/sim800l.rs][Rust implementation example]]) ... cheapest one there is. + +** TODO [#A] Connect to SIM data (GPRS/3G/4G/LTE) +Get a library, or write minimal code that will *only connect to mobile +data* and send the coordinates retrieved from the GPS module. + +** TODO [#A] Accelerometer tracking + +** TODO [#B] GSM triangulation for better accuracy + +** CANCELED Hardware button to switch the device on and off? +- State "CANCELED" from "WONTFIX" [2022-05-26 Thu 19:55] +In case the phone is lost or whatnot, the device needs to have a hw +switch so it doesn't bother anyone. There is an edge-case here, maybe +even an anti-feature where the bike gets stolen and the thief clicks +the hw button and disables all alerts. + +** HOLD [#A] Lock/Unlock mode on the device +The device will need to store a state (lock/unlock). When locked and +the bike moves, the device will send coordinates through GPRS/3G/4G +(depends which GSM module we choose). +In this scenario an alert must be sent to the mobile app. + + +* Software on the device + +We should consider the scenario where we send GPS data independently +from other modules (like BMS, Accelerometer ...) because if the bike +gets stolen it would be great to send the coordinates as fast as +possible. In this case I don't think that battery data would be of +much relevance. + +The other way around, when the owner of the device is riding the bike, +then there's no need to send GPS, or Accelerometer data to the server. + +Also, the battery status could be measured at different intervals that +GPS and acceleration, depending on the mode the device is in ofc. + +Therefore we send every measurment separately for every device. + +#+begin_src plantuml :file img/device_arch.png +participant BMS_Thread +participant Accelerometer_Thread +participant GPS_Thread +entity MPSC_Queue + +Consumer -> MPSC_Queue : recv() +activate Consumer +... +BMS_Thread -> MPSC_Queue : send(battery) +activate BMS_Thread +MPSC_Queue --> Consumer +Consumer -> GSM_Modem : write(json) +... +Accelerometer_Thread -> MPSC_Queue : send(acceleration) +activate Accelerometer_Thread +MPSC_Queue --> Consumer +Consumer -> GSM_Modem : write(json) +... +GPS_Thread -> MPSC_Queue : send(position) +activate GPS_Thread +MPSC_Queue --> Consumer +Consumer -> GSM_Modem : write(json) +... +MPSC_Queue --> GPS_Thread +MPSC_Queue --> Accelerometer_Thread +MPSC_Queue --> BMS_Thread + +deactivate GPS_Thread +deactivate Accelerometer_Thread +deactivate BMS_Thread +deactivate Consumer +#+end_src + +We'll read different things from different modules, so it's best to +have proper structs for all of them. + +#+begin_src rust + #[derive(Serialize, Deserialize)] + struct BatteryStatus { + capacity: f32, + cells: usize, + active_cells: usize, + voltage: f32, + } + + #[derive(Serialize, Deserialize)] + struct GpsCoordinates { + latitude: f32, + longitude: f32, + } + + #[derive(Serialize, Deserialize)] + struct AccelerometerStatus { + acceleration: f32, + } +#+end_src + +Messages sent from the producers (senders) will be of different +types. Therefore we need to create an enum for those messages and fill +in a struct that will be serialized to JSON and then sent to the +server. + +#+begin_src rust + enum SensorData { + GPS(GpsCoordinates), + Battery(BatteryStatus), + Accelerometer(AccelerometerStatus), + } +#+end_src + +Then in some function executed in a thread ... + +#+begin_src rust + fn write_gprs(modem: GsmModem, rx: Receiver) -> Result<()> { + let json_for_server = match rx.recv() { + GPS(coordinates) => serde_json::to_string(&coordinates)?, + Battery(status) => serde_json::to_string(&status)?, + Accelerometer(status) => serde_json::to_string(&status)?, + }; + modem.write(json_for_server)?; + } +#+end_src + +* Device and phone registration +#+begin_src plantuml :file img/registration.png +Phone -> Device: Get device ID +Device --> Phone: Device ID + +Phone -> Server: Register IDs (device_id, phone_id) +Phone <-- Server: Client TLS certificate +Phone -> Device: Set TLS certificate +Phone <-- Device: TLS certificate set + +Device -> Server: ID verification request +Device <-- Server: ID verification response +#+end_src + +** TODO [#A] Phone gets its own device ID +The phone needs to get its own device ID as part of the registration +procedure. Some code exists in [[https://stackoverflow.com/questions/45031499/how-to-get-unique-device-id-in-flutter][this example]], needs to be verified +though. + +** TODO [#A] Phone gets device ID via BLE +The phone needs to retrieve the device ID via BLE and pack it together +with the phone's ID before sending it to the server as part of the +registration procedure. + +** TODO [#A] Generate client certificates with rustls +After the CA cert and server keys are all set up, we can use it to +generate client certificates for the devices. This should all be done +in the web server code, i.e. no exit to shell and call openssl, but +use rustls to generate the cert itself. + +** TODO [#A] Phone sets client certs to device +The phone needs to retrieve the certificate from the server and pass +it to the device. + +** TODO [#A] Device sends an HTTPS request with its own ID +The device needs to send a verification HTTPS request using the +certificate it received with its ID as the body of the request. This +is the final part of the registration procedure. + +** TODO [#A] Handler that registers the phone +The phone needs to get its ID and send it within the registration data. + +Registration data: +#+begin_src +{ phone_id +, device_id +} +#+end_src + +After the server receives this it needs to generate a client cert that +the device will use to send its updates. + +** TODO [#A] Handler that registers the device +The final stage of the registration process. The server would need to +validate that the request came with the cert generated for that +device, and that the device id sent in the body matches the one for +which the cert was generated, + +** TODO Investigate if we can use Wireguard on the device +See if possible at all. There are some implementations and if it works +we will have much better security than tokens, JWTs and the +like. maybe not much better than TLS certificates though :) + +If possible, the keys should be generated on the device, but not sure +if it has physical limitations (cpu, randomness ...). If the device +has physical limitations then we could generate the keys on the phone. + + +* Tracking +The tracking can be done in different ways. Some possible scenarios +where we could send alerts: +- The device and phone could both send their location, and if they + diverge we could start raising alerts on the network. +- Add a lock in the app that will trigger alerts when the device moves. +- etc. + +** TODO [#A] Report phone coordinates? +** TODO [#A] Report device coordinates +** TODO [#A] Handle new coordinates on the server + - Check if the phone and device are sending same coordinates (or within range). + - If the device and phone are paired, do nothing. + - If the device and phone are not paired, send alerts to the phone that new coordinates are received. + - If the device and phone are not paired and wifi is disconnected, send alerts to the phone and all phones near by (configurable). + +** Outgoing message configuration: + - broadcast - broadcast to all subscribers that are listening to broadcast messages + - multicast - sends alerts and status reports to a list of devices/users + - unicast - sends alerts and status reports only to the phone that owns the device + +** Incoming message configuration: + - broadcast - receives and shows all alerts that are broadcasting outgoing messages + - multicast - receives and shows alerts from a list of device/users