Initial Commit
This commit is contained in:
25
content/_index.md
Normal file
25
content/_index.md
Normal file
@@ -0,0 +1,25 @@
|
||||
+++
|
||||
title = "Home"
|
||||
date = 2021-10-23T00:11:38-07:00
|
||||
+++
|
||||
|
||||
# ITD
|
||||
|
||||
{{% notice warning %}}
|
||||
There is currently a bug in the bluetooth library used for ITD that will cause the following error when using BlueZ 5.62+:
|
||||
|
||||
```
|
||||
MapToStruct: Field not found: MTU
|
||||
```
|
||||
|
||||
This is mentioned in [an issue](https://gitea.arsenm.dev/Arsen6331/infinitime/issues/3).
|
||||
{{% /notice %}}
|
||||
|
||||
ITD is a daemon written in Go that communicates with the [InfinitTime](https://github.com/InfiniTimeOrg/InfiniTime) firmware running on the [PineTime](https://www.pine64.org/pinetime/) smartwatch.
|
||||
|
||||
ITD is meant to be fast and easy to use. As such, it is is only a single binary that works on all Linux systems since it is statically compiled and thus does not rely on any dynamic libraries.
|
||||
|
||||
ITD comes with `itctl`, a binary that uses the provided socket to control ITD and, by extension, the connected watch.
|
||||
|
||||
|
||||
`itgui` is a gui frontend in ITD's repo. I do not compile it in CI as it requires OpenGL which makes cross-compiling a massive pain.
|
||||
12
content/configuration/_index.md
Normal file
12
content/configuration/_index.md
Normal file
@@ -0,0 +1,12 @@
|
||||
+++
|
||||
chapter = true
|
||||
pre = "<b>II. </b>"
|
||||
title = "Configuration"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
### Chapter II
|
||||
|
||||
# Configuration
|
||||
|
||||
This chapter is about configuring ITD, including documentation about its config file and locations where it can be put.
|
||||
12
content/configuration/about.md
Normal file
12
content/configuration/about.md
Normal file
@@ -0,0 +1,12 @@
|
||||
+++
|
||||
title = "About"
|
||||
date = 2021-10-23T23:04:51-07:00
|
||||
draft = true
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
ITD has a config file. It's a TOML file that is, by default, at `/etc/itd.toml`. ITD will also search `~/.config/itd.toml` for a config and will choose the one in home if possible.
|
||||
|
||||
ITD can also be configured with environment variables. They take priority over the config. Variable names should be formatted as follows: ITD_<config field>. For example, socket path is `socket.path` in the config, so it would be `ITD_SOCKET_PATH` as an environment variable. To change which transliterators to use, `ITD_NOTIFS_TRANSLIT_USE` would be the variable, since the config field is `notifs.translit.use`.
|
||||
|
||||
In most cases, config edits come into effect immediately, and no restart of ITD is needed.
|
||||
105
content/configuration/sections.md
Normal file
105
content/configuration/sections.md
Normal file
@@ -0,0 +1,105 @@
|
||||
+++
|
||||
title = "Sections"
|
||||
date = 2021-10-23T23:04:51-07:00
|
||||
draft = true
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
This page is about the various sections in the config, their purpose, and how to use them.
|
||||
|
||||
### cfg.version
|
||||
|
||||
This field is temporary and was added because I changed the config format a while ago and wanted to make sure no one was still using the old config with a new version of ITD.
|
||||
|
||||
---
|
||||
|
||||
### socket
|
||||
|
||||
This section contains options for the control socket exposed by ITD.
|
||||
|
||||
#### path
|
||||
|
||||
This field is a string indicating the filepath at which the control socket should be opened.
|
||||
|
||||
---
|
||||
|
||||
### conn
|
||||
|
||||
The conn secton contains options for ITD's connection to the PineTime.
|
||||
|
||||
#### reconnect
|
||||
|
||||
This field is a boolean that dictates whether ITD will attempt to reconnect to the PineTime in case of a disconnect.
|
||||
|
||||
---
|
||||
|
||||
### on.connect
|
||||
|
||||
This section contains options for what happens when ITD first connects to a PineTime.
|
||||
|
||||
#### notify
|
||||
|
||||
This field is a boolean that dictates whether a notification should be sent to InfiniTime upon connection.
|
||||
|
||||
---
|
||||
|
||||
### on.reconnect
|
||||
|
||||
This section contains options for what happens when ITD reconnects to a PineTime after a disconnect.
|
||||
|
||||
#### notify
|
||||
|
||||
This field is a boolean that dictates whether a notification should be sent to InfiniTime upon reconnect.
|
||||
|
||||
#### setTime
|
||||
|
||||
This field is a boolean that dictates whether the time should be updated when ITD reconnects to InfiniTime.
|
||||
|
||||
---
|
||||
|
||||
### notifs.translit
|
||||
|
||||
#### use
|
||||
|
||||
This field is an array of strings which sets which transliterators should be used when transliterating text. The full list of transliterators can be found [here](https://gitea.arsenm.dev/Arsen6331/itd#transliteration) in the readme.
|
||||
|
||||
#### custom
|
||||
|
||||
This field is an array of strings which is a custom transliteration map. It can replace anything with something else. For example:
|
||||
|
||||
```toml
|
||||
custom = [
|
||||
"test", "replaced",
|
||||
"æ", "ae",
|
||||
"ē", "e",
|
||||
]
|
||||
```
|
||||
|
||||
An array is used because Golang does not preserve the order of a map.
|
||||
|
||||
---
|
||||
|
||||
### notifs.ignore
|
||||
|
||||
#### sender
|
||||
|
||||
This field is an array of strings which contains senders from which notifications are ignored.
|
||||
|
||||
#### summary
|
||||
|
||||
This field is an array of strings which contains notification summaries whose notifications will be ignored.
|
||||
|
||||
|
||||
#### body
|
||||
|
||||
This field is an array of strings which contains notification bodies whose notifications will be ignored.
|
||||
|
||||
---
|
||||
|
||||
### music
|
||||
|
||||
This section contains options for music control
|
||||
|
||||
#### vol.interval
|
||||
|
||||
This field is an integer indicating how much the volume should be changed for each volume up or down event from the music control app.
|
||||
12
content/getting-started/_index.md
Normal file
12
content/getting-started/_index.md
Normal file
@@ -0,0 +1,12 @@
|
||||
+++
|
||||
chapter = true
|
||||
pre = "<b>I. </b>"
|
||||
title = "Getting Started"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
### Chapter I
|
||||
|
||||
# Getting Started
|
||||
|
||||
This chapter is about `itd`, its purpose, and what it does. It also includes a note about my age and ability to respond.
|
||||
37
content/getting-started/features.md
Normal file
37
content/getting-started/features.md
Normal file
@@ -0,0 +1,37 @@
|
||||
+++
|
||||
title = "Features"
|
||||
date = 2021-10-23T23:04:51-07:00
|
||||
draft = true
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
The list of features is mentioned [here](https://gitea.arsenm.dev/Arsen6331/itd#features) in the readme. This page will describe how certain features work and how new ones are added.
|
||||
|
||||
### Notification Relay
|
||||
|
||||
The notification relay works by listening for method calls on the `org.freedesktop.Notifications` DBus interface. Any such method call represents a notification being sent. ITD reads the data from the method call and creates a notification suitable for ANS (Alert Notification Service) which is used by InfniTime to display notifications. This means DBus must be installed and running for ITD to relay notifications.
|
||||
|
||||
### Transliteration
|
||||
|
||||
Transliteration for ITD is implemented in a custom `translit` package. It consists of a `Transliterator` interface which looks like this:
|
||||
|
||||
```go
|
||||
type Transliterator interface {
|
||||
Transliterate(string) string
|
||||
Init()
|
||||
}
|
||||
```
|
||||
|
||||
Anything that satisfies that interface can be added to the `Transliterators` map and then used in ITD's config in the `notifs.translit.use` array.
|
||||
|
||||
### Music Control
|
||||
|
||||
Music control is implemented using `playerctl` which uses the MPRIS DBus interface. This means it will work with any music player which supports MPRIS. `playerctl` must be installed for ITD to do music control.
|
||||
|
||||
### Control Socket
|
||||
|
||||
ITD exposes a UNIX socket at `/tmp/itd/socket` by default. This socket can be used to control the daemon. It is how `itctl` and `itgui` work. This can be used in any language which supports UNIX sockets which is nearly all of them. Even bash can be used with `netcat`.
|
||||
|
||||
### New Features
|
||||
|
||||
New features are added whenever I find out they exist from InfiniTime's repo or developers. This means ITD's master branch may contain features not yet released in InfiniTime.
|
||||
15
content/getting-started/note.md
Normal file
15
content/getting-started/note.md
Normal file
@@ -0,0 +1,15 @@
|
||||
+++
|
||||
title = "Note"
|
||||
date = 2021-10-23T22:55:22-07:00
|
||||
draft = true
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
This is a note for anyone using or planning to contribute to ITD. I am {{<raw>}}<span id="age">Loading...</span>{{</raw>}} years old and, at times, may be busy with school and unable to answer questions and/or work on the project for a while. If you do not get an answer quickly, I am probably busy. However, I sometimes answer questions, comment on issues, or push code while in school. That means there may be pauses where I cannot answer questions or comment on issues because I am moving between classes or busy doing an assignment. Please do not bombard me with messages if this occurs, I will answer as soon as I can.
|
||||
|
||||
{{<raw>}}
|
||||
<script>
|
||||
birthday = new Date("April 24, 2005")
|
||||
document.getElementById("age").innerHTML = (new Date).getFullYear() - birthday.getFullYear()
|
||||
</script>
|
||||
{{</raw>}}
|
||||
10
content/getting-started/purpose.md
Normal file
10
content/getting-started/purpose.md
Normal file
@@ -0,0 +1,10 @@
|
||||
+++
|
||||
title = "Purpose"
|
||||
date = 2021-10-23T22:34:32-07:00
|
||||
draft = true
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
ITD was created because I could not find a good InfiniTime companion for Linux. There is [Siglo](https://github.com/alexr4535/siglo) which cannot do much beyond syncing time and updating the watch and is not very reliable. There is [Amazfish](https://github.com/piggz/harbour-amazfish) which works, but at least for me, is a bit clunky and unreliable.
|
||||
|
||||
I wanted something that was easy enough to use that I could just run it and forget about it, and had any feature I may want to use. Also, I needed it to work on Linux because I only own Linux devices, including my phone, which is a PinePhone. This leads to the next requirement. I needed it to be easily cross-compiled so that I could use it on all my computers as well as aarch64 devices such as my PinePhone and Raspberry Pi 4s. All of these reasons contributed to me deciding to make ITD and they are what I try to emphasize.
|
||||
338
content/socket/API.md
Normal file
338
content/socket/API.md
Normal file
@@ -0,0 +1,338 @@
|
||||
+++
|
||||
title = "API"
|
||||
date = 2021-10-23T23:04:51-07:00
|
||||
draft = true
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
This page documents the API of ITD's control socket.
|
||||
|
||||
## Request format
|
||||
|
||||
Request sent to ITD's socket should be valid JSON with the following format:
|
||||
|
||||
| Field | Type |
|
||||
|-------|------|
|
||||
| type | int |
|
||||
| data | any |
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{"type": 5, "data": {"title": "title1", "body": "body1"}}
|
||||
```
|
||||
|
||||
Sends notification titled "title1" with a body "body1".
|
||||
|
||||
---
|
||||
|
||||
## Response format
|
||||
|
||||
Responses received from ITD will be valid JSON and have the following format:
|
||||
|
||||
| Field | Type |
|
||||
|--------|--------|
|
||||
| type | int |
|
||||
| value? | any |
|
||||
| msg? | string |
|
||||
| id? | string |
|
||||
| error | bool |
|
||||
|
||||
(Fields marked with "?" may not exist in all responses)
|
||||
|
||||
Examples:
|
||||
|
||||
```json
|
||||
{"type":1,"value":66,"error":false}
|
||||
```
|
||||
```json
|
||||
{"type":6,"msg":"Data required for settime request","error":true}
|
||||
```
|
||||
```json
|
||||
{"type":6,"error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Requests
|
||||
|
||||
This section will document each request type, its response, and what data it needs.
|
||||
|
||||
### Heart Rate
|
||||
|
||||
The heart rate request's type is 0. It requires no data and returns a `uint8` in its value field.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":0}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":0,"value":92,"error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Battery Level
|
||||
|
||||
The battery level request's type is 1. It requires no data and returns a `uint8` in its value field.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":1}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":1,"value":65,"error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Firmware Version
|
||||
|
||||
The firmware version request's type is 2. It requires no data and returns a string in its value field.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":2}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":2,"value":"1.6.0","error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Firmware Upgrade
|
||||
|
||||
The firmware upgrade request's type is 3. It requires data in the following format:
|
||||
|
||||
| Field | Type |
|
||||
|-------|----------|
|
||||
| type | int |
|
||||
| files | []string |
|
||||
|
||||
Example requests:
|
||||
|
||||
```json
|
||||
{"type": 3, "data": {"type": 0, "files": ["pinetime-mcuboot-app-dfu-1.6.0.zip"]}}
|
||||
```
|
||||
|
||||
```json
|
||||
{"type": 3, "data": {"type": 1, "files": ["pinetime-mcuboot-app-image-1.6.0.bin", "pinetime-mcuboot-app-image-1.6.0.dat"]}}
|
||||
```
|
||||
|
||||
The paths need to be absolute. They are not absolute here as this is an example.
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":3,"value":{"sent":2800,"recvd":2800,"total":361152},"error":false}
|
||||
```
|
||||
|
||||
Responses will be sent continuously until the transfer is complete.
|
||||
|
||||
---
|
||||
|
||||
### Bluetooth Address
|
||||
|
||||
The bluetooth address request's type is 4. It requires no data and returns a string in its value field.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":4}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":4,"value":"ED:47:AC:47:F4:FB","error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Notify
|
||||
|
||||
The notify request's type is 5. It reques data in the following format:
|
||||
|
||||
| Field | Type |
|
||||
|-------|--------|
|
||||
| title | string |
|
||||
| body | string |
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type": 5, "data": {"title": "title1", "body": "body1"}}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":5,"error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Set Time
|
||||
|
||||
The set time request's type is 6. It requires a string as data. The string must be a date and time formatted as ISO8601/RFC3339 or the string "now".
|
||||
|
||||
Example requests:
|
||||
|
||||
```json
|
||||
{"type":6,"data":"2021-10-24T06:40:35-07:00"}
|
||||
```
|
||||
```json
|
||||
{"type":6,"data":"now"}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":6,"error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Watch Heart Rate
|
||||
|
||||
The watch heart rate request's type is 7. It requires no data. It returns a uint8 as its value every time the heart rate changes until it is canceled via the cancel request. It also returns an ID for use with the cancel request.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":7}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":7,"value":83,"id":"d12e2ec2-accd-400c-9da7-be86580b067f","error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Watch Battery Level
|
||||
|
||||
The watch battery level request's type is 8. It requires no data. It returns a uint8 as its value every time the battery level changes until it is canceled via the cancel request. It also returns an ID for use with the cancel request.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":8}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":8,"value":63,"id":"70cce449-d8b8-4e07-a000-0ca4ee7a9c42","error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Motion
|
||||
|
||||
The motion request's type is 9. It requires no data. It returns data in the following format:
|
||||
|
||||
| Field | Type |
|
||||
|-------|--------|
|
||||
| X | 1nt16 |
|
||||
| Y | 1nt16 |
|
||||
| Z | 1nt16 |
|
||||
|
||||
The values will only update if the watch is not sleeping.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":9}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":9,"value":{"X":-220,"Y":475,"Z":-893},"error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Watch Motion
|
||||
|
||||
The watch motion request's type is 10. It requires no data. It returns the same data as the motion request as its value every time the watch moves until it is canceled via the cancel request. It also returns an ID for use with the cancel request.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":10}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":10,"value":{"X":-220,"Y":475,"Z":-893},"id":"d084789d-9fdc-4fce-878b-4408cd616901","error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step Count
|
||||
|
||||
The step count request's type is 11. It requires no data and returns a `uint32` in its value field.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":11}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":11,"value":1043,"error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Watch Step Count
|
||||
|
||||
The watch step count request's type is 12. It requires no data. It returns a `uint32` in its value field every time the step count changes until it is canceled via the cancel request. It also returns an ID for use with the cancel request.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":12}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":12,"value":1045,"id":"54583e8f-80f6-45e3-a97f-b111defc0edc","error":false}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cancel
|
||||
|
||||
The cancel request's type is 13. It requires a string as data, containing the ID returned by a watch request. Once run, it will terminate the watch request, clean up anything it was using, and cause ITD to stop listening for its value from the watch.
|
||||
|
||||
Example request:
|
||||
|
||||
```json
|
||||
{"type":13,"data":"54583e8f-80f6-45e3-a97f-b111defc0edc"}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{"type":13,"error":false}
|
||||
```
|
||||
12
content/socket/_index.md
Normal file
12
content/socket/_index.md
Normal file
@@ -0,0 +1,12 @@
|
||||
+++
|
||||
chapter = true
|
||||
pre = "<b>III. </b>"
|
||||
title = "Socket"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
### Chapter III
|
||||
|
||||
# Socket
|
||||
|
||||
This chapter will document the API of the control socket exposed by ITD.
|
||||
33
content/socket/types.md
Normal file
33
content/socket/types.md
Normal file
@@ -0,0 +1,33 @@
|
||||
+++
|
||||
title = "Types"
|
||||
date = 2021-10-23T23:04:51-07:00
|
||||
draft = true
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
When making a request to ITD or receiving a response from it, a type integer is used to indicate what kind of request is being made. This page will document the integers and what they mean.
|
||||
|
||||
Here is a list of all the request types:
|
||||
|
||||
```go
|
||||
const (
|
||||
ReqTypeHeartRate = 0
|
||||
ReqTypeBattLevel = 1
|
||||
ReqTypeFwVersion = 2
|
||||
ReqTypeFwUpgrade = 3
|
||||
ReqTypeBtAddress = 4
|
||||
ReqTypeNotify = 5
|
||||
ReqTypeSetTime = 6
|
||||
ReqTypeWatchHeartRate = 7
|
||||
ReqTypeWatchBattLevel = 8
|
||||
ReqTypeMotion = 9
|
||||
ReqTypeWatchMotion = 10
|
||||
ReqTypeStepCount = 11
|
||||
ReqTypeWatchStepCount = 12
|
||||
ReqTypeCancel = 13
|
||||
)
|
||||
```
|
||||
|
||||
The response types are always the same as the request type used.
|
||||
|
||||
ITD uses Go's `iota` keyword to generate these numbers, but I have placed their actual values on this page to make it easier to use them in other languages.
|
||||
Reference in New Issue
Block a user