Commit 95a54a31 authored by Marco Buttu's avatar Marco Buttu
Browse files

Wind check

parent 28461bab
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@ module Antenna {
    struct SupervisorDataBlock {
        ACS::Time timeMark;
        boolean tracking;
        double sunAvoidanceOffset;
    };

    const string SUPERVISOR_DATA_CHANNEL = "SupervisorData";
@@ -80,6 +79,20 @@ module Antenna {
        double getWindSafeLimit() raises (ComponentErrors::ComponentErrorsEx);


        /** Get the average wind value.
         * 
         * @throw ComponentErrors::ComponentErrorsEx
         */
        double getAverageWind() raises (ComponentErrors::ComponentErrorsEx);


        /** Distance from the Sun: sqrt(delta_az**2 + delta_el**2)
         * 
         * @throw ComponentErrors::ComponentErrorsEx
         */
        double getSunDistance() raises (ComponentErrors::ComponentErrorsEx);


        /** Set Sun avoidance to "ON" or "OFF"
         *
         * In case the Sun avoidance is "ON", the Supervisor component sets
@@ -118,13 +131,6 @@ module Antenna {
        double getSunSafeLimit() raises (ComponentErrors::ComponentErrorsEx);

         
        /** Get the current offset applied to the antenna coordinates
         *
         * @throw ComponentErrors::ComponentErrorsEx
         */
        double getSunOffset() raises (ComponentErrors::ComponentErrorsEx);


        /** Return true when the Supervisor is not setting any offset related
         * to the Sun avoidance
         *
+145 −44
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ class SupervisorImpl(POA, cc, services, lcycle):
        'supervisorGetSunAvoidance': ('getSunAvoidance', ()), 
        'supervisorSetSunSafeLimit': ('setSunSafeLimit', (float,)), 
        'supervisorGetSunSafeLimit': ('getSunSafeLimit', ()), 
        'supervisorGetSunOffset': ('getSunOffset', ()),
        'supervisorGetSunDistance': ('getSunDistance', ()),
        'supervisorGetWind': ('getAverageWind', ()),
        'supervisorIsTracking': ('isTracking', ()), 
    }

@@ -63,14 +64,14 @@ class SupervisorImpl(POA, cc, services, lcycle):

    def cleanUp(self):
        self.stop_threads = True
        # self.supplier.disconnect()

    def setup(self, code):
        self.log(f"Supervisor.setup({code})", Management.C_INFO)
        self.receiverSetup = "unknown"
        self.windAvoidance = "ON"
        self.sunAvoidance = "ON"
        self.sunOffset = 0
        self.sunDistance = 180
        self.wind = 0
        dao = ACSCorba.cdb().get_DAO_Servant(self.dao_path)
        self.windLimit = float(dao.get_field_data("WindLimit"))
        code = code.upper()
@@ -123,25 +124,15 @@ class SupervisorImpl(POA, cc, services, lcycle):
    def getSunSafeLimit(self):
        return self.sunLimit

    def getSunOffset(self):
        return self.sunOffset
    def getSunDistance(self):
        return self.sunDistance

    def getAverageWind(self):
        return self.wind

    def isTracking(self):
        return True

    # TODO: fare un metodo/funzione che ottiene il component, passandole
    # il nome del component. Questo serve per il logging e per ogni volta
    # che ci occorre un client

    def windCheck(self):
        while True:
            if self.stop_threads:
                print("Stopping windCheck")
                break
            time.sleep(10)
            print("WIND: windAvoidance: ", self.windAvoidance)
        print("windCheck() stopped")

    def disconnect(self, client):
        try:
            if client.isLoggedIn():
@@ -166,6 +157,111 @@ class SupervisorImpl(POA, cc, services, lcycle):
        finally:
            self.disconnect(client)

    def windCheck(self):
        print("windCheck() thread started")
        stow_notified = False
        mount_name = "ANTENNA/Mount"
        scheduler_name = "IDL:alma/Management/Scheduler:1.0"
        weather_name = "WEATHERSTATION/WeatherStation"
        antenna_name = "ANTENNA/Boss"
        wind_values = []
        while True:
            for i in range(5):  # Sleep for 5 seconds, check stop signal
                if self.stop_threads:
                    break
                else:
                    time.sleep(1)

            if self.stop_threads:
                print("Stopping windCheck() thread")
                break

            if self.windAvoidance == "OFF":
                continue  # Sleep again

            client = PySimpleClient()
            try:
                el_mode = ""
                mount = client.getComponent(mount_name)
                el_mode, compl = mount.elevationMode.get_sync()
            except CannotGetComponentEx as ex:
                self.log(
                    f"Can not get component {mount_name}",
                    Management.C_WARNING,
                )
            except Exception as ex:
                self.log(f"Can not get component {mount_name}: {ex}")

            try:
                ws = client.getComponent(weather_name)
                value = ws.getWindSpeedAverage()
            except CannotGetComponentEx as ex:
                self.log(
                    f"Can not get component {weather_name}",
                    Management.C_ERROR,
                )
            except Exception as ex:
                self.log(f"Unexpected exception: {ex}")
                self.disconnect(client)
                continue  # Sleep again

            if len(wind_values) < 30:
                wind_values.append(value)
            else:
                wind_values.pop()
                wind_values.insert(0, value)

            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 not stow_notified:
                        self.log(
                            f"Antenna parked, 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.stopSchedule()
                except CannotGetComponentEx as ex:
                    self.log(
                        f"Supervisor can not get {scheduler_name}",
                        Management.C_WARNING,
                    )
                except Exception as ex:
                    self.log(f"Can not get {scheduler_name}: {ex}")

                try:
                    antenna = client.getComponent(antenna_name)
                except CannotGetComponentEx as ex:
                    self.log(
                        f"Can not get component {antenna_name}",
                        Management.C_ERROR,
                    )
                except Exception as ex:
                    self.log(f"Can not get {antenna_name}: {ex}")
                    self.disconnect(client)
                    continue  # Sleep again

                try:
                    antenna.park()  # Finally park the antenna
                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)

        print("sunCheck() thread stopped")


    def sunCheck(self):
        print("sunCheck() thread started")
        antenna_name = "ANTENNA/Boss"
@@ -192,7 +288,7 @@ class SupervisorImpl(POA, cc, services, lcycle):
                except CannotGetComponentEx as ex:
                    self.log(f"Supervisor can not get {observatory_name}")
                except Exception as ex:
                    print(f"Unexpected exception: {ex}")
                    self.log(f"Can not get component {observatory_name}: {ex}")
                finally:
                    self.disconnect(client)
                    continue  # Sleep again
@@ -220,21 +316,32 @@ class SupervisorImpl(POA, cc, services, lcycle):
                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
            except CannotGetComponentEx as ex:
                self.log(
                    f"Can not get component {mount_name}",
                    Management.C_WARNING,
                )
            except Exception as ex:
                self.log(f"Can not get component {mount_name}: {ex}")
 
            obs.lat, obs.lon, obs.date = str(lat), str(lon), dt.utcnow()
            sun.compute(obs)
            sun_az, sun_el = degrees(sun.az), degrees(sun.alt)

            if (diff := abs(sun_az - az)) <= 180:
                delta_az = diff
            else:
                delta_az = 360 - diff

            distance = sqrt(delta_az**2 + (sun_el - el)**2)
            if distance < self.sunLimit:
                try:
                    mount = client.getComponent(mount_name)
                    az_mode, compl = mount.azimuthMode.get_sync()
                    el_mode, compl = mount.elevationMode.get_sync()
            self.sunDistance = sqrt(delta_az**2 + (sun_el - el)**2)
            if self.sunDistance < limit:
                if str(az_mode) == str(el_mode) == "ACU_STOP":
                    if not stop_notified:
                        self.log(
@@ -242,20 +349,14 @@ class SupervisorImpl(POA, cc, services, lcycle):
                            Management.C_WARNING,
                        )
                        stop_notified = True
                        continue
                except CannotGetComponentEx as ex:
                    self.log(
                        f"Can not get component {mount_name}",
                        Management.C_WARNING,
                    )
                except Exception:
                    pass
                    self.disconnect(client)
                    continue  # Sleep again

                self.log(f"Supervisor: stopping antenna, pointing close to the Sun")
                self.log(f"Sun(az, el) -> ({sun_az:.2f}, {sun_el:.2f})", Management.C_INFO)
                self.log(f"Ant(az, el) -> ({az:.2f}, {el:.2f})", Management.C_INFO)
                self.log(f"Safe Limit -> {self.sunLimit:.2f}", Management.C_INFO)
                self.log(f"Distance from Sun -> {distance:.2f}", Management.C_INFO)
                self.log(f"Safe Limit -> {limit:.2f}", Management.C_INFO)
                self.log(f"Distance from Sun -> {self.sunDistance:.2f}", Management.C_INFO)
                try:
                    antenna.stop()
                except Exception as ex: