mirror of https://github.com/arendst/Tasmota.git
385 lines
6.9 KiB
Python
385 lines
6.9 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""
|
|
templates.py - template beautify TEMPLATES.md for Tasmota
|
|
|
|
Copyright (C) 2021 Theo Arends
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Requirements:
|
|
- Python
|
|
|
|
Instructions:
|
|
Execute command to produce file TEMPLATE.md as found in the Tasmota root folder
|
|
|
|
Usage:
|
|
python templates.py
|
|
|
|
"""
|
|
|
|
import sys
|
|
import io
|
|
import requests
|
|
from io import BytesIO
|
|
from io import StringIO
|
|
from datetime import datetime
|
|
import json
|
|
|
|
|
|
LIST_URL = "https://templates.blakadder.com/list.json"
|
|
TEMPLATES = "../../TEMPLATES.md"
|
|
|
|
COLUMN = 27 # Start position of {"NAME":... in line
|
|
|
|
# Some values from support.ino and tasmota_templates.h
|
|
AGPIO = lambda x : x << 5
|
|
GPIO_NONE = 0
|
|
GPIO_USER = AGPIO(GPIO_NONE)+1
|
|
GPIO_ADC_INPUT = 147
|
|
GPIO_ADC_JOY = 104
|
|
|
|
# Conversion table extracted from Tasmota code
|
|
GPIO_CONVERT = [
|
|
0x0000,
|
|
0x04A0,
|
|
0x04C0,
|
|
0x04E0,
|
|
0x0520,
|
|
0x0260,
|
|
0x0280,
|
|
0x0560,
|
|
0x0420,
|
|
0x00A0,
|
|
0x00A1,
|
|
0x00A2,
|
|
0x00A3,
|
|
0x00A4,
|
|
0x00A5,
|
|
0x00A6,
|
|
0x00A7,
|
|
0x0020,
|
|
0x0021,
|
|
0x0022,
|
|
0x0023,
|
|
0x00E0,
|
|
0x00E1,
|
|
0x00E2,
|
|
0x00E3,
|
|
0x00E4,
|
|
0x00E5,
|
|
0x00E6,
|
|
0x00E7,
|
|
0x0100,
|
|
0x0101,
|
|
0x0102,
|
|
0x0103,
|
|
0x0104,
|
|
0x0105,
|
|
0x0106,
|
|
0x0107,
|
|
0x01A0,
|
|
0x01A1,
|
|
0x01A2,
|
|
0x01A3,
|
|
0x01A4,
|
|
0x0160,
|
|
0x0161,
|
|
0x0162,
|
|
0x0163,
|
|
0x01C0,
|
|
0x01C1,
|
|
0x01C2,
|
|
0x01C3,
|
|
0x01C4,
|
|
0x0440,
|
|
0x0120,
|
|
0x0121,
|
|
0x0122,
|
|
0x0123,
|
|
0x0140,
|
|
0x0141,
|
|
0x0142,
|
|
0x0143,
|
|
0x0580,
|
|
0x05A0,
|
|
0x05C0,
|
|
0x05E0,
|
|
0x0640,
|
|
0x0660,
|
|
0x0300,
|
|
0x0320,
|
|
0x03E0,
|
|
0x06A0,
|
|
0x06E0,
|
|
0x0700,
|
|
0x0720,
|
|
0x0740,
|
|
0x0760,
|
|
0x0780,
|
|
0x07A0,
|
|
0x07C0,
|
|
0x07E0,
|
|
0x0800,
|
|
0x0820,
|
|
0x0840,
|
|
0x00C0,
|
|
0x00C1,
|
|
0x00C2,
|
|
0x00C3,
|
|
0x00C4,
|
|
0x00C5,
|
|
0x00C6,
|
|
0x00C7,
|
|
0x0040,
|
|
0x0041,
|
|
0x0042,
|
|
0x0043,
|
|
0x0180,
|
|
0x0181,
|
|
0x0182,
|
|
0x0183,
|
|
0x0600,
|
|
0x0620,
|
|
0x0860,
|
|
0x06C0,
|
|
0x0880,
|
|
0x08A0,
|
|
0x08C0,
|
|
0x0460,
|
|
0x0480,
|
|
0x08E0,
|
|
0x0900,
|
|
0x0920,
|
|
0x0940,
|
|
0x0340,
|
|
0x0360,
|
|
0x0380,
|
|
0x03A0,
|
|
0x03C0,
|
|
0x0960,
|
|
0x0980,
|
|
0x09A0,
|
|
0x09C0,
|
|
0x09E0,
|
|
0x0A00,
|
|
0x0060,
|
|
0x0061,
|
|
0x0062,
|
|
0x0063,
|
|
0x0080,
|
|
0x0081,
|
|
0x0082,
|
|
0x0083,
|
|
0x0A20,
|
|
0x0A40,
|
|
0x0A60,
|
|
0x0A80,
|
|
0x0AA0,
|
|
0x0AC0,
|
|
0x0AE0,
|
|
0x0B00,
|
|
0x0B20,
|
|
0x0B40,
|
|
0x0B60,
|
|
0x0B80,
|
|
0x0BA0,
|
|
0x0BC0,
|
|
0x0BE0,
|
|
0x0C00,
|
|
0x0C20,
|
|
0x0C40,
|
|
0x0C80,
|
|
0x0CA0,
|
|
0x0CC0,
|
|
0x0CE0,
|
|
0x0CC1,
|
|
0x0CE1,
|
|
0x0D40,
|
|
0x0D60,
|
|
0x0D80,
|
|
0x0220,
|
|
0x0240,
|
|
0x0C60,
|
|
0x01E0,
|
|
0x0200,
|
|
0x0400,
|
|
0x0DA0,
|
|
0x0DC0,
|
|
0x0DE0,
|
|
0x0E00,
|
|
0x0E20,
|
|
0x0E40,
|
|
0x0E60,
|
|
0x0E80,
|
|
0x0EA0,
|
|
0x0EC0,
|
|
0x0EE0,
|
|
0x0EE1,
|
|
0x0EE2,
|
|
0x0F40,
|
|
0x0F60,
|
|
0x0F80,
|
|
0x0FA0,
|
|
0x0FC0,
|
|
0x0FE0,
|
|
0x1000,
|
|
0x1020,
|
|
0x1040,
|
|
0x1060,
|
|
0x1080,
|
|
0x10A0,
|
|
0x10C0,
|
|
0x10E0,
|
|
0x1100,
|
|
0x1120,
|
|
0x0540,
|
|
0x0500,
|
|
0x1140,
|
|
0x1160,
|
|
0x1180,
|
|
0x11A0,
|
|
0x11C0,
|
|
0x11E0,
|
|
0x1200,
|
|
0x1220,
|
|
0x1240,
|
|
0x0680,
|
|
0x1340,
|
|
0x1360,
|
|
0x1380,
|
|
0x13C0,
|
|
0x13E0,
|
|
0x1400,
|
|
0x1420,
|
|
0x1440,
|
|
0x1460,
|
|
0x1480,
|
|
0x14A0,
|
|
0x14C0,
|
|
0x14E0
|
|
]
|
|
|
|
|
|
def is_old_template(template):
|
|
"""find out it the template is old format"""
|
|
# Old format <=> 13 gpios AND all gpios <= 255
|
|
# print(f"Template {template}\n")
|
|
if "GPIO" in template and len(template["GPIO"]) == 13:
|
|
for g in template["GPIO"]:
|
|
if g > 255:
|
|
return False
|
|
return True
|
|
return False
|
|
|
|
def gpio_convert(gpio):
|
|
"""Conversion as per https://tasmota.github.io/docs/Components/#gpio-conversion"""
|
|
if gpio >= len(GPIO_CONVERT):
|
|
return GPIO_USER
|
|
return GPIO_CONVERT[gpio]
|
|
|
|
def adc0_convert(adc0):
|
|
"""Conversion as per https://tasmota.github.io/docs/Components/#adc-conversion"""
|
|
adc0 = adc0 & 0x0F
|
|
if 0 == adc0:
|
|
return GPIO_NONE
|
|
elif 8 == adc0:
|
|
return AGPIO(GPIO_ADC_JOY); # Joystick
|
|
elif adc0 > 7:
|
|
return GPIO_USER
|
|
return AGPIO(GPIO_ADC_INPUT + adc0 -1)
|
|
|
|
def convert_gpios(gpios, flag):
|
|
new_gpios = []
|
|
for g in gpios:
|
|
new_gpios.append(gpio_convert(g))
|
|
new_gpios.append(adc0_convert(flag))
|
|
return new_gpios
|
|
|
|
def convert_template(template):
|
|
if not is_old_template(template):
|
|
return template
|
|
return { "NAME": template["NAME"],
|
|
"GPIO": convert_gpios(template["GPIO"], template["FLAG"]),
|
|
"FLAG":0,
|
|
"BASE": template["BASE"] }
|
|
|
|
def get_templates_list():
|
|
"""Download templates list from template website"""
|
|
response = requests.get(LIST_URL)
|
|
if response.status_code != 200:
|
|
printf(f"Error GET({URL}) returned code {response.status_code}\n")
|
|
exit()
|
|
return response.text.split('\n')
|
|
|
|
def main():
|
|
print ("\n*** templates.py v20201121 by Theo Arends and Barbudor ***")
|
|
|
|
now = datetime.now()
|
|
month = now.strftime('%B')
|
|
year = now.strftime('%Y')
|
|
|
|
# if stdin is a file, read the file instead of downloading (usefull for testing)
|
|
if sys.__stdin__.isatty():
|
|
print(f"Get template list from {LIST_URL}\n")
|
|
template_list = get_templates_list()
|
|
else:
|
|
print("Get template list from stdin\n")
|
|
template_list = sys.__stdin__.readlines()
|
|
|
|
# Write to root/TEMPLATES.md
|
|
fout = open(TEMPLATES,"w+")
|
|
|
|
fout.write("<picture>\n")
|
|
fout.write(" <source media=\"(prefers-color-scheme: dark)\" srcset=\"./tools/logo/TASMOTA_FullLogo_Vector_White.svg\">\n")
|
|
fout.write(" <img alt=\"Logo\" src=\"./tools/logo/TASMOTA_FullLogo_Vector.svg\" align=\"right\" height=\"76\">\n")
|
|
fout.write("</picture>\n")
|
|
fout.write("\n")
|
|
fout.write("# Templates\n")
|
|
fout.write("\n")
|
|
fout.write("Find below the available templates as of " + month + " " + year + ". More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)\n")
|
|
|
|
first = True
|
|
for line in template_list:
|
|
if line.strip():
|
|
if line.startswith("##"):
|
|
if not first:
|
|
fout.write('```\n')
|
|
fout.write('\n')
|
|
fout.write(line+'\n')
|
|
fout.write('```\n')
|
|
first = False
|
|
elif line.startswith("#"):
|
|
pass
|
|
else:
|
|
json_start = line.find("{")
|
|
if json_start > -1:
|
|
name = line[:json_start].strip()
|
|
try:
|
|
template = json.loads(line[json_start:])
|
|
template = convert_template(template)
|
|
except json.decoder.JSONDecodeError as ex:
|
|
template = "Not available"
|
|
|
|
fout.write(f"{name:<{COLUMN}} {json.dumps(template, separators=(',', ':'))}\n")
|
|
# else:
|
|
# fout.write(line+'\n')
|
|
|
|
fout.write('```\n')
|
|
|
|
fout.close()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|