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 = []