clean up beta 202204 (#2020)
This commit is contained in:
parent
3e1d429243
commit
a14c881b43
|
@ -12,7 +12,7 @@ For this sensor to work, a :doc:`/components/sensor/hydreon_rgxx` must be set up
|
|||
.. code-block:: yaml
|
||||
|
||||
# Example RG-9 entry
|
||||
|
||||
|
||||
uart:
|
||||
rx_pin: GPIO16
|
||||
tx_pin: GPIO17
|
||||
|
@ -25,8 +25,8 @@ For this sensor to work, a :doc:`/components/sensor/hydreon_rgxx` must be set up
|
|||
update_interval: 1s
|
||||
moisture:
|
||||
name: "rain"
|
||||
expire_after: 30s
|
||||
|
||||
expire_after: 30s
|
||||
|
||||
binary_sensor:
|
||||
- platform: hydreon_rgxx
|
||||
hydreon_rgxx_id: "hydreon_1"
|
||||
|
@ -38,12 +38,12 @@ Configuration variables:
|
|||
|
||||
- **hydreon_rgxx_id** (*Optional*, :ref:`config-id`): The ID of the Hydreon Rain Sensor display.
|
||||
|
||||
- **too_cold** (*Optional*): `true` if the sensor reports being too cold. Hydreon only mentions this feature for the RG-9.
|
||||
- **too_cold** (*Optional*): ``true`` if the sensor reports being too cold. Hydreon only mentions this feature for the RG-9.
|
||||
|
||||
- **name** (**Required**, string): The name for the voltage sensor.
|
||||
|
||||
|
||||
- **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for use in lambdas.
|
||||
|
||||
|
||||
- All other options from :ref:`Binary Sensor <config-binary_sensor>`.
|
||||
|
||||
|
||||
|
|
|
@ -88,8 +88,8 @@ Automations:
|
|||
|
||||
.. _canbus-on-frame:
|
||||
|
||||
``on_frame``
|
||||
************
|
||||
``on_frame`` Trigger
|
||||
********************
|
||||
|
||||
This automation will be triggered when a CAN frame is received. A variable ``x`` of type
|
||||
``std::vector<uint8_t>`` containing the frame data and a variable ``can_id`` of type ``uint32_t``
|
||||
|
|
|
@ -4,7 +4,7 @@ Shelly Dimmer
|
|||
.. seo::
|
||||
:description: Instructions for setting up a Shelly Dimmer 2.
|
||||
:image: shellydimmer2.jpg
|
||||
|
||||
|
||||
The ``shelly_dimmer`` component adds support for the dimming and power-metering functionality that can be found the `Shelly Dimmer 2 <https://shelly.cloud/knowledge-base/devices/shelly-dimmer-2/>`_. The interaction with mains is done via an STM32 microcontroller that is flashed with an `open source firmware <https://github.com/jamesturton/shelly-dimmer-stm32>`_.
|
||||
A detailed analysis of the Shelly Dimmer 2 hardware is given `here <https://github.com/arendst/Tasmota/issues/6914>`_.
|
||||
|
||||
|
@ -46,11 +46,11 @@ Configuration variables:
|
|||
------------------------
|
||||
|
||||
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
|
||||
- **uart_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the UART hub.
|
||||
- **uart_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the UART hub.
|
||||
|
||||
.. note::
|
||||
|
||||
Currently, only the first hardware UART of the ESP is supported, which has to be configured like this:
|
||||
Currently, only the first hardware UART of the ESP is supported, which has to be configured like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -61,21 +61,22 @@ Configuration variables:
|
|||
|
||||
|
||||
- **name** (**Required**, string): The name of the light.
|
||||
- **leading_edge** (**Optional**, boolean): `Dimming mode <https://en.wikipedia.org/wiki/Dimmer#Solid-state_dimmer>`_: "true" means leading edge, "false" (default) is trailing edge.
|
||||
- **min_brightness** (**Optional**, int): Minimum brightness value on a scale from 0..1000, the default is 0.
|
||||
- **max_brightness** (**Optional**, int): Maximum brightness value on a scale from 0..1000, the default is 1000.
|
||||
- **warmup_brightness** (**Optional**, int): Brightness threshold below which the dimmer switches on later in mains current cycle. `This might help with dimming LEDs <https://github.com/jamesturton/shelly-dimmer-stm32/pull/23>`_. The value is from 0..1000 with an default of 0.
|
||||
- **nrst_pin** (**Optional**, :ref:`config-pin`): Pin connected with "NRST" of STM32. The default is "GPIO5".
|
||||
- **boot0_pin** (**Optional**, :ref:`config-pin`): Pin connected with "BOOT0" of STM32. The default is "GPIO4".
|
||||
- **current** (**Optional**): Sensor of the current in Amperes. All options from
|
||||
- **leading_edge** (*Optional*, boolean): `Dimming mode <https://en.wikipedia.org/wiki/Dimmer#Solid-state_dimmer>`_: ``true`` means leading edge, ``false`` is trailing edge. Defaults to ``false``.
|
||||
- **min_brightness** (*Optional*, int): Minimum brightness value on a scale from 0..1000, the default is 0.
|
||||
- **max_brightness** (*Optional*, int): Maximum brightness value on a scale from 0..1000, the default is 1000.
|
||||
- **warmup_brightness** (*Optional*, int): Brightness threshold below which the dimmer switches on later in mains current cycle. `This might help with dimming LEDs <https://github.com/jamesturton/shelly-dimmer-stm32/pull/23>`_. The value is from 0..1000 with an default of 0.
|
||||
- **nrst_pin** (*Optional*, :ref:`config-pin`): Pin connected with "NRST" of STM32. The default is "GPIO5".
|
||||
- **boot0_pin** (*Optional*, :ref:`config-pin`): Pin connected with "BOOT0" of STM32. The default is "GPIO4".
|
||||
- **current** (*Optional*): Sensor of the current in Amperes. All options from
|
||||
:ref:`Sensor <config-sensor>`.
|
||||
- **voltage** (**Optional**): Sensor of the voltage in Volts. Only accurate if neutral is connected. All options from :ref:`Sensor <config-sensor>`.
|
||||
- **power** (**Optional**): Sensor of the active power in Watts. Only accurate if neutral is connected. All options from :ref:`Sensor <config-sensor>`.
|
||||
- **firmware** (**Optional**):
|
||||
- **version** (**Optional**): Version string of the `firmware <https://github.com/jamesturton/shelly-dimmer-stm32>`_ that will be expected on the microcontroller. The default is "51.6", another known-good firmware is "51.5".
|
||||
- **url** (**Optional**): An URL to download the firmware from. Defaults to github for known firmware versions.
|
||||
- **sha256** (**Optional**): A hash to compare the downloaded firmware against. Defaults a proper hash of known firmware versions.
|
||||
- **update** (**Optional**): Should the firmware of the STM be updated if necessary? The default is false.
|
||||
- **voltage** (*Optional*): Sensor of the voltage in Volts. Only accurate if neutral is connected. All options from :ref:`Sensor <config-sensor>`.
|
||||
- **power** (*Optional*): Sensor of the active power in Watts. Only accurate if neutral is connected. All options from :ref:`Sensor <config-sensor>`.
|
||||
- **firmware** (*Optional*):
|
||||
|
||||
- **version** (*Optional*): Version string of the `firmware <https://github.com/jamesturton/shelly-dimmer-stm32>`_ that will be expected on the microcontroller. The default is "51.6", another known-good firmware is "51.5".
|
||||
- **url** (*Optional*, string): An URL to download the firmware from. Defaults to github for known firmware versions.
|
||||
- **sha256** (*Optional*): A hash to compare the downloaded firmware against. Defaults a proper hash of known firmware versions.
|
||||
- **update** (*Optional*): Should the firmware of the STM be updated if necessary? The default is false.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Sonoff D1 Dimmer
|
|||
The ``sonoff_d1`` light platform creates a simple brightness-only light for the
|
||||
hardware found in `Sonoff D1 dimmer <https://itead.cc/product/sonoff-d1-smart-dimmer-switch/>`__. Installations with Sonoff RM433 433MHz radio
|
||||
remotes are also supported. Use this component to integrate Sonoff D1 dimmer into
|
||||
ESPHome / Home Assistant ecosystem.
|
||||
ESPHome / Home Assistant ecosystem.
|
||||
|
||||
.. figure:: images/sonoff_d1.jpg
|
||||
:align: center
|
||||
|
@ -16,11 +16,11 @@ ESPHome / Home Assistant ecosystem.
|
|||
|
||||
Sonoff D1 dimmer front and back view. Image by `ITEAD <https://itead.cc/product/sonoff-d1-smart-dimmer-switch/>`__.
|
||||
|
||||
Sonoff D1 uses another MCU for light dimming and handling of radio commands.
|
||||
Sonoff D1 uses another MCU for light dimming and handling of radio commands.
|
||||
It's hooked up to ESP8266 via UART bus with default RX / TX pins being used on
|
||||
ESP8266 side. Bi-directional symmetric request / response protocol is implemented
|
||||
between ESP8266 and MCU. ``sonoff_d1`` component implements this protocol and
|
||||
translates between HA light commands and serial messages.
|
||||
translates between HA light commands and serial messages.
|
||||
|
||||
For detailed instructions on how to replace the stock firmware with ESPHome see :doc:`/devices/sonoff_s20`.
|
||||
You will need to locate GPIO0 pin and serial port. Photos below should help.
|
||||
|
@ -52,7 +52,7 @@ This component is useless for devices other than Sonoff D1 dimmer.
|
|||
# Example configuration entry
|
||||
esphome:
|
||||
name: my-d1-dimmer
|
||||
|
||||
|
||||
# Restore from flash if you want to keep the last state at power up
|
||||
esp8266:
|
||||
board: esp8285
|
||||
|
@ -91,15 +91,15 @@ This component is useless for devices other than Sonoff D1 dimmer.
|
|||
default_transition_length: 1s
|
||||
|
||||
|
||||
Configuration variables
|
||||
-----------------------
|
||||
Configuration variables:
|
||||
------------------------
|
||||
|
||||
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
|
||||
- **name** (**Required**, string): The name of the light.
|
||||
- **use_rm433_remote** (*Optional*, boolean): Set to ``True`` if your setup uses Sonoff RM433
|
||||
or any other radio remote control. Properly setting this parameter allows the platform to
|
||||
identify what to do with incoming UART commands. RF chip is known to catch random commands
|
||||
if not paired with a real remote (so called ghost commands). This problem is observed even
|
||||
if not paired with a real remote (so called ghost commands). This problem is observed even
|
||||
with the stock firmware and most probably is a bug in the MCU firmware or in the RF chip
|
||||
firmware. Setting this to ``False`` instructs the platform to properly ignore such commands
|
||||
and thus prevent unexpected switches or light intensity changes.
|
||||
|
|
|
@ -79,11 +79,11 @@ Configuration variables:
|
|||
- **ssl_fingerprints** (*Optional*, list): Only on ESP8266. A list of SHA1 hashes used
|
||||
for verifying SSL connections. See :ref:`mqtt-ssl_fingerprints`.
|
||||
for more information.
|
||||
- **certificate_authority** *(Optional*, string): Only with `esp-idf`. CA certificate in PEM format. See :ref:`mqtt-tls-idf` for more information
|
||||
- **skip_cert_cn_check** (*Optional*, bool): Only with `esp-idf`. Don't verify if the common name in the server certificate matches the value of ``broker``.
|
||||
- **idf_send_async** (*Optional*, bool): Only with `esp-idf`. Default is false. If true publishing the message happens from the internal mqtt task. The client only enqueues the message.
|
||||
- **certificate_authority** (*Optional*, string): Only with ``esp-idf``. CA certificate in PEM format. See :ref:`mqtt-tls-idf` for more information
|
||||
- **skip_cert_cn_check** (*Optional*, bool): Only with ``esp-idf``. Don't verify if the common name in the server certificate matches the value of ``broker``.
|
||||
- **idf_send_async** (*Optional*, bool): Only with ``esp-idf``. If true publishing the message happens from the internal mqtt task. The client only enqueues the message. Defaults to ``false``.
|
||||
The advantage of asyncronous publishing is that it doesn't block the esphome main thread. The disadvantage is a delay (up to 1-2 seconds) until the messages are actually sent out.
|
||||
Set this to true if ypi send large amounts of of data over mqtt.
|
||||
Set this to true if ypi send large amounts of of data over mqtt.
|
||||
- **reboot_timeout** (*Optional*, :ref:`config-time`): The amount of time to wait before rebooting when no
|
||||
MQTT connection exists. Can be disabled by setting this to ``0s``. Defaults to ``15min``.
|
||||
- **keepalive** (*Optional*, :ref:`config-time`): The time
|
||||
|
@ -279,11 +279,11 @@ then run the ``mqtt-fingerprint`` script of ESPHome to get the certificate:
|
|||
TLS with esp-idf (esp32)
|
||||
------------------------
|
||||
|
||||
If used with the esp-idf framework a TLS connection to a mqtt broker can be established.
|
||||
The servers CA certificate is required to validate the connection.
|
||||
If used with the esp-idf framework a TLS connection to a mqtt broker can be established.
|
||||
The servers CA certificate is required to validate the connection.
|
||||
|
||||
You have to download the server CA certficiate in PEM format and add it to ``certificate_authority``.
|
||||
Usually these are .crt files and you can open them with any text editor.
|
||||
Usually these are .crt files and you can open them with any text editor.
|
||||
Also make sure to change the ``port`` of the mqtt broker. Most brokers use port 8883 for TLS connections.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
@ -293,7 +293,7 @@ Also make sure to change the ``port`` of the mqtt broker. Most brokers use port
|
|||
port: 8883
|
||||
discovery: true
|
||||
discovery_prefix: ${mqtt_prefix}/homeassistant
|
||||
log_topic: ${mqtt_prefix}/logs
|
||||
log_topic: ${mqtt_prefix}/logs
|
||||
skip_cert_cn_check: true
|
||||
idf_send_async: false
|
||||
certificate_authority: |
|
||||
|
|
|
@ -78,7 +78,7 @@ Configuration variables:
|
|||
- **use_write_multiple** (*Optional*, boolean): By default the modbus command ``Preset Single Registers``
|
||||
(function code 6) is used for setting the holding register if only 1 register is set. If your device only supports *Preset Multiple Registers* (function code 16) set this option to ``true``. Defaults
|
||||
to ``false``.
|
||||
- **optimistic**: (*Optional*, boolean): Whether to operate in optimistic mode - when in this mode,
|
||||
- **optimistic** (*Optional*, boolean): Whether to operate in optimistic mode - when in this mode,
|
||||
any command sent to the Modbus Select will immediately update the reported state. Defaults
|
||||
to ``false``.
|
||||
- All other options from :ref:`Select <config-select>`.
|
||||
|
|
|
@ -20,7 +20,7 @@ required to be set up in your configuration for this sensor to work.
|
|||
.. code-block:: yaml
|
||||
|
||||
# Example RG-9 entry
|
||||
|
||||
|
||||
uart:
|
||||
rx_pin: GPIO16
|
||||
tx_pin: GPIO17
|
||||
|
@ -32,8 +32,8 @@ required to be set up in your configuration for this sensor to work.
|
|||
update_interval: 60s
|
||||
moisture:
|
||||
name: "rain"
|
||||
expire_after: 120s
|
||||
|
||||
expire_after: 120s
|
||||
|
||||
binary_sensor:
|
||||
- platform: hydreon_rgxx
|
||||
too_cold:
|
||||
|
@ -64,38 +64,38 @@ required to be set up in your configuration for this sensor to work.
|
|||
Configuration variables:
|
||||
------------------------
|
||||
|
||||
- **model**: (**Required**, int): Specify which rain sensor you have connected. Must be either ``RG_9`` or ``RG_15``.
|
||||
- **model** (**Required**, int): Specify which rain sensor you have connected. Must be either ``RG_9`` or ``RG_15``.
|
||||
|
||||
- **uart_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the :ref:`UART Component <uart>` if you want
|
||||
to use multiple UART buses.
|
||||
|
||||
- **moisture** (*Optional*): Rain intensity level from 0-7. Only on RG-9.
|
||||
|
||||
- **name** (**Required**, string): The name for the voltage sensor.
|
||||
- **name** (**Required**, string): The name for the sensor.
|
||||
- **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for use in lambdas.
|
||||
- All other options from :ref:`Sensor <config-sensor>`.
|
||||
|
||||
- **acc** (*Optional*): Amount of rain since last message (see `update_interval`), in `mm`. Only on RG-15.
|
||||
- **acc** (*Optional*): Amount of rain since last message (see ``update_interval``), in ``mm``. Only on RG-15.
|
||||
|
||||
- **name** (**Required**, string): The name for the voltage sensor.
|
||||
- **name** (**Required**, string): The name for the sensor.
|
||||
- **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for use in lambdas.
|
||||
- All other options from :ref:`Sensor <config-sensor>`.
|
||||
|
||||
- **event_acc** (*Optional*): Amount of rain for this event (i.e. since it last stopped raining), in `mm`. Only on RG-15.
|
||||
- **event_acc** (*Optional*): Amount of rain for this event (i.e. since it last stopped raining), in ``mm``. Only on RG-15.
|
||||
|
||||
- **name** (**Required**, string): The name for the voltage sensor.
|
||||
- **name** (**Required**, string): The name for the sensor.
|
||||
- **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for use in lambdas.
|
||||
- All other options from :ref:`Sensor <config-sensor>`.
|
||||
|
||||
- **total_acc** (*Optional*): Total amount of rain this sensor has ever measured, in `mm`. Only on RG-15.
|
||||
- **total_acc** (*Optional*): Total amount of rain this sensor has ever measured, in ``mm``. Only on RG-15.
|
||||
|
||||
- **name** (**Required**, string): The name for the voltage sensor.
|
||||
- **name** (**Required**, string): The name for the sensor.
|
||||
- **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for use in lambdas.
|
||||
- All other options from :ref:`Sensor <config-sensor>`.
|
||||
|
||||
- **r_int** (*Optional*): Current rain intensity in `mm/h`. Only on RG-15.
|
||||
- **r_int** (*Optional*): Current rain intensity in ``mm/h``. Only on RG-15.
|
||||
|
||||
- **name** (**Required**, string): The name for the voltage sensor.
|
||||
- **name** (**Required**, string): The name for the sensor.
|
||||
- **id** (*Optional*, :ref:`config-id`): Set the ID of this sensor for use in lambdas.
|
||||
- All other options from :ref:`Sensor <config-sensor>`.
|
||||
|
||||
|
|
|
@ -22,10 +22,10 @@ interface are hosted by esphome.io. If you want to use your own service, use the
|
|||
.. figure:: /components/images/web_server.png
|
||||
|
||||
Example web server frontend (Version 1)
|
||||
|
||||
|
||||
Version 2:
|
||||
----------
|
||||
.. figure:: /components/images/web_server-v2.png
|
||||
.. figure:: /components/images/web_server-v2.png
|
||||
|
||||
Web Components (Version 2)
|
||||
|
||||
|
@ -59,7 +59,7 @@ Configuration variables:
|
|||
web interface. Defaults to ``false``.
|
||||
- **ota** (*Optional*, boolean): Turn on or off the OTA feature inside webserver. Strongly not suggested without enabled authentication settings. Defaults to ``true``.
|
||||
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
|
||||
- **version** (*Optional*, string): 1 or 2. Version 1 displays as a table. Version 2 uses web components and has more functionality. Default: `2`
|
||||
- **version** (*Optional*, string): ``1`` or ``2``. Version 1 displays as a table. Version 2 uses web components and has more functionality. Defaults to ``2``.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -73,7 +73,7 @@ Configuration variables:
|
|||
auth:
|
||||
username: admin
|
||||
password: !secret web_server_password
|
||||
|
||||
|
||||
Example web_server configuration using version 1 (previous behaviour):
|
||||
|
||||
.. code-block:: yaml
|
||||
|
@ -82,7 +82,7 @@ Configuration variables:
|
|||
web_server:
|
||||
port: 80
|
||||
version: 1
|
||||
|
||||
|
||||
Example web_server configuration using version 2 - no internet/intranet required:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
@ -90,14 +90,14 @@ Configuration variables:
|
|||
# Example configuration entry
|
||||
web_server:
|
||||
local: true
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
All of the assets are inlined, compressed and served from flash
|
||||
|
||||
Here be Dragons
|
||||
===============
|
||||
|
||||
|
||||
The following assume copies of the files with local paths - which are config dependant.
|
||||
|
||||
Example web_server version 1 configuration with CSS and JS included from esphome-docs.
|
||||
|
@ -129,7 +129,7 @@ V2 embeds the css within the js file so is not required, however you could inclu
|
|||
|
||||
|
||||
Copy https://oi.esphome.io/v2/www.js to a V2 folder in your yaml folder.
|
||||
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
|
|
@ -2,7 +2,6 @@ from genericpath import exists
|
|||
import re
|
||||
import json
|
||||
import urllib
|
||||
import traceback
|
||||
|
||||
from typing import MutableMapping
|
||||
from sphinx.util import logging
|
||||
|
@ -63,13 +62,7 @@ def doctree_resolved(app, doctree, docname):
|
|||
if docname == "components/index":
|
||||
# nothing useful here
|
||||
return
|
||||
try:
|
||||
handle_component(app, doctree, docname)
|
||||
|
||||
except Exception as e:
|
||||
err_str = f"In {docname}: {str(e)}"
|
||||
logger.warning(err_str)
|
||||
traceback.print_exc()
|
||||
handle_component(app, doctree, docname)
|
||||
|
||||
|
||||
PLATFORMS_TITLES = {
|
||||
|
@ -110,7 +103,7 @@ CUSTOM_DOCS = {
|
|||
"components/climate/climate_ir": {"_LoadSchema": False, "IR Remote Climate": []},
|
||||
"components/display/index": {
|
||||
"Images": "image.schemas.CONFIG_SCHEMA",
|
||||
"Drawing Static Text": "font.schemas.CONFIG_SCHEMA",
|
||||
"Fonts": "font.schemas.CONFIG_SCHEMA",
|
||||
"Color": "color.schemas.CONFIG_SCHEMA",
|
||||
"Animation": "animation.schemas.CONFIG_SCHEMA",
|
||||
},
|
||||
|
@ -396,6 +389,8 @@ class SchemaGeneratorVisitor(nodes.NodeVisitor):
|
|||
json_component = self.find_component(self.custom_doc[title_text])
|
||||
if not json_component:
|
||||
return
|
||||
if self.json_component is None:
|
||||
self.json_component = json_component
|
||||
|
||||
parts = self.custom_doc[title_text].split(".")
|
||||
if parts[0] not in ["core", "remote_base"] and parts[-1] != "pin":
|
||||
|
@ -1144,14 +1139,20 @@ def handle_component(app, doctree, docname):
|
|||
return
|
||||
|
||||
v = SchemaGeneratorVisitor(app, doctree, docname)
|
||||
doctree.walkabout(v)
|
||||
try:
|
||||
doctree.walkabout(v)
|
||||
except Exception as e:
|
||||
err_str = f"In {docname}.rst: {str(e)}"
|
||||
logger.warning(err_str)
|
||||
# print stack
|
||||
# traceback.print_exc()
|
||||
|
||||
|
||||
def build_finished(app, exception):
|
||||
# TODO: create report of missing descriptions
|
||||
|
||||
for fname, contents in app.files.items():
|
||||
f = open(SCHEMA_PATH + fname + ".json", "w")
|
||||
f = open(SCHEMA_PATH + fname + ".json", "w", newline="\n")
|
||||
if JSON_DUMP_PRETTY:
|
||||
f.write(json.dumps(contents, indent=2))
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue