From 699c94fb28e92f5db41d30166925a8daa4418117 Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 16 Feb 2017 17:27:42 +0100 Subject: [PATCH 1/1] Check in --- owRead.py | 81 ++++++++++++++ owlib.py | 325 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 406 insertions(+) create mode 100755 owRead.py create mode 100644 owlib.py diff --git a/owRead.py b/owRead.py new file mode 100755 index 0000000..11de54f --- /dev/null +++ b/owRead.py @@ -0,0 +1,81 @@ +#!/usr/bin/python +# Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# * All advertising materials mentioning features or use of this +# software must display the following acknowledgement: This product +# includes software developed by tm3d.de and its contributors. +# * Neither the name of tm3d.de nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +execfile("owlib.py") + +devlist=owfind(""); +dc=len(devlist) +if dc==0: + print "No 1-Wire Device found" + exit(0) +i=1 +#for s in devlist: +# print("%i) %s" %(i,s)) +# i=i+1 +#n=int(raw_input("No. of Device: ")) +#n=n-1 +#if (n>dc-1)or(n<0): +# exit(0) +#s=devlist[n] +devobj=[]; +for s in devlist: + if (s[0:2]=="28"): + dev=owDS18B20(s) + elif (s[0:2]=="20"): + dev=owDS2450(s) + elif (s[0:2]=="26"): + dev=owDS2438(s) + elif (s[0:2]=="1d"): + dev=owDS2423(s) + else: + continue + dev.readConfig() + dev.convertAll() + devobj.append(dev) + +str="" +for dev in devobj: + print dev.getChips() + print dev.getProperties() + print dev.getUnits() + +while (1): + for dev in devobj: + dev.convertAll() + print dev.owid,dev.values + print + time.sleep(3) + + + +#P0=Press/((1-h/44330)**5.255) diff --git a/owlib.py b/owlib.py new file mode 100644 index 0000000..04f2ade --- /dev/null +++ b/owlib.py @@ -0,0 +1,325 @@ +#!/usr/bin/python +# Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# * All advertising materials mentioning features or use of this +# software must display the following acknowledgement: This product +# includes software developed by tm3d.de and its contributors. +# * Neither the name of tm3d.de nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + + +import time +import subprocess +import sys +devInfo= ["","temperature","pressure","illuminance","humidity","constant","voltage","current","VOC","counter","CO2","resistance"] +devUnit= ["","°C","hPa","lux","%","","V","mA","ppm","","ppm","kOhm"] + +devController=["","Old code","Attiny84A","Attiny44","Atmega328"] + +devChip=["","DS18B20","DS2438","DS2438","DS2438","DS2450","Thermoelement","SHT21","SHT25","DHT22","HIH9021","HDC1080","HIH4030","HIH5030","BMP280","MAX44009","CDM7160","MAX1164/TGS8100","TGS8100","DS2423"] + + +def calcValue(code,vn,V): + if code==0: + return V[vn] + if code==1: + return V[vn] / 16.0; + if code==2: + return V[vn]/1.6; + if code==3: + return V[vn]*0.2 + 700; + if code==4: + return exp(V[vn] / 160.0); + if code==5: + return V[vn]*62.5 + 55000; + if code==6: + return V[vn] / 256.0; + if code==7: + return ((float(V[2]) / float(V[1]) - 0.16) / 0.0062) / (1.0546 - 0.00216*V[0]/256.0); + if code==8: + return V[vn] / 100.0; + if code==9: + return V[vn] / 65535.0*5.1; + if code==10: + return V[vn] / 65535.0*2.55; + if code==11: + return V[vn] / 65535.0*1.1; + if code==12: + return V[vn] / 10.0; + if code==13: + return V[vn]; + if code==14: + return (V[vn] - 32767.0) / 100.0; + if code==15: + return exp((V[vn]-32767.0)/1000.0); + if code==16: + return V[vn]/32.0; + return 0; + + + +def owcom(dev,send,rc): + res=[] + try: + f=open("/sys/bus/w1/devices/%s/rw" %(dev),"r+b",0) + except IOError: + l=subprocess.check_output("rmmod w1_therm",shell=True) + f=open("/sys/bus/w1/devices/%s/rw" %(dev),"r+b",0) + f.write("".join(map(chr, send))) + if (rc!=0): + res=map(ord,f.read(rc)) + f.close() + return res + + +def crc8(arr): + lscrc=0x0; + for v in arr: + bit=1; + while bit<256: + if (v&bit)==bit: + lb=1 + else: + lb=0 + if (lscrc&1)!=lb: + lscrc=(lscrc>>1)^0x8c + else: + lscrc=(lscrc>>1) + bit=bit*2 + return (lscrc==0) + + +oddparity = [ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 ] + + +def crc16(arr): + crc16=0 + for cdata in arr: + cdata = (cdata ^ (crc16 & 0xff)) & 0xff; + crc16 = crc16>>8; + if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]): + crc16 = crc16 ^ 0xc001; + cdata = (cdata << 6)&0xffff; + crc16 = crc16 ^ cdata; + cdata = (cdata << 1)&0xffff; + crc16 = crc16^cdata; + #r=crc16==0xB001 + return (crc16==0xB001) + + +def ow_fconvert(b1, b2): + tsht = b1 | (b2 << 8) + if (b2 & 0x080): + tsht=-(tsht&0x7FFF) + return tsht + + +def testnr(s): + for c in s.lower()[:]: + if not((c) in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','-']): + return False + return True + +def addid(id,val): + for i in range(7): + id[i+1]=id[i+1]+val + if id[i+1]>254: + id[i+1]=id[i+1]-254 + val=1 + else: + return id + return id +# + +def owfind(famcodes): + l=subprocess.check_output("ls /sys/bus/w1/devices/", shell=True) + dl=[] + for g in (l.split("\n")): + if len(g)>2: + if testnr(g[0:2]): + if (g[0:2] in famcodes) or len(famcodes)==0: + dl.append(g) + print g + return dl; + + +class owDevice: + raw=[0,0,0,0] + values=[0.0,0.0,0.0,0.0] + owid="" + config=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + def __init__(self, owid): + self.owid = owid + + def setdefaultConfig(self): + raise NotImplementedError() + + def readConfig(self): + self.config=owcom(self.owid,[0x85],26) + if self.config[0]==0xFF: + print("No Deviceconfig. Not a Device form tm3d.de. Set Default"); + self.setdefaultConfig() + else: + if self.config[25]==0xFF: + if not(crc8(self.config[0:24])): + print("CRC Error reading Deviceconfig. Set Default") + self.setdefaultConfig() + else: + if not(crc16([0x85]+self.config)): + print("CRC Error reading Deviceconfig. Set Default") + self.setdefaultConfig() + + def convertAll(self): + raise NotImplementedError() + + def getChips(self): + l=[]; + for i in range(0,4): + l.append(devChip[self.config[i+9]]) + return l + + def getUnits(self): + l=[]; + for i in range(0,4): + l.append(devUnit[self.config[i*2]]) + return l + + def getProperties(self): + l=[]; + for i in range(0,4): + l.append(devInfo[self.config[i*2]]) + return l + + +class owDS2450(owDevice): + def setdefaultConfig(self): + self.config=[6,9, 6,9, 6,9, 6,9, 0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0] + + def convertAll(self): + ret=owcom(self.owid,[0x3C,0x0F,0x00],2) + if not(crc16([0x3C,0x0F,0x00]+ret)): + print("CRC ERROR") + return + time.sleep(1) + ret=owcom(self.owid,[0xAA,0x00,0x00],10) + if not(crc16([0xAA,0x00,0x00]+ret)): + print("CRC ERROR") + return + for i in range(0,4): + self.raw[i]=ret[2*i]|(ret[2*i+1]<<8); + for i in range(0,4): + self.values[i]=calcValue(self.config[i*2+1],i,self.raw) + + +class owDS18B20(owDevice): + def setdefaultConfig(self): + self.config=[1,1, 0,0, 0,0, 0,0, 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + + def convertAll(self): + owcom(self.owid,[0x44],0) + time.sleep(1) + ret=owcom(self.owid,[0xBE],9) + if not(crc8(ret)): + print("CRC ERROR") + return + self.raw[0]=ow_fconvert(ret[0],ret[1]); + self.values[0]=calcValue(self.config[0*2+1],0,self.raw) + self.values[1]=0; + self.values[2]=0; + self.values[3]=0; + +class owDS2438(owDevice): + def setdefaultConfig(self): + self.config=[1,6, 6,8, 4,7, 7,17, 0,2,3,12,4,0,0,0,0,0,0,0,0,0,0,0] + + def readScratchpad(self,page,recall): + if (recall): + owcom(self.owid,[0xB8,page],0) + ret=owcom(self.owid,[0xBE,page],9) + if not(crc8(ret)): + print("CRC ERROR") + return [] + return ret + + def setConfigByte(self, cb): + for i in range(3): + owcom(self.owid,[0x4E,0x00,cb],0) + sp=self.readScratchpad(0,False) + if (sp!=[]): + if sp[0]==cb: + return True + return False + + + + def convertAll(self): + owcom(self.owid,[0x44],0) + time.sleep(0.01) + self.setConfigByte(0x08) + owcom(self.owid,[0xB4],0) + time.sleep(0.01) + sp=self.readScratchpad(0,True) + temp=ow_fconvert(sp[1],sp[2]); + VDD=ow_fconvert(sp[3],sp[4]); + self.setConfigByte(0x00) + owcom(self.owid,[0xB4],0) + time.sleep(0.01) + sp=self.readScratchpad(0,True); + I=ow_fconvert(sp[5],sp[6]); + VAD=ow_fconvert(sp[3],sp[4]); + self.raw[0]=temp; + self.raw[1]=VDD; + self.raw[2]=VAD; + self.raw[3]=I; + for i in range(0,4): + self.values[i]=calcValue(self.config[i*2+1],i,self.raw) + +class owDS2423(owDevice): + def setdefaultConfig(self): + self.config=[9,13, 9,13, 9,13, 9,13, 0,19,19,19,19,0,0,0,0,0,0,0,0,0,0,0] + + def readCounter(self,page): + addr=(page<<5)+31 + ret=owcom(self.owid,[0xA5,addr&0xFF,addr>>8],11) + if not(crc16([0xA5,addr&0xFF,addr>>8]+ret)): + print("CRC ERROR") + return 0 + c=0 + for i in range (4): + c<<=8; + c|=ret[4-i]; + return c; + + + def convertAll(self): + for i in range(4): + self.raw[i]=self.readCounter(i+12); + for i in range(0,4): + self.values[i]=calcValue(self.config[i*2+1],i,self.raw) + -- 2.34.1