Merge branch 'development' of https://github.com/Blueforcer/awtrix-light into development
This commit is contained in:
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: "[BUG]"
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Make sure to read the README before opening an issue. [https://xaviml.github.io/controllerx/faq](https://blueforcer.github.io/awtrix-light/#/README) -->
|
||||||
|
|
||||||
|
# Bug report
|
||||||
|
|
||||||
|
## Describe the bug
|
||||||
|
Add a description of the bug. Detail the expected behaviour in contrast with the behaviour you're observing.
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
- Devices involved:
|
||||||
|
- Model: Ulanzi Awtrix Smart Pixel Clock 2882 (TC001)
|
||||||
|
- AWTRIX-LIGHT version: [ eg. v0.45 ]
|
||||||
|
|
||||||
|
## To Reproduce
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
|
||||||
|
|
||||||
|
## Expected behavior
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
|
||||||
|
```text
|
||||||
|
(optional) Add relevant logs which could help tackle the problem.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional context
|
||||||
|
Add any other context about the problem here.
|
||||||
28
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: "[FEATURE REQUEST]"
|
||||||
|
labels: feature request
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Make sure to read the README before opening an issue. [https://xaviml.github.io/controllerx/faq](https://blueforcer.github.io/awtrix-light/#/README) -->
|
||||||
|
|
||||||
|
# Feature Request
|
||||||
|
|
||||||
|
### Is your feature request related to a problem?
|
||||||
|
|
||||||
|
If so, then add a clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
### Describe the solution / feature you'd like
|
||||||
|
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
### Describe alternatives you've considered
|
||||||
|
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
### Additional context
|
||||||
|
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
30
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: Question
|
||||||
|
about: Open an issue to ask something
|
||||||
|
title: "[QUESTION]"
|
||||||
|
labels: question
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Make sure to read the README before opening an issue. [https://xaviml.github.io/controllerx/faq](https://blueforcer.github.io/awtrix-light/#/README) -->
|
||||||
|
|
||||||
|
# Question
|
||||||
|
|
||||||
|
Add here your question.
|
||||||
|
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
- Devices involved:
|
||||||
|
- Model: Ulanzi Awtrix Smart Pixel Clock 2882 (TC001)
|
||||||
|
- AWTRIX-LIGHT version: [ eg. v0.45 ]
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
|
||||||
|
```text
|
||||||
|
(optional) Add relevant logs which could help tackle the problem.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional context
|
||||||
|
Add any other context about the problem here.
|
||||||
8
.github/workflows/main.yml
vendored
8
.github/workflows/main.yml
vendored
@@ -89,14 +89,6 @@ jobs:
|
|||||||
asset_name: firmware.bin
|
asset_name: firmware.bin
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
- name: Discord notification
|
|
||||||
env:
|
|
||||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
|
||||||
uses: Ilshidur/action-discord@master
|
|
||||||
with:
|
|
||||||
args: 'https://github.com/Blueforcer/awtrix-light/releases/tag/${{ steps.version_number.outputs.firmware_version }}'
|
|
||||||
|
|
||||||
|
|
||||||
- name: Commit
|
- name: Commit
|
||||||
id: commit
|
id: commit
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -14,12 +14,17 @@
|
|||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
[](https://github.com/Blueforcer/awtrix-light/actions/workflows/main.yml)
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
AWTRIX Light is an open‑source custom firmware for the [Ulanzi Smart Pixel clock TC001](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882) which lives on your smarthome.
|
AWTRIX Light is an open‑source custom firmware for the [Ulanzi Smart Pixel clock TC001](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882)
|
||||||
|
|
||||||
|
AWL meant to be a companion for your smarthome like HomeAssistant, IOBroker, NodeRed and so on.
|
||||||
|
Even if you don't have a Smarthome system, but would like to experiment with NodeRed or N8N, you are still welcome to join us.
|
||||||
|
There are many users who are willing to help you!
|
||||||
|
|
||||||
It is ready to use straight out of the box, with time, date, temperature, and humidity pages pre-installed. You don't need to do anything other than turning it on to start using these features.
|
It is ready to use straight out of the box, with time, date, temperature, and humidity pages pre-installed. You don't need to do anything other than turning it on to start using these features.
|
||||||
|
|
||||||
@@ -35,8 +40,10 @@ Join the thousands of satisfied awtrix users who have already chosen Awtrix 2 an
|
|||||||
- Onscreen menu where you can change your settings directly on the device
|
- Onscreen menu where you can change your settings directly on the device
|
||||||
- Pre-installed Apps like time, date, temperature, humidity and battery
|
- Pre-installed Apps like time, date, temperature, humidity and battery
|
||||||
- Add customapps without recompiling straight from your Smarthome.
|
- Add customapps without recompiling straight from your Smarthome.
|
||||||
|
- Noitification support
|
||||||
- Easy to use icon system
|
- Easy to use icon system
|
||||||
- Powerful MQTT commands
|
- Powerful MQTT commands
|
||||||
|
- HTTP API
|
||||||
- RTTTL melody player
|
- RTTTL melody player
|
||||||
- Integrated filebrowser
|
- Integrated filebrowser
|
||||||
- No cloud
|
- No cloud
|
||||||
@@ -47,7 +54,15 @@ Join the thousands of satisfied awtrix users who have already chosen Awtrix 2 an
|
|||||||
Starting is easy as 1-2-3
|
Starting is easy as 1-2-3
|
||||||
[with the documentation](https://blueforcer.github.io/awtrix-light/)
|
[with the documentation](https://blueforcer.github.io/awtrix-light/)
|
||||||
|
|
||||||
|
# Contributors
|
||||||
|
<a href="https://github.com/Blueforcer/awtrix-light/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=Blueforcer/awtrix-light" />
|
||||||
|
</a>
|
||||||
|
|
||||||
# Community
|
# Community
|
||||||
Join the discord channel with over 1500 Users
|
Join the discord channel with over 1500 Users
|
||||||
https://discord.gg/cyBCpdx
|
https://discord.gg/cyBCpdx
|
||||||
|
|
||||||
|
# Support
|
||||||
|
If you like my work, please consider supporting the project.
|
||||||
|
https://github.com/sponsors/Blueforcer
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
# AWTRIX-LIGHT
|
# AWTRIX-LIGHT
|
||||||
|
|
||||||
If you like my work, please consider supporting the project.
|
|
||||||
https://github.com/sponsors/Blueforcer
|
|
||||||
https://paypal.me/blueforcer
|
|
||||||
|
|
||||||
Awtrix Light is a custom firmware for the [Ulanzi Smart Pixel clock](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882).
|
Awtrix Light is a custom firmware for the [Ulanzi Smart Pixel clock](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882).
|
||||||
That offers a simple and user-friendly interface, making it the perfect solution for non-techies who want to enjoy the benefits of the popular awtrix system.
|
It meant to be a companion for your smarthome like HomeAssistant, IOBroker, NodeRed and so on.
|
||||||
|
Even if you don't have a Smarthome system, but would like to experiment, you are still welcome to join us. There are many users who are willing to help you!
|
||||||
|
|
||||||
It is ready to use straight out of the box, with time, date, temperature, and humidity apps pre-installed. You don't need to do anything other than turning it on to start using these features.
|
It is ready to use straight out of the box, with time, date, temperature, and humidity apps pre-installed. You don't need to do anything other than turning it on to start using these features.
|
||||||
|
|
||||||
During the development of Awtrix Light, usability and simplicity are my top priorities. My aim is to make it easy for non-tech-savvy users to benefit from Awtrix Light without any headaches or hours of scripting.
|
During the development of Awtrix Light, usability and simplicity are my top priorities. My aim is to make it easy for non-tech-savvy users to benefit from Awtrix Light without any headaches or hours of scripting.
|
||||||
Awtrix Light is ready to use straight out of the box, without the need for a single line of code or commands.
|
Awtrix Light is ready to use straight out of the box, without the need for a single line of code.
|
||||||
However, for those with more advanced skills, the customization options available with custom apps allow you to take Awtrix Light to its full potential.
|
However, for those with more advanced skills, the customization options available with custom apps allow you to take Awtrix Light to its full potential.
|
||||||
With Awtrix Light, you can effortlessly bring your ideas to life and enjoy a hassle-free experience.
|
With Awtrix Light, you can effortlessly bring your ideas to life and enjoy a hassle-free experience.
|
||||||
Join the thousands of satisfied awtrix users who have already chosen Awtrix 2 and Awtrix Light and experience the difference today!
|
Join the thousands of satisfied awtrix users who have already chosen Awtrix 2 and Awtrix Light and experience the difference today!
|
||||||
https://discord.gg/cyBCpdx
|
https://discord.gg/cyBCpdx
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
If you like my work, please consider supporting the project.
|
||||||
|
https://github.com/sponsors/Blueforcer
|
||||||
|
https://paypal.me/blueforcer
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
- Features
|
- Features
|
||||||
- [Apps](apps.md)
|
- [Apps](apps.md)
|
||||||
- [Alarm clock](alarm.md)
|
- [Alarm clock](alarm.md)
|
||||||
- [Timer](timer.md)
|
|
||||||
- [Icons](icons.md)
|
- [Icons](icons.md)
|
||||||
- [Sounds](sounds.md)
|
- [Sounds](sounds.md)
|
||||||
- [Hidden features](dev.md)
|
- [Hidden features](dev.md)
|
||||||
|
|||||||
60
docs/api.md
60
docs/api.md
@@ -6,6 +6,13 @@ In MQTT awtrix send its stats every 10s to `[PREFIX]/stats`
|
|||||||
With HTTP, make GET request to `http://[IP]/api/stats`
|
With HTTP, make GET request to `http://[IP]/api/stats`
|
||||||
|
|
||||||
|
|
||||||
|
## Update
|
||||||
|
Awtrix searches for an update every 1 Hour. If a new one is found it will be published to HA and in the stats.
|
||||||
|
You can start the update with update button in HA or:
|
||||||
|
| Topic | URL | Payload/Body | HTTP Header | HTTP method |
|
||||||
|
| --- | --- | --- |--- |--- |
|
||||||
|
| `[PREFIX]/doupdate` |`http://[IP]/api/doupdate` | JSON | empty payload/body | POST |
|
||||||
|
|
||||||
## Add custom app
|
## Add custom app
|
||||||
create custom apps or notifications to display your own text and icons.
|
create custom apps or notifications to display your own text and icons.
|
||||||
Have a look at [this section](custom?id=custom-apps-and-notifications)
|
Have a look at [this section](custom?id=custom-apps-and-notifications)
|
||||||
@@ -27,7 +34,7 @@ Switch to next or previous app.
|
|||||||
| Topic | URL | Payload/Body | HTTP method |
|
| Topic | URL | Payload/Body | HTTP method |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `[PREFIX]/nextapp` | `http://[IP]/api/nextapp` | empty payload/body | POST |
|
| `[PREFIX]/nextapp` | `http://[IP]/api/nextapp` | empty payload/body | POST |
|
||||||
| `[PREFIX]/previousapp` | `http://[IP]/api/previousapp` | payload/body | POST |
|
| `[PREFIX]/previousapp` | `http://[IP]/api/previousapp` | empty payload/body | POST |
|
||||||
|
|
||||||
## Switch to Specific App
|
## Switch to Specific App
|
||||||
Switch to a specific app by name.
|
Switch to a specific app by name.
|
||||||
@@ -43,7 +50,8 @@ Built-in app names are:
|
|||||||
- `hum`
|
- `hum`
|
||||||
- `bat`
|
- `bat`
|
||||||
|
|
||||||
For custom apps, use the name you set in the topic. For example, if `[PREFIX]/custom/test` is your topic, then `test` is the name.
|
For custom apps, use the name you set in the topic or http request header.
|
||||||
|
In MQTT for example, if `[PREFIX]/custom/test` is your topic, then `test` is the name.
|
||||||
|
|
||||||
## Add/remove and rearange apps
|
## Add/remove and rearange apps
|
||||||
|
|
||||||
@@ -63,10 +71,14 @@ This provides flexibility in organizing apps according to personal preference.
|
|||||||
|
|
||||||
The JSON payload is an array of objects, where each object represents an app to be displayed on awtrix. Each app object contains the following fields:
|
The JSON payload is an array of objects, where each object represents an app to be displayed on awtrix. Each app object contains the following fields:
|
||||||
|
|
||||||
`"name"`: The name of the app ("time", "date", "temp", "hum", "bat") are the native apps.
|
### JSON Properties
|
||||||
For custom apps, use the name you set in the topic. For example, if `[PREFIX]/custom/test` is your topic, then `test` is the name.
|
|
||||||
`"show"`: A boolean indicating whether the app should be shown on the screen or not. If not present, the app is considered active by default.
|
| Property | Description |Default |
|
||||||
`"pos"`: An integer indicating the position of the app in the list. If not present, the app will be added to the end of the list.
|
|----------|-------------|-------------|
|
||||||
|
| name | The name of the app. If it's a native app, it can be one of "time", "date", "temp", "hum", or "bat". For custom apps, use the name you set in the topic. For example, if `[PREFIX]/custom/test` is your topic, then `test` is the name. | |
|
||||||
|
| show | A boolean indicating whether the app should be shown on the screen or not. If not present, the app is considered active by default. | true |
|
||||||
|
| pos | An integer indicating the position of the app in the list. If not present, the app will be added to the end of the list. | Last Item |
|
||||||
|
|
||||||
|
|
||||||
> You can also just send the information for one app.
|
> You can also just send the information for one app.
|
||||||
|
|
||||||
@@ -128,6 +140,8 @@ Change various settings related to the app display.
|
|||||||
| --- | --- | --- |--- |
|
| --- | --- | --- |--- |
|
||||||
| `[PREFIX]/settings` |`http://[IP]/api/settings`| JSON | POST |
|
| `[PREFIX]/settings` |`http://[IP]/api/settings`| JSON | POST |
|
||||||
|
|
||||||
|
|
||||||
|
#### JSON Properties
|
||||||
Each property is optional; you do not need to send all.
|
Each property is optional; you do not need to send all.
|
||||||
|
|
||||||
| Key | Type | Description | Value Range | Default |
|
| Key | Type | Description | Value Range | Default |
|
||||||
@@ -139,3 +153,37 @@ Each property is optional; you do not need to send all.
|
|||||||
| `brightness` | number | Determines the brightness of the matrix. | An integer between 0 and 255. | N/A |
|
| `brightness` | number | Determines the brightness of the matrix. | An integer between 0 and 255. | N/A |
|
||||||
| `autobrightness` | boolean | Determines if automatic brightness control is active. | `true` or `false`. | N/A |
|
| `autobrightness` | boolean | Determines if automatic brightness control is active. | `true` or `false`. | N/A |
|
||||||
| `autotransition` | boolean | Determines if automatic switching to the next app is active. | `true` or `false`. | N/A |
|
| `autotransition` | boolean | Determines if automatic switching to the next app is active. | `true` or `false`. | N/A |
|
||||||
|
|
||||||
|
|
||||||
|
## Timer
|
||||||
|
|
||||||
|
With AWTRIX Light, you can set a timer using MQTT. Simply send a JSON object to the topic **[PREFIX]/timer** to start a timer.
|
||||||
|
|
||||||
|
When the timer goes off, the display will show a notification, and you can dismiss the timer by pressing the middle button.
|
||||||
|
|
||||||
|
#### JSON Properties
|
||||||
|
|
||||||
|
The JSON object has the following properties:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| --- | ---- | ----------- |
|
||||||
|
| `hours` | number | The number of hours after midnight when the timer should be triggered. |
|
||||||
|
| `minutes` | number | The number of minutes after the hour when the timer should be triggered. |
|
||||||
|
| `seconds` | number | The number of seconds after the minute when the timer should be triggered. |
|
||||||
|
| `sound` | string | The name of the sound file (without extension) to play when the timer is triggered. |
|
||||||
|
|
||||||
|
Each value is optional, so you can set a timer for just minutes, or any combination of hours, minutes, and seconds. If you only want to start a timer in some minutes, just send the minutes.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Here's an example JSON object to start a timer for 1 hour, 30 minutes, and 10 seconds, with the sound "friends":
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hours": 1,
|
||||||
|
"minutes": 30,
|
||||||
|
"seconds": 10,
|
||||||
|
"sound": "friends"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ The JSON object has the following properties:
|
|||||||
| `icon` | string | The icon ID or filename (without extension) to display on the page. | |
|
| `icon` | string | The icon ID or filename (without extension) to display on the page. | |
|
||||||
| `repeat` | number | Sets how many times the text should be scrolled through the matrix before the display ends. | 1 |
|
| `repeat` | number | Sets how many times the text should be scrolled through the matrix before the display ends. | 1 |
|
||||||
| `rainbow` | boolean | Fades each letter in the text differently through the entire RGB spectrum. | false |
|
| `rainbow` | boolean | Fades each letter in the text differently through the entire RGB spectrum. | false |
|
||||||
| `duration` | number | Sets how long the page should be displayed. | 5 |
|
| `duration` | number | Sets how long the notification should be displayed. | 5 |
|
||||||
| `color` | string | A color hex string for the text color, or an array of R,G,B values | "#FFFFFF" or [255,255,0] |
|
| `color` | string | A color hex string for the text color, or an array of R,G,B values | "#FFFFFF" or [255,255,0] |
|
||||||
| `hold` | boolean | Set it to true, to hold your notification on top until you press the middle button or dismiss it via HomeAssistant. This key only belongs to notification. | false |
|
| `hold` | boolean | Set it to true, to hold your notification on top until you press the middle button or dismiss it via HomeAssistant. This key only belongs to notification. | false |
|
||||||
| `sound` | string | The filename of your RTTTL ringtone file (without extension). | |
|
| `sound` | string | The filename of your RTTTL ringtone file (without extension). | |
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ The JSON object has the following properties:
|
|||||||
|
|
||||||
| Key | Type | Description | Default |
|
| Key | Type | Description | Default |
|
||||||
| --- | ---- | ----------- | ------- |
|
| --- | ---- | ----------- | ------- |
|
||||||
| `bootsound` | string | Uses a custom melodie from the MELODIES folder | standart |
|
| `bootsound` | string | Uses a custom melodie from the MELODIES folder | |
|
||||||
| `uppercase` | boolean | Print every character in uppercase | true |
|
| `uppercase` | boolean | Print every character in uppercase | true |
|
||||||
|
|||||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "AWTRIX Light",
|
"name": "AWTRIX Light",
|
||||||
"version": "0.43",
|
"version": "0.47",
|
||||||
"home_assistant_domain": "AwtrixLight",
|
"home_assistant_domain": "AwtrixLight",
|
||||||
"funding_url": "https://blueforcer.de",
|
"funding_url": "https://blueforcer.de",
|
||||||
"new_install_prompt_erase": true,
|
"new_install_prompt_erase": true,
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
# Timer
|
|
||||||
|
|
||||||
With AWTRIX Light, you can set a timer using MQTT. Simply send a JSON object to the topic **[PREFIX]/timer** to start a timer.
|
|
||||||
|
|
||||||
When the timer goes off, the display will show a notification, and you can dismiss the timer by pressing the middle button.
|
|
||||||
|
|
||||||
## JSON Properties
|
|
||||||
|
|
||||||
The JSON object has the following properties:
|
|
||||||
|
|
||||||
| Key | Type | Description |
|
|
||||||
| --- | ---- | ----------- |
|
|
||||||
| `hours` | number | The number of hours after midnight when the timer should be triggered. |
|
|
||||||
| `minutes` | number | The number of minutes after the hour when the timer should be triggered. |
|
|
||||||
| `seconds` | number | The number of seconds after the minute when the timer should be triggered. |
|
|
||||||
| `sound` | string | The name of the sound file (without extension) to play when the timer is triggered. |
|
|
||||||
|
|
||||||
Each value is optional, so you can set a timer for just minutes, or any combination of hours, minutes, and seconds. If you only want to start a timer in some minutes, just send the minutes.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
Here's an example JSON object to start a timer for 1 hour, 30 minutes, and 10 seconds, with the sound "friends":
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"hours": 1,
|
|
||||||
"minutes": 30,
|
|
||||||
"seconds": 10,
|
|
||||||
"sound": "friends"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -69,6 +69,17 @@ const char HAtransID[] PROGMEM = {"%s_tra"};
|
|||||||
const char HAtransName[] PROGMEM = {"Transition"};
|
const char HAtransName[] PROGMEM = {"Transition"};
|
||||||
const char HAtransIcon[] PROGMEM = {"mdi:swap-vertical"};
|
const char HAtransIcon[] PROGMEM = {"mdi:swap-vertical"};
|
||||||
|
|
||||||
|
const char HAupdateID[] PROGMEM = {"%s_upd"};
|
||||||
|
const char HAupdateName[] PROGMEM = {"Update"};
|
||||||
|
const char HAupdateClass[] PROGMEM = {"update"};
|
||||||
|
const char HAupdateIcon[] PROGMEM = {"mdi:update"};
|
||||||
|
|
||||||
|
|
||||||
|
const char HAdoUpID[] PROGMEM = {"%s_doupd"};
|
||||||
|
const char HAdoUpName[] PROGMEM = {"Start Update"};
|
||||||
|
const char HAdoUpIcon[] PROGMEM = {"mdi:update"};
|
||||||
|
|
||||||
|
|
||||||
const char HAsigID[] PROGMEM = {"%s_sig"};
|
const char HAsigID[] PROGMEM = {"%s_sig"};
|
||||||
const char HAsigIcon[] PROGMEM = {"mdi:sun-wireless"};
|
const char HAsigIcon[] PROGMEM = {"mdi:sun-wireless"};
|
||||||
const char HAsigName[] PROGMEM = {"WiFi strength"};
|
const char HAsigName[] PROGMEM = {"WiFi strength"};
|
||||||
@@ -104,3 +115,4 @@ const char TempKey[] PROGMEM = {"temp"};
|
|||||||
const char HumKey[] PROGMEM = {"hum"};
|
const char HumKey[] PROGMEM = {"hum"};
|
||||||
const char UpTimeKey[] PROGMEM = {"uptime"};
|
const char UpTimeKey[] PROGMEM = {"uptime"};
|
||||||
const char SignalStrengthKey[] PROGMEM = {"wifi_signal"};
|
const char SignalStrengthKey[] PROGMEM = {"wifi_signal"};
|
||||||
|
const char UpdateKey[] PROGMEM = {"up_available"};
|
||||||
|
|||||||
@@ -77,10 +77,19 @@ extern const char HAupID[];
|
|||||||
extern const char HAupName[];
|
extern const char HAupName[];
|
||||||
extern const char HAupClass[];
|
extern const char HAupClass[];
|
||||||
|
|
||||||
|
extern const char HAdoUpID[];
|
||||||
|
extern const char HAdoUpName[];
|
||||||
|
extern const char HAdoUpIcon[];
|
||||||
|
|
||||||
extern const char HAtransID[];
|
extern const char HAtransID[];
|
||||||
extern const char HAtransName[];
|
extern const char HAtransName[];
|
||||||
extern const char HAtransIcon[];
|
extern const char HAtransIcon[];
|
||||||
|
|
||||||
|
extern const char HAupdateID[];
|
||||||
|
extern const char HAupdateName[];
|
||||||
|
extern const char HAupdateClass[];
|
||||||
|
extern const char HAupdateIcon[];
|
||||||
|
|
||||||
extern const char HAbtnLID[];
|
extern const char HAbtnLID[];
|
||||||
extern const char HAbtnLName[];
|
extern const char HAbtnLName[];
|
||||||
|
|
||||||
@@ -106,5 +115,5 @@ extern const char TempKey[];
|
|||||||
extern const char HumKey[];
|
extern const char HumKey[];
|
||||||
extern const char UpTimeKey[];
|
extern const char UpTimeKey[];
|
||||||
extern const char SignalStrengthKey[];
|
extern const char SignalStrengthKey[];
|
||||||
|
extern const char UpdateKey[];
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ void DisplayManager_::generateCustomPage(String name, const char *json)
|
|||||||
customApp.barSize = 0;
|
customApp.barSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
customApp.duration = doc.containsKey("duration") ? doc["duration"].as<int>() * 1000 : -1;
|
customApp.duration = doc.containsKey("duration") ? doc["duration"].as<int>() * 1000 : 0;
|
||||||
int pos = doc.containsKey("pos") ? doc["pos"].as<uint8_t>() : -1;
|
int pos = doc.containsKey("pos") ? doc["pos"].as<uint8_t>() : -1;
|
||||||
customApp.rainbow = doc.containsKey("rainbow") ? doc["rainbow"] : false;
|
customApp.rainbow = doc.containsKey("rainbow") ? doc["rainbow"] : false;
|
||||||
customApp.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
|
customApp.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
|
||||||
@@ -519,7 +519,7 @@ void DisplayManager_::loadNativeApps()
|
|||||||
|
|
||||||
void DisplayManager_::setup()
|
void DisplayManager_::setup()
|
||||||
{
|
{
|
||||||
|
|
||||||
TJpgDec.setCallback(jpg_output);
|
TJpgDec.setCallback(jpg_output);
|
||||||
TJpgDec.setJpgScale(1);
|
TJpgDec.setJpgScale(1);
|
||||||
FastLED.addLeds<NEOPIXEL, MATRIX_PIN>(leds, MATRIX_WIDTH * MATRIX_HEIGHT);
|
FastLED.addLeds<NEOPIXEL, MATRIX_PIN>(leds, MATRIX_WIDTH * MATRIX_HEIGHT);
|
||||||
@@ -907,8 +907,10 @@ String DisplayManager_::getStat()
|
|||||||
{
|
{
|
||||||
StaticJsonDocument<200> doc;
|
StaticJsonDocument<200> doc;
|
||||||
char buffer[5];
|
char buffer[5];
|
||||||
|
#ifdef ULANZI
|
||||||
doc[BatKey] = BATTERY_PERCENT;
|
doc[BatKey] = BATTERY_PERCENT;
|
||||||
doc[BatRawKey] = BATTERY_RAW;
|
doc[BatRawKey] = BATTERY_RAW;
|
||||||
|
#endif
|
||||||
snprintf(buffer, 5, "%.0f", CURRENT_LUX);
|
snprintf(buffer, 5, "%.0f", CURRENT_LUX);
|
||||||
doc[LuxKey] = buffer;
|
doc[LuxKey] = buffer;
|
||||||
doc[LDRRawKey] = LDR_RAW;
|
doc[LDRRawKey] = LDR_RAW;
|
||||||
@@ -920,6 +922,7 @@ String DisplayManager_::getStat()
|
|||||||
doc[HumKey] = buffer;
|
doc[HumKey] = buffer;
|
||||||
doc[UpTimeKey] = PeripheryManager.readUptime();
|
doc[UpTimeKey] = PeripheryManager.readUptime();
|
||||||
doc[SignalStrengthKey] = WiFi.RSSI();
|
doc[SignalStrengthKey] = WiFi.RSSI();
|
||||||
|
doc[UpdateKey] = UPDATE_AVAILABLE;
|
||||||
String jsonString;
|
String jsonString;
|
||||||
serializeJson(doc, jsonString);
|
serializeJson(doc, jsonString);
|
||||||
return jsonString;
|
return jsonString;
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ IPAddress gateway;
|
|||||||
IPAddress subnet;
|
IPAddress subnet;
|
||||||
IPAddress primaryDNS;
|
IPAddress primaryDNS;
|
||||||
IPAddress secondaryDNS;
|
IPAddress secondaryDNS;
|
||||||
const char *VERSION = "0.46";
|
const char *VERSION = "0.47";
|
||||||
String MQTT_HOST = "";
|
String MQTT_HOST = "";
|
||||||
uint16_t MQTT_PORT = 1883;
|
uint16_t MQTT_PORT = 1883;
|
||||||
String MQTT_USER;
|
String MQTT_USER;
|
||||||
@@ -187,4 +187,5 @@ bool SOUND_ACTIVE;
|
|||||||
String BOOT_SOUND = "";
|
String BOOT_SOUND = "";
|
||||||
uint8_t VOLUME;
|
uint8_t VOLUME;
|
||||||
uint8_t VOLUME_PERCENT;
|
uint8_t VOLUME_PERCENT;
|
||||||
int MATRIX_LAYOUT;
|
int MATRIX_LAYOUT;
|
||||||
|
bool UPDATE_AVAILABLE = false;
|
||||||
@@ -71,6 +71,7 @@ extern String BOOT_SOUND;
|
|||||||
extern uint8_t VOLUME;
|
extern uint8_t VOLUME;
|
||||||
extern uint8_t VOLUME_PERCENT;
|
extern uint8_t VOLUME_PERCENT;
|
||||||
extern int MATRIX_LAYOUT;
|
extern int MATRIX_LAYOUT;
|
||||||
|
extern bool UPDATE_AVAILABLE;
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
#endif // Globals_H
|
#endif // Globals_H
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include "Dictionary.h"
|
#include "Dictionary.h"
|
||||||
#include "PeripheryManager.h"
|
#include "PeripheryManager.h"
|
||||||
|
#include "UpdateManager.h"
|
||||||
|
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
uint8_t lastBrightness;
|
uint8_t lastBrightness;
|
||||||
@@ -36,6 +37,8 @@ HASensor *ram = nullptr;
|
|||||||
HABinarySensor *btnleft = nullptr;
|
HABinarySensor *btnleft = nullptr;
|
||||||
HABinarySensor *btnmid = nullptr;
|
HABinarySensor *btnmid = nullptr;
|
||||||
HABinarySensor *btnright = nullptr;
|
HABinarySensor *btnright = nullptr;
|
||||||
|
HABinarySensor *update = nullptr;
|
||||||
|
HAButton *doUpdate = nullptr;
|
||||||
|
|
||||||
// The getter for the instantiated singleton instance
|
// The getter for the instantiated singleton instance
|
||||||
MQTTManager_ &MQTTManager_::getInstance()
|
MQTTManager_ &MQTTManager_::getInstance()
|
||||||
@@ -61,6 +64,11 @@ void onButtonCommand(HAButton *sender)
|
|||||||
{
|
{
|
||||||
DisplayManager.previousApp();
|
DisplayManager.previousApp();
|
||||||
}
|
}
|
||||||
|
else if (sender == doUpdate)
|
||||||
|
{
|
||||||
|
if (UPDATE_AVAILABLE)
|
||||||
|
UpdateManager.updateFirmware();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSwitchCommand(bool state, HASwitch *sender)
|
void onSwitchCommand(bool state, HASwitch *sender)
|
||||||
@@ -183,6 +191,12 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length)
|
|||||||
DisplayManager.previousApp();
|
DisplayManager.previousApp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (strTopic == MQTT_PREFIX + "/doupdate")
|
||||||
|
{
|
||||||
|
if (UPDATE_AVAILABLE)
|
||||||
|
UpdateManager.updateFirmware();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
else if (strTopic.startsWith(MQTT_PREFIX + "/custom"))
|
else if (strTopic.startsWith(MQTT_PREFIX + "/custom"))
|
||||||
{
|
{
|
||||||
@@ -212,6 +226,7 @@ void onMqttConnected()
|
|||||||
"/settings",
|
"/settings",
|
||||||
"/previousapp",
|
"/previousapp",
|
||||||
"/nextapp",
|
"/nextapp",
|
||||||
|
"/doupdate",
|
||||||
"/nextapp",
|
"/nextapp",
|
||||||
"/apps"};
|
"/apps"};
|
||||||
for (const char *topic : topics)
|
for (const char *topic : topics)
|
||||||
@@ -222,7 +237,6 @@ void onMqttConnected()
|
|||||||
Serial.println(F("MQTT Connected"));
|
Serial.println(F("MQTT Connected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void connect()
|
void connect()
|
||||||
{
|
{
|
||||||
mqtt.onMessage(onMqttMessage);
|
mqtt.onMessage(onMqttMessage);
|
||||||
@@ -241,7 +255,7 @@ void connect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
char matID[40], briID[40];
|
char matID[40], briID[40];
|
||||||
char btnAID[40], btnBID[40], btnCID[40], appID[40], tempID[40], humID[40], luxID[40], verID[40], ramID[40], upID[40], sigID[40], btnLID[40], btnMID[40], btnRID[40], transID[40];
|
char btnAID[40], btnBID[40], btnCID[40], appID[40], tempID[40], humID[40], luxID[40], verID[40], ramID[40], upID[40], sigID[40], btnLID[40], btnMID[40], btnRID[40], transID[40], updateID[40], doUpdateID[40];
|
||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
char batID[40];
|
char batID[40];
|
||||||
#endif
|
#endif
|
||||||
@@ -302,6 +316,12 @@ void MQTTManager_::setup()
|
|||||||
dismiss->setIcon(HAbtnaIcon);
|
dismiss->setIcon(HAbtnaIcon);
|
||||||
dismiss->setName(HAbtnaName);
|
dismiss->setName(HAbtnaName);
|
||||||
|
|
||||||
|
sprintf(doUpdateID, HAdoUpID, macStr);
|
||||||
|
doUpdate = new HAButton(doUpdateID);
|
||||||
|
doUpdate->setIcon(HAdoUpIcon);
|
||||||
|
doUpdate->setName(HAdoUpName);
|
||||||
|
doUpdate->onCommand(onButtonCommand);
|
||||||
|
|
||||||
sprintf(transID, HAtransID, macStr);
|
sprintf(transID, HAtransID, macStr);
|
||||||
transition = new HASwitch(transID);
|
transition = new HASwitch(transID);
|
||||||
transition->setIcon(HAtransIcon);
|
transition->setIcon(HAtransIcon);
|
||||||
@@ -376,6 +396,12 @@ void MQTTManager_::setup()
|
|||||||
btnleft = new HABinarySensor(btnLID);
|
btnleft = new HABinarySensor(btnLID);
|
||||||
btnleft->setName(HAbtnLName);
|
btnleft->setName(HAbtnLName);
|
||||||
|
|
||||||
|
sprintf(updateID, HAupdateID, macStr);
|
||||||
|
update = new HABinarySensor(updateID);
|
||||||
|
update->setIcon(HAupdateIcon);
|
||||||
|
update->setName(HAupdateName);
|
||||||
|
update->setDeviceClass(HAupdateClass);
|
||||||
|
|
||||||
sprintf(btnMID, HAbtnMID, macStr);
|
sprintf(btnMID, HAbtnMID, macStr);
|
||||||
btnmid = new HABinarySensor(btnMID);
|
btnmid = new HABinarySensor(btnMID);
|
||||||
btnmid->setName(HAbtnMName);
|
btnmid->setName(HAbtnMName);
|
||||||
@@ -459,6 +485,8 @@ void MQTTManager_::sendStats()
|
|||||||
uptime->setValue(PeripheryManager.readUptime());
|
uptime->setValue(PeripheryManager.readUptime());
|
||||||
version->setValue(VERSION);
|
version->setValue(VERSION);
|
||||||
transition->setState(AUTO_TRANSITION, false);
|
transition->setState(AUTO_TRANSITION, false);
|
||||||
|
|
||||||
|
update->setState(UPDATE_AVAILABLE, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
#include <ServerManager.h>
|
#include <ServerManager.h>
|
||||||
#include <DisplayManager.h>
|
#include <DisplayManager.h>
|
||||||
#include <PeripheryManager.h>
|
#include <PeripheryManager.h>
|
||||||
#include <updater.h>
|
//#include <update.h>
|
||||||
#include <icons.h>
|
#include <icons.h>
|
||||||
|
#include <UpdateManager.h>
|
||||||
|
|
||||||
String menuText;
|
String menuText;
|
||||||
int menuSelection;
|
int menuSelection;
|
||||||
@@ -377,9 +378,9 @@ void MenuManager_::selectButton()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 13:
|
case 13:
|
||||||
if (FirmwareVersionCheck())
|
if (UpdateManager.checkUpdate(true))
|
||||||
{
|
{
|
||||||
updateFirmware();
|
UpdateManager.updateFirmware();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "DisplayManager.h"
|
#include "DisplayManager.h"
|
||||||
|
#include "UpdateManager.h"
|
||||||
|
|
||||||
WebServer server(80);
|
WebServer server(80);
|
||||||
FSWebServer mws(LittleFS, server);
|
FSWebServer mws(LittleFS, server);
|
||||||
@@ -37,7 +38,6 @@ void saveHandler()
|
|||||||
webRequest->send(200);
|
webRequest->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ServerManager_::setup()
|
void ServerManager_::setup()
|
||||||
{
|
{
|
||||||
if (!local_IP.fromString(NET_IP) || !gateway.fromString(NET_GW) || !subnet.fromString(NET_SN) || !primaryDNS.fromString(NET_PDNS) || !secondaryDNS.fromString(NET_SDNS))
|
if (!local_IP.fromString(NET_IP) || !gateway.fromString(NET_GW) || !subnet.fromString(NET_SN) || !primaryDNS.fromString(NET_PDNS) || !secondaryDNS.fromString(NET_SDNS))
|
||||||
@@ -53,7 +53,7 @@ void ServerManager_::setup()
|
|||||||
|
|
||||||
if (isConnected)
|
if (isConnected)
|
||||||
{
|
{
|
||||||
|
|
||||||
mws.addOptionBox("Network");
|
mws.addOptionBox("Network");
|
||||||
mws.addOption("Static IP", NET_STATIC);
|
mws.addOption("Static IP", NET_STATIC);
|
||||||
mws.addOption("Local IP", NET_IP);
|
mws.addOption("Local IP", NET_IP);
|
||||||
@@ -97,6 +97,9 @@ void ServerManager_::setup()
|
|||||||
{ DisplayManager.generateCustomPage(mws.webserver->arg("name"),mws.webserver->arg("plain").c_str()); mws.webserver->send(200,"OK"); });
|
{ DisplayManager.generateCustomPage(mws.webserver->arg("name"),mws.webserver->arg("plain").c_str()); mws.webserver->send(200,"OK"); });
|
||||||
mws.addHandler("/api/stats", HTTP_GET, []()
|
mws.addHandler("/api/stats", HTTP_GET, []()
|
||||||
{ mws.webserver->sendContent(DisplayManager.getStat()); });
|
{ mws.webserver->sendContent(DisplayManager.getStat()); });
|
||||||
|
mws.addHandler("/api/doupdate", HTTP_POST, []()
|
||||||
|
{ if (UPDATE_AVAILABLE)
|
||||||
|
UpdateManager.updateFirmware(); mws.webserver->send(200,"OK"); });
|
||||||
Serial.println("Webserver loaded");
|
Serial.println("Webserver loaded");
|
||||||
}
|
}
|
||||||
mws.addHandler("/version", HTTP_GET, versionHandler);
|
mws.addHandler("/version", HTTP_GET, versionHandler);
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern ServerManager_ &ServerManager;
|
extern ServerManager_ &ServerManager;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,20 +1,34 @@
|
|||||||
|
#include <UpdateManager.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#include <HTTPUpdate.h>
|
#include <HTTPUpdate.h>
|
||||||
#include <WiFiClientSecure.h>
|
#include <WiFiClientSecure.h>
|
||||||
#include "cert.h"
|
#include "cert.h"
|
||||||
#include "DisplayManager.h"
|
#include "DisplayManager.h"
|
||||||
|
#include <Ticker.h>
|
||||||
|
#include "Globals.h"
|
||||||
|
|
||||||
#define URL_fw_Version "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/version"
|
#define URL_fw_Version "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/version"
|
||||||
#define URL_fw_Bin "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/docs/flasher/firmware/firmware.bin"
|
#define URL_fw_Bin "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/docs/flasher/firmware/firmware.bin"
|
||||||
|
|
||||||
|
Ticker UpdateTicker;
|
||||||
|
|
||||||
|
// The getter for the instantiated singleton instance
|
||||||
|
UpdateManager_ &UpdateManager_::getInstance()
|
||||||
|
{
|
||||||
|
static UpdateManager_ instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the global shared instance
|
||||||
|
UpdateManager_ &UpdateManager = UpdateManager.getInstance();
|
||||||
|
|
||||||
void update_started()
|
void update_started()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_finished()
|
void update_finished()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_progress(int cur, int total)
|
void update_progress(int cur, int total)
|
||||||
@@ -29,7 +43,7 @@ void update_error(int err)
|
|||||||
DisplayManager.show();
|
DisplayManager.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateFirmware()
|
void UpdateManager_::updateFirmware()
|
||||||
{
|
{
|
||||||
WiFiClientSecure client;
|
WiFiClientSecure client;
|
||||||
client.setCACert(rootCACertificate);
|
client.setCACert(rootCACertificate);
|
||||||
@@ -56,13 +70,15 @@ void updateFirmware()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UpdateManager_::checkUpdate(bool withScreen)
|
||||||
bool FirmwareVersionCheck()
|
|
||||||
{
|
{
|
||||||
|
if (withScreen)
|
||||||
|
{
|
||||||
|
DisplayManager.clear();
|
||||||
|
DisplayManager.printText(0, 6, "CHECK", true, true);
|
||||||
|
DisplayManager.show();
|
||||||
|
}
|
||||||
|
|
||||||
DisplayManager.clear();
|
|
||||||
DisplayManager.printText(0, 6, "CHECK", true, true);
|
|
||||||
DisplayManager.show();
|
|
||||||
String payload;
|
String payload;
|
||||||
int httpCode;
|
int httpCode;
|
||||||
String fwurl = "";
|
String fwurl = "";
|
||||||
@@ -103,20 +119,34 @@ bool FirmwareVersionCheck()
|
|||||||
payload.trim();
|
payload.trim();
|
||||||
if (payload.equals(VERSION))
|
if (payload.equals(VERSION))
|
||||||
{
|
{
|
||||||
Serial.printf("\nDevice already on latest firmware version:%s\n", VERSION);
|
UPDATE_AVAILABLE = false;
|
||||||
DisplayManager.clear();
|
Serial.printf("\nDevice already on latest firmware version: %s\n", VERSION);
|
||||||
DisplayManager.printText(0, 6, "NO UP :(", true, true);
|
if (withScreen)
|
||||||
DisplayManager.show();
|
{
|
||||||
delay(1000);
|
DisplayManager.clear();
|
||||||
|
DisplayManager.printText(0, 6, "NO UP :(", true, true);
|
||||||
|
DisplayManager.show();
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.println(payload);
|
UPDATE_AVAILABLE = true;
|
||||||
Serial.println("New firmware detected");
|
|
||||||
DisplayManager.printText(0, 6, payload.c_str(), true, true);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UPDATE_AVAILABLE = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkUpdateNoReturn()
|
||||||
|
{
|
||||||
|
Serial.println("Check Update");
|
||||||
|
UpdateManager.getInstance().checkUpdate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateManager_::setup()
|
||||||
|
{
|
||||||
|
UpdateTicker.attach(3600, checkUpdateNoReturn);
|
||||||
|
}
|
||||||
18
src/UpdateManager.h
Normal file
18
src/UpdateManager.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef UpdateManager_h
|
||||||
|
#define UpdateManager_h
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class UpdateManager_
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
UpdateManager_() = default;
|
||||||
|
public:
|
||||||
|
static UpdateManager_ &getInstance();
|
||||||
|
void setup();
|
||||||
|
bool checkUpdate(bool);
|
||||||
|
void updateFirmware();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern UpdateManager_ &UpdateManager;
|
||||||
|
#endif
|
||||||
@@ -75,6 +75,8 @@ void setup()
|
|||||||
{
|
{
|
||||||
MQTTManager.setup();
|
MQTTManager.setup();
|
||||||
DisplayManager.loadNativeApps();
|
DisplayManager.loadNativeApps();
|
||||||
|
UpdateManager.setup();
|
||||||
|
UpdateManager.checkUpdate(false);
|
||||||
StopTask = true;
|
StopTask = true;
|
||||||
float x = 4;
|
float x = 4;
|
||||||
while (x >= -85)
|
while (x >= -85)
|
||||||
@@ -101,7 +103,6 @@ void loop()
|
|||||||
PeripheryManager.tick();
|
PeripheryManager.tick();
|
||||||
if (ServerManager.isConnected)
|
if (ServerManager.isConnected)
|
||||||
{
|
{
|
||||||
|
|
||||||
MQTTManager.tick();
|
MQTTManager.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user