Skip to content

Commit

Permalink
Bleak port (#66)
Browse files Browse the repository at this point in the history
bleak port
  • Loading branch information
cyrils authored Nov 21, 2024
1 parent 458603d commit 6ee6ba5
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 193 deletions.
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,28 +16,28 @@
# 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.ble_manager.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()

# error callback
def on_error(client, error):
logging.error(f"on_error: {error}")

# start client
if config['device']['type'] == 'RNG_CTRL':
RoverClient(config, on_data_received, on_error).connect()
RoverClient(config, on_data_received, on_error).start()
elif config['device']['type'] == 'RNG_CTRL_HIST':
RoverHistoryClient(config, on_data_received, on_error).connect()
RoverHistoryClient(config, on_data_received, on_error).start()
elif config['device']['type'] == 'RNG_BATT':
BatteryClient(config, on_data_received, on_error).connect()
BatteryClient(config, on_data_received, on_error).start()
elif config['device']['type'] == 'RNG_INVT':
InverterClient(config, on_data_received, on_error).connect()
InverterClient(config, on_data_received, on_error).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

0 comments on commit 6ee6ba5

Please sign in to comment.