diff --git a/_P084_VEML6070.py b/_P084_VEML6070.py new file mode 100644 index 0000000..1895f18 --- /dev/null +++ b/_P084_VEML6070.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +############################################################################# +##################### VEML6070 plugin for RPIEasy ########################### +############################################################################# +# +# Based on original ESPEasy P084 plugin +# +# Copyright (C) 2020 by Alexander Nagy - https://bitekmindenhol.blog.hu/ +# +import plugin +import webserver +import rpieGlobals +import rpieTime +import misc +import gpios +import time + +class Plugin(plugin.PluginProto): + PLUGIN_ID = 84 + PLUGIN_NAME = "Environment - VEML6070 UV sensor (TESTING)" + PLUGIN_VALUENAME1 = "UV-Raw" + PLUGIN_VALUENAME2 = "UV-Risk" + PLUGIN_VALUENAME3 = "UV-Power" + VEML6070_ADDR_H = 0x39 + VEML6070_ADDR_L = 0x38 + VEML6070_RSET_DEFAULT = 270000 # 270K default resistor value 270000 ohm, range from 220K..1Meg + VEML6070_UV_MAX_INDEX = 15 # normal 11, internal on weather laboratories and NASA it's 15 so far the sensor is linear + VEML6070_UV_MAX_DEFAULT = 11 # 11 = public default table values + VEML6070_POWER_COEFFCIENT = 0.025 # based on calculations from Karel Vanicek and reorder by hand + VEML6070_TABLE_COEFFCIENT = 32.86270591 + VEML6070_base_value = ((VEML6070_RSET_DEFAULT / VEML6070_TABLE_COEFFCIENT) / VEML6070_UV_MAX_DEFAULT) * (1) + VEML6070_max_value = ((VEML6070_RSET_DEFAULT / VEML6070_TABLE_COEFFCIENT) / VEML6070_UV_MAX_DEFAULT) * (VEML6070_UV_MAX_INDEX) + + def __init__(self,taskindex): # general init + plugin.PluginProto.__init__(self,taskindex) + self.dtype = rpieGlobals.DEVICE_TYPE_I2C + self.vtype = rpieGlobals.SENSOR_TYPE_TRIPLE + self.readinprogress = 0 + self.valuecount = 3 + self.senddataoption = True + self.timeroption = True + self.timeroptional = False + self.formulaoption = True + self._nextdataservetime = 0 + self.lastread = 0 + self.i2cbus = None + + def plugin_init(self,enableplugin=None): + plugin.PluginProto.plugin_init(self,enableplugin) + self.uservar[0] = 0 + self.readinprogress = 0 + if self.enabled: + try: + try: + i2cl = self.i2c + except: + i2cl = -1 + self.i2cbus = gpios.HWPorts.i2c_init(i2cl) + if i2cl==-1: + self.i2cbus = gpios.HWPorts.i2cbus + if self.i2cbus is not None: + if self.interval>2: + nextr = self.interval-2 + else: + nextr = self.interval + self._lastdataservetime = rpieTime.millis()-(nextr*1000) + self.lastread = 0 + self.i2cbus.write_byte(self.VEML6070_ADDR_L, (( self.taskdevicepluginconfig[0] << 2) | 0x02)) # init veml + else: + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"I2C can not be initialized!") + self.initialized = False + except Exception as e: + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,str(e)) + self.initialized = False + self.i2cbus = None + + def webform_load(self): # create html page for settings + webserver.addFormNote("Enable I2C bus first, than search for the used address!") + choice1 = self.taskdevicepluginconfig[0] + options = ["1/2T","1T","2T","4T"] + optionvalues = [0,1,2,3] + webserver.addFormSelector("Refresh Time Determination","itime",len(options),options,optionvalues,None,int(choice1)) + return True + + def webform_save(self,params): # process settings post reply + par = webserver.arg("itime",params) + if par == "": + par = 4 + self.taskdevicepluginconfig[0] = int(par) + return True + + def plugin_read(self): # deal with data processing at specified time interval + result = False + if self.enabled and self.initialized and self.readinprogress==0: + self.readinprogress = 1 + try: + raw = self.VEML6070_readraw() + except Exception as e: + raw = None + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"VEML6070: "+str(e)) + if raw is not None: + self.set_value(1,raw,False) + risk = self.VEML6070_uvrisklevel(raw) + self.set_value(2,risk,False) + self.set_value(3,self.VEML6070_uvpower(risk),False) + self.plugin_senddata() + self._lastdataservetime = rpieTime.millis() + result = True + self.readinprogress = 0 + return result + + def VEML6070_readraw(self): + uv_raw = 0 + try: + data1 = self.i2cbus.read_byte(self.VEML6070_ADDR_H) + data0 = self.i2cbus.read_byte(self.VEML6070_ADDR_L) + uv_raw = data1*256 + data0 + except Exception as e: + pass + return uv_raw + + def VEML6070_uvrisklevel(self,uv_level): + risk = 0 + if (uv_level < self.VEML6070_max_value): + return (uv_level / self.VEML6070_base_value) + else: + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"VEML6070 out of range: "+str(uv_level)) + return 99 + + def VEML6070_uvpower(self,uvrisk): + return (self.VEML6070_POWER_COEFFCIENT * uvrisk) diff --git a/_P201_GenSerial.py b/_P201_GenSerial.py index f763532..d9a1ba7 100644 --- a/_P201_GenSerial.py +++ b/_P201_GenSerial.py @@ -12,6 +12,7 @@ # serialwrite,0xFF01 - sends two bytes (written in hexadecimal form): 255,1 # serialwrite,0x1045AA - sends three bytes (written in hexadecimal form): 16,69,170 # serialwrite,this is a message - sends a simple string "this is a message" +# serialwriteln,this is a message - sends a simple string "this is a message\n" # # Copyright (C) 2018-2019 by Alexander Nagy - https://bitekmindenhol.blog.hu/ # @@ -65,7 +66,7 @@ def plugin_init(self,enableplugin=None): plugin.PluginProto.plugin_init(self,enableplugin) try: if str(self.taskdevicepluginconfig[0])!="0" and str(self.taskdevicepluginconfig[0]).strip()!="" and self.baud != 0: - self.serdev = None +# self.serdev = None self.initialized = False if self.enabled: self.calctimeout() @@ -80,6 +81,10 @@ def plugin_init(self,enableplugin=None): else: self.baud = 0 self.ports = 0 + try: + self.serdev.close() # close in case if already opened by ourself + except: + pass except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,str(e)) @@ -192,8 +197,13 @@ def convert(self,inbuf): return res def connect(self): + try: + self.serdev.close() # close in case if already opened by ourself + except: + pass try: self.serdev = rpiSerial.SerialPort(self.taskdevicepluginconfig[0],self.baud,ptimeout=self.timeout,pbytesize=self.bsize,pstopbits=self.sbit) + misc.addLog(rpieGlobals.LOG_LEVEL_INFO,"Serial connected "+str(self.taskdevicepluginconfig[0])) except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"Serial failed "+str(e)) try: @@ -233,7 +243,7 @@ def plugin_write(self,cmd): res = False cmdarr = cmd.split(",") cmdarr[0] = cmdarr[0].strip().lower() - if cmdarr[0] == "serialwrite": + if cmdarr[0] == "serialwrite" or cmdarr[0] == "serialwriteln": res = True sepp = cmd.find(',') text = cmd[sepp+1:] @@ -249,6 +259,8 @@ def plugin_write(self,cmd): sbuf = str(text) else: sbuf = str(text) + if cmdarr[0] == "serialwriteln": + sbuf += "\n" if self.serdev is not None: try: self.serdev.write(sbuf) diff --git a/gpios.py b/gpios.py index b9637db..340b1dc 100644 --- a/gpios.py +++ b/gpios.py @@ -26,6 +26,8 @@ "addr": [0x29]}, {"name": "TSL2561 light sensor", "addr": [0x29,0x39,0x49]}, + {"name": "VEML6070", + "addr": [0x38,0x39]}, {"name": "APDS-9960 IR/Color/Proximity Sensor", "addr": [0x39]}, {"name": "SSD1305/SSD1306 monochrome OLED", @@ -48,6 +50,8 @@ "addr": [0x4A]}, {"name": "BH1750", "addr": [0x23,0x5C]}, + {"name": "MLX90614", + "addr": [0x5a]}, {"name": "MPR121 touch sensor", "addr": [0x5a,0x5b,0x5c,0x5d]}, {"name": "DHT12/AM2320", @@ -56,7 +60,7 @@ "addr": [0x60,0x61]}, {"name": "DS1307/DS3231/PCF8523 RTC", "addr": [0x68]}, - {"name": "MPU6050 Triple axis gyroscope & accelerometer", + {"name": "MPU6050;AMG88xx", "addr": [0x68,0x69]}, {"name": "PCA9685 'All Call'", "addr": [0x70]}, diff --git a/lib/lib_serial.py b/lib/lib_serial.py index d1e2d42..c7f4489 100644 --- a/lib/lib_serial.py +++ b/lib/lib_serial.py @@ -130,9 +130,18 @@ def close(self): def serial_portlist(): ports = [] - for port in serial.tools.list_ports.comports(): - ports.append(str(port.device)) + try: + for port in serial.tools.list_ports.comports(True): #include symlinks + ports.append(str(port.device)) + except: + pass if len(ports)<1: + try: + for port in serial.tools.list_ports.comports(): #failsafe + ports.append(str(port.device)) + except: + pass + if len(ports)<1: #alternative systems like orangepi import glob try: devlist1 = glob.glob('/dev/ttyS*') diff --git a/linux_os.py b/linux_os.py index bb8ca0f..b045f36 100644 --- a/linux_os.py +++ b/linux_os.py @@ -409,6 +409,15 @@ def getRPIVer(): "lan":"1", "bt":"1" } + elif (hwid == "c03130"): + hwarr = { + "name": "Pi 400 Rev1", + "ram": "4GB", + "pins": "40", + "wlan": "1", + "lan":"1", + "bt":"1" + } elif (hwid == "d03114"): hwarr = { "name": "Pi 4 Model B", diff --git a/plugindeps.py b/plugindeps.py index b78016d..2b71597 100644 --- a/plugindeps.py +++ b/plugindeps.py @@ -431,6 +431,9 @@ {"pluginid": "82", #GPS "supported_os_level": [1,2,3,10], "modules":["pyserial"]}, +{"pluginid": "84", # VEML6070 + "supported_os_level": [3,10], + "modules":["i2c"]}, {"pluginid": "111", #RF433 receiver "supported_os_level": [10], "modules":["GPIO","wpi","rcswitch"]}, diff --git a/rpieGlobals.py b/rpieGlobals.py index d3ff2d7..bdbe69e 100644 --- a/rpieGlobals.py +++ b/rpieGlobals.py @@ -6,7 +6,7 @@ # Copyright (C) 2018-2020 by Alexander Nagy - https://bitekmindenhol.blog.hu/ # PROGNAME = "RPIEasy" -BUILD = 20320 +BUILD = 20327 PROGVER = str(BUILD)[:1]+"."+str(BUILD)[1:2]+"."+str(BUILD)[2:] gpMenu = []