# Source code for noctua.devices.meteo

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-

    # System modules
    from datetime import datetime, timedelta

    # Third-party modules
    import numpy as np
    from pyvantagepro import VantagePro2
    from pyvantagepro.device import NoDeviceException

    # Other templates
    from ..utils import check
    from ..utils.logger import log

    class Meteo:
        def __init__(self, url):
            self.url = url
            self.error = None
            self.station = None

        @check.telnet_errors
        def connect(self):
            self.station = VantagePro2.from_url(self.url)

        @property
        def original(self):
            self.connect()

            if self.station:
                try:
                    current = self.station.get_current_data()
                    params = {k: current[k] for k in current.keys()}
                except BrokenPipeError as e:
                    params = None
                except NoDeviceException:
                    params = None

            else:
                params = None

            return params

        @property
        def data(self):
            params = self.original
            if not params:
                conv = None

            else:
                tempout = round((params['TempOut'] - 32) * 5. / 9, 1)
                humout = params['HumOut']
                dewpoint = round(tempout - ((100. - humout) / 5), 1)

                inches_to_mm = 25.4
                mph_to_kmh = 1.60934

                conv = {  # Come conversion in SI units
                    "Datetime": params["Datetime"].isoformat()[:-7],
                    # °F to °C
                    "Temperature_first_floor": round((params['TempIn'] - 32) * 5. / 9, 1),
                    "Humidity_first_floor": params["HumIn"],
                    "Temperature_meteo_station": tempout,  # °F to °C
                    "Humidity_meteo_station": humout,
                    "Dewpoint": dewpoint,
                    # inHg to hPa
                    "Barometer": round(params["Barometer"] * 33.8638, 1),
                    "Barometric_trend": params["BarTrend"],
                    # mph to Km/h
                    "Wind_speed": round(params["WindSpeed"] * mph_to_kmh, 1),
                    # mph to Km/h
                    "Wind_speed_last_10_min": round(params["WindSpeed10Min"] * mph_to_kmh, 1),
                    "Wind_direction": params["WindDir"],
                    "Rain_rate": params["RainRate"],
                    "UV": params["UV"],
                    "Solar_radiation": params["SolarRad"],
                    "Rain_storm": params["RainStorm"] * inches_to_mm,
                    "Storm_start_date": params["StormStartDate"],
                    "Rain_day": params["RainDay"],
                    "Rain_month": params["RainMonth"],
                    "Rain_year": params["RainYear"],
                    # inches to mm
                    "ET_day": round(params["ETDay"] * inches_to_mm, 0),
                    # inches to mm
                    "ET_month": round(params["ETMonth"] * inches_to_mm, 0),
                    # inches to mm
                    "ET_year": round(params["ETYear"] * inches_to_mm, 0),
                    "Battery_status": params["BatteryStatus"],
                    "Battery_volts": round(params["BatteryVolts"], 2),
                    "Forecast_icon": params["ForecastIcon"],
                    "Forecast_rule_number": params["ForecastRuleNo"],
                    "Sun_rise": params["SunRise"],
                    "Sun_set": params["SunSet"],
                }

            return conv

        def summary(self):
            params0 = self.data
            print(f"Summary:")
            print(f"Datetime  {params0['Datetime']}")
            print(f"Dew Point {params0['Dewpoint']:.1f}°")
            print(f"TempIn    {params0['TempIn']:.1f}°")
            print(f"TempOut   {params0['TempOut']:.1f}°")
            print(f"HumIn     {params0['HumIn']}%")
            print(f"HumOut    {params0['HumOut']}%")
            print(f"WindSpeed {params0['WindSpeed']:.1f} km/h")
            print(f"Barometer {params0['Barometer']:.1f} hPa")

        @property
        def time(self):
            self.connect()
            current = self.station.gettime().isoformat()
            return current

        def synctime(self):
            self.connect()
            now = datetime.now()
            print(now)
            self.station.settime(now)

        def archive(self):
            now = datetime.now()
            now = datetime(year=now.year, month=now.month,
                           day=now.day, hour=now.hour)
            older = now - timedelta(days=4, hours=22)  # max 4 days, 22:00:00

            self.connect()
            archive = self.station.get_archives(older, now)  # takes some seconds
            params = {k: np.array([a[k] for a in archive])
                      for k in archive[0].keys()}

            return params

    def main():

        now = datetime.now()
        now = datetime(year=now.year, month=now.month, day=now.day, hour=now.hour)
        older = now - timedelta(days=4, hours=22)  # max 4 days, 22:00:00

        m = Meteo("tcp:meteo.orsa.unige.net:5001")
        m.summary()

        # System modules
        import json
        print(f"All data:")
        print(json.dumps(m.data, indent=4))

        # params = m.archive() # takes some seconds
        # params = { k: np.array([a[k] for a in archive ]) for k in archive[0].keys() }

        # from matplotlib import pyplot as plt
        # params = m.archive() # takes some seconds
        # params = { k: np.array([a[k] for a in archive ]) for k in archive[0].keys() }

        # fig, axs = plt.subplots(2, 2)

        # date = params["Datetime"]

        # axs[0,0].title.set_text('Temperature out/in/dewpoint')
        # axs[0,0].plot(date, (params["TempOut"]-32)*5./9.)
        # axs[0,0].plot(date, (params["TempIn"]-32)*5./9.)
        # dewplot = ( (params['TempOut']-32)*5./9.) - ((100. - params['HumOut'])/5.)
        # axs[0,0].plot(date, dewplot)
        # axs[0,0].set(ylabel='°C')

        # axs[0,1].title.set_text('Humidity out/in')
        # axs[0,1].plot(date, params["HumOut"])
        # axs[0,1].plot(date, params["HumIn"])
        # axs[0,1].set(ylabel='%')

        # axs[1,0].title.set_text('Wind speed avg/hi')
        # axs[1,0].plot(date, params['WindAvg']*mph_to_kmh)
        # axs[1,0].plot(date, params['WindHi']*mph_to_kmh)
        # axs[1,0].set(ylabel='Km/h')

        # axs[1,1].title.set_text('Pressure')
        # axs[1,1].plot(date, params['Barometer']*33.8638)
        # axs[1,1].set(ylabel='hPa')

        # for ax in axs.flat:
        #     ax.set(xlabel='Date')

        # # # Hide x labels and tick labels for top plots and y ticks for right plots.
        # # for ax in axs.flat:
        # #     ax.label_outer()

        # plt.show()

    if __name__ == "__main__":
        main()

    #############################################################

    # dic = ['Datetime', 'TempOut', 'TempOutHi', 'TempOutLow', 'RainRate', 'RainRateHi', 'Barometer', 'SolarRad', 'WindSamps', 'TempIn', 'HumIn', 'HumOut', 'WindAvg', 'WindHi', 'WindHiDir', 'WindAvgDir', 'UV', 'ETHour', 'SolarRadHi', 'UVHi', 'ForecastRuleNo']

    # datadict = {
    #     "Datetime": "date",
    #     "TempOut": "outside temp (°F)",
    #     "TempOutHi": "outside temp high (°F)",
    #     "TempOutLow": "outside temp low (°F)",
    #     "RainRate": "rainfall (clicks)", 1 click = 0.2mm?? "by stefano90"
    #     "RainRateHi": "highest rain rate (clicks/hr)",
    #     "Barometer": "barometer (inches Hg)",
    #     "SolarRad": "average solar radiation (W/m^2)",
    #     "WindSamps": "number of wind samples",
    #     "TempIn": "insideTemp (°F)",
    #     "HumIn": "inside humidity (%)",
    #     "HumOut": "outside humidity (%)",
    #     "WindAvg": "average wind speed (mph)",
    #     "WindHi": "highest wind speed (mph)",
    #     "WindHiDir": "highest wind direction (°)",
    #     "WindAvgDir": "prevailing wind direction (°)",
    #     "UV": "average uv index",
    #     "ETHour": "accumulated et (in)", EvapoTranspiration (ET)
    #     "SolarRadHi": "maximum solar radiation (W/m^2)",
    #     "UVHi": "max uv",
    #     "ForecastRuleNo": "forecast at end of period",
    # }