Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bleak port #66

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import asyncio
import logging
import configparser
import os
import sys
from renogybt import InverterClient, RoverClient, RoverHistoryClient, BatteryClient, DataLogger, Utils

logging.basicConfig(level=logging.DEBUG)
logging.basicConfig(level=logging.INFO)

config_file = sys.argv[1] if len(sys.argv) > 1 else 'config.ini'
config_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), config_file)
Expand All @@ -15,24 +16,24 @@
# the callback func when you receive data
def on_data_received(client, data):
filtered_data = Utils.filter_fields(data, config['data']['fields'])
logging.debug("{} => {}".format(client.device.alias(), filtered_data))
logging.info(f"{client.bleManager.device.name} => {filtered_data}")
if config['remote_logging'].getboolean('enabled'):
data_logger.log_remote(json_data=filtered_data)
if config['mqtt'].getboolean('enabled'):
data_logger.log_mqtt(json_data=filtered_data)
if config['pvoutput'].getboolean('enabled') and config['device']['type'] == 'RNG_CTRL':
data_logger.log_pvoutput(json_data=filtered_data)
if not config['data'].getboolean('enable_polling'):
client.disconnect()
client.stop()

# start client
if config['device']['type'] == 'RNG_CTRL':
RoverClient(config, on_data_received).connect()
RoverClient(config, on_data_received).start()
elif config['device']['type'] == 'RNG_CTRL_HIST':
RoverHistoryClient(config, on_data_received).connect()
RoverHistoryClient(config, on_data_received).start()
elif config['device']['type'] == 'RNG_BATT':
BatteryClient(config, on_data_received).connect()
BatteryClient(config, on_data_received).start()
elif config['device']['type'] == 'RNG_INVT':
InverterClient(config, on_data_received).connect()
InverterClient(config, on_data_received).start()
else:
logging.error("unknown device type")
115 changes: 0 additions & 115 deletions renogybt/BLE.py

This file was deleted.

66 changes: 66 additions & 0 deletions renogybt/BLEManager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import asyncio
import logging
from bleak import BleakClient, BleakScanner, BLEDevice

DISCOVERY_TIMEOUT = 5 # max wait time to complete the bluetooth scanning (seconds)

class BLEManager:
def __init__(self, mac_address, alias, on_data, on_connect_fail, notify_uuid, write_uuid):
self.mac_address = mac_address
self.device_alias = alias
self.data_callback = on_data
self.connect_fail_callback = on_connect_fail
self.notify_char_uuid = notify_uuid
self.write_char_uuid = write_uuid
self.device: BLEDevice = None
self.client: BleakClient = None
self.discovered_devices = []

async def discover(self):
mac_address = self.mac_address.upper()
logging.info("Starting discovery...")
self.discovered_devices = await BleakScanner.discover(timeout=DISCOVERY_TIMEOUT)
logging.info("Devices found: %s", len(self.discovered_devices))

for dev in self.discovered_devices:
if dev.address != None and (dev.address.upper() == mac_address or (dev.name and dev.name.strip() == self.device_alias)):
logging.info(f"Found matching device {dev.name} => {dev.address}")
self.device = dev

async def connect(self):
if not self.device: return logging.error("No device connected!")

self.client = BleakClient(self.device)
try:
await self.client.connect()
logging.info(f"Client connection: {self.client.is_connected}")
if not self.client.is_connected: return logging.error("Unable to connect")

for service in self.client.services:
for characteristic in service.characteristics:
if characteristic.uuid == self.notify_char_uuid:
await self.client.start_notify(characteristic, self.notification_callback)
logging.info(f"subscribed to notification {characteristic.uuid}")
if characteristic.uuid == self.write_char_uuid:
logging.info(f"found write characteristic {characteristic.uuid}")
except Exception as e:
logging.error(f"Error connecting: {e}")
self.connect_fail_callback(e)

async def notification_callback(self, characteristic, data: bytearray):
logging.info("notification_callback")
await self.data_callback(data)

async def characteristic_write_value(self, data):
try:
logging.info(f'writing to {self.write_char_uuid} {data}')
await self.client.write_gatt_char(self.write_char_uuid, bytearray(data))
logging.info('characteristic_write_value succeeded')
await asyncio.sleep(0.5)
except Exception as e:
logging.info(f'characteristic_write_value failed {e}')

async def disconnect(self):
if self.client and self.client.is_connected:
logging.info(f"Exit: Disconnecting device: {self.device.name} {self.device.address}")
await self.client.disconnect()
Loading