basic initial todo list with some docs

This commit is contained in:
Vladan Popovic 2022-05-27 03:53:26 +02:00
parent 74a1303caf
commit a5792233e2
3 changed files with 390 additions and 0 deletions

View file

@ -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

View file

@ -0,0 +1,3 @@
#+OPTIONS: org-html-head-include-default-style:nil
#+HTML_HEAD: <style type="text/css"> * { font-family: "Georgia";}h1, h2, h3, h4, h5, h6,h1 span, h2 span, h3 span, h4 span, h5 span, h6 span,h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-family: "Arial";}pre, code { font-family: Monaco, "Courier New", Courier;}#text-table-of-contents a { font-family: "Arial";}/* @end *//* @group Baseline */body { font-size: 14px; line-height: 1.5em; padding: 0; margin: 0;}h1 { margin: 0; font-size: 1.6666666666666667em; line-height: 0.9em; margin-bottom: 0.9em;}h2 { margin: 0; font-size: 1.5em; line-height: 1em; margin-bottom: 1em;}h3 { margin: 0; font-size: 1.3333333333333333em; line-height: 1.125em; margin-bottom: 1.125em;}h4 { margin: 0; font-size: 1.1666666666666667em; line-height: 1.2857142857142858em; margin-bottom: 1.2857142857142858em;}p, ul, blockquote, pre, td, th, label { margin: 0; font-size: 1em; line-height: 1.5em; margin-bottom: 1.5em;}p.small, #postamble { margin: 0; font-size: 0.8333333333333334em; line-height: 1.8em; margin-bottom: 1.8em;}table { border-collapse: collapse; margin-bottom: 1.5em;}/* @end *//* @group Layout */#content { max-width: 72em; width: 72em; margin-left: auto; margin-right: auto;}/* #header { height: 10em;}*/#table-of-contents { width: 15em; float: left; overflow: auto;}/* #main { */div.outline-2 { width: 52em; float: right; /* The lines below are useful if the "main" div isn't available and div.outline-2 has to be used. */ position: relative;}#postamble { clear: both; text-align: center;}div.outline-2 pre { overflow: auto;}/* @end *//* @group Header */h1.title { margin-top: 10px; text-align: center;}h1.title { font-size: 3em; font-weight: bold; margin-bottom: 0.8em;}/* @end *//* @group Org Keywords */.todo { color: red;}.done { color: green;}.tag { color: blue; text-transform: lowercase; /* This will be obscured by the surrounding span tag, so blank everything. */ background: #fff; border: none; /* position: relative; text-align: right; right: 1em; */}.timestamp {}.timestamp-kwd { /* keyword associated with a time stamp, like SCHEDULED */}.target { /* target for links */}/* @end *//* @group Table of Contents */#table-of-contents h2 { letter-spacing: -0.1em;}#table-of-contents ul,#table-of-contents ol { padding-left: 1em;}/* @end *//* @group Outline Level 2 */.outline-2 h2 { background: #ffc; border-bottom: 1px solid #95c0e6;}.outline-2 h2, .outline-2 h3 { letter-spacing: -0.05em;}.outline-2 { padding: 5px; /* margin-bottom: 10px; */ /* border-top: 1px solid #ccc; */}/* @end */td { border: 1px solid #ccc;}h1 span, h2 span, h3 span, h4 span, h5 span, h6 span { background-color: #eee; padding: 2px; border: 1px solid #ccc;}.outline-1, .outline-2, .outline-3, .outline-4, .outline-5, .outline-6 { margin-left: 2em;}a { text-decoration: none; color: #57d; /* TODO: Find a better colour for this. */}a:hover { border-bottom: 1px dotted #57d;}#postamble p { margin: 0px;}.footpara { display: inline; }.footdef { margin-bottom: 3em; font-size: 80%; }/*]]>*/--></style><script type="text/javascript">/*@licstart The following is the entire license notice for theJavaScript code in this tag.Copyright (C) 2012-2013 Free Software Foundation, Inc.The JavaScript code in this tag is free software: you canredistribute it and/or modify it under the terms of the GNUGeneral Public License (GNU GPL) as published by the Free SoftwareFoundation, either version 3 of the License, or (at your option)any later version. The code is distributed WITHOUT ANY WARRANTY;without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE. See the GNU GPL for more details.As additional permission under GNU GPL version 3 section 7, youmay distribute non-source (e.g., minimized or compacted) forms ofthat code without the copy of the GNU GPL normally required bysection 4, provided you include this license notice and a URLthrough which recipients can access the Corresponding Source.@licend The above is the entire license noticefor the JavaScript code in this tag.*/<!--/*--><![CDATA[/*><!--*/ function CodeHighlightOn(elem, id) { var target = document.getElementById(id); if(null != target) { elem.cacheClassElem = elem.className; elem.cacheClassTarget = target.className; target.className = "code-highlighted"; elem.className = "code-highlighted"; } } function CodeHighlightOff(elem, id) { var target = document.getElementById(id); if(elem.cacheClassElem) elem.className = elem.cacheClassElem; if(elem.cacheClassTarget) target.className = elem.cacheClassTarget; }</script>

255
todo.org Normal file
View file

@ -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