Add tlmConfirm to tlm_dl ota packet-structure (#2991)
[ExpressLRS.git] / src / python / build_flags.py
blob7298ac7339d8dd15dc0e772e07213e739efa7a9c
1 Import("env")
2 import os
3 from random import randint
4 import sys
5 import hashlib
6 import fnmatch
7 import time
8 import re
9 import elrs_helpers
11 build_flags = env.get('BUILD_FLAGS', [])
12 json_flags = {}
13 UIDbytes = ""
14 define = ""
15 target_name = env.get('PIOENV', '').upper()
17 isRX = True if '_RX_' in target_name else False
19 def print_error(error):
20 time.sleep(1)
21 sys.stdout.write("\n\n\033[47;31m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
22 sys.stdout.write("\033[47;31m!!! ExpressLRS Warning Below !!!\n")
23 sys.stdout.write("\033[47;31m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
24 sys.stdout.write("\033[47;30m %s \n" % error)
25 sys.stdout.write("\033[47;31m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n")
26 sys.stdout.flush()
27 time.sleep(3)
28 raise Exception('!!! %s !!!' % error)
31 def dequote(str):
32 if str[0] == '"' and str[-1] == '"':
33 return str[1:-1]
34 return str
36 def process_json_flag(define):
37 parts = re.search(r"-D(.*)\s*=\s*(.*)$", define)
38 if parts and define.startswith("-D"):
39 if parts.group(1) == "MY_BINDING_PHRASE":
40 json_flags['uid'] = [x for x in hashlib.md5(define.encode()).digest()[0:6]]
41 if parts.group(1) == "HOME_WIFI_SSID":
42 json_flags['wifi-ssid'] = dequote(parts.group(2))
43 if parts.group(1) == "HOME_WIFI_PASSWORD":
44 json_flags['wifi-password'] = dequote(parts.group(2))
45 if parts.group(1) == "AUTO_WIFI_ON_INTERVAL":
46 parts = re.search(r"-D(.*)\s*=\s*\"?([0-9]+).*\"?$", define)
47 json_flags['wifi-on-interval'] = int(dequote(parts.group(2)))
48 if parts.group(1) == "TLM_REPORT_INTERVAL_MS" and not isRX:
49 parts = re.search(r"-D(.*)\s*=\s*\"?([0-9]+).*\"?$", define)
50 json_flags['tlm-interval'] = int(dequote(parts.group(2)))
51 if parts.group(1) == "FAN_MIN_RUNTIME" and not isRX:
52 parts = re.search(r"-D(.*)\s*=\s*\"?([0-9]+).*\"?$", define)
53 json_flags['fan-runtime'] = int(dequote(parts.group(2)))
54 if parts.group(1) == "RCVR_UART_BAUD" and isRX:
55 parts = re.search(r"-D(.*)\s*=\s*\"?([0-9]+).*\"?$", define)
56 json_flags['rcvr-uart-baud'] = int(dequote(parts.group(2)))
57 if parts.group(1) == "USE_AIRPORT_AT_BAUD":
58 parts = re.search(r"-D(.*)\s*=\s*\"?([0-9]+).*\"?$", define)
59 json_flags['is-airport'] = True
60 if isRX:
61 json_flags['rcvr-uart-baud'] = int(dequote(parts.group(2)))
62 else:
63 json_flags['airport-uart-baud'] = int(dequote(parts.group(2)))
64 if define == "-DUNLOCK_HIGHER_POWER" and not isRX:
65 json_flags['unlock-higher-power'] = True
66 if define == "-DLOCK_ON_FIRST_CONNECTION" and isRX:
67 json_flags['lock-on-first-connection'] = True
69 def process_build_flag(define):
70 if define.startswith("-D") or define.startswith("!-D"):
71 if "MY_BINDING_PHRASE" in define:
72 bindingPhraseHash = hashlib.md5(define.encode()).digest()
73 UIDbytes = ",".join(list(map(str, bindingPhraseHash))[0:6])
74 define = "-DMY_UID=" + UIDbytes
75 sys.stdout.write("\u001b[32mUID bytes: " + UIDbytes + "\n")
76 sys.stdout.flush()
77 if "HOME_WIFI_SSID=" in define:
78 parts = re.search(r"(.*)=\w*\"(.*)\"$", define)
79 if parts and parts.group(2):
80 define = "-DHOME_WIFI_SSID=" + string_to_ascii(parts.group(2))
81 if "HOME_WIFI_PASSWORD=" in define:
82 parts = re.search(r"(.*)=\w*\"(.*)\"$", define)
83 if parts and parts.group(2):
84 define = "-DHOME_WIFI_PASSWORD=" + string_to_ascii(parts.group(2))
85 if "DEVICE_NAME=" in define:
86 parts = re.search(r"(.*)=\w*'?\"(.*)\"'?$", define)
87 if parts and parts.group(2):
88 env['DEVICE_NAME'] = parts.group(2)
89 if not define in build_flags:
90 build_flags.append(define)
92 def parse_flags(path):
93 global build_flags
94 global json_flags
95 try:
96 with open(path, "r") as _f:
97 for define in _f:
98 define = define.strip()
99 process_build_flag(define)
100 process_json_flag(define)
102 except IOError:
103 print("File '%s' does not exist" % path)
105 def process_flags(path):
106 global build_flags
107 if not os.path.isfile(path):
108 return
109 parse_flags(path)
111 def condense_flags():
112 global build_flags
113 for line in build_flags:
114 # Some lines have multiple flags so this will split them and remove them all
115 for flag in re.findall(r"!-D\s*[^\s]+", line):
116 build_flags = [x.replace(flag,"") for x in build_flags] # remove the removal flag
117 build_flags = [x.replace(flag[1:],"") for x in build_flags] # remove the flag if it matches the removal flag
118 build_flags = [x for x in build_flags if (x.strip() != "")] # remove any blank items
120 def version_to_env():
121 ver = elrs_helpers.get_git_version()
122 env.Append(GIT_SHA = ver['sha'], GIT_VERSION= ver['version'])
124 def string_to_ascii(str):
125 return ",".join(["%s" % ord(char) for char in str])
127 def get_git_sha():
128 return string_to_ascii(env.get('GIT_SHA'))
130 def get_version():
131 return string_to_ascii(env.get('GIT_VERSION'))
133 json_flags['flash-discriminator'] = randint(1,2**32-1)
134 json_flags['wifi-on-interval'] = -1
136 process_flags("user_defines.txt")
137 process_flags("super_defines.txt") # allow secret super_defines to override user_defines
138 version_to_env()
139 build_flags.append("-DLATEST_COMMIT=" + get_git_sha())
140 build_flags.append("-DLATEST_VERSION=" + get_version())
141 build_flags.append("-DTARGET_NAME=" + re.sub("_VIA_.*", "", target_name))
142 condense_flags()
144 if '-DRADIO_SX127X=1' in build_flags or '-DRADIO_LR1121=1' in build_flags:
145 # disallow setting 2400s for 900
146 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_ISM_2400') or \
147 fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_CE_2400'):
148 print_error('Regulatory_Domain 2400 not compatible with RADIO_SX127X/RADIO_LR1121')
150 # require a domain be set for 900
151 if not fnmatch.filter(build_flags, '*-DRegulatory_Domain*'):
152 print_error('Please define a Regulatory_Domain in user_defines.txt')
154 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_AU_915'):
155 json_flags['domain'] = 0
156 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_FCC_915'):
157 json_flags['domain'] = 1
158 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_868'):
159 json_flags['domain'] = 2
160 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_IN_866'):
161 json_flags['domain'] = 3
162 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_AU_433'):
163 json_flags['domain'] = 4
164 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_433'):
165 json_flags['domain'] = 5
166 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_US_433'):
167 json_flags['domain'] = 6
168 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_US_433_WIDE'):
169 json_flags['domain'] = 7
170 else:
171 json_flags['domain'] = 0
173 # Remove ISM_2400 domain flag if not unit test, it is defined per target config
174 if fnmatch.filter(build_flags, '*Regulatory_Domain_ISM_2400*') and \
175 target_name != "NATIVE":
176 build_flags = [f for f in build_flags if "Regulatory_Domain_ISM_2400" not in f]
178 env['OPTIONS_JSON'] = json_flags
179 env['BUILD_FLAGS'] = build_flags
180 sys.stdout.write("\nbuild flags: %s\n\n" % build_flags)
182 if fnmatch.filter(build_flags, '*PLATFORM_ESP32*'):
183 sys.stdout.write("\u001b[32mBuilding for ESP32 Platform\n")
184 elif fnmatch.filter(build_flags, '*PLATFORM_ESP8266*'):
185 sys.stdout.write("\u001b[32mBuilding for ESP8266/ESP8285 Platform\n")
186 if fnmatch.filter(build_flags, '-DAUTO_WIFI_ON_INTERVAL*'):
187 sys.stdout.write("\u001b[32mAUTO_WIFI_ON_INTERVAL = ON\n")
188 else:
189 sys.stdout.write("\u001b[32mAUTO_WIFI_ON_INTERVAL = OFF\n")
191 sys.stdout.flush()
192 time.sleep(.5)