Veml6075 MicroPython driver?

Any body find a working MicroPython driver for the VEML6075 UV sensor breakout? I had one at one time but can’t find it now? Lost in the shuffle at some point I guess.
I did a search but of the two i found, neither one worked?

I have it working using machine i2c as posted below. Can’t get it to work using Pimoroni i2c though. And can’t get my weather station file to run with machine i2c.

import machine
sda=machine.Pin(4) # Explorer 20 Breakout 4
scl=machine.Pin(5) # Explorer 21 Breakout 5
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)

import veml6075
import time
import machine

time.sleep_ms(500)

uv = veml6075.VEML6075(i2c)
connected = uv.initUV()
import picodisplay2 as display2
display_buffer = bytearray(320 * 240 * 2)  # 2-bytes per pixel (RGB565)
display2.init(display_buffer)
display2.set_backlight(0.8)


while True:
    UVI, UVIA, UVIB = uv.readUV()
    display2.set_pen(0, 255, 0)
    display2.text("uv", 0, 70, 240, 3)
    display2.text("UVIA        {0:.1f}" .format(UVIA), 0, 90, 240, 3)
    display2.text("UVIB        {0:.1f}" .format(UVIB), 0, 110, 240, 3)
    display2.text("UVI avg     {0:.1f}" .format(UVI), 0, 130, 240, 3) 

    display2.update()
    display2.set_pen(0, 0, 0)
    display2.clear()

    time.sleep(1.0)

With this micro python library file.

import time
import ubinascii

class VEML6075:
	
	# Device information
	
	VEML6075_ADDR  = 0x10
	VEML6075_DEVID = 0x26

	REG_CONF        = 0x00  # Configuration register (options below)
	REG_UVA         = 0x07  # UVA register
	REG_UVD	        = 0x08  # Dark current register (NOT DUMMY)
	REG_UVB         = 0x09  # UVB register
	REG_UVCOMP1     = 0x0A  # Visible compensation register
	REG_UVCOMP2     = 0x0B  # IR compensation register
	REG_DEVID       = 0x0C  # Device ID register

	CONF_IT_50MS    = 0x00  # Integration time = 50ms (default)
	CONF_IT_100MS   = 0x10  # Integration time = 100ms
	CONF_IT_200MS   = 0x20  # Integration time = 200ms
	CONF_IT_400MS   = 0x30  # Integration time = 400ms
	CONF_IT_800MS   = 0x40  # Integration time = 800ms
	CONF_IT_MASK    = 0x8F  # Mask off other config bits

	CONF_HD_NORM    = 0x00  # Normal dynamic seetting (default)
	CONF_HD_HIGH    = 0x08  # High dynamic seetting

	CONF_TRIG       = 0x04  # Trigger measurement, clears by itself

	CONF_AF_OFF     = 0x00  # Active force mode disabled (default)
	CONF_AF_ON      = 0x02  # Active force mode enabled (?)

	CONF_SD_OFF     = 0x00  # Power up
	CONF_SD_ON      = 0x01  # Power down

	# To calculate the UV Index, a bunch of empirical/magical coefficients need to
	# be applied to UVA and UVB readings to get a proper composite index value.

	UVA_A_COEF = 2.22 
	UVA_B_COEF = 1.33 
	UVB_C_COEF = 2.95 
	UVB_D_COEF = 1.74 

	# Once the above offsets and crunching is done, there's a last weighting
	# function to convert the ADC counts into the UV index values. This handles
	# both the conversion into irradiance (W/m^2) and the skin erythema weighting
	# by wavelength--UVB is way more dangerous than UVA, due to shorter
	# wavelengths and thus more energy per photon. These values convert the compensated values 

	UVA_RESPONSIVITY = 0.0011
	UVB_RESPONSIVITY = 0.00125

	def __init__(self, i2c=None):
		self.i2c = i2c
		self.address = self.VEML6075_ADDR
		
	
	# initialize device
	def initUV(self):
		try:
			deviceID = bytearray(2)
			self.i2c.readfrom_mem_into(self.address, self.REG_DEVID, deviceID)
			if (deviceID[0] != self.VEML6075_DEVID):
				return False
			else:	
				# Write Dynamic and Integration Time Settings to Sensor
				conf_data = bytearray(2)
				conf_data[0] = self.CONF_IT_100MS| \
						  self.CONF_HD_NORM| \
						  self.CONF_SD_OFF
				conf_data[1] = 0
				self.i2c.writeto_mem(self.address, self.REG_CONF, conf_data)  
				return True
		except:
			return False
			
	# Read UV data from device, return UV index
	def readUV(self):
		time.sleep_ms(150)  
		uv_data = bytearray(2)
		
		self.i2c.readfrom_mem_into(self.address,self.REG_UVA, uv_data)
		uva = int.from_bytes(uv_data, 'little')
		
		self.i2c.readfrom_mem_into(self.address,self.REG_UVD, uv_data)
		uvd = int.from_bytes(uv_data, 'little')
		
		self.i2c.readfrom_mem_into(self.address,self.REG_UVB, uv_data)
		uvb = int.from_bytes(uv_data, 'little')
		
		self.i2c.readfrom_mem_into(self.address,self.REG_UVCOMP1, uv_data)
		uvcomp1 = int.from_bytes(uv_data, 'little')
		
		self.i2c.readfrom_mem_into(self.address,self.REG_UVCOMP2, uv_data)
		uvcomp2 = int.from_bytes(uv_data, 'little')
		
		uvacomp = (uva-uvd) - (self.UVA_A_COEF * (uvcomp1-uvd)) - (self.UVA_B_COEF * (uvcomp2-uvd))
		uvbcomp = (uvb-uvd) - (self.UVB_C_COEF * (uvcomp1-uvd)) - (self.UVB_D_COEF * (uvcomp2-uvd))
		
# Do not allow negative readings which can occur in no UV light environments e.g. indoors
		if uvacomp < 0:  
			uvacomp = 0
		if uvbcomp < 0:
			uvbcomp = 0

		uvai = uvacomp * self.UVA_RESPONSIVITY
		uvbi = uvbcomp * self.UVB_RESPONSIVITY
		uvi = (uvai + uvbi) / 2
		
		return (uvi, uvai, uvbi)

Traceback (most recent call last):
  File "<stdin>", line 20, in <module>
  File "veml6075.py", line 83, in readUV
AttributeError: 'pimoroni_i2c' object has no attribute 'readfrom_mem_into'

Line 20 is UVI, UVIA, UVIB = uv.readUV()

import veml6075

import time
from pimoroni_i2c import PimoroniI2C
from breakout_ltr559 import BreakoutLTR559

PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}

i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
uv = veml6075.VEML6075(i2c)

import picodisplay2 as display2
display_buffer = bytearray(320 * 240 * 2)  # 2-bytes per pixel (RGB565)
display2.init(display_buffer)
display2.set_backlight(0.8)


while True:
    UVI, UVIA, UVIB = uv.readUV()
    display2.set_pen(0, 255, 0)
    display2.text("uv", 0, 70, 240, 3)
    display2.text("UVIA         {0:.1f}" .format(UVIA), 0, 90, 240, 3)
    display2.text("UVIB         {0:.1f}" .format(UVIB), 0, 110, 240, 3)
    display2.text("UVI avg    {0:.1f}" .format(UVI), 0, 130, 240, 3) 
    
    
    display2.update()
    display2.set_pen(0, 0, 0)
    display2.clear()
 
    time.sleep(1.0)

@hel @gadgetoid

Traceback (most recent call last):
  File "<stdin>", line 12, in <module>
ValueError: BreakoutLTR559: Bad i2C object

Line 12 is ltr = BreakoutLTR559(i2c)

#import machine
from machine import I2C, Pin
sda=machine.Pin(4) # Explorer 20 Breakout 4
scl=machine.Pin(5) # Explorer 21 Breakout 5
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)

import veml6075
import time
import machine

from breakout_ltr559 import BreakoutLTR559
ltr = BreakoutLTR559(i2c)
uv = veml6075.VEML6075(i2c)
connected = uv.initUV()
import picodisplay2 as display2
display_buffer = bytearray(320 * 240 * 2)  # 2-bytes per pixel (RGB565)
display2.init(display_buffer)
display2.set_backlight(0.8)


while True:

    reading = ltr.get_reading()
    #print("Lux:", reading[BreakoutLTR559.LUX], "Prox:", reading[BreakoutLTR559.PROXIMITY])
    light = reading[BreakoutLTR559.LUX]
    
    display2.set_pen(0, 255, 0)
    display2.text("sun", 0, 70, 240, 3)
    
    #Convert light level in lux to descriptive value.
     
    if light < 50:
        display2.text("dark", 60, 70, 240, 3)
    elif 50 <= light < 100:
        display2.text("dim", 60, 70, 240, 3)
    elif 100 <= light < 500:
        display2.text("light", 60, 70, 240, 3)
    elif light >= 500:
        display2.text("bright", 60, 70, 240, 3)


    
    
    
    
    UVI, UVIA, UVIB = uv.readUV()
    display2.set_pen(0, 255, 0)
    #display2.text("uv", 0, 70, 240, 3)
    display2.text("UVIA         {0:.1f}" .format(UVIA), 0, 180, 240, 3)
    display2.text("UVIB         {0:.1f}" .format(UVIB), 0, 200, 240, 3)
    display2.text("UVI avg    {0:.1f}" .format(UVI), 0, 220, 240, 3) 
    
    
    display2.update()
    display2.set_pen(0, 0, 0)
    display2.clear()
 
    time.sleep(1.0)