Merge branch 'current' into next
11
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Issue Tracker
|
||||||
|
url: https://github.com/esphome/issues
|
||||||
|
about: Please create bug reports in the dedicated issue tracker.
|
||||||
|
- name: Feature Request Tracker
|
||||||
|
url: https://github.com/esphome/feature-requests
|
||||||
|
about: Please create feature requests in the dedicated feature request tracker.
|
||||||
|
- name: Frequently Asked Question
|
||||||
|
url: https://esphome.io/guides/faq.html
|
||||||
|
about: Please view the FAQ for common questions and what to include in a bug report.
|
@ -193,6 +193,26 @@ Configuration for TTGO T-Camera V05
|
|||||||
name: My Camera
|
name: My Camera
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
|
Configuration for TTGO T-Camera V162
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
esp32_camera:
|
||||||
|
external_clock:
|
||||||
|
pin: GPIO4
|
||||||
|
frequency: 20MHz
|
||||||
|
i2c_pins:
|
||||||
|
sda: GPIO18
|
||||||
|
scl: GPIO23
|
||||||
|
data_pins: [GPIO34, GPIO13, GPIO14, GPIO35, GPIO39, GPIO38, GPIO37, GPIO36]
|
||||||
|
vsync_pin: GPIO5
|
||||||
|
href_pin: GPIO27
|
||||||
|
pixel_clock_pin: GPIO25
|
||||||
|
jpeg_quality: 10
|
||||||
|
vertical_flip: true
|
||||||
|
horizontal_mirror: false
|
||||||
|
# ...
|
||||||
|
|
||||||
Configuration for TTGO T-Camera V17
|
Configuration for TTGO T-Camera V17
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
@ -136,6 +136,7 @@ Configuration options:
|
|||||||
``0%`` to ``100%`` or ``0.0`` to ``1.0``. Defaults to not changing blue channel.
|
``0%`` to ``100%`` or ``0.0`` to ``1.0``. Defaults to not changing blue channel.
|
||||||
- **white** (*Optional*, percentage, :ref:`templatable <config-templatable>`): The white channel value of RGBW lights. Must be in range
|
- **white** (*Optional*, percentage, :ref:`templatable <config-templatable>`): The white channel value of RGBW lights. Must be in range
|
||||||
``0%`` to ``100%`` or ``0.0`` to ``1.0``. Defaults to not changing white value.
|
``0%`` to ``100%`` or ``0.0`` to ``1.0``. Defaults to not changing white value.
|
||||||
|
- **color_temperature** (*Optional*, float, :ref:`templatable <config-templatable>`): The white color temperature value (in `mireds <https://en.wikipedia.org/wiki/Mired>`__ or Kelvin) for CWWW / RGBWW lights. Defaults to not changing the color temperature value.
|
||||||
- **flash_length** (*Optional*, :ref:`config-time`, :ref:`templatable <config-templatable>`): If set, will flash the given color
|
- **flash_length** (*Optional*, :ref:`config-time`, :ref:`templatable <config-templatable>`): If set, will flash the given color
|
||||||
for this period of time and then go back to the previous state.
|
for this period of time and then go back to the previous state.
|
||||||
- **effect** (*Optional*, string, :ref:`templatable <config-templatable>`): If set, will attempt to
|
- **effect** (*Optional*, string, :ref:`templatable <config-templatable>`): If set, will attempt to
|
||||||
|
@ -10,6 +10,8 @@ The Mirabella Genio is a Tuya-based smart bulb sold by Kmart in Australia.
|
|||||||
Originally intended to be used with their companion app once flashed using `tuya-convert <https://github.com/ct-Open-Source/tuya-convert>`__ ESPHome generated
|
Originally intended to be used with their companion app once flashed using `tuya-convert <https://github.com/ct-Open-Source/tuya-convert>`__ ESPHome generated
|
||||||
firmware can be uploaded allowing you to control the bulbs via Home Assistant.
|
firmware can be uploaded allowing you to control the bulbs via Home Assistant.
|
||||||
|
|
||||||
|
Please note that the new version of this bulb that comes in a cardboard box does NOT have an ESP chipset inside and cannot be flashed.
|
||||||
|
|
||||||
1. Create the ESPHome Firmware
|
1. Create the ESPHome Firmware
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ Custom Components & Code
|
|||||||
- `Custom Mitsubishi HVAC HeatPump control using UART <https://github.com/geoffdavis/esphome-mitsubishiheatpump>`__ by :ghuser:`geoffdavis`
|
- `Custom Mitsubishi HVAC HeatPump control using UART <https://github.com/geoffdavis/esphome-mitsubishiheatpump>`__ by :ghuser:`geoffdavis`
|
||||||
- `Jura Impressa J6 coffee machine custom component <https://github.com/ryanalden/esphome-jura-component>`__ by :ghuser:`ryanalden`
|
- `Jura Impressa J6 coffee machine custom component <https://github.com/ryanalden/esphome-jura-component>`__ by :ghuser:`ryanalden`
|
||||||
- `Paradox alarm system sensors custom component <https://github.com/Margriko/Paradox-ESPHome>`__ by :ghuser:`Margriko`
|
- `Paradox alarm system sensors custom component <https://github.com/Margriko/Paradox-ESPHome>`__ by :ghuser:`Margriko`
|
||||||
|
- `DSC POWER832 (PC5010) alarm system custom component <https://github.com/Dilbert66/esphome-dsckeybus>`__ by :ghuser:`Dilbert66`
|
||||||
|
|
||||||
Sample Configurations
|
Sample Configurations
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -14,11 +14,11 @@ Installation
|
|||||||
|
|
||||||
Installing ESPHome is very easy. All you need to do is have `Python
|
Installing ESPHome is very easy. All you need to do is have `Python
|
||||||
<https://www.python.org/>`__ installed and install the console script through
|
<https://www.python.org/>`__ installed and install the console script through
|
||||||
``pip``.
|
``pip3``.
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
pip install esphome
|
pip3 install esphome
|
||||||
|
|
||||||
Alternatively, there’s also a Docker image available for easy
|
Alternatively, there’s also a Docker image available for easy
|
||||||
installation (the Docker hub image is only available for AMD64 right now; if you have
|
installation (the Docker hub image is only available for AMD64 right now; if you have
|
||||||
|
96
script/bump-version.py
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Version:
|
||||||
|
major: int
|
||||||
|
minor: int
|
||||||
|
patch: int
|
||||||
|
beta: int = 0
|
||||||
|
dev: bool = False
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.major}.{self.minor}.{self.full_patch}'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def full_patch(self):
|
||||||
|
res = f'{self.patch}'
|
||||||
|
if self.beta > 0:
|
||||||
|
res += f'b{self.beta}'
|
||||||
|
if self.dev:
|
||||||
|
res += '-dev'
|
||||||
|
return res
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse(cls, value):
|
||||||
|
match = re.match(r'(\d+).(\d+).(\d+)(b\d+)?(-dev)?', value)
|
||||||
|
assert match is not None
|
||||||
|
major = int(match[1])
|
||||||
|
minor = int(match[2])
|
||||||
|
patch = int(match[3])
|
||||||
|
beta = int(match[4][1:]) if match[4] else 0
|
||||||
|
dev = bool(match[5])
|
||||||
|
return Version(
|
||||||
|
major=major, minor=minor, patch=patch,
|
||||||
|
beta=beta, dev=dev
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sub(path, pattern, repl, expected_count=1):
|
||||||
|
with open(path) as fh:
|
||||||
|
content = fh.read()
|
||||||
|
content, count = re.subn(pattern, repl, content, re.MULTILINE)
|
||||||
|
if expected_count is not None:
|
||||||
|
assert count == expected_count
|
||||||
|
with open(path, "wt") as fh:
|
||||||
|
fh.write(content)
|
||||||
|
|
||||||
|
|
||||||
|
def write_version(version: Version):
|
||||||
|
# ESPHOME_REF = v1.14.4
|
||||||
|
sub(
|
||||||
|
'Makefile',
|
||||||
|
r'ESPHOME_REF = .*',
|
||||||
|
f'ESPHOME_REF = v{version}'
|
||||||
|
)
|
||||||
|
# PROJECT_NUMBER = 1.14.4
|
||||||
|
sub(
|
||||||
|
'Doxygen',
|
||||||
|
r'PROJECT_NUMBER = .*',
|
||||||
|
f'PROJECT_NUMBER = {version}'
|
||||||
|
)
|
||||||
|
# version = '1.14'
|
||||||
|
sub(
|
||||||
|
'conf.py',
|
||||||
|
r"version = '.*'",
|
||||||
|
f"version = '{version.major}.{version.minor}'"
|
||||||
|
)
|
||||||
|
# release = '1.14.4'
|
||||||
|
sub(
|
||||||
|
'conf.py',
|
||||||
|
r"release = '.*'",
|
||||||
|
f"release = '{version}'"
|
||||||
|
)
|
||||||
|
with open('_static/version', 'wt') as fh:
|
||||||
|
fh.write(str(version))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('new_version', type=str)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
version = Version.parse(args.new_version)
|
||||||
|
print(f"Bumping to {version}")
|
||||||
|
write_version(version)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main() or 0)
|
49
svg2png.py
@ -2,6 +2,9 @@ from pathlib import Path
|
|||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import threading
|
||||||
|
import queue
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
to_p = Path('svg2png')
|
to_p = Path('svg2png')
|
||||||
@ -11,14 +14,40 @@ for f in to_p.glob('*.png'):
|
|||||||
|
|
||||||
images = [f for f in Path('_build/html/_images/').glob('*.svg')
|
images = [f for f in Path('_build/html/_images/').glob('*.svg')
|
||||||
if not re.match(r'^seg[0-9A-F]{2}$', f.stem)]
|
if not re.match(r'^seg[0-9A-F]{2}$', f.stem)]
|
||||||
|
q = queue.Queue()
|
||||||
|
|
||||||
for from_ in sorted(images):
|
|
||||||
to_ = to_p / from_.with_suffix('.png').name
|
def worker():
|
||||||
args = ['inkscape', '-z', '-e', str(to_.absolute()), '-w', '800',
|
while True:
|
||||||
'-background', 'white', str(from_.absolute())]
|
item = q.get()
|
||||||
print("Running: {}".format(' '.join(shlex.quote(x) for x in args)))
|
if item is None:
|
||||||
proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
break
|
||||||
if b'Bitmap saved as' not in proc.stdout:
|
|
||||||
print("Error!")
|
to = to_p / item.with_suffix('.png').name
|
||||||
print(proc.stdout)
|
args = ['inkscape', '-z', '-e', str(to.absolute()), '-w', '800',
|
||||||
raise ValueError
|
'-background', 'white', str(item.absolute())]
|
||||||
|
print("Running: {}".format(' '.join(shlex.quote(x) for x in args)))
|
||||||
|
proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
if b'Bitmap saved as' not in proc.stdout:
|
||||||
|
print("Error!")
|
||||||
|
print(proc.stdout)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
q.task_done()
|
||||||
|
|
||||||
|
NUM_THREADS = 8
|
||||||
|
threads = []
|
||||||
|
for i in range(NUM_THREADS):
|
||||||
|
t = threading.Thread(target=worker)
|
||||||
|
t.start()
|
||||||
|
threads.append(t)
|
||||||
|
|
||||||
|
for img in sorted(images):
|
||||||
|
q.put(img)
|
||||||
|
|
||||||
|
q.join()
|
||||||
|
|
||||||
|
for i in range(NUM_THREADS):
|
||||||
|
q.put(None)
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
||||||
|
BIN
svg2png/ac_dimmer.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
svg2png/connection.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
svg2png/dac.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
svg2png/diy.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
svg2png/function.png
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |