Coverage for /home/pi/Software/model-railway-signalling/model_railway_signals/editor/settings.py: 87%

177 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-04-08 18:20 +0100

1#------------------------------------------------------------------------------------ 

2# This module maintains the settings for the schematic editor 

3# 

4# External API functions intended for use by other editor modules: 

5# restore_defaults() - Restores all defaults 

6# get_all() - returns dictionary of settings 

7# set_all(new_settings) - pass in dictionary of new settings 

8# get_canvas() - Get the current canvas settings (for editing) 

9# set_canvas() - Save the new canvas settings (as specified) 

10# get_logging() - Get the current log level (for editing) 

11# set_logging(level) - Save the new log level (as specified) 

12# get_general() - Get the current settings (layout info, version for info/editing) 

13# set_general() - Save the new settings (only layout info can be edited/saved) 

14# get_sprog() - Get the current SPROG settings (for editing) 

15# set_sprog() - Save the new SPROG settings (as specified) 

16# get_mqtt() - Get the current MQTT settings (for editing) 

17# set_mqtt() - Save the new MQTT settings (as specified) 

18# get_gpio() - Get the current GPIO settings (for editing) 

19# set_gpio() - Save the new GPIO settings (as specified) 

20# get_sub_dcc_nodes() - get the list of subscribed dccc command feeds 

21# get_sub_signals() - get the list of subscribed items 

22# get_sub_sections() - get the list of subscribed items 

23# get_sub_instruments() - get the list of subscribed items 

24# get_sub_sensors() - get the list of subscribed items 

25# get_pub_dcc() - get the publish dcc command feed flag 

26# get_pub_signals() - get the list of items to publish 

27# get_pub_sections() - get the list of items to publish 

28# get_pub_instruments() - get the list of items to publish 

29# get_pub_sensors() - get the list of items to publish 

30# set_sub_dcc_nodes() - set the list of subscribed nodes 

31# set_sub_signals() - set the list of subscribed items 

32# set_sub_sections() - set the list of subscribed items 

33# set_sub_instruments() - set the list of subscribed items 

34# set_sub_sensors() - set the list of subscribed items 

35# set_pub_dcc() - set the publish dcc command feed flag 

36# set_pub_signals() - set the list of items to publish 

37# set_pub_sections() - set the list of items to publish 

38# set_pub_instruments() - set the list of items to publish 

39# set_pub_sensors() - set the list of items to publish 

40#------------------------------------------------------------------------------------ 

41 

42import copy 

43import logging 

44 

45#------------------------------------------------------------------------------------ 

46# These are the default settings 

47#------------------------------------------------------------------------------------ 

48 

49default_settings = {} 

50default_settings["general"] = {} 

51default_settings["general"]["filename"] = "new_layout.sig" 

52default_settings["general"]["editmode"] = True 

53default_settings["general"]["version"] = "Version 4.2.0" 

54default_settings["general"]["info"] = "Document your layout here" 

55default_settings["general"]["automation"] = True 

56default_settings["general"]["spadpopups"] = False 

57default_settings["canvas"] = {} 

58default_settings["canvas"]["width"] = 1000 

59default_settings["canvas"]["height"] = 500 

60default_settings["canvas"]["grid"] = 25 

61default_settings["canvas"]["snaptogrid"] = True 

62default_settings["logging"] = {} 

63default_settings["logging"]["level"] = 2 # Warning 

64default_settings["sprog"] = {} 

65default_settings["sprog"]["port"] = "/dev/serial0" 

66default_settings["sprog"]["baud"] = 460800 

67default_settings["sprog"]["debug"] = False 

68default_settings["sprog"]["startup"] = False 

69default_settings["sprog"]["power"] = False 

70default_settings["mqtt"] = {} 

71default_settings["mqtt"]["url"] = "127.0.0.1" 

72default_settings["mqtt"]["port"] = 1883 

73default_settings["mqtt"]["network"] = "network" 

74default_settings["mqtt"]["node"] = "node" 

75default_settings["mqtt"]["username"] = "" 

76default_settings["mqtt"]["password"] = "" 

77default_settings["mqtt"]["debug"] = False 

78default_settings["mqtt"]["startup"] = False 

79default_settings["mqtt"]["pubshutdown"] = False 

80default_settings["mqtt"]["subshutdown"] = False 

81default_settings["mqtt"]["subdccnodes"] = [] 

82default_settings["mqtt"]["subsignals"] = [] 

83default_settings["mqtt"]["subsections"] = [] 

84default_settings["mqtt"]["subinstruments"] = [] 

85default_settings["mqtt"]["subsensors"] = [] 

86default_settings["mqtt"]["pubdcc"] = False 

87default_settings["mqtt"]["pubsignals"] = [] 

88default_settings["mqtt"]["pubsections"] = [] 

89default_settings["mqtt"]["pubinstruments"] = [] 

90default_settings["mqtt"]["pubsensors"] = [] 

91default_settings["gpio"] = {} 

92default_settings["gpio"]["triggerdelay"] = 0.001 

93default_settings["gpio"]["timeoutperiod"] = 1.000 

94default_settings["gpio"]["portmappings"] = [] 

95 

96#------------------------------------------------------------------------------------ 

97# These are the 'current' settings - changed by the user as required 

98#------------------------------------------------------------------------------------ 

99 

100settings = copy.deepcopy (default_settings) 

101 

102#------------------------------------------------------------------------------------ 

103# Function to restore the default settings 

104#------------------------------------------------------------------------------------ 

105 

106def restore_defaults(): 

107 global filename, settings 

108 settings = copy.deepcopy (default_settings) 

109 return() 

110 

111#------------------------------------------------------------------------------------ 

112# Functions to set/get all settings (for load and save) 

113#------------------------------------------------------------------------------------ 

114 

115def get_all(): 

116 return(settings) 

117 

118def set_all(new_settings): 

119 global settings 

120 # Maintain the logging level across re-loads (use case - set debugging to see load warnings) 

121 current_logging_level = settings["logging"]["level"] 

122 # Defensive programming to populate the settings gracefully 

123 restore_defaults() 

124 # Populate an element at a time - and report any elements we don't recognise 

125 for group in new_settings: 

126 if group not in settings.keys(): 

127 logging.debug("LOAD LAYOUT - Unexpected settings group '"+group+"' - DISCARDED") 

128 else: 

129 for element in new_settings[group]: 

130 if element not in settings[group].keys(): 

131 logging.debug("LOAD LAYOUT - Unexpected settings element '"+group+":"+element+"' - DISCARDED") 

132 else: 

133 

134 settings[group][element] = new_settings[group][element] 

135 # Now report any elements missing from the new configuration - intended to provide a 

136 # level of backward capability (able to load old config files into an extended config 

137 for group in settings: 

138 if group not in new_settings.keys(): 

139 logging.debug("LOAD LAYOUT - Missing settings group: '"+group+"' - Asigning default values:") 

140 for element in default_settings[group]: 

141 logging.debug("LOAD LAYOUT - Missing settings element '"+group+":"+element+ 

142 "' - Asigning default value '"+ str(default_settings[group][element])+"'") 

143 else: 

144 for element in settings[group]: 

145 if element not in new_settings[group].keys(): 

146 logging.debug("LOAD LAYOUT - Missing settings element '"+group+":"+element+ 

147 "' - Assigning Default Value '"+ str(default_settings[group][element])+"'") 

148 # We always maintain the current version of the application 

149 settings["general"]["version"] = default_settings["general"]["version"] 

150 # Maintain the logging level across re-loads (use case - set debugging to see load warnings) 

151 settings["logging"]["level"] = current_logging_level 

152 return() 

153 

154#------------------------------------------------------------------------------------ 

155# Functions to set/get the general settings 

156#------------------------------------------------------------------------------------ 

157 

158def get_general(param=None): 

159 filename = settings["general"]["filename"] 

160 editmode = settings["general"]["editmode"] 

161 version = settings["general"]["version"] 

162 info = settings["general"]["info"] 

163 automation = settings["general"]["automation"] 

164 spad = settings["general"]["spadpopups"] 

165 return(filename, editmode, version, info, automation, spad) 

166 

167def set_general(filename:str=None, editmode:bool=None, version:str=None, info:str=None, automation:bool=None, spad:bool=None): 

168 if filename is not None: settings["general"]["filename"] = filename 

169 if editmode is not None: settings["general"]["editmode"] = editmode 

170 if version is not None: settings["general"]["version"] = version 

171 if info is not None: settings["general"]["info"] = info 

172 if automation is not None: settings["general"]["automation"] = automation 

173 if spad is not None: settings["general"]["spadpopups"] = spad 

174 return() 

175 

176#------------------------------------------------------------------------------------ 

177# Functions to set/get the canvas settings 

178#------------------------------------------------------------------------------------ 

179 

180def get_canvas(): 

181 width = settings["canvas"]["width"] 

182 height = settings["canvas"]["height"] 

183 grid = settings["canvas"]["grid"] 

184 snap_to_grid = settings["canvas"]["snaptogrid"] 

185 return (width, height, grid, snap_to_grid) 

186 

187def set_canvas(width:int=None, height:int=None, grid:int=None, snap_to_grid:bool=None): 

188 if width is not None: settings["canvas"]["width"] = width 

189 if height is not None: settings["canvas"]["height"] = height 

190 if grid is not None: settings["canvas"]["grid"] = grid 

191 if snap_to_grid is not None: settings["canvas"]["snaptogrid"] = snap_to_grid 

192 return() 

193 

194#------------------------------------------------------------------------------------ 

195# Functions to set/get the canvas settings 

196#------------------------------------------------------------------------------------ 

197 

198def get_logging(): 

199 level = settings["logging"]["level"] 

200 return (level) 

201 

202def set_logging(level:int=None): 

203 if level is not None: settings["logging"]["level"] = level 

204 return() 

205 

206#------------------------------------------------------------------------------------ 

207# Functions to set/get the SPROG settings 

208#------------------------------------------------------------------------------------ 

209 

210def get_sprog(): 

211 port = settings["sprog"]["port"] 

212 baud = settings["sprog"]["baud"] 

213 debug = settings["sprog"]["debug"] 

214 startup = settings["sprog"]["startup"] 

215 power = settings["sprog"]["power"] 

216 return (port, baud, debug, startup, power) 

217 

218def set_sprog(port:str=None, baud:int=None, debug:bool=None, startup:bool=None, power:bool=None): 

219 if port is not None: settings["sprog"]["port"] = port 

220 if baud is not None: settings["sprog"]["baud"] = baud 

221 if debug is not None: settings["sprog"]["debug"] = debug 

222 if startup is not None: settings["sprog"]["startup"] = startup 

223 if power is not None: settings["sprog"]["power"] = power 

224 return() 

225 

226#------------------------------------------------------------------------------------ 

227# Functions to set/get the GPIO settings 

228#------------------------------------------------------------------------------------ 

229 

230def get_gpio(): 

231 trigger = settings["gpio"]["triggerdelay"] 

232 timeout = settings["gpio"]["timeoutperiod"] 

233 mappings = settings["gpio"]["portmappings"] 

234 return (trigger, timeout, mappings) 

235 

236def set_gpio(trigger:float=None, timeout:float=None, mappings:list=None): 

237 if trigger is not None: settings["gpio"]["triggerdelay"] = trigger 

238 if timeout is not None: settings["gpio"]["timeoutperiod"] = timeout 

239 if mappings is not None: settings["gpio"]["portmappings"] = mappings 

240 return() 

241 

242#------------------------------------------------------------------------------------ 

243# Functions to set/get the MQTT settings 

244#------------------------------------------------------------------------------------ 

245 

246def get_mqtt(): 

247 url = settings["mqtt"]["url"] 

248 port = settings["mqtt"]["port"] 

249 network = settings["mqtt"]["network"] 

250 node = settings["mqtt"]["node"] 

251 username = settings["mqtt"]["username"] 

252 password = settings["mqtt"]["password"] 

253 debug = settings["mqtt"]["debug"] 

254 startup = settings["mqtt"]["startup"] 

255 pubshutdown = settings["mqtt"]["pubshutdown"] 

256 subshutdown = settings["mqtt"]["subshutdown"] 

257 return (url, port, network, node, username, password, debug, startup, pubshutdown, subshutdown) 

258 

259def set_mqtt(url:str=None, port:int=None, network:str=None, node:str=None, 

260 username:str=None, password:str=None, debug:bool=None, startup:bool=None, 

261 publish_shutdown:bool=None, subscribe_shutdown:bool=None ): 

262 if url is not None: settings["mqtt"]["url"] = url 

263 if port is not None: settings["mqtt"]["port"] = port 

264 if network is not None: settings["mqtt"]["network"] = network 

265 if node is not None: settings["mqtt"]["node"] = node 

266 if username is not None: settings["mqtt"]["username"] = username 

267 if password is not None: settings["mqtt"]["password"] = password 

268 if debug is not None: settings["mqtt"]["debug"] = debug 

269 if startup is not None: settings["mqtt"]["startup"] = startup 

270 if publish_shutdown is not None: settings["mqtt"]["pubshutdown"] = publish_shutdown 

271 if subscribe_shutdown is not None: settings["mqtt"]["subshutdown"] = subscribe_shutdown 

272 return() 

273 

274def get_pub_dcc(): return (settings["mqtt"]["pubdcc"]) 

275def get_pub_signals(): return (settings["mqtt"]["pubsignals"]) 

276def get_pub_sections(): return (settings["mqtt"]["pubsections"]) 

277def get_pub_instruments(): return (settings["mqtt"]["pubinstruments"]) 

278def get_pub_sensors(): return (settings["mqtt"]["pubsensors"]) 

279def get_sub_dcc_nodes(): return (settings["mqtt"]["subdccnodes"]) 

280def get_sub_signals(): return (settings["mqtt"]["subsignals"]) 

281def get_sub_sections(): return (settings["mqtt"]["subsections"]) 

282def get_sub_instruments(): return (settings["mqtt"]["subinstruments"]) 

283def get_sub_sensors(): return (settings["mqtt"]["subsensors"]) 

284 

285def set_pub_dcc(value:bool): settings["mqtt"]["pubdcc"] = value 285 ↛ exitline 285 didn't return from function 'set_pub_dcc'

286def set_pub_signals(values:list): settings["mqtt"]["pubsignals"] = values 286 ↛ exitline 286 didn't return from function 'set_pub_signals'

287def set_pub_sections(values:list): settings["mqtt"]["pubsections"] = values 287 ↛ exitline 287 didn't return from function 'set_pub_sections'

288def set_pub_instruments(values:list): settings["mqtt"]["pubinstruments"] = values 288 ↛ exitline 288 didn't return from function 'set_pub_instruments'

289def set_pub_sensors(values:list): settings["mqtt"]["pubsensors"] = values 289 ↛ exitline 289 didn't return from function 'set_pub_sensors'

290def set_sub_dcc_nodes(values:list): settings["mqtt"]["subdccnodes"] = values 290 ↛ exitline 290 didn't return from function 'set_sub_dcc_nodes'

291def set_sub_signals(values:list): settings["mqtt"]["subsignals"] = values 291 ↛ exitline 291 didn't return from function 'set_sub_signals'

292def set_sub_sections(values:list): settings["mqtt"]["subsections"] = values 292 ↛ exitline 292 didn't return from function 'set_sub_sections'

293def set_sub_instruments(values:list): settings["mqtt"]["subinstruments"] = values 293 ↛ exitline 293 didn't return from function 'set_sub_instruments'

294def set_sub_sensors(values:list): settings["mqtt"]["subsensors"] = values 294 ↛ exitline 294 didn't return from function 'set_sub_sensors'

295 

296###################################################################################### 

297 

298