3 # © Copyright 2021-2022, Scott Gasch
5 """Location/site dependent data."""
9 from dataclasses import dataclass
10 from typing import Callable, Optional
12 # Note: this module is fairly early loaded. Be aware of dependencies.
14 from type.locations import Location
16 logger = logging.getLogger(__name__)
18 args = config.add_commandline_args(
19 f'Global Site Config ({__file__})',
20 'Args related to global site-specific configuration',
23 '--site_config_override_location',
27 choices=['HOUSE', 'CABIN', 'NONE'],
28 help='Where are we, HOUSE, CABIN? Overrides standard detection code.',
33 class SiteConfig(object):
34 """The set of information specific to where the program is running."""
40 network_router_ip: str
41 presence_location: Location
42 is_anyone_present: Callable
43 arper_minimum_device_count: int
47 def get_location_name():
51 >>> location = get_location_name()
52 >>> location == 'HOUSE' or location == 'CABIN'
56 return get_config().location_name
61 Returns location as an enum instead of a string.
63 >>> from type.locations import Location
64 >>> location = get_location()
65 >>> location == Location.HOUSE or location == Location.CABIN
69 return get_config().location
72 def is_anyone_present_wrapper(location: Location):
75 p = base_presence.PresenceDetection()
76 return p.is_anyone_in_location_now(location)
79 def other_location() -> str:
81 Returns the location where this program is _NOT_ running.
83 >>> x = other_location()
84 >>> x in set(['HOUSE', 'CABIN'])
87 >>> y = this_location()
92 this = this_location()
98 raise Exception(f"{this} doesn't tell me where I'm running?!")
101 def this_location() -> str:
103 Returns the location where this program _IS_ running.
105 >>> x = this_location()
106 >>> x in set(['HOUSE', 'CABIN'])
110 hostname = platform.node()
111 if '.house' in hostname:
113 elif '.cabin' in hostname:
115 elif '.local' in hostname:
118 raise Exception(f"{hostname} doesn't help me know where I'm running?!")
122 def effective_location(location_override: Optional[str] = None) -> str:
123 """Detects and returns a location taking into account two override
126 >>> x = effective_location()
127 >>> x in set(['HOUSE', 'CABIN'])
130 >>> effective_location('HOUSE')
134 if location_override is None:
136 location_override = config.config['site_config_override_location']
138 location_override = None
140 if location_override is None or location_override == 'NONE':
141 location = this_location()
143 logger.debug('site_config\'s location_override was set to: %s', location_override)
144 location = location_override
148 def get_config(location_override: Optional[str] = None):
150 Get a configuration dataclass with information that is
151 site-specific including the current running location.
153 >>> cfg = get_config()
154 >>> cfg.location_name == 'HOUSE' or cfg.location_name == 'CABIN'
158 location = effective_location(location_override)
159 if location == 'HOUSE':
161 location_name='HOUSE',
162 location=Location.HOUSE,
163 network='10.0.0.0/24',
164 network_netmask='255.255.255.0',
165 network_router_ip='10.0.0.1',
166 presence_location=Location.HOUSE,
167 is_anyone_present=lambda x=Location.HOUSE: is_anyone_present_wrapper(x),
168 arper_minimum_device_count=50,
169 arper_cache_file='/home/scott/cache/.arp_table_cache_house',
171 elif location == 'CABIN':
173 location_name='CABIN',
174 location=Location.CABIN,
175 network='192.168.0.0/24',
176 network_netmask='255.255.255.0',
177 network_router_ip='192.168.0.1',
178 presence_location=Location.CABIN,
179 is_anyone_present=lambda x=Location.CABIN: is_anyone_present_wrapper(x),
180 arper_minimum_device_count=15,
181 arper_cache_file='/home/scott/cache/.arp_table_cache_cabin',
184 raise Exception(f'Unknown site location: {location}')
187 if __name__ == '__main__':