Loading Common/Servers/PySupervisor/src/Supervisor/SupervisorImpl.py +214 −158 Original line number Diff line number Diff line Loading @@ -54,6 +54,9 @@ class SupervisorImpl(POA, cc, services, lcycle): self.dao_path = 'alma/ANTENNA/Supervisor' self.setup("default") self.stop_threads = False self.sunClient = self.windClient = None self.loadSunClient() self.loadWindClient() for thread in (self.sunCheck, self.windCheck): t = Thread(target=thread, daemon=True) t.start() Loading Loading @@ -133,13 +136,47 @@ class SupervisorImpl(POA, cc, services, lcycle): def isTracking(self): return True def disconnect(self, client): def loadWindClient(self): try: if client.isLoggedIn(): client.disconnect() if self.windClient and self.windClient.isLoggedIn(): pass else: self.disconnectWindClient() self.windClient = PySimpleClient() except Exception as ex: self.log( "Cannot disconnect the client", f"loadWindClient: {ex}", Management.C_ERROR, ) def loadSunClient(self): try: if self.sunClient and self.sunClient.isLoggedIn(): pass else: self.disconnectSunClient() self.sunClient = PySimpleClient() except Exception as ex: self.log( f"loadSunClient: {ex}", Management.C_ERROR, ) def disconnectSunClient(self): try: self.sunClient.disconnect() except Exception as ex: self.log( "Cannot disconnect sunClient", Management.C_WARNING, ) def disconnectWindClient(self): try: self.windClient.disconnect() except Exception as ex: self.log( "Cannot disconnect windClient", Management.C_WARNING, ) Loading @@ -155,7 +192,10 @@ class SupervisorImpl(POA, cc, services, lcycle): except Exception as ex: print(f"Unexpected exception in log(): {ex}") finally: self.disconnect(client) try: client.disconnect() except Exception: print(f"Error disconnecting the log client") def windCheck(self): print("windCheck() thread started") Loading @@ -166,6 +206,7 @@ class SupervisorImpl(POA, cc, services, lcycle): antenna_name = "ANTENNA/Boss" wind_values = [] while True: try: for i in range(5): # Sleep for 5 seconds, check stop signal if self.stop_threads: break Loading @@ -179,11 +220,13 @@ class SupervisorImpl(POA, cc, services, lcycle): if self.windAvoidance == "OFF": continue # Sleep again client = PySimpleClient() self.loadWindClient() try: el_mode = "" mount = client.getComponent(mount_name) el_mode, compl = mount.elevationMode.get_sync() el = 0 mount = self.windClient.getComponent(mount_name) el_mode = str(mount.elevationMode.get_sync()[0]) el = mount.elevation.get_sync()[0] except CannotGetComponentEx as ex: self.log( f"Can not get component {mount_name}", Loading @@ -193,7 +236,7 @@ class SupervisorImpl(POA, cc, services, lcycle): self.log(f"Can not get component {mount_name}: {ex}") try: ws = client.getComponent(weather_name) ws = self.windClient.getComponent(weather_name) value = ws.getWindSpeedAverage() except CannotGetComponentEx as ex: self.log( Loading @@ -202,7 +245,6 @@ class SupervisorImpl(POA, cc, services, lcycle): ) except Exception as ex: self.log(f"Unexpected exception: {ex}") self.disconnect(client) continue # Sleep again if len(wind_values) < 30: Loading @@ -213,21 +255,17 @@ class SupervisorImpl(POA, cc, services, lcycle): self.wind = sum(wind_values)/len(wind_values) if wind_values else 0 if self.wind >= self.windLimit: if str(el_mode) == "ACU_STOW": if el_mode == "ACU_STOW": if not stow_notified: self.log( f"Antenna parked, too much wind", f"Parking antenna, too much wind", Management.C_WARNING, ) stow_notified = True self.disconnect(client) continue self.log(f"Supervisor: stopping antenna, windy") self.log(f"Safe limit -> {self.windLimit:.2f}", Management.C_INFO) self.log(f"Average wind -> {self.wind:.2f}", Management.C_INFO) try: scheduler = client.getDefaultComponent(scheduler_name) scheduler = self.windClient.getDefaultComponent(scheduler_name) scheduler.stopSchedule() except CannotGetComponentEx as ex: self.log( Loading @@ -238,7 +276,7 @@ class SupervisorImpl(POA, cc, services, lcycle): self.log(f"Can not get {scheduler_name}: {ex}") try: antenna = client.getComponent(antenna_name) antenna = self.windClient.getComponent(antenna_name) except CannotGetComponentEx as ex: self.log( f"Can not get component {antenna_name}", Loading @@ -246,18 +284,27 @@ class SupervisorImpl(POA, cc, services, lcycle): ) except Exception as ex: self.log(f"Can not get {antenna_name}: {ex}") self.disconnect(client) continue # Sleep again if el_mode == "ACU_STANDBY" and abs(90-el) < 0.5: continue # Antenna parked try: self.log("Too much wind", Management.C_WARNING) self.log(f"Safe limit -> {self.windLimit:.2f}", Management.C_INFO) self.log(f"Average wind -> {self.wind:.2f}", Management.C_INFO) self.log(f"Supervisor: parking antenna, windy") antenna.stop() antenna.park() # Finally park the antenna self.log("Parking antenna", Management.C_INFO) stow_notified = True except Exception as ex: self.log(f"Can not park the antenna: {ex}") self.disconnect(client) continue # Sleep again stow_notified = False self.disconnect(client) except Exception as ex: self.log(f"Unexpected exception in windCheck(): {ex}") print("sunCheck() thread stopped") Loading @@ -272,6 +319,7 @@ class SupervisorImpl(POA, cc, services, lcycle): sun = ephem.Sun() stop_notified = False while True: try: time.sleep(1) if self.stop_threads: print("Stopping sunCheck() thread") Loading @@ -279,10 +327,10 @@ class SupervisorImpl(POA, cc, services, lcycle): if self.sunAvoidance == "OFF": continue # Sleep again client = PySimpleClient() self.loadSunClient() if not (lat and lon): try: observatory = client.getComponent(observatory_name) observatory = self.sunClient.getComponent(observatory_name) lat, compl = observatory.latitude.get_sync() lon, compl = observatory.longitude.get_sync() except CannotGetComponentEx as ex: Loading @@ -290,17 +338,15 @@ class SupervisorImpl(POA, cc, services, lcycle): except Exception as ex: self.log(f"Can not get component {observatory_name}: {ex}") finally: self.disconnect(client) continue # Sleep again try: antenna = client.getComponent(antenna_name) antenna = self.sunClient.getComponent(antenna_name) except CannotGetComponentEx as ex: self.log( f"Can not get component {antenna_name}", Management.C_ERROR, ) self.disconnect(client) continue # Sleep again t = getTimeStamp().value Loading @@ -313,17 +359,14 @@ class SupervisorImpl(POA, cc, services, lcycle): f"Cannot get antenna coordinates: {ex}", Management.C_ERROR, ) self.disconnect(client) continue # Sleep again limit = self.sunLimit az_mode = el_mode = "" try: mount = client.getComponent(mount_name) az_mode, compl = mount.azimuthMode.get_sync() el_mode, compl = mount.elevationMode.get_sync() if str(az_mode) == str(el_mode) == "ACU_PRESET": limit = self.sunLimit * 3 mount = self.sunClient.getComponent(mount_name) az_mode = str(mount.azimuthMode.get_sync()[0]) el_mode = str(mount.elevationMode.get_sync()[0]) except CannotGetComponentEx as ex: self.log( f"Can not get component {mount_name}", Loading @@ -342,14 +385,22 @@ class SupervisorImpl(POA, cc, services, lcycle): self.sunDistance = sqrt(delta_az**2 + (sun_el - el)**2) if self.sunDistance < limit: if str(az_mode) == str(el_mode) == "ACU_STOP": if az_mode == el_mode == "ACU_STOP": time.sleep(5) self.log( f"Distance from Sun -> {self.sunDistance:.2f}", Management.C_INFO ) self.log( f"Sun safe limit -> {limit:.2f}", Management.C_INFO ) if not stop_notified: self.log( f"Antenna stopped, pointing close to the Sun", "Antenna stopped, pointing close to the Sun", Management.C_WARNING, ) stop_notified = True self.disconnect(client) continue # Sleep again self.log(f"Supervisor: stopping antenna, pointing close to the Sun") Loading @@ -359,15 +410,20 @@ class SupervisorImpl(POA, cc, services, lcycle): self.log(f"Distance from Sun -> {self.sunDistance:.2f}", Management.C_INFO) try: antenna.stop() self.log( f"Antenna stopped, pointing close to the Sun", Management.C_WARNING, ) stop_notified = True except Exception as ex: self.log(f"Cannot stop the antenna: {ex}") self.disconnect(client) finally: continue # Sleep again if stop_notified: self.log(f"Antenna is now pointing at safe distance from the Sun") stop_notified = False self.disconnect(client) except Exception as ex: self.log(f"Unexpected exception in sunCheck(): {ex}") print("sunCheck() thread stopped") Loading Common/Servers/PySupervisor/test/no-auto/get_components.py 0 → 100644 +62 −0 Original line number Diff line number Diff line import time from math import degrees from datetime import datetime as dt import ephem import Antenna from Acspy.Clients.SimpleClient import PySimpleClient from Acspy.Common.TimeHelper import getTimeStamp client = PySimpleClient() def disconnect(): if client.isLoggedIn(): client.disconnect() print("Getting mount, boss and supervisor components...") mount = client.getComponent('ANTENNA/Mount') boss = client.getComponent('ANTENNA/Boss') supervisor = client.getComponent('ANTENNA/Supervisor') print("Got component!") def getAntennaCoordinates(): az = boss.observedAzimuth.get_sync() el = boss.observedElevation.get_sync() az, compl = boss.observedAzimuth.get_sync() el, compl = boss.observedElevation.get_sync() return degrees(az), degrees(el) def getAntennaMode(): az_mode = mount.azimuthMode.get_sync()[0] el_mode = mount.elevationMode.get_sync()[0] return az_mode, el_mode def goToSun(): obs = ephem.Observer() sun = ephem.Sun() obs.lat, obs.lon, obs.date = "39.4930", "9.2451", dt.utcnow() sun.compute(obs) sun_az, sun_el = degrees(sun.az), degrees(sun.alt) mount.changeMode(Antenna.ACU_PRESET, Antenna.ACU_PRESET) mount.preset(sun_az, sun_el) def getSunPosition(): obs = ephem.Observer() sun = ephem.Sun() obs.lat, obs.lon, obs.date = "39.4930", "9.2451", dt.utcnow() sun.compute(obs) return degrees(sun.az), degrees(sun.alt) def antennaSetup(code="CCB"): boss.setup(code) print(f"Waiting for AntennaBoss.setup({code})") time.sleep(8) mount.changeMode(Antenna.ACU_PRESET, Antenna.ACU_PRESET) mount.preset(0, 88) print("Moving to (0, 88)") def setWindLimit(value): supervisor.setWindSafeLimit(value) Loading
Common/Servers/PySupervisor/src/Supervisor/SupervisorImpl.py +214 −158 Original line number Diff line number Diff line Loading @@ -54,6 +54,9 @@ class SupervisorImpl(POA, cc, services, lcycle): self.dao_path = 'alma/ANTENNA/Supervisor' self.setup("default") self.stop_threads = False self.sunClient = self.windClient = None self.loadSunClient() self.loadWindClient() for thread in (self.sunCheck, self.windCheck): t = Thread(target=thread, daemon=True) t.start() Loading Loading @@ -133,13 +136,47 @@ class SupervisorImpl(POA, cc, services, lcycle): def isTracking(self): return True def disconnect(self, client): def loadWindClient(self): try: if client.isLoggedIn(): client.disconnect() if self.windClient and self.windClient.isLoggedIn(): pass else: self.disconnectWindClient() self.windClient = PySimpleClient() except Exception as ex: self.log( "Cannot disconnect the client", f"loadWindClient: {ex}", Management.C_ERROR, ) def loadSunClient(self): try: if self.sunClient and self.sunClient.isLoggedIn(): pass else: self.disconnectSunClient() self.sunClient = PySimpleClient() except Exception as ex: self.log( f"loadSunClient: {ex}", Management.C_ERROR, ) def disconnectSunClient(self): try: self.sunClient.disconnect() except Exception as ex: self.log( "Cannot disconnect sunClient", Management.C_WARNING, ) def disconnectWindClient(self): try: self.windClient.disconnect() except Exception as ex: self.log( "Cannot disconnect windClient", Management.C_WARNING, ) Loading @@ -155,7 +192,10 @@ class SupervisorImpl(POA, cc, services, lcycle): except Exception as ex: print(f"Unexpected exception in log(): {ex}") finally: self.disconnect(client) try: client.disconnect() except Exception: print(f"Error disconnecting the log client") def windCheck(self): print("windCheck() thread started") Loading @@ -166,6 +206,7 @@ class SupervisorImpl(POA, cc, services, lcycle): antenna_name = "ANTENNA/Boss" wind_values = [] while True: try: for i in range(5): # Sleep for 5 seconds, check stop signal if self.stop_threads: break Loading @@ -179,11 +220,13 @@ class SupervisorImpl(POA, cc, services, lcycle): if self.windAvoidance == "OFF": continue # Sleep again client = PySimpleClient() self.loadWindClient() try: el_mode = "" mount = client.getComponent(mount_name) el_mode, compl = mount.elevationMode.get_sync() el = 0 mount = self.windClient.getComponent(mount_name) el_mode = str(mount.elevationMode.get_sync()[0]) el = mount.elevation.get_sync()[0] except CannotGetComponentEx as ex: self.log( f"Can not get component {mount_name}", Loading @@ -193,7 +236,7 @@ class SupervisorImpl(POA, cc, services, lcycle): self.log(f"Can not get component {mount_name}: {ex}") try: ws = client.getComponent(weather_name) ws = self.windClient.getComponent(weather_name) value = ws.getWindSpeedAverage() except CannotGetComponentEx as ex: self.log( Loading @@ -202,7 +245,6 @@ class SupervisorImpl(POA, cc, services, lcycle): ) except Exception as ex: self.log(f"Unexpected exception: {ex}") self.disconnect(client) continue # Sleep again if len(wind_values) < 30: Loading @@ -213,21 +255,17 @@ class SupervisorImpl(POA, cc, services, lcycle): self.wind = sum(wind_values)/len(wind_values) if wind_values else 0 if self.wind >= self.windLimit: if str(el_mode) == "ACU_STOW": if el_mode == "ACU_STOW": if not stow_notified: self.log( f"Antenna parked, too much wind", f"Parking antenna, too much wind", Management.C_WARNING, ) stow_notified = True self.disconnect(client) continue self.log(f"Supervisor: stopping antenna, windy") self.log(f"Safe limit -> {self.windLimit:.2f}", Management.C_INFO) self.log(f"Average wind -> {self.wind:.2f}", Management.C_INFO) try: scheduler = client.getDefaultComponent(scheduler_name) scheduler = self.windClient.getDefaultComponent(scheduler_name) scheduler.stopSchedule() except CannotGetComponentEx as ex: self.log( Loading @@ -238,7 +276,7 @@ class SupervisorImpl(POA, cc, services, lcycle): self.log(f"Can not get {scheduler_name}: {ex}") try: antenna = client.getComponent(antenna_name) antenna = self.windClient.getComponent(antenna_name) except CannotGetComponentEx as ex: self.log( f"Can not get component {antenna_name}", Loading @@ -246,18 +284,27 @@ class SupervisorImpl(POA, cc, services, lcycle): ) except Exception as ex: self.log(f"Can not get {antenna_name}: {ex}") self.disconnect(client) continue # Sleep again if el_mode == "ACU_STANDBY" and abs(90-el) < 0.5: continue # Antenna parked try: self.log("Too much wind", Management.C_WARNING) self.log(f"Safe limit -> {self.windLimit:.2f}", Management.C_INFO) self.log(f"Average wind -> {self.wind:.2f}", Management.C_INFO) self.log(f"Supervisor: parking antenna, windy") antenna.stop() antenna.park() # Finally park the antenna self.log("Parking antenna", Management.C_INFO) stow_notified = True except Exception as ex: self.log(f"Can not park the antenna: {ex}") self.disconnect(client) continue # Sleep again stow_notified = False self.disconnect(client) except Exception as ex: self.log(f"Unexpected exception in windCheck(): {ex}") print("sunCheck() thread stopped") Loading @@ -272,6 +319,7 @@ class SupervisorImpl(POA, cc, services, lcycle): sun = ephem.Sun() stop_notified = False while True: try: time.sleep(1) if self.stop_threads: print("Stopping sunCheck() thread") Loading @@ -279,10 +327,10 @@ class SupervisorImpl(POA, cc, services, lcycle): if self.sunAvoidance == "OFF": continue # Sleep again client = PySimpleClient() self.loadSunClient() if not (lat and lon): try: observatory = client.getComponent(observatory_name) observatory = self.sunClient.getComponent(observatory_name) lat, compl = observatory.latitude.get_sync() lon, compl = observatory.longitude.get_sync() except CannotGetComponentEx as ex: Loading @@ -290,17 +338,15 @@ class SupervisorImpl(POA, cc, services, lcycle): except Exception as ex: self.log(f"Can not get component {observatory_name}: {ex}") finally: self.disconnect(client) continue # Sleep again try: antenna = client.getComponent(antenna_name) antenna = self.sunClient.getComponent(antenna_name) except CannotGetComponentEx as ex: self.log( f"Can not get component {antenna_name}", Management.C_ERROR, ) self.disconnect(client) continue # Sleep again t = getTimeStamp().value Loading @@ -313,17 +359,14 @@ class SupervisorImpl(POA, cc, services, lcycle): f"Cannot get antenna coordinates: {ex}", Management.C_ERROR, ) self.disconnect(client) continue # Sleep again limit = self.sunLimit az_mode = el_mode = "" try: mount = client.getComponent(mount_name) az_mode, compl = mount.azimuthMode.get_sync() el_mode, compl = mount.elevationMode.get_sync() if str(az_mode) == str(el_mode) == "ACU_PRESET": limit = self.sunLimit * 3 mount = self.sunClient.getComponent(mount_name) az_mode = str(mount.azimuthMode.get_sync()[0]) el_mode = str(mount.elevationMode.get_sync()[0]) except CannotGetComponentEx as ex: self.log( f"Can not get component {mount_name}", Loading @@ -342,14 +385,22 @@ class SupervisorImpl(POA, cc, services, lcycle): self.sunDistance = sqrt(delta_az**2 + (sun_el - el)**2) if self.sunDistance < limit: if str(az_mode) == str(el_mode) == "ACU_STOP": if az_mode == el_mode == "ACU_STOP": time.sleep(5) self.log( f"Distance from Sun -> {self.sunDistance:.2f}", Management.C_INFO ) self.log( f"Sun safe limit -> {limit:.2f}", Management.C_INFO ) if not stop_notified: self.log( f"Antenna stopped, pointing close to the Sun", "Antenna stopped, pointing close to the Sun", Management.C_WARNING, ) stop_notified = True self.disconnect(client) continue # Sleep again self.log(f"Supervisor: stopping antenna, pointing close to the Sun") Loading @@ -359,15 +410,20 @@ class SupervisorImpl(POA, cc, services, lcycle): self.log(f"Distance from Sun -> {self.sunDistance:.2f}", Management.C_INFO) try: antenna.stop() self.log( f"Antenna stopped, pointing close to the Sun", Management.C_WARNING, ) stop_notified = True except Exception as ex: self.log(f"Cannot stop the antenna: {ex}") self.disconnect(client) finally: continue # Sleep again if stop_notified: self.log(f"Antenna is now pointing at safe distance from the Sun") stop_notified = False self.disconnect(client) except Exception as ex: self.log(f"Unexpected exception in sunCheck(): {ex}") print("sunCheck() thread stopped") Loading
Common/Servers/PySupervisor/test/no-auto/get_components.py 0 → 100644 +62 −0 Original line number Diff line number Diff line import time from math import degrees from datetime import datetime as dt import ephem import Antenna from Acspy.Clients.SimpleClient import PySimpleClient from Acspy.Common.TimeHelper import getTimeStamp client = PySimpleClient() def disconnect(): if client.isLoggedIn(): client.disconnect() print("Getting mount, boss and supervisor components...") mount = client.getComponent('ANTENNA/Mount') boss = client.getComponent('ANTENNA/Boss') supervisor = client.getComponent('ANTENNA/Supervisor') print("Got component!") def getAntennaCoordinates(): az = boss.observedAzimuth.get_sync() el = boss.observedElevation.get_sync() az, compl = boss.observedAzimuth.get_sync() el, compl = boss.observedElevation.get_sync() return degrees(az), degrees(el) def getAntennaMode(): az_mode = mount.azimuthMode.get_sync()[0] el_mode = mount.elevationMode.get_sync()[0] return az_mode, el_mode def goToSun(): obs = ephem.Observer() sun = ephem.Sun() obs.lat, obs.lon, obs.date = "39.4930", "9.2451", dt.utcnow() sun.compute(obs) sun_az, sun_el = degrees(sun.az), degrees(sun.alt) mount.changeMode(Antenna.ACU_PRESET, Antenna.ACU_PRESET) mount.preset(sun_az, sun_el) def getSunPosition(): obs = ephem.Observer() sun = ephem.Sun() obs.lat, obs.lon, obs.date = "39.4930", "9.2451", dt.utcnow() sun.compute(obs) return degrees(sun.az), degrees(sun.alt) def antennaSetup(code="CCB"): boss.setup(code) print(f"Waiting for AntennaBoss.setup({code})") time.sleep(8) mount.changeMode(Antenna.ACU_PRESET, Antenna.ACU_PRESET) mount.preset(0, 88) print("Moving to (0, 88)") def setWindLimit(value): supervisor.setWindSafeLimit(value)