Python Forum
How to use an Emulator and a MttQ broker?
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to use an Emulator and a MttQ broker?
#1
Hello,

I am having trouble using an Emulator and mqtt broker.
When one click button lumiere entree or lumiere salon "ON" the GPIO in the emulator should be red.
Instead i get an error message i dont know what it means.
Also i dont know where to implement the mttq broker, so that when we click the button it send the info.

Any idea how to solve those issues?
Thank you

from tkinter import *
import datetime
ct = datetime.datetime.now()
from RPiSim import GPIO
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
import paho.mqtt.client as mqtt 
from random import randrange, uniform
import time

LED1= 22
LED2=18

mqttBroker ="mqtt.eclipseprojects.io"
client = mqtt.Client("Alarme")
client.connect(mqttBroker) 
  
root = Tk()
root.title('Ma console')  
root.geometry('430x800')
  
title = Label(root, text="Alarme", bg="grey", font=("bold", 20))
title.pack()
c = Canvas(root, width=330, height=160, bg="grey")
c.place(x=50, y=50)

def push():
    arme = Label(root, text="Arm�", bg="red", font=("bold", 20)).place(x = 170, y = 210)
    print("Alarme arm�e:-", ct)
    client.publish("Alarme", ct)            <----------------------------------------Mttq broker?
    print("Just published " + str(ct) + " to topic ALARME")


btn = Button(root, text='On', width=10,
             height=5, bd='10', command = push)

def pushOff():
   arme = Label(root, text="         ", bg="grey", font=("normal", 20)).place(x = 160, y = 210)
   print("Alarme d�sarm�e:-", ct)

btn1 = Button(root, text='Off', width=10,
             height=5, bd='10', command = pushOff)
 
btn.place(x=65, y=70)
btn1.place(x=225, y=70)


#2e paire de boutons

c1 = Canvas(root, width=330, height=200, bg="grey")
c1.place(x=50, y=250)

def pushOn():
   arme = Label(root, text="On", bg="red", font=("bold", 20)).place(x = 190, y = 420)
   GPIO.setup(LED1,GPIO.OUT)                             <-----------------------------GPIO? wrong place?
   print("Lumi�re entr�e allum�e:-", ct)

btn2 = Button(root, text='On', width=10,
             height=5, bd='10', command = pushOn)

def pushOff():
   arme = Label(root, text="Off", bg="red", font=("bold", 20)).place(x = 190, y = 420)
   print("Lumi�re entr�e ferm�e:-", ct)

btn3 = Button(root, text='Off', width=10,
             height=5, bd='10', command = pushOff)
 
btn2.place(x=65, y=300)
btn3.place(x=225, y=300)
title1 = Label(root, text="Lumi�re entr�e", bg="grey", font=("bold", 20)).place(x = 110, y = 255)
#title1.pack() 
  
#3e paire de boutons

c2 = Canvas(root, width=330, height=280, bg="grey")
c2.place(x=50, y=450)

def pushOn1():
   arme = Label(root, text="On", bg="red", font=("bold", 20)).place(x = 190, y = 620)
   GPIO.setup(LED2,GPIO.OUT)
   print("Lumi�re salon allum�e:-", ct)

btn4 = Button(root, text='On', width=10,
             height=5, bd='10', command = pushOn1)

def pushOff1():
   arme = Label(root, text="Off", bg="red", font=("bold", 20)).place(x = 190, y = 620)
   print("Lumi�re salon ferm�e:-", ct)

btn5 = Button(root, text='Off', width=10,
             height=5, bd='10', command = pushOff1)
 
btn4.place(x=65, y=500)
btn5.place(x=225, y=500)
title2 = Label(root, text="Lumi�re salon", bg="grey", font=("bold", 20)).place(x = 110, y = 460)
#title2.pack()
  
  
#3e Bouton historique

c3 = Canvas(root, width=330, height=280, bg="grey")
c3.place(x=50, y=650)

def Histo():
     root = Tk()
     root.title('Historique')  
     root.geometry('630x450')
     resultat = Text(root)
     #resultat.config(width=630, height = 450)
     #resultat.insert(Insert, "Date\ tHeure\ t�v�nement\n==============\n")
     resultat.grid(row = 0, column = 0, columnspan = 2)
     bouton = Button(root, text = "Quitter", command = root.destroy)
     bouton.grid(row = 1, column = 1)
     root.mainloop()
     
     
btn6 = Button(root, text='Afficher', width=28,
             height=3, bd='10', command = Histo)
 
btn6.place(x=65, y=700)
title3 = Label(root, text="Historique", bg="grey", font=("bold", 20)).place(x = 150, y = 660)
#title3.pack()
    
 
root.mainloop()
Reply
#2
Post the error message. We'll help you understand what it means

The code looks horrible. You've been coding long enough that this is no longer rude to say. Place all you functions near the top of the module and place main code below. Use consistent indentation. Your indentation is all over the place (3, 4, 5 spaces?). Setup your editor to use 4 spaces when you press the tab key. Use more descriptive function names. What does pushOn1() do? Does it turn on the salon lights? Can you make a variable name that indicates what it does? Write a doc string for every function. Use better variable names. What is btn4? If you need a variable that references a button, give it a better name, one that indicates it's purpose. Doing all of this will make it easier to read the code and will help you make fewer mistakes.

One thing that jumps out right away is the function Histo() calls Tk(). You cannot do that. A tkinter program can only call Tk() once. If you want another toplevel window use Toplevel(). Histo() also calls mainloop(). A tkinter program can only have one mainloop()

You have functions that create labels when you push a button. You should create the labels and buttons and do all the layout in one place for each window. If you have to change a label, change the text. Do no create a new label that hides the old.

Do not use "place()" to position widgets, use pack() or grid(). place() should only be used if the code is generated by a designer, or if you are forced into doing your own layout.

This assigns Non to the variable arme.
arme = Label(root, text="Off", bg="red", font=("bold", 20)).place(x = 190, y = 420)
If you need a variable to reference the label object do this:
arme = Label(root, text="Off", bg="red", font=("bold", 20))
arme.place(x = 190, y = 420)
If you don't need a variable that references the label, don't use a variable.
Label(root, text="Off", bg="red", font=("bold", 20)).place(x = 190, y = 420)
Your GPIO code is wrong. I thought you had some projects that used GPIO in the past. Am I wrong? You should setup your outputs in your main code (GPIO.setup(LED1, GPIO.OUT)) and set the outputs in your functions (GPIO.output(LED1, True)). Here again your variable names are terrible. What is LED1? Can you come up with a better name?
Reply
#3
Hi,

Quote:You cannot do that. A tkinter program can only call Tk() once. If you want another toplevel window use Toplevel(). Histo() also calls mainloop().

I didn't know that.

Quote:Do not use "place()" to position widgets, use pack() or grid(). place() should only be used if the code is generated by a designer, or if you are forced into doing your own layout.

I find out about place() looking at example on the web. I am in a rush it is due monday.

Quote: You should setup your outputs in your main code (GPIO.setup(LED1, GPIO.OUT)) and set the outputs in your functions (GPIO.output(LED1, True)).

GPIO is tough to use with Tkinter. But thats the project and i have to live with that. Its just a first draft the variable name will change. Led or Salon_led its got to work anyway. I always change all my variable names before submitting the work.
Reply
#4
GPIO works just fine with tkinter. The only thing you cannot do is use forever loops or sleep(), and those can be replaced by using after() and some state logic. In your most recent program you don't even need that.
Reply
#5
Quote:GPIO is tough to use with Tkinter. But thats the project and i have to live with that. Its just a first draft the variable name will change. Led or Salon_led its got to work anyway. I always change all my variable names before submitting the work.
That is goofy! If you used good variable names in the first place you would have less clean up work at the end. More importantly you would have informative names helping you do your work.
ndc85430 likes this post
Reply
#6
Hello,

I did some change.
In Def() Histo: why ct variable wont appear?
Lumière salon fermée:-", ct, but Lumière salon fermée: will.
Thank you

from tkinter import *
import datetime
ct = datetime.datetime.now()
from RPiSim import GPIO
from time import sleep
import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt 
from random import randrange, uniform
from time import sleep
#import pymongo
Ent= 22
Sal=18

#client = pymongo.MongoClient("localhost")
#db = client.Timestamp.py

#collection = db.alarmes


mqttBroker ="mqtt.eclipseprojects.io"
client = mqtt.Client("Alarme_Interieur")
client.connect(mqttBroker) 
  
root = Tk()
root.title('Ma console')  
root.geometry('430x800')
  
title = Label(root, text="Alarme", bg="grey", font=("bold", 20))
title.pack()
c = Canvas(root, width=330, height=160, bg="grey")
c.place(x=50, y=50)

def AlarmeOn():
    Label(root, text="On", bg="red", font=("bold", 20)).place(x = 190, y = 210)
    print("Alarme armée:-", ct)
    client.publish("ALARME", str(ct))
    print("Publication message" + str(ct) + "Alarme armée")
    #time = {"Alarme armée": str(ct)}
    #print(collection.insert_one(time).inserted_id)

btn = Button(root, text='On', width=10,
             height=5, bd='10', command = AlarmeOn)

def AlarmeOff():
   Label(root, text="Off", bg="red", font=("bold", 20)).place(x = 190, y = 210)
   print("Alarme désarmée:-", ct)
   client.publish("ALARME", str(ct))
   print("Publication message" + str(ct) + "Alarme déssarmée")
    
btn1 = Button(root, text='Off', width=10,
             height=5, bd='10', command = AlarmeOff)
 
btn.place(x=65, y=70)
btn1.place(x=225, y=70)


#2e paire de boutons

c1 = Canvas(root, width=330, height=200, bg="grey")
c1.place(x=50, y=250)

def EntOn():
   Label(root, text="On", bg="red", font=("bold", 20)).place(x = 190, y = 420)
   GPIO.setmode(GPIO.BCM)
   GPIO.setup(Ent,GPIO.OUT)
   GPIO.setwarnings(False)
   GPIO.output(Ent,GPIO.HIGH)
   print("Pin 22 - HIGH")
   GPIO.cleanup()
    #print("Lumière entrée allumée:-", ct)
    #client.publish("ALARME", str(ct))
    #print("Publication message" + str(ct) + "Alarme entrée")

btn2 = Button(root, text='On', width=10,
             height=5, bd='10', command = EntOn)

def EntOff():
   Label(root, text="Off", bg="red", font=("bold", 20)).place(x = 190, y = 420)
   print("Lumière entrée fermée:-", ct)
   client.publish("ALARME", str(ct))
   print("Publication message" + str(ct) + "Alarme entrée off")

btn3 = Button(root, text='Off', width=10,
             height=5, bd='10', command = EntOff)
 
btn2.place(x=65, y=300)
btn3.place(x=225, y=300)
title1 = Label(root, text="Lumière entrée", bg="grey", font=("bold", 20)).place(x = 110, y = 255)
#title1.pack() 
  
#3e paire de boutons

c2 = Canvas(root, width=330, height=280, bg="grey")
c2.place(x=50, y=450)

def SalonOn():
   Label(root, text="On", bg="red", font=("bold", 20)).place(x = 190, y = 620)
   GPIO.setmode(GPIO.BCM)
   GPIO.setup(Sal,GPIO.OUT)
   GPIO.setwarnings(False)
   GPIO.output(Sal,GPIO.HIGH)
   print("Pin 22 - HIGH")
   GPIO.cleanup()
   print("Lumière salon allumée:-", ct)
   client.publish("ALARME", str(ct))
   print("Publication message" + str(ct) + "Alarme Salon On")

btn4 = Button(root, text='On', width=10,
             height=5, bd='10', command = SalonOn)

def SalonOff():
    Label(root, text="Off", bg="red", font=("bold", 20)).place(x = 190, y = 620)
    print("Lumière salon fermée:-", ct)
    client.publish("ALARME", str(ct))
    print("Publication message" + str(ct) + "Alarme Salon Off")

btn5 = Button(root, text='Off', width=10,
             height=5, bd='10', command = SalonOff)
 
btn4.place(x=65, y=500)
btn5.place(x=225, y=500)
title2 = Label(root, text="Lumière salon", bg="grey", font=("bold", 20)).place(x = 110, y = 460)
#title2.pack()
  
  
#3e Bouton historique

c3 = Canvas(root, width=330, height=280, bg="grey")
c3.place(x=50, y=650)

def Histo():
     root = Toplevel()
     root.title('Historique')  
     root.geometry('630x450')
     resultat = Text(root)
     #resultat.config(width=630, height = 450)
     resultat.insert(INSERT, "Date\tHeure\tÉvènement\n===========================\n")
     #db.name
     #db.list_collection_names()
     #for item in db.alarmes.find():
     #if EntOn():
     resultat.insert(INSERT, "Lumière salon fermée:-",  ct)
     resultat.grid(row = 0, column = 0, columnspan = 2)
     bouton = Button(root, text = "Quitter", command = root.destroy)
     bouton.grid(row = 1, column = 1)
     
     
     
btn6 = Button(root, text='Afficher', width=28,
             height=3, bd='10', command = Histo)
 
btn6.place(x=65, y=700)
title3 = Label(root, text="Historique", bg="grey", font=("bold", 20)).place(x = 150, y = 660)
#title3.pack()
    
 
root.mainloop()
Reply
#7
You cannot insert multiple strings that way. You can insert multiple strings separated by tag lists. This is one way you can highlight, underline, change font, etc of portions of the text. What you should do is concatenate the strings so you are inserting one string.
Reply
#8
I am trying to test if EntOn() == True: than resultat.insert(INSERT, "Lumière salon fermée:-" + str(ct))
but when i click Historique Entree is ON and should not be and timestamp wont show up in the window if i click entree On.
I tried with EntOn = False and if EntOn() == True:
Any suggestions?

Also is there a way to test the mongodb part of my script online?
I am using the rasbian but pymongo return error type cant find pymongo when it is actually installed. I tried with ubuntu online but its not working and i am unable to install a virtual machine on my pc. I guess ill have to ask a collegue.
Reply
#9
EntOn() does not have a return, so by default it returns None. None does not equal True or False. None is false-ey, so it acts like False when used in an if statement, but it is not False (because they are different objects) and it does not equal False (because they are different types (None is class NoneType, False is class bool).

EntOn = False assigns EntOn to reference the object False. Now EntOn is False and cannot be used to call the function EntOn(). It is like you deleted the function from the program. It can no longer be used.
def EntOn():
    pass

print("EntOn", EntOn, type(EntOn), id(EntOn))
print("EntOn()", EntOn(), type(EntOn()), id(EntOn()))

EntOn = False
print("EntOn = False", EntOn, False, id(EntOn), id(False))

print("Call EntOn")
EntOn()
Output:
EntOn <function EntOn at 0x000001C713F108B0> <class 'function'> 1954544683184 EntOn() None <class 'NoneType'> 140735532587136 EntOn = False False False 140735532537712 140735532537712 Call EntOn Traceback (most recent call last): File "c:/Users/djhys/Documents/python/musings/junk.py", line 11, in <module> EntOn() TypeError: 'bool' object is not callable
From the program output you can see that EntOn starts out as a function and calling the function returns None. After assigning EntOn = False, EntOn is now the object False (They have the same object ID which means they are the same object). Now that EntOn is the same as False, calling EntOn() is the same as calling False().
Reply
#10
Ok i understand there is no argument and my func is type none.
but trying this leads nowhere either it will produce the opposite.
if EntOn() is None:
        resultat.insert(INSERT, "Lumi�re salon ferm�e:-" + str(ct))
Nothing is pass in (). The function is like a wrapper. Click On will only execute what's in the function. The idea is to test if what's in the function is executed than execute if statement. What you seem to say is it is irrelevant if its true , false or none.

EDIT:

ok i tried this:

def EntOn():
   EntOn.has_been_called = True
   Label(root, text="On", bg="red", font=("bold", 20)).place(x = 190, y = 420)
   GPIO.setmode(GPIO.BCM)
   GPIO.setup(Ent,GPIO.OUT)
   GPIO.setwarnings(False)
   GPIO.output(Ent,GPIO.HIGH)
   print("Pin 22 - HIGH")
   GPIO.cleanup()
    #print("Lumi�re entr�e allum�e:-", ct)
    #client.publish("ALARME", str(ct))
    #print("Publication message" + str(ct) + "Alarme entr�e")
EntOn.has_been_called = False
Than:
 if EntOn.has_been_called:
        resultat.insert(INSERT, "Lumi�re salon ferm�e:-" + str(ct))
Only one bug, it appears one time in the historique window. Seem if i push 10 times the button On i get only one output.
i cant understand either why the timestamp output the same time. Like 14:09:02, if i click 5 seconds later if should show 14:09:07
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pyautogui with a display emulator? gumby4231 0 2,550 Jul-30-2020, 02:46 PM
Last Post: gumby4231
  running python script from shell invoked with os.system("x-terminal-emulator -e /bin/ markhaus 2 3,017 Feb-21-2019, 11:55 PM
Last Post: markhaus

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020