2020-05-19 10:31:24 +01:00
#!/usr/bin/env python3
"""
templates . py - template beautify TEMPLATES . md for Tasmota
2021-01-01 12:57:04 +00:00
Copyright ( C ) 2021 Theo Arends
2020-05-19 10:31:24 +01:00
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
"""
2020-11-20 20:49:52 +00:00
import sys
2020-05-19 10:31:24 +01:00
import io
2020-11-20 20:49:52 +00:00
import requests
2020-05-19 10:31:24 +01:00
from io import BytesIO
from io import StringIO
from datetime import datetime
2020-11-19 22:52:44 +00:00
import json
2020-05-19 10:31:24 +01:00
2020-11-20 20:49:52 +00:00
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
2020-11-19 22:52:44 +00:00
AGPIO = lambda x : x << 5
GPIO_NONE = 0
2020-11-20 20:49:52 +00:00
GPIO_USER = AGPIO ( GPIO_NONE ) + 1
2020-11-19 22:52:44 +00:00
GPIO_ADC_INPUT = 147
2020-11-20 20:49:52 +00:00
GPIO_ADC_JOY = 104
2020-11-19 22:52:44 +00:00
2020-11-20 20:49:52 +00:00
# Conversion table extracted from Tasmota code
GPIO_CONVERT = [
2020-11-19 22:52:44 +00:00
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
]
2020-11-20 20:49:52 +00:00
2020-11-19 22:52:44 +00:00
def is_old_template ( template ) :
2020-11-20 20:49:52 +00:00
""" find out it the template is old format """
# Old format <=> 13 gpios AND all gpios <= 255
2022-02-07 13:53:45 +00:00
# print(f"Template {template}\n")
2020-11-19 22:52:44 +00:00
if " GPIO " in template and len ( template [ " GPIO " ] ) == 13 :
for g in template [ " GPIO " ] :
2020-11-20 20:49:52 +00:00
if g > 255 :
return False
return True
2020-11-19 22:52:44 +00:00
return False
def gpio_convert ( gpio ) :
2020-11-20 20:49:52 +00:00
""" Conversion as per https://tasmota.github.io/docs/Components/#gpio-conversion """
if gpio > = len ( GPIO_CONVERT ) :
return GPIO_USER
return GPIO_CONVERT [ gpio ]
2020-11-19 22:52:44 +00:00
def adc0_convert ( adc0 ) :
2020-11-20 20:49:52 +00:00
""" Conversion as per https://tasmota.github.io/docs/Components/#adc-conversion """
2020-11-19 22:52:44 +00:00
adc0 = adc0 & 0x0F
2020-11-20 20:49:52 +00:00
if 0 == adc0 :
2020-11-19 22:52:44 +00:00
return GPIO_NONE
2020-11-20 20:49:52 +00:00
elif 8 == adc0 :
return AGPIO ( GPIO_ADC_JOY ) ; # Joystick
elif adc0 > 7 :
return GPIO_USER
2020-11-19 22:52:44 +00:00
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 " ] }
2020-11-20 20:49:52 +00:00
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 ' )
2020-11-19 22:52:44 +00:00
2020-05-19 10:31:24 +01:00
def main ( ) :
2020-11-21 11:27:11 +00:00
print ( " \n *** templates.py v20201121 by Theo Arends and Barbudor *** " )
2020-05-19 10:31:24 +01:00
now = datetime . now ( )
month = now . strftime ( ' % B ' )
year = now . strftime ( ' % Y ' )
2020-11-20 20:49:52 +00:00
# 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 ( )
2020-05-19 10:31:24 +01:00
# Write to root/TEMPLATES.md
2020-11-20 20:49:52 +00:00
fout = open ( TEMPLATES , " w+ " )
2020-05-19 10:31:24 +01:00
2023-01-24 09:48:38 +00:00
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 " )
2020-05-19 10:31:24 +01:00
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 " )
2020-11-19 22:52:44 +00:00
first = True
2020-11-20 20:49:52 +00:00
for line in template_list :
2020-05-19 10:31:24 +01:00
if line . strip ( ) :
if line . startswith ( " ## " ) :
2020-11-19 22:52:44 +00:00
if not first :
2020-05-19 10:31:24 +01:00
fout . write ( ' ``` \n ' )
fout . write ( ' \n ' )
2020-11-20 20:49:52 +00:00
fout . write ( line + ' \n ' )
2020-05-19 10:31:24 +01:00
fout . write ( ' ``` \n ' )
2020-11-19 22:52:44 +00:00
first = False
2020-05-19 10:31:24 +01:00
elif line . startswith ( " # " ) :
2020-11-19 22:52:44 +00:00
pass
2020-05-19 10:31:24 +01:00
else :
2020-11-19 22:52:44 +00:00
json_start = line . find ( " { " )
2022-02-07 13:53:45 +00:00
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')
2020-05-19 10:31:24 +01:00
fout . write ( ' ``` \n ' )
fout . close ( )
if __name__ == " __main__ " :
main ( )