Ignis
Posts: 4
Joined: Thu May 10, 2018 8:18 pm

Python lux + wiringpi

Thu May 10, 2018 8:41 pm

Hey,
let me start by saying im very new to python. Ive been trying to write a python script to switch lights on a relay depending on how dark it gets however lately i ran into a very confusing problem.

TypeError: in method digitalRead, argument 1 is int

Now this confuses the hell out of me because the argument HAS to be int.
And the argument IS an integer. So im not sure why the code is giving that error, unless it somehow means something else?

Code: Select all

  if wiringpi.digitalRead(Relay[s]) == 0 and RelayCtrl[s] == "True":
This is the line of code where it happens.

Code: Select all

def turnoff(Relay,rlcfgfile,s):
  RelayCtrl = pondmodule.rdcfile(rlcfgfile)
  if not pondmodule.is_intstring(s):
    print "Cannot turn off relay is not a number."
  s = int(s)
  if wiringpi.digitalRead(Relay[s]) == 0 and RelayCtrl[s] == "True":
    RelayCtrl[s] = "False"
    wiringpi.digitalWrite(Relay[s], 1)
  pondmodule.clean(rlcfgfile)
  pondmodule.writelist(rlcfgfile,RelayCtrl)
  return RelayCtrl
This is the actual function. Relay is a list of integers (it really is cause if i add a check before it it comes back as true).

The thing is tho, i copied it over from another program that works fine. So I'm hoping its just a beginners thing that im missing.

User avatar
joan
Posts: 14960
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Python lux + wiringpi

Fri May 11, 2018 5:17 am

Is this in a class? You might need self as the first parameter.

Could you post the complete program? That would allow others to run the script in the same environment (if thy have the same environment).

ghp
Posts: 1517
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Python lux + wiringpi

Fri May 11, 2018 6:19 am

Hello,
most possibly the term

Code: Select all

Relay[s]
does not return an integer.
You could check the content of Relay with an additional line of code

Code: Select all

	
s = int(s)
pin = Relay[s]
if not isinstance( pin, int):
    print("ERROR, Relay[s] is not an int", Relay[s])
if wiringpi.digitalRead(pin) == 0 and RelayCtrl[s] == "True":
    RelayCtrl[s] = "False"
    wiringpi.digitalWrite(pin, 1)
 

Ignis
Posts: 4
Joined: Thu May 10, 2018 8:18 pm

Re: Python lux + wiringpi

Fri May 11, 2018 9:07 pm

Hey, thanks for the quick replies.

It shouldnt be a class ;P (I had to look up what a class was cause i didnt know, never used one.)

And it is an integer thats the problem because if i add the integer check into it it will return true but still give the error. And it does indeed work if i create another variable and just make it Relay (s) but the problem then is what about the other script i run the code from and doesnt give an error. Id like to know why it gives that error so i can make sure it doesnt occur in the other script.

So i'll basicly add the entire scripts and try to explain a bit more about what they do (keep in mind im an absolute beginner so the code may look horrible to you lot)

Code: Select all

import time
import sys
import smbus
import datetime
import wiringpi
import os
import glob

wiringpi.wiringPiSetup()
bus = smbus.SMBus(1)

def isTimeFormat(input):
    try:
        time.strptime(input, '%H:%M')
        return True
    except ValueError:
        return False

def isNowInTimePeriod(startTime, endTime):
    if isTimeFormat(startTime):
      startTime = datetime.datetime.strptime(startTime,"%H:%M")
      startTime = startTime.time()
#      print startTime
    if isTimeFormat(endTime):
      endTime = datetime.datetime.strptime(endTime,"%H:%M")
      endTime = endTime.time()
#      print endTime
    nowTime =  datetime.datetime.time(datetime.datetime.now())
    if startTime < endTime:
        return nowTime >= startTime and nowTime <= endTime
    else: #Over midnight
        return nowTime >= startTime or nowTime <= endTime

def is_intstring(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

def luxread():
  # TSL2561 address, 0x39(57)
  # Select control register, 0x00(00) with command register, 0x80(128)
  #             0x03(03)        Power ON mode
  bus.write_byte_data(0x39, 0x00 | 0x80, 0x03)
  # TSL2561 address, 0x39(57)
  # Select timing register, 0x01(01) with command register, 0x80(128)
  #             0x02(02)        Nominal integration time = 402ms
  bus.write_byte_data(0x39, 0x01 | 0x80, 0x02)
  time.sleep(0.5)

  # Read data back from 0x0C(12) with command register, 0x80(128), 2 bytes
  # ch0 LSB, ch0 MSB
  data = bus.read_i2c_block_data(0x39, 0x0C | 0x80, 2)

  # Read data back from 0x0E(14) with command register, 0x80(128), 2 bytes
  # ch1 LSB, ch1 MSB
  data1 = bus.read_i2c_block_data(0x39, 0x0E | 0x80, 2)

  # Convert the data
  ch0 = data[1] * 256 + data[0]
  ch1 = data1[1] * 256 + data1[0]
  ch2 = ch0 - ch1
  print ch2
  return int(ch2)

def getprobe(Pondconfig,s):
        # enable kernel modules
    os.system('sudo modprobe w1-gpio')
    os.system('sudo modprobe w1-therm')
    # search in config file for the serial number and add it to path
#    with open(Pondconfig,"r") as file:
#      data = file.readlines()
#      newdata = [x[:-1] for x in data]
    list = rdcfile(Pondconfig)
    a = srchlist(list, s)
#      a = filter(lambda x: s in x, newdata)
    a = a[0]
    a = a[-12:]
    a = "/sys/bus/w1/devices/28-" + a + "/w1_slave"
    probe = glob.glob(a)
    if probe == '':
        return None
    else:
        return probe


def get_temp(devicefile):

    try:
        fileobj = open(devicefile,'r')
        lines = fileobj.readlines()
        fileobj.close()
    except:
        return None

    # get the status from the end of line 1 
    status = lines[0][-4:-1]
#    print status

    # is the status is ok, get the temperature from line 2
    if status=="YES":
#        print status
        tempstr= lines[1][-6:-1]
        tempvalue=float(tempstr)/1000
        print tempvalue
        return tempvalue
    else:
        print "There was an error."
        return None

def rdcfile(filename):
  newdata = []
  with open(filename,"r") as file:
    data = file.readlines()
    for x in data:
        if x[-1:] == "\n":
            newdata.append(x[:-1])
        else:
            newdata.append(x)
    return newdata

def srchlist(list, searchstring):
    a = filter(lambda x: searchstring in x, list)
    return a

def returnreqlux(filename):
   reqluxlist = rdcfile(filename)
   reqlux = srchlist(reqluxlist, "reqlux")
   reqlux = reqlux[0]
   reqlux = reqlux[7:]
   if not is_intstring(reqlux):
      return None
   else:
      return int(reqlux)

def returntimes(configfile, searchstring):
    list = rdcfile(configfile)
    list = srchlist(list, searchstring)
    start = [x[-11:-6] for x in list]
    end = [x[-5:] for x in list]
    return start, end

def setpins(Relay):
    RelayCtrl = []
    for x in range(0, len(Relay)):
      if is_intstring(Relay[x]) == True:
        Relay[x] = int(Relay[x])
        wiringpi.pinMode(Relay[x],1)
        wiringpi.digitalWrite(Relay[x],0)
        RelayCtrl.append("True")
    return RelayCtrl

def checktemp(pondconfig, s):
    list = rdcfile(pondconfig)
    Ltemp = srchlist(list, "lowtemp")
    Ltemp = Ltemp[0]
    Ltemp = Ltemp[8:]
    if is_intstring(Ltemp) == True:
      Ltemp = int(Ltemp)
    Htemp = srchlist(list, "hightemp")
    Htemp = Htemp[0]
    Htemp = Htemp[9:]
    if is_intstring(Htemp) == True:
      Htemp = int(Htemp)
    s = s[0]
    Ctemp = get_temp(s)
    if Ctemp != None:
      if Ctemp < Ltemp or Ctemp > Htemp:
          return "PriorityOn"
      else:
          return "PriorityOff"
    else:
      Ctemp = get_temp(s)
      if Ctemp < Ltemp or Ctemp > Htemp:
        return "PriorityOn"
      else:
        return "PriorityOff"

def clean(s):
  open(s,"w").close()

def writelist(thefile,thelist):
  with open(thefile,"r+") as thefile:
    for item in thelist:
      thefile.write("%s\n" % item)

def write(f,s):
  with open(f,"r+") as file:
#    print s
    file.write(s)

def statuschange(s):
  with open("status.conf","r+") as file:
    lines = file.readlines()
    print lines
    file.seek(0)
    for i in lines:
        if i != s + "\n":
            file.write(i)
    file.truncate()

  with open("status.conf","r") as file:
    lines = file.readlines()
    print lines

def returnrelay(cfg,s):
  list = rdcfile(cfg)
  a = srchlist(list, s)
  a = a[0]
  a = a[-1:]
  if not is_intstring(a):
      print "Invalid relay number for %s in config file" %s
  else:
    return int(a)

def turnon(Relay,rlcfgfile,s):
  RelayCtrl = rdcfile(rlcfgfile)
  if not is_intstring(s):
    print "Cannot turn on relay is not a number."
  s = int(s)
  if wiringpi.digitalRead(Relay[s]) == 1 and RelayCtrl[s] == "False":
   RelayCtrl[s] = "True"
   wiringpi.digitalWrite(Relay[s], 0)
  writelist(rlcfgfile,RelayCtrl)
  return RelayCtrl


def turnoff(Relay,rlcfgfile, s):
  RelayCtrl = rdcfile(rlcfgfile)
  if not is_intstring(s):
    print "Cannot turn off relay is not a number."
  s = int(s)
  if wiringpi.digitalRead(Relay[s]) == 0 and RelayCtrl[s] == "True":
     RelayCtrl[s] = "False"
     wiringpi.digitalWrite(Relay[s], 1)
  writelist(rlcfgfile,RelayCtrl)
  return RelayCtrl
This is the pondmodule.py file wich contains a bunch of function i call from the other scripts.

Code: Select all

import sys
import time
import datetime
import pondmodule
import wiringpi

#Global Variables
#Config Files
pondconfig = "pond.conf"
statusconfig = "status.conf"
airprio = "air.conf"
lightprio = "light.conf"
rlcfg = "relayctrl.conf"

def turnon(Relay,rlcfgfile,s):
  RelayCtrl = pondmodule.rdcfile(rlcfgfile)
  if not pondmodule.is_intstring(s):
    print "Cannot turn on relay is not a number."
  s = int(s)
  if wiringpi.digitalRead(Relay[s]) == 1 and RelayCtrl[s] == "False":
   RelayCtrl[s] = "True"
   wiringpi.digitalWrite(Relay[s], 0)
  pondmodule.writelist(rlcfgfile,RelayCtrl)
  return RelayCtrl


def turnoff(Relay,rlcfgfile, s):
  RelayCtrl = pondmodule.rdcfile(rlcfgfile)
  if not pondmodule.is_intstring(s):
    print "Cannot turn off relay is not a number."
  s = int(s)
  print pondmodule.is_intstring(Relay[s])
  if wiringpi.digitalRead(Relay[s]) == 0 and RelayCtrl[s] == "True":
     RelayCtrl[s] = "False"
     wiringpi.digitalWrite(Relay[s], 1)
  pondmodule.writelist(rlcfgfile,RelayCtrl)
  return RelayCtrl

def main():
#Set relay pins.
  Relay = pondmodule.srchlist(pondmodule.rdcfile(pondconfig), "Relay")
  Relay = [x[-2:] for x in Relay]
#  print Relay
  RelayCtrl = pondmodule.setpins(Relay)
#  print RelayCtrl
  pondmodule.clean(rlcfg)
  pondmodule.writelist(rlcfg,RelayCtrl)
  pondmodule.clean(statusconfig)
  pondmodule.write(statusconfig,"BOOT OK")
  TempProbe = pondmodule.getprobe(pondconfig,"Tempprobe")
  Lights = pondmodule.returnrelay(pondconfig,"LiRel")
  Airpump = pondmodule.returnrelay(pondconfig,"AirPRel")
  Skimmer = pondmodule.returnrelay(pondconfig,"SkimRel")
  temperature = pondmodule.checktemp(pondconfig, TempProbe) 
  if temperature == "PriorityOn":
    print "Priority On."
    RelayCtrl[Skimmer] = False
    pondmodule.writelist(rlcfg,RelayCtrl)
    wiringpi.digitalWrite(Relay[Skimmer],1)
    pondmodule.clean("manskim.conf")
    pondmodule.write("manskim.conf","OFF")
    pondmodule.clean("manair.conf")
    pondmodule.write("manair.conf","ON")
    pondmodule.clean(airprio)
    pondmodule.write(airprio,"ACTIVE")
  elif temperature == "PriorityOff":
    print "Priority Off."
    pondmodule.clean(airprio)
    AirTimeStart, AirTimeEnd = pondmodule.returntimes(pondconfig,"AirTime")
    airpumptime = "nok"
    for x in range(0, len(AirTimeStart)):
      if pondmodule.isNowInTimePeriod(AirTimeStart[x],AirTimeEnd[x]):
        airpumptime = "ok"
    if airpumptime == "ok":
      print "Now is within the specified timerange for Airpump."
    else:
      RelayCtrl = turnoff(Relay, rlcfg, Airpump)
      print "Now is not within specified timerange for Airpump."
    SkimmerTimeStart, SkimmerTimeEnd = pondmodule.returntimes(pondconfig,"SkimmerTime")
    skimmerpumptime = "nok"
    for x in range(0, len(SkimmerTimeStart)):
      if pondmodule.isNowInTimePeriod(SkimmerTimeStart[x],SkimmerTimeEnd[x]):
         skimmerpumptime = "ok"
    if skimmerpumptime == "ok":
      print "Now is within the specified timerange for Skimmerpump."
    else:
      RelayCtrl = turnoff(Relay, rlcfg, Skimmer)
      print "Now is not within the specified timerange for Skimmerpump."
    LightsTimeStart, LightsTimeEnd = pondmodule.returntimes(pondconfig, "LightsTime")
    lightstime = "nok"
    for x in range(0, len(LightsTimeStart)):
      if pondmodule.isNowInTimePeriod(LightsTimeStart[x],LightsTimeEnd[x]):
        lightstime = "ok"
    if lightstime == "ok":
      if pondmodule.returnreqlux(pondconfig) > pondmodule.luxread():
        print "It is dark enough."
      else:
        print "It is not dark enough."
        RelayCtrl = turnoff(Relay, rlcfg, Lights)
    else:
      print "Now is not within the specified timerange for lights."
      RelayCtrl = turnoff(Relay, rlcfg, Lights)
  print RelayCtrl

if __name__=="__main__":
    main()

This is bootscript.py a script that will be run at startup to initialize the pins to output and set them to their starting mode, this uses the same turnoff function with the same list variables and works without a hitch.

Basicly the thing im trying to achieve is to control 3 relays in all wich have to do with my pond & garden. One is for the lights (switch on between a certain time period and if dark enough). One is an airpump in my pond (on below a certain temp to avoid freezing, on above a certain temp to add extra oxygen and on scheduled times if normal temperatures). Last is the skimmerpump (on in scheduled intervals IF the airpump isnt on).
The point of the relayctrl list is to make sure the state of the pins (high/low) are the same as the script last set them. The point of this is so that if i manually switch on the lights (with my mobile & cayenne) the script doesnt turn them off again.

Code: Select all

import sys
import time
import datetime
import pondmodule
import wiringpi

#Global Variables
#Config Files
pondconfig = "pond.conf"
airprio = "air.conf"
rlcfg = "relayctrl.conf"

def turnon(Relay,rlcfgfile,s):
  RelayCtrl = pondmodule.rdcfile(rlcfgfile)
  if not pondmodule.is_intstring(s):
    print "Cannot turn on relay is not a number."
  s = int(s)
  Rel = int(Relay[s])
  if wiringpi.digitalRead(Rel) == 1 and RelayCtrl[s] == "False":
    RelayCtrl[s] = "True"
    wiringpi.digitalWrite(Rel, 0)
  pondmodule.clean(rlcfgfile)
  pondmodule.writelist(rlcfgfile,RelayCtrl)
  return RelayCtrl

def turnoff(Relay,rlcfgfile,s):
  RelayCtrl = pondmodule.rdcfile(rlcfgfile)
  if not pondmodule.is_intstring(s):
    print "Cannot turn off relay is not a number."
  s = int(s)
  print pondmodule.is_intstring(Relay[s])
  if wiringpi.digitalRead(Relay[s]) == 0 and RelayCtrl[s] == "True":
    RelayCtrl[s] = "False"
    wiringpi.digitalWrite(Relay[s], 1)
  pondmodule.clean(rlcfgfile)
  pondmodule.writelist(rlcfgfile,RelayCtrl)
  return RelayCtrl

def main():
  RelayCtrl = pondmodule.rdcfile(rlcfg)
  Relay = pondmodule.srchlist(pondmodule.rdcfile(pondconfig), "Relay")
  Relay = [x[-2:] for x in Relay]
  Lights = int(pondmodule.returnrelay(pondconfig,"LiRel"))
  LightsTimeStart, LightsTimeEnd = pondmodule.returntimes(pondconfig, "LightsTime")
  lightstime = "nok"
  for x in range(0, len(LightsTimeStart)):
    if pondmodule.isNowInTimePeriod(LightsTimeStart[x],LightsTimeEnd[x]):
      lightstime = "ok"
  if lightstime == "ok":
    if pondmodule.returnreqlux(pondconfig) > pondmodule.luxread():
      print "It is dark enough."
      RelayCtrl = turnon(Relay, rlcfg, Lights)
    else:
      print "It is not dark enough."
      RelayCtrl = turnoff(Relay, rlcfg, Lights)
  else:
    print "Now is not within the specified timerange for lights."
    RelayCtrl = turnoff(Relay, rlcfg, Lights)


if __name__=="__main__":
    main()

And this finally is the checklight.py wich i just started on and its purpose would be to run every 5minutes and see if the lights need to be turned on or off. But like i said most things here are copy pastes from the bootscript.py in wich they do run.

To complete ill also copy the contents of the config files:

Code: Select all

Relay0 22
Relay1 23
Relay2 24
Relay3 25
Relay4 26
Relay5 27
Relay6 28
Relay7 29
AirTime 02:00 04:00
AirTime 08:00 10:00
AirTime 14:00 16:00
AirTime 20:00 22:00
SkimmerTime 05:00 07:00
SkimmerTime 17:00 19:00
Tempprobe 0117c0a4ccff
lowtemp 3
hightemp 30
SkimRel 7
AirPRel 6
LiRel 0
LightsTime 18:00 22:00
reqlux 200
Pond.conf

This is done so if id wanna change times/temperatures etc i could just edit the conf file and wouldnt have to change code.

Ignis
Posts: 4
Joined: Thu May 10, 2018 8:18 pm

Re: Python lux + wiringpi

Fri May 11, 2018 9:18 pm

Actually,

when i use your integer check it sais its false and itll show in checklight.py '22' as value for Relay (s) where in bootscript.py it will say True and show 22 as value for Relay(s).

Im still not sure as to why it considers both lists different tho.

Ignis
Posts: 4
Joined: Thu May 10, 2018 8:18 pm

Re: Python lux + wiringpi

Fri May 11, 2018 10:07 pm

Problem is solved,

it was as expected a silly error i was overlooking:

in the bootscript i run the function setpins it changes the list into integers.

Return to “Python”