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
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)
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 = {}
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 = {}
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
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