Skip to content

Commit

Permalink
Extend Equipment Functionalty to Object Image Preview (#263)
Browse files Browse the repository at this point in the history
* Add equipment selection to main menu, rework equipment ui to jump to it

* Switch logging to use equipment eyepiece menu, fix serialization of solution

* Make object images use eyepieces

* Remove errant raw camera file

* Refresh equipment config on web interface updates
  • Loading branch information
brickbots authored Feb 2, 2025
1 parent fda1fbe commit 4874c2c
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 152 deletions.
9 changes: 6 additions & 3 deletions python/PiFinder/cat_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
logger = logging.getLogger("Catalog.Images")


def get_display_image(catalog_object, source, fov, roll, display_class, burn_in=True):
def get_display_image(
catalog_object, eyepiece_text, fov, roll, display_class, burn_in=True
):
"""
Returns a 128x128 image buffer for
the catalog object/source
Expand All @@ -29,8 +31,9 @@ def get_display_image(catalog_object, source, fov, roll, display_class, burn_in=
degrees
"""

object_image_path = resolve_image_name(catalog_object, source)
object_image_path = resolve_image_name(catalog_object, source="POSS")
logger.debug("object_image_path = %s", object_image_path)
print("object_image_path = %s", object_image_path)
if not os.path.exists(object_image_path):
return_image = Image.new("RGB", display_class.resolution)
ri_draw = ImageDraw.Draw(return_image)
Expand Down Expand Up @@ -118,7 +121,7 @@ def get_display_image(catalog_object, source, fov, roll, display_class, burn_in=
ui_utils.shadow_outline_text(
ri_draw,
(1, display_class.resY - (display_class.fonts.base.height * 1.1)),
source,
eyepiece_text,
font=display_class.fonts.base,
align="left",
fill=display_class.colors.get(128),
Expand Down
29 changes: 25 additions & 4 deletions python/PiFinder/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ def __init__(self):
"""
load all settings from config file
"""
# Set up session config items
# These are transient
self._session_config_dict = {}
self.load_config()

def load_config(self):
"""
Loads all config from disk useful if another
process has changed config
"""
cwd = Path.cwd()
self.config_file_path = Path(utils.data_dir, "config.json")

Expand All @@ -30,10 +40,6 @@ def __init__(self):
with open(self.default_file_path, "r") as config_file:
self._default_config_dict = json.load(config_file)

# Set up session config items
# These are transient
self._session_config_dict = {}

# Load the equipment config
eq_config = self.get_option("equipment")
if eq_config is None:
Expand All @@ -57,13 +63,28 @@ def dump_config(self):
def set_option(self, option, value):
if option.startswith("session."):
self._session_config_dict[option] = value
elif option.startswith("equipment."):
option = option.split(".")[1]
if option == "active_telescope":
self.equipment.set_active_telescope(value)
if option == "active_eyepiece":
self.equipment.set_active_eyepiece(value)

self.save_equipment()

else:
self._config_dict[option] = value
self.dump_config()

def get_option(self, option, default: Any = None):
if option.startswith("session."):
return self._session_config_dict.get(option, default)
elif option.startswith("equipment."):
option = option.split(".")[1]
if option == "active_telescope":
return self.equipment.active_telescope
if option == "active_eyepiece":
return self.equipment.active_eyepiece
else:
return self._config_dict.get(
option, self._default_config_dict.get(option, default)
Expand Down
2 changes: 1 addition & 1 deletion python/PiFinder/db/observations_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def log_object(self, session_uuid, obs_time, catalog, sequence, solution, notes)
"obs_time": obs_time,
"catalog": catalog,
"sequence": sequence,
"solution": json.dumps(solution),
"solution": utils.serialize_solution(solution),
"notes": json.dumps(notes),
},
)
Expand Down
17 changes: 15 additions & 2 deletions python/PiFinder/equipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class Eyepiece:
afov: int
field_stop: float = 0

def __str__(self):
return f"{self.focal_length_mm}mm {self.name}"


@dataclass
class Telescope:
Expand All @@ -31,8 +34,8 @@ class Telescope:
class Equipment:
telescopes: list[Telescope]
eyepieces: list[Eyepiece]
active_telescope_index: Union[None, int] = None
active_eyepiece_index: Union[None, int] = None
active_telescope_index: int = -1
active_eyepiece_index: int = -1

def set_active_telescope(self, telescope: Telescope):
self.active_telescope_index = self.telescopes.index(telescope)
Expand All @@ -54,6 +57,16 @@ def active_eyepiece(self):
except (IndexError, TypeError):
return None

def cycle_eyepieces(self, direction: int) -> Eyepiece:
self.active_eyepiece_index += direction
if self.active_eyepiece_index >= len(self.eyepieces):
self.active_eyepiece_index = 0

if self.active_eyepiece_index < 0:
self.active_eyepiece_index = len(self.eyepieces) - 1

return self.active_eyepiece

def calc_magnification(
self,
telescope: Union[None, Telescope] = None,
Expand Down
17 changes: 15 additions & 2 deletions python/PiFinder/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,21 @@ def main(
)
p.start()

# Web server
console.write(" Webserver")
console.update()

server_process = Process(
name="Webserver",
target=server.run_server,
args=(keyboard_queue, gps_queue, shared_state, server_logqueue, verbose),
args=(
keyboard_queue,
ui_queue,
gps_queue,
shared_state,
server_logqueue,
verbose,
),
)
server_process.start()

Expand Down Expand Up @@ -423,7 +434,7 @@ def main(
integrator_process.start()

# Server
console.write(" Server")
console.write(" POS Server")
console.update()
posserver_process = Process(
name="SkySafariServer",
Expand Down Expand Up @@ -517,6 +528,8 @@ def main(
set_brightness(screen_brightness, cfg)
elif ui_command == "push_object":
menu_manager.jump_to_label("recent")
elif ui_command == "reload_config":
cfg.load_config()

# Keyboard
keycode = None
Expand Down
52 changes: 42 additions & 10 deletions python/PiFinder/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@ def auth_wrapper(*args, **kwargs):


class Server:
def __init__(self, q, gps_queue, shared_state, is_debug=False):
def __init__(
self, keyboard_queue, ui_queue, gps_queue, shared_state, is_debug=False
):
self.version_txt = f"{utils.pifinder_dir}/version.txt"
self.q = q
self.keyboard_queue = keyboard_queue
self.ui_queue = ui_queue
self.gps_queue = gps_queue
self.shared_state = shared_state
self.ki = KeyboardInterface()
Expand Down Expand Up @@ -306,6 +309,7 @@ def set_active_instrument(instrument_id: int):
cfg = config.Config()
cfg.equipment.set_active_telescope(cfg.equipment.telescopes[instrument_id])
cfg.save_equipment()
self.ui_queue.put("reload_config")
return template(
"equipment",
equipment=cfg.equipment,
Expand All @@ -321,6 +325,7 @@ def set_active_eyepiece(eyepiece_id: int):
cfg = config.Config()
cfg.equipment.set_active_eyepiece(cfg.equipment.eyepieces[eyepiece_id])
cfg.save_equipment()
self.ui_queue.put("reload_config")
return template(
"equipment",
equipment=cfg.equipment,
Expand Down Expand Up @@ -409,7 +414,12 @@ def equipment_import():
cfg.equipment.eyepieces.append(new_eyepiece)

cfg.save_equipment()
return template("equipment", equipment=config.Config().equipment)
self.ui_queue.put("reload_config")
return template(
"equipment",
equipment=config.Config().equipment,
success_message="Equipment Imported, restart your PiFinder to use this new data",
)

@app.route("/equipment/edit_eyepiece/<eyepiece_id:int>")
@auth_required
Expand Down Expand Up @@ -447,18 +457,28 @@ def equipment_add_eyepiece(eyepiece_id: int):
cfg.equipment.eyepieces.append(eyepiece)

cfg.save_equipment()
self.ui_queue.put("reload_config")
except Exception as e:
logger.error(f"Error adding eyepiece: {e}")

return template("equipment", equipment=config.Config().equipment)
return template(
"equipment",
equipment=config.Config().equipment,
success_message="Eyepiece added, restart your PiFinder to use",
)

@app.route("/equipment/delete_eyepiece/<eyepiece_id:int>")
@auth_required
def equipment_delete_eyepiece(eyepiece_id: int):
cfg = config.Config()
cfg.equipment.eyepieces.pop(eyepiece_id)
cfg.save_equipment()
return template("equipment", equipment=config.Config().equipment)
self.ui_queue.put("reload_config")
return template(
"equipment",
equipment=config.Config().equipment,
success_message="Eyepiece Deleted, restart your PiFinder to remove from menu",
)

@app.route("/equipment/edit_instrument/<instrument_id:int>")
@auth_required
Expand Down Expand Up @@ -511,17 +531,27 @@ def equipment_add_instrument(instrument_id: int):
cfg.equipment.telescopes.append(instrument)

cfg.save_equipment()
self.ui_queue.put("reload_config")
except Exception as e:
logger.error(f"Error adding instrument: {e}")
return template("equipment", equipment=config.Config().equipment)
return template(
"equipment",
equipment=config.Config().equipment,
success_message="Instrument Added, restart your PiFinder to use",
)

@app.route("/equipment/delete_instrument/<instrument_id:int>")
@auth_required
def equipment_delete_instrument(instrument_id: int):
cfg = config.Config()
cfg.equipment.telescopes.pop(instrument_id)
cfg.save_equipment()
return template("equipment", equipment=config.Config().equipment)
self.ui_queue.put("reload_config")
return template(
"equipment",
equipment=config.Config().equipment,
success_message="Instrument Deleted, restart your PiFinder to remove from menu",
)

@app.route("/observations")
@auth_required
Expand Down Expand Up @@ -672,7 +702,7 @@ def time_lock(time=datetime.now()):
)

def key_callback(self, key):
self.q.put(key)
self.keyboard_queue.put(key)

def update_gps(self):
location = self.shared_state.location()
Expand All @@ -691,6 +721,8 @@ def update_gps(self):
self.altitude = None


def run_server(q, gps_q, shared_state, log_queue, verbose=False):
def run_server(
keyboard_queue, ui_queue, gps_queue, shared_state, log_queue, verbose=False
):
MultiprocLogging.configurer(log_queue)
Server(q, gps_q, shared_state, verbose)
Server(keyboard_queue, ui_queue, gps_queue, shared_state, verbose)
2 changes: 2 additions & 0 deletions python/PiFinder/ui/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def __init__(
item_definition={},
add_to_stack=None,
remove_from_stack=None,
jump_to_label=None,
):
assert shared_state is not None
self.title = self.__title__
Expand All @@ -61,6 +62,7 @@ def __init__(
self.command_queues = command_queues
self.add_to_stack = add_to_stack
self.remove_from_stack = remove_from_stack
self.jump_to_label = jump_to_label

# mode stuff
self._display_mode_cycle = cycle(self._display_mode_list)
Expand Down
Loading

0 comments on commit 4874c2c

Please sign in to comment.