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
|
||||
# ...
|
||||
|
||||
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
|
||||
-----------------------------------
|
||||
|
@ -136,6 +136,7 @@ Configuration options:
|
||||
``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
|
||||
``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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
------------------------------
|
||||
|
||||
|
@ -67,6 +67,7 @@ Custom Components & Code
|
||||
- `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`
|
||||
- `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
|
||||
---------------------
|
||||
|
@ -14,11 +14,11 @@ Installation
|
||||
|
||||
Installing ESPHome is very easy. All you need to do is have `Python
|
||||
<https://www.python.org/>`__ installed and install the console script through
|
||||
``pip``.
|
||||
``pip3``.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install esphome
|
||||
pip3 install esphome
|
||||
|
||||
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
|
||||
|
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 shlex
|
||||
import subprocess
|
||||
import threading
|
||||
import queue
|
||||
import sys
|
||||
|
||||
|
||||
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')
|
||||
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
|
||||
args = ['inkscape', '-z', '-e', str(to_.absolute()), '-w', '800',
|
||||
'-background', 'white', str(from_.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)
|
||||
raise ValueError
|
||||
|
||||
def worker():
|
||||
while True:
|
||||
item = q.get()
|
||||
if item is None:
|
||||
break
|
||||
|
||||
to = to_p / item.with_suffix('.png').name
|
||||
args = ['inkscape', '-z', '-e', str(to.absolute()), '-w', '800',
|
||||
'-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 |