Exemple #1
0
def test_client():
    """Test influx output function."""

    username = os.environ['USERNAME']
    password = os.environ['PASSWORD']
    client = HydroQuebecClient(username, password, 30)

    loop = asyncio.get_event_loop()

    async_func = client.login()
    loop.run_until_complete(asyncio.gather(async_func))
    assert len(client.customers) > 0
    assert client.customers[0].contract_id is not None
    assert client.customers[0].account_id is not None
Exemple #2
0
 def __init__(self, username, password, contract, time_zone, REQUESTS_TIMEOUT, httpsession):
     self._contract = contract
     self._hqclient = HydroQuebecClient(
         username, password, REQUESTS_TIMEOUT, httpsession  # , 'DEBUG'
     )
     self._daily = {}
     self._period = {}
     self._tz = tz.gettz(time_zone)
Exemple #3
0
    def __init__(self, username, password, httpsession, contract=None):
        """Initialize the data object."""
        from pyhydroquebec.client import HydroQuebecClient

        self.client = HydroQuebecClient(
            username, password, REQUESTS_TIMEOUT, httpsession
        )

        self._contract = contract
        self.data = {}
Exemple #4
0
    def __init__(self,
                 username,
                 password,
                 httpsession,
                 contract=None,
                 time_zone='America/Montreal'):
        """Initialize the data object."""

        self._client = HydroQuebecClient(
            username,
            password,
            REQUESTS_TIMEOUT,
            httpsession  #, 'DEBUG'
        )

        self._tz = tz.gettz(time_zone)
        self._contract = contract
        self._data = {}
Exemple #5
0
    async def _main_loop(self):
        """Run main loop."""
        self.logger.debug("Running the main loop.")
        for account in self.config['accounts']:
            client = HydroQuebecClient(account['username'],
                                       account['password'],
                                       self.timeout,
                                       log_level=self.logging_level)
            await client.login()
            datapoints = []
            for contract_data in account['contracts']:
                # Get contract
                customer = None
                contract_id = str(contract_data['id'])
                # Find the right customer data according to the contract ID.
                for client_customer in client.customers:
                    if str(client_customer.contract_id) == contract_id:
                        customer = client_customer

                if customer is None:
                    self.logger.warning('Contract %s not found', contract_id)
                    continue

                await customer.fetch_current_period()

                # Look for yesterday's data.
                yesterday = datetime.now(HQ_TIMEZONE) - timedelta(days=1)
                yesterday_str = yesterday.strftime("%Y-%m-%d")
                await customer.fetch_daily_data(yesterday_str, yesterday_str)
                await customer.fetch_hourly_data(yesterday_str)

                # If it's not there, look for the day before.
                if not customer.current_daily_data:
                    yesterday = yesterday - timedelta(days=1)
                    yesterday_str = yesterday.strftime("%Y-%m-%d")
                    await customer.fetch_daily_data(yesterday_str,
                                                    yesterday_str)

                # Look at the date of the data we received.
                date_of_data = list(customer.current_daily_data.keys())[0]

                # Write balance
                datapoints.append(
                    create_influxdb_datapoint(COST_MEASUREMENT, contract_id,
                                              'daily_balance', date_of_data, 0,
                                              float(customer.balance)))

                # # Current period
                # for data_name, data in CURRENT_MAP.items():
                #     # Publish sensor
                #     sensor_topic = self._publish_sensor(data_name,
                #                                         customer.contract_id,
                #                                         unit=data['unit'],
                #                                         icon=data['icon'],
                #                                         device_class=data['device_class'])
                #     # Send sensor data
                #     self.mqtt_client.publish(
                #             topic=sensor_topic,
                #             payload=customer.current_period[data_name])

                # # Yesterday data
                # for data_name, data in DAILY_MAP.items():
                #     # Publish sensor
                #     sensor_topic = self._publish_sensor('yesterday_' + data_name,
                #                                         customer.contract_id,
                #                                         unit=data['unit'],
                #                                         icon=data['icon'],
                #                                         device_class=data['device_class'])
                #     # Send sensor data
                #     self.mqtt_client.publish(
                #             topic=sensor_topic,
                #             payload=customer.current_daily_data[yesterday_str][data_name])
                for hour, data in customer.hourly_data[date_of_data][
                        "hours"].items():
                    datapoints.append(
                        create_influxdb_datapoint(
                            KWH_MEASUREMENT, contract_id,
                            'total_consumption', date_of_data, hour,
                            float(data['total_consumption'])))

            self.client.write_points(datapoints)
            await client.close_session()

        if self.frequency is None:
            self.logger.info("Frequency is None, so it's a one shot run")
            self.must_run = False
            return

        self.logger.info("Waiting for %d seconds before the next check",
                         self.frequency)
        i = 0
        while i < self.frequency and self.must_run:
            await asyncio.sleep(1)
            i += 1
def main():
    """Entrypoint function."""
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--username', help='Hydro Quebec username')
    parser.add_argument('-p', '--password', help='Password')
    parser.add_argument('-j',
                        '--json',
                        action='store_true',
                        default=False,
                        help='Json output')
    parser.add_argument('-i',
                        '--influxdb',
                        action='store_true',
                        default=False,
                        help='InfluxDb output')
    parser.add_argument('-c',
                        '--contract',
                        default=None,
                        help='Contract number')
    parser.add_argument('--client-number',
                        default=None,
                        help='Use client Number to speed up login')
    parser.add_argument('-l',
                        '--list-contracts',
                        action='store_true',
                        default=False,
                        help='List all your contracts')
    parser.add_argument('-H',
                        '--hourly',
                        action='store_true',
                        default=False,
                        help='Show yesterday hourly consumption')
    parser.add_argument('-D',
                        '--dump-data',
                        action='store_true',
                        default=False,
                        help='Show contract python object as dict')
    parser.add_argument('-t',
                        '--timeout',
                        default=REQUESTS_TIMEOUT,
                        help='Request timeout')
    parser.add_argument(
        '-L',
        '--log-level',
        choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
        default='WARNING',
        help='Log level')
    parser.add_argument('-V',
                        '--version',
                        action='store_true',
                        default=False,
                        help='Show version')
    raw_group = parser.add_argument_group(
        'Detailled-energy raw download option')
    raw_group.add_argument('--detailled-energy',
                           action='store_true',
                           default=False,
                           help='Get raw json output download')
    raw_group.add_argument('--start-date',
                           default=(datetime.now(HQ_TIMEZONE) -
                                    timedelta(days=1)).strftime("%Y-%m-%d"),
                           help='Start date for detailled-output')
    raw_group.add_argument(
        '--end-date',
        default=datetime.now(HQ_TIMEZONE).strftime("%Y-%m-%d"),
        help="End date for detailled-output")

    args = parser.parse_args()

    if args.version:
        print(VERSION)
        return 0

    # Check input for Username, Password and Contract - CLI overwrite ENV variable

    # Check Env
    hydro_user = os.environ.get("PYHQ_USER")
    hydro_pass = os.environ.get("PYHQ_PASSWORD")
    hydro_contract = os.environ.get("PYHQ_CONTRACT")
    hydro_client_number = os.environ.get("PYHQ_CLIENT_NUMBER")

    # Check Cli
    if args.username:
        hydro_user = args.username
    if args.password:
        hydro_pass = args.password
    if args.contract:
        hydro_contract = args.contract
    if args.client_number:
        hydro_client_number = args.client_number

    if not hydro_user or not hydro_pass:
        parser.print_usage()
        print("pyhydroquebec: error: the following arguments are required: "
              "-u/--username, -p/--password")
        return 3

    client = HydroQuebecClient(hydro_user,
                               hydro_pass,
                               args.timeout,
                               log_level=args.log_level)
    loop = asyncio.get_event_loop()

    # Get the async_func
    if args.list_contracts:
        async_func = list_contracts(client)
    elif args.dump_data:
        async_func = dump_data(client, hydro_contract)
    elif args.detailled_energy is False:
        async_func = fetch_data(client, hydro_contract, hydro_client_number,
                                args.hourly)
    else:
        start_date = datetime.strptime(args.start_date, '%Y-%m-%d')
        end_date = datetime.strptime(args.end_date, '%Y-%m-%d')
        async_func = fetch_data_detailled_energy_use(client, hydro_contract,
                                                     hydro_client_number,
                                                     start_date, end_date)

    # Fetch data
    try:
        results = loop.run_until_complete(asyncio.gather(async_func))
    except BaseException as exp:
        print(exp)
        print(traceback.print_tb(exp.__traceback__))
        return 1
    finally:
        close_fut = asyncio.wait([client.close_session()])
        loop.run_until_complete(close_fut)
        loop.close()

    # Output data
    if args.list_contracts:
        for customer in results[0]:
            print("Contract: {contract_id}\n\t"
                  "Account: {account_id}\n\t"
                  "Customer: {customer_id}".format(**customer))
    elif args.dump_data or args.detailled_energy:
        pprint(results[0].__dict__)
    elif args.influxdb:
        output_influx(results[0])
    elif args.json:
        output_json(results[0])
    else:
        output_text(results[0], args.hourly)
    return 0
Exemple #7
0
    async def _main_loop(self):
        """Run main loop."""
        self.logger.debug("Get Data")
        for account in self.config['accounts']:
            client = HydroQuebecClient(account['username'],
                                       account['password'],
                                       self.timeout,
                                       log_level=self._loglevel)
            await client.login()
            for contract_data in account['contracts']:
                # Get contract
                customer = None
                for client_customer in client.customers:
                    if str(client_customer.contract_id) == str(contract_data['id']):
                        customer = client_customer

                if customer is None:
                    self.logger.warning('Contract %s not found', contract_data['id'])
                    continue

                await customer.fetch_current_period()
                # await customer.fetch_annual_data()
                # await customer.fetch_monthly_data()
                yesterday = datetime.now(HQ_TIMEZONE) - timedelta(days=1)
                yesterday_str = yesterday.strftime("%Y-%m-%d")
                await customer.fetch_daily_data(yesterday_str, yesterday_str)
                if not customer.current_daily_data:
                    yesterday = yesterday - timedelta(days=1)
                    yesterday_str = yesterday.strftime("%Y-%m-%d")
                    await customer.fetch_daily_data(yesterday_str, yesterday_str)

                # Balance
                # Publish sensor
                balance_topic = self._publish_sensor('balance', customer.account_id,
                                                     unit="$", device_class=None,
                                                     icon="mdi:currency-usd")
                # Send sensor data
                self.mqtt_client.publish(
                        topic=balance_topic,
                        payload=customer.balance)

                # Current period
                for data_name, data in CURRENT_MAP.items():
                    # Publish sensor
                    sensor_topic = self._publish_sensor(data_name,
                                                        customer.contract_id,
                                                        unit=data['unit'],
                                                        icon=data['icon'],
                                                        device_class=data['device_class'])
                    # Send sensor data
                    self.mqtt_client.publish(
                            topic=sensor_topic,
                            payload=customer.current_period[data_name])

                # Yesterday data
                for data_name, data in DAILY_MAP.items():
                    # Publish sensor
                    sensor_topic = self._publish_sensor('yesterday_' + data_name,
                                                        customer.contract_id,
                                                        unit=data['unit'],
                                                        icon=data['icon'],
                                                        device_class=data['device_class'])
                    # Send sensor data
                    self.mqtt_client.publish(
                            topic=sensor_topic,
                            payload=customer.current_daily_data[yesterday_str][data_name])

            await client.close_session()

        if self.frequency is None:
            self.logger.info("Frequency is None, so it's a one shot run")
            self.must_run = False
            return

        self.logger.info("Waiting for %d seconds before the next check", self.frequency)
        i = 0
        while i < self.frequency and self.must_run:
            await asyncio.sleep(1)
            i += 1