mirror of
https://github.com/esphome/esphome.git
synced 2026-01-16 23:14:52 -07:00
Compare commits
8 Commits
api_const
...
web_server
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6181982e8 | ||
|
|
6832efbacc | ||
|
|
3057a0484f | ||
|
|
bc78f80f77 | ||
|
|
916b028fb2 | ||
|
|
16adae7359 | ||
|
|
4906f87751 | ||
|
|
5b37d2fb27 |
96
.claude/skills/pr-workflow/SKILL.md
Normal file
96
.claude/skills/pr-workflow/SKILL.md
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
name: pr-workflow
|
||||
description: Create pull requests for esphome. Use when creating PRs, submitting changes, or preparing contributions.
|
||||
allowed-tools: Read, Bash, Glob, Grep
|
||||
---
|
||||
|
||||
# ESPHome PR Workflow
|
||||
|
||||
When creating a pull request for esphome, follow these steps:
|
||||
|
||||
## 1. Create Branch from Upstream
|
||||
|
||||
Always base your branch on **upstream** (not origin/fork) to ensure you have the latest code:
|
||||
|
||||
```bash
|
||||
git fetch upstream
|
||||
git checkout -b <branch-name> upstream/dev
|
||||
```
|
||||
|
||||
## 2. Read the PR Template
|
||||
|
||||
Before creating a PR, read `.github/PULL_REQUEST_TEMPLATE.md` to understand required fields.
|
||||
|
||||
## 3. Create the PR
|
||||
|
||||
Use `gh pr create` with the **full template** filled in. Never skip or abbreviate sections.
|
||||
|
||||
Required fields:
|
||||
- **What does this implement/fix?**: Brief description of changes
|
||||
- **Types of changes**: Check ONE appropriate box (Bugfix, New feature, Breaking change, etc.)
|
||||
- **Related issue**: Use `fixes <link>` syntax if applicable
|
||||
- **Pull request in esphome-docs**: Link if docs are needed
|
||||
- **Test Environment**: Check platforms you tested on
|
||||
- **Example config.yaml**: Include working example YAML
|
||||
- **Checklist**: Verify code is tested and tests added
|
||||
|
||||
## 4. Example PR Body
|
||||
|
||||
```markdown
|
||||
# What does this implement/fix?
|
||||
|
||||
<describe your changes here>
|
||||
|
||||
## Types of changes
|
||||
|
||||
- [ ] Bugfix (non-breaking change which fixes an issue)
|
||||
- [x] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Developer breaking change (an API change that could break external components)
|
||||
- [ ] Code quality improvements to existing code or addition of tests
|
||||
- [ ] Other
|
||||
|
||||
**Related issue or feature (if applicable):**
|
||||
|
||||
- fixes https://github.com/esphome/esphome/issues/XXX
|
||||
|
||||
**Pull request in [esphome-docs](https://github.com/esphome/esphome-docs) with documentation (if applicable):**
|
||||
|
||||
- esphome/esphome-docs#XXX
|
||||
|
||||
## Test Environment
|
||||
|
||||
- [x] ESP32
|
||||
- [x] ESP32 IDF
|
||||
- [ ] ESP8266
|
||||
- [ ] RP2040
|
||||
- [ ] BK72xx
|
||||
- [ ] RTL87xx
|
||||
- [ ] LN882x
|
||||
- [ ] nRF52840
|
||||
|
||||
## Example entry for `config.yaml`:
|
||||
|
||||
```yaml
|
||||
# Example config.yaml
|
||||
component_name:
|
||||
id: my_component
|
||||
option: value
|
||||
```
|
||||
|
||||
## Checklist:
|
||||
- [x] The code change is tested and works locally.
|
||||
- [x] Tests have been added to verify that the new code works (under `tests/` folder).
|
||||
|
||||
If user exposed functionality or configuration variables are added/changed:
|
||||
- [ ] Documentation added/updated in [esphome-docs](https://github.com/esphome/esphome-docs).
|
||||
```
|
||||
|
||||
## 5. Push and Create PR
|
||||
|
||||
```bash
|
||||
git push -u origin <branch-name>
|
||||
gh pr create --repo esphome/esphome --base dev --title "[component] Brief description"
|
||||
```
|
||||
|
||||
Title should be prefixed with the component name in brackets, e.g. `[safe_mode] Add feature`.
|
||||
2
.github/actions/restore-python/action.yml
vendored
2
.github/actions/restore-python/action.yml
vendored
@@ -22,7 +22,7 @@ runs:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: venv
|
||||
# yamllint disable-line rule:line-length
|
||||
|
||||
30
.github/workflows/ci.yml
vendored
30
.github/workflows/ci.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: venv
|
||||
# yamllint disable-line rule:line-length
|
||||
@@ -157,7 +157,7 @@ jobs:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
- name: Save Python virtual environment cache
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/save@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: venv
|
||||
key: ${{ runner.os }}-${{ steps.restore-python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
|
||||
@@ -193,7 +193,7 @@ jobs:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||
- name: Restore components graph cache
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: .temp/components_graph.json
|
||||
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
|
||||
@@ -223,7 +223,7 @@ jobs:
|
||||
echo "component-test-batches=$(echo "$output" | jq -c '.component_test_batches')" >> $GITHUB_OUTPUT
|
||||
- name: Save components graph cache
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/save@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: .temp/components_graph.json
|
||||
key: components-graph-${{ hashFiles('esphome/components/**/*.py') }}
|
||||
@@ -245,7 +245,7 @@ jobs:
|
||||
python-version: "3.13"
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: venv
|
||||
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }}
|
||||
@@ -334,14 +334,14 @@ jobs:
|
||||
|
||||
- name: Cache platformio
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
|
||||
|
||||
- name: Cache platformio
|
||||
if: github.ref != 'refs/heads/dev'
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-${{ matrix.pio_cache_key }}-${{ hashFiles('platformio.ini') }}
|
||||
@@ -413,14 +413,14 @@ jobs:
|
||||
|
||||
- name: Cache platformio
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
|
||||
|
||||
- name: Cache platformio
|
||||
if: github.ref != 'refs/heads/dev'
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
|
||||
@@ -502,14 +502,14 @@ jobs:
|
||||
|
||||
- name: Cache platformio
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
|
||||
|
||||
- name: Cache platformio
|
||||
if: github.ref != 'refs/heads/dev'
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-tidyesp32-${{ hashFiles('platformio.ini') }}
|
||||
@@ -735,7 +735,7 @@ jobs:
|
||||
- name: Restore cached memory analysis
|
||||
id: cache-memory-analysis
|
||||
if: steps.check-script.outputs.skip != 'true'
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: memory-analysis-target.json
|
||||
key: ${{ steps.cache-key.outputs.cache-key }}
|
||||
@@ -759,7 +759,7 @@ jobs:
|
||||
|
||||
- name: Cache platformio
|
||||
if: steps.check-script.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
|
||||
@@ -800,7 +800,7 @@ jobs:
|
||||
|
||||
- name: Save memory analysis to cache
|
||||
if: steps.check-script.outputs.skip != 'true' && steps.cache-memory-analysis.outputs.cache-hit != 'true' && steps.build.outcome == 'success'
|
||||
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/save@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: memory-analysis-target.json
|
||||
key: ${{ steps.cache-key.outputs.cache-key }}
|
||||
@@ -847,7 +847,7 @@ jobs:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
cache-key: ${{ needs.common.outputs.cache-key }}
|
||||
- name: Cache platformio
|
||||
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: platformio-memory-${{ fromJSON(needs.determine-jobs.outputs.memory_impact).platform }}-${{ hashFiles('platformio.ini') }}
|
||||
|
||||
@@ -101,4 +101,225 @@ DriverChip(
|
||||
(0xFF, 0x77, 0x01, 0x00, 0x00, 0x00),
|
||||
]
|
||||
)
|
||||
|
||||
# jc8012P4A1 Driver Configuration (jd9365)
|
||||
# Using parameters from esp_lcd_jd9365.h and the working full init sequence
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
# * Resolution: 800x1280
|
||||
# * PCLK Frequency: 60 MHz
|
||||
# * DSI Lane Bit Rate: 1 Gbps (using 2-Lane DSI configuration)
|
||||
# * Horizontal Timing (hsync_pulse_width=20, hsync_back_porch=20, hsync_front_porch=40)
|
||||
# * Vertical Timing (vsync_pulse_width=4, vsync_back_porch=8, vsync_front_porch=20)
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
DriverChip(
|
||||
"JC8012P4A1",
|
||||
width=800,
|
||||
height=1280,
|
||||
hsync_back_porch=20,
|
||||
hsync_pulse_width=20,
|
||||
hsync_front_porch=40,
|
||||
vsync_back_porch=8,
|
||||
vsync_pulse_width=4,
|
||||
vsync_front_porch=20,
|
||||
pclk_frequency="60MHz",
|
||||
lane_bit_rate="1Gbps",
|
||||
swap_xy=cv.UNDEFINED,
|
||||
color_order="RGB",
|
||||
reset_pin=27,
|
||||
initsequence=[
|
||||
(0xE0, 0x00),
|
||||
(0xE1, 0x93),
|
||||
(0xE2, 0x65),
|
||||
(0xE3, 0xF8),
|
||||
(0x80, 0x01),
|
||||
(0xE0, 0x01),
|
||||
(0x00, 0x00),
|
||||
(0x01, 0x39),
|
||||
(0x03, 0x10),
|
||||
(0x04, 0x41),
|
||||
(0x0C, 0x74),
|
||||
(0x17, 0x00),
|
||||
(0x18, 0xD7),
|
||||
(0x19, 0x00),
|
||||
(0x1A, 0x00),
|
||||
(0x1B, 0xD7),
|
||||
(0x1C, 0x00),
|
||||
(0x24, 0xFE),
|
||||
(0x35, 0x26),
|
||||
(0x37, 0x69),
|
||||
(0x38, 0x05),
|
||||
(0x39, 0x06),
|
||||
(0x3A, 0x08),
|
||||
(0x3C, 0x78),
|
||||
(0x3D, 0xFF),
|
||||
(0x3E, 0xFF),
|
||||
(0x3F, 0xFF),
|
||||
(0x40, 0x06),
|
||||
(0x41, 0xA0),
|
||||
(0x43, 0x14),
|
||||
(0x44, 0x0B),
|
||||
(0x45, 0x30),
|
||||
(0x4B, 0x04),
|
||||
(0x55, 0x02),
|
||||
(0x57, 0x89),
|
||||
(0x59, 0x0A),
|
||||
(0x5A, 0x28),
|
||||
(0x5B, 0x15),
|
||||
(0x5D, 0x50),
|
||||
(0x5E, 0x37),
|
||||
(0x5F, 0x29),
|
||||
(0x60, 0x1E),
|
||||
(0x61, 0x1D),
|
||||
(0x62, 0x12),
|
||||
(0x63, 0x1A),
|
||||
(0x64, 0x08),
|
||||
(0x65, 0x25),
|
||||
(0x66, 0x26),
|
||||
(0x67, 0x28),
|
||||
(0x68, 0x49),
|
||||
(0x69, 0x3A),
|
||||
(0x6A, 0x43),
|
||||
(0x6B, 0x3A),
|
||||
(0x6C, 0x3B),
|
||||
(0x6D, 0x32),
|
||||
(0x6E, 0x1F),
|
||||
(0x6F, 0x0E),
|
||||
(0x70, 0x50),
|
||||
(0x71, 0x37),
|
||||
(0x72, 0x29),
|
||||
(0x73, 0x1E),
|
||||
(0x74, 0x1D),
|
||||
(0x75, 0x12),
|
||||
(0x76, 0x1A),
|
||||
(0x77, 0x08),
|
||||
(0x78, 0x25),
|
||||
(0x79, 0x26),
|
||||
(0x7A, 0x28),
|
||||
(0x7B, 0x49),
|
||||
(0x7C, 0x3A),
|
||||
(0x7D, 0x43),
|
||||
(0x7E, 0x3A),
|
||||
(0x7F, 0x3B),
|
||||
(0x80, 0x32),
|
||||
(0x81, 0x1F),
|
||||
(0x82, 0x0E),
|
||||
(0xE0, 0x02),
|
||||
(0x00, 0x1F),
|
||||
(0x01, 0x1F),
|
||||
(0x02, 0x52),
|
||||
(0x03, 0x51),
|
||||
(0x04, 0x50),
|
||||
(0x05, 0x4B),
|
||||
(0x06, 0x4A),
|
||||
(0x07, 0x49),
|
||||
(0x08, 0x48),
|
||||
(0x09, 0x47),
|
||||
(0x0A, 0x46),
|
||||
(0x0B, 0x45),
|
||||
(0x0C, 0x44),
|
||||
(0x0D, 0x40),
|
||||
(0x0E, 0x41),
|
||||
(0x0F, 0x1F),
|
||||
(0x10, 0x1F),
|
||||
(0x11, 0x1F),
|
||||
(0x12, 0x1F),
|
||||
(0x13, 0x1F),
|
||||
(0x14, 0x1F),
|
||||
(0x15, 0x1F),
|
||||
(0x16, 0x1F),
|
||||
(0x17, 0x1F),
|
||||
(0x18, 0x52),
|
||||
(0x19, 0x51),
|
||||
(0x1A, 0x50),
|
||||
(0x1B, 0x4B),
|
||||
(0x1C, 0x4A),
|
||||
(0x1D, 0x49),
|
||||
(0x1E, 0x48),
|
||||
(0x1F, 0x47),
|
||||
(0x20, 0x46),
|
||||
(0x21, 0x45),
|
||||
(0x22, 0x44),
|
||||
(0x23, 0x40),
|
||||
(0x24, 0x41),
|
||||
(0x25, 0x1F),
|
||||
(0x26, 0x1F),
|
||||
(0x27, 0x1F),
|
||||
(0x28, 0x1F),
|
||||
(0x29, 0x1F),
|
||||
(0x2A, 0x1F),
|
||||
(0x2B, 0x1F),
|
||||
(0x2C, 0x1F),
|
||||
(0x2D, 0x1F),
|
||||
(0x2E, 0x52),
|
||||
(0x2F, 0x40),
|
||||
(0x30, 0x41),
|
||||
(0x31, 0x48),
|
||||
(0x32, 0x49),
|
||||
(0x33, 0x4A),
|
||||
(0x34, 0x4B),
|
||||
(0x35, 0x44),
|
||||
(0x36, 0x45),
|
||||
(0x37, 0x46),
|
||||
(0x38, 0x47),
|
||||
(0x39, 0x51),
|
||||
(0x3A, 0x50),
|
||||
(0x3B, 0x1F),
|
||||
(0x3C, 0x1F),
|
||||
(0x3D, 0x1F),
|
||||
(0x3E, 0x1F),
|
||||
(0x3F, 0x1F),
|
||||
(0x40, 0x1F),
|
||||
(0x41, 0x1F),
|
||||
(0x42, 0x1F),
|
||||
(0x43, 0x1F),
|
||||
(0x44, 0x52),
|
||||
(0x45, 0x40),
|
||||
(0x46, 0x41),
|
||||
(0x47, 0x48),
|
||||
(0x48, 0x49),
|
||||
(0x49, 0x4A),
|
||||
(0x4A, 0x4B),
|
||||
(0x4B, 0x44),
|
||||
(0x4C, 0x45),
|
||||
(0x4D, 0x46),
|
||||
(0x4E, 0x47),
|
||||
(0x4F, 0x51),
|
||||
(0x50, 0x50),
|
||||
(0x51, 0x1F),
|
||||
(0x52, 0x1F),
|
||||
(0x53, 0x1F),
|
||||
(0x54, 0x1F),
|
||||
(0x55, 0x1F),
|
||||
(0x56, 0x1F),
|
||||
(0x57, 0x1F),
|
||||
(0x58, 0x40),
|
||||
(0x59, 0x00),
|
||||
(0x5A, 0x00),
|
||||
(0x5B, 0x10),
|
||||
(0x5C, 0x05),
|
||||
(0x5D, 0x50),
|
||||
(0x5E, 0x01),
|
||||
(0x5F, 0x02),
|
||||
(0x60, 0x50),
|
||||
(0x61, 0x06),
|
||||
(0x62, 0x04),
|
||||
(0x63, 0x03),
|
||||
(0x64, 0x64),
|
||||
(0x65, 0x65),
|
||||
(0x66, 0x0B),
|
||||
(0x67, 0x73),
|
||||
(0x68, 0x07),
|
||||
(0x69, 0x06),
|
||||
(0x6A, 0x64),
|
||||
(0x6B, 0x08),
|
||||
(0x6C, 0x00),
|
||||
(0x6D, 0x32),
|
||||
(0x6E, 0x08),
|
||||
(0xE0, 0x04),
|
||||
(0x2C, 0x6B),
|
||||
(0x35, 0x08),
|
||||
(0x37, 0x00),
|
||||
(0xE0, 0x00),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
@@ -189,8 +189,7 @@ bool MQTTComponent::send_discovery_() {
|
||||
StringRef object_id = this->get_default_object_id_to_(object_id_buf);
|
||||
if (discovery_info.unique_id_generator == MQTT_MAC_ADDRESS_UNIQUE_ID_GENERATOR) {
|
||||
char friendly_name_hash[9];
|
||||
sprintf(friendly_name_hash, "%08" PRIx32, fnv1_hash(this->friendly_name_()));
|
||||
friendly_name_hash[8] = 0; // ensure the hash-string ends with null
|
||||
snprintf(friendly_name_hash, sizeof(friendly_name_hash), "%08" PRIx32, fnv1_hash(this->friendly_name_()));
|
||||
// Format: mac-component_type-hash (e.g. "aabbccddeeff-sensor-12345678")
|
||||
// MAC (12) + "-" (1) + domain (max 20) + "-" (1) + hash (8) + null (1) = 43
|
||||
char unique_id[MAC_ADDRESS_BUFFER_SIZE + ESPHOME_DOMAIN_MAX_LEN + 11];
|
||||
|
||||
@@ -23,7 +23,7 @@ void NTC::process_(float value) {
|
||||
double v = this->a_ + this->b_ * lr + this->c_ * lr * lr * lr;
|
||||
auto temp = float(1.0 / v - 273.15);
|
||||
|
||||
ESP_LOGD(TAG, "'%s' - Temperature: %.1f°C", this->name_.c_str(), temp);
|
||||
ESP_LOGV(TAG, "'%s' - Temperature: %.1f°C", this->name_.c_str(), temp);
|
||||
this->publish_state(temp);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ void ResistanceSensor::process_(float value) {
|
||||
}
|
||||
|
||||
res *= this->resistor_;
|
||||
ESP_LOGD(TAG, "'%s' - Resistance %.1fΩ", this->name_.c_str(), res);
|
||||
ESP_LOGV(TAG, "'%s' - Resistance %.1fΩ", this->name_.c_str(), res);
|
||||
this->publish_state(res);
|
||||
}
|
||||
|
||||
|
||||
@@ -1178,11 +1178,7 @@ std::string WebServer::date_json_(datetime::DateEntity *obj, JsonDetail start_co
|
||||
|
||||
// Format: YYYY-MM-DD (max 10 chars + null)
|
||||
char value[12];
|
||||
#ifdef USE_ESP8266
|
||||
snprintf_P(value, sizeof(value), PSTR("%d-%02d-%02d"), obj->year, obj->month, obj->day);
|
||||
#else
|
||||
snprintf(value, sizeof(value), "%d-%02d-%02d", obj->year, obj->month, obj->day);
|
||||
#endif
|
||||
buf_append_printf(value, sizeof(value), 0, "%d-%02d-%02d", obj->year, obj->month, obj->day);
|
||||
set_json_icon_state_value(root, obj, "date", value, value, start_config);
|
||||
if (start_config == DETAIL_ALL) {
|
||||
this->add_sorting_info_(root, obj);
|
||||
@@ -1241,11 +1237,7 @@ std::string WebServer::time_json_(datetime::TimeEntity *obj, JsonDetail start_co
|
||||
|
||||
// Format: HH:MM:SS (8 chars + null)
|
||||
char value[12];
|
||||
#ifdef USE_ESP8266
|
||||
snprintf_P(value, sizeof(value), PSTR("%02d:%02d:%02d"), obj->hour, obj->minute, obj->second);
|
||||
#else
|
||||
snprintf(value, sizeof(value), "%02d:%02d:%02d", obj->hour, obj->minute, obj->second);
|
||||
#endif
|
||||
buf_append_printf(value, sizeof(value), 0, "%02d:%02d:%02d", obj->hour, obj->minute, obj->second);
|
||||
set_json_icon_state_value(root, obj, "time", value, value, start_config);
|
||||
if (start_config == DETAIL_ALL) {
|
||||
this->add_sorting_info_(root, obj);
|
||||
@@ -1304,13 +1296,8 @@ std::string WebServer::datetime_json_(datetime::DateTimeEntity *obj, JsonDetail
|
||||
|
||||
// Format: YYYY-MM-DD HH:MM:SS (max 19 chars + null)
|
||||
char value[24];
|
||||
#ifdef USE_ESP8266
|
||||
snprintf_P(value, sizeof(value), PSTR("%d-%02d-%02d %02d:%02d:%02d"), obj->year, obj->month, obj->day, obj->hour,
|
||||
obj->minute, obj->second);
|
||||
#else
|
||||
snprintf(value, sizeof(value), "%d-%02d-%02d %02d:%02d:%02d", obj->year, obj->month, obj->day, obj->hour, obj->minute,
|
||||
obj->second);
|
||||
#endif
|
||||
buf_append_printf(value, sizeof(value), 0, "%d-%02d-%02d %02d:%02d:%02d", obj->year, obj->month, obj->day, obj->hour,
|
||||
obj->minute, obj->second);
|
||||
set_json_icon_state_value(root, obj, "datetime", value, value, start_config);
|
||||
if (start_config == DETAIL_ALL) {
|
||||
this->add_sorting_info_(root, obj);
|
||||
|
||||
@@ -487,19 +487,26 @@ static constexpr const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
// Helper function to find the index of a base64 character in the lookup table.
|
||||
// Helper function to find the index of a base64/base64url character in the lookup table.
|
||||
// Returns the character's position (0-63) if found, or 0 if not found.
|
||||
// Supports both standard base64 (+/) and base64url (-_) alphabets.
|
||||
// NOTE: This returns 0 for both 'A' (valid base64 char at index 0) and invalid characters.
|
||||
// This is safe because is_base64() is ALWAYS checked before calling this function,
|
||||
// preventing invalid characters from ever reaching here. The base64_decode function
|
||||
// stops processing at the first invalid character due to the is_base64() check in its
|
||||
// while loop condition, making this edge case harmless in practice.
|
||||
static inline uint8_t base64_find_char(char c) {
|
||||
// Handle base64url variants: '-' maps to '+' (index 62), '_' maps to '/' (index 63)
|
||||
if (c == '-')
|
||||
return 62;
|
||||
if (c == '_')
|
||||
return 63;
|
||||
const char *pos = strchr(BASE64_CHARS, c);
|
||||
return pos ? (pos - BASE64_CHARS) : 0;
|
||||
}
|
||||
|
||||
static inline bool is_base64(char c) { return (isalnum(c) || (c == '+') || (c == '/')); }
|
||||
// Check if character is valid base64 or base64url
|
||||
static inline bool is_base64(char c) { return (isalnum(c) || (c == '+') || (c == '/') || (c == '-') || (c == '_')); }
|
||||
|
||||
std::string base64_encode(const std::vector<uint8_t> &buf) { return base64_encode(buf.data(), buf.size()); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user