PiFace Digital Not Supported Yet


#21

Here it is! I’ll make a project post in the next couple days with all the how to stuff. You will have to create the widgets on your MQTT dashboard for this to work. Digital outputs can be created using add new>device/widget>custom widgets>button and the digital inputs can be created using add new>device/widget>custom widgets>2 state. Digital outputs are channel 0-7 and digital inputs are channel 8-14

import paho.mqtt.client as mqtt
import time
import sys
import pifacedigitalio

#time.sleep(30) #Sleep to allow wireless to connect before starting MQTT

#set up user info
username = "username from mqtt dashboard"
password = "password from mqtt dashboard"
clientid = "clientid from mqtt dashboard"

#handle incoming messages from Cayenne
def on_message(client, userdata, message):
    #print("Received message '" + str(message.payload) + "' on topic '" + message.topic + "' with QoS " + str(message.qos)) #uncomment to print recieved message
    updatevaluetopic = str(message.topic.rsplit('/',2)[0]) + "/data/" + str(message.topic.rsplit('/',2)[2]) #topic to send updated value to dashboard
    commandresponsetopic = str(message.topic.rsplit('/',2)[0]) + "/response" #topic to send response to dashboard
    try: #if there is an error let Cayenne know about it
        pfd.output_pins[int(message.topic.rsplit('/',2)[2])].value = int(message.payload.split(',')[1]) #set output to the value recieved
        updatevalue = message.payload.split(',')[1] #set value to send back to dashboard
        mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send back the value that was recieved to update the dashboard widget
        commandresponse = "ok," + str(message.payload.split(',')[0]) #set the response to send back to the dasboard
        mqttc.publish(commandresponsetopic, payload=commandresponse, retain=True) #send response to the dashboard
    except:
        commandresponse = "error," + str(message.payload.split(',')[0])
        mqttc.publish(topic, payload=commandresponse, retain=True)

#handle falling events
def updatedashboardfalling(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=1" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#handle rising events
def updatedashboardrising(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=0" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#Set up PiFace Digital
pifacedigitalio.init()
pfd = pifacedigitalio.PiFaceDigital()

#set up MQTT
mqttc = mqtt.Client(client_id=clientid)
mqttc.username_pw_set(username, password=password)
mqttc.connect("mqtt.mydevices.com", port=1883, keepalive=60)
mqttc.loop_start()
mqttc.subscribe("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#")
mqttc.message_callback_add("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#", on_message)

#set up interrupts
listener = pifacedigitalio.InputEventListener(chip=pfd)
for i in range(4):
    listener.register(i, pifacedigitalio.IODIR_FALLING_EDGE, updatedashboardfalling)
    listener.register(i, pifacedigitalio.IODIR_RISING_EDGE, updatedashboardrising)
listener.activate()

while True:
    try:
        for i in range(8): #since interrupts can be unreliable send the actual value to the dashboard every 1 second as well
            updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(i + 8) #topic to send updated value to dashboard
            updatevalue = "digital,d=" + str(pfd.input_pins[i].value) #set value to send back to dashboard
            mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard
        time.sleep(1)
    except (EOFError, SystemExit, KeyboardInterrupt): #handle ctrl+c and reboots cleanly
        mqttc.disconnect()
        listener.deactivate()
        sys.exit()


PiFace 2 support
[RESOLVED] No change "2 state" widget esp8266
#22

Looks great.
I tried AddNew / Bring your own thing but without luck.
Seems like the tutorial videos are no longer up to date. Should I use Cayenne MQTT Python?

Also in Add new Device / Custom Widgets, I cannot select a Device


#23

Yep, leave your dashboard at the bring your own thing screen then copy/paste the username, password, client id there in to the python script I posted. Run the script and when the script makes a connection the screen with your user, pass, and client id will disappear and show you your dashboard. Once you are at this stage then you can add the custom widgets.

btw I didn’t use the Cayenne python MQTT library, I just used the standard paho library.


#24

Sorry - can’t get it to work.
Started python3
Pasted the code (with the pated, Uid,Pwd and clientID) but get the errors:
Traceback (most recent call last):
File “”, line 6, in
NameError: name ‘mqttc’ is not defined

Should I crate a file, make it executable or smoothing and maybe in a special directory.
Sorry for being such a rookie.


#25

Oh, you’ll have to install the MQTT library too. Use this command:

sudo pip install paho-mqtt
sudo pip3 install paho-mqtt (for python 3 if you need it)

Also, I’m not sure if you meant that you were using the command python3 and then pasting in that code or not but you will need to create a new file, say piface.py, paste in the code from above, and then run it using the command python piface.py


#26

Hi adam
I tried to follow your instructions and finally got able to control the two relays.
However. When pressing one of the four input ports 8-11 the state is not visible.
Furthermore when leaving the device on for some hours, it suddenly stops responding. (unable to control relais)
Is there a plan for when this solution will be added as a “normal” plug and play device? (I mean since it is present in the available devices - or am I misunderstanding this as well?)
Sorry for all the crazy questions.


#27

You can try to add it via the extension, I didn’t know it was there. It looks like the one that is available to add as an extension is a PiFace 1. From a quick read it looks like they are identical other than the 2 fits the b+ and newer models. Worth a shot to see if it works.


#28

This was my very first attempt when trying out Cayenne and I never got it to work.
Actually I thought Raspberry-PI+PiFaxe+Cayenne would be the perfect match for my project, controlling two relays and reading digital inputs. :disappointed_relieved:
According to @eptak on Dec. 2015 the Piface 1 and 2 should be supported.


#29

@wek I came back to this thread from another post and just now realized where the mistake is. Try the code below:

import paho.mqtt.client as mqtt
import time
import sys
import pifacedigitalio

#time.sleep(30) #Sleep to allow wireless to connect before starting MQTT

#set up user info
username = "username from mqtt dashboard"
password = "password from mqtt dashboard"
clientid = "clientid from mqtt dashboard"

#handle incoming messages from Cayenne
def on_message(client, userdata, message):
    #print("Received message '" + str(message.payload) + "' on topic '" + message.topic + "' with QoS " + str(message.qos)) #uncomment to print recieved message
    updatevaluetopic = str(message.topic.rsplit('/',2)[0]) + "/data/" + str(message.topic.rsplit('/',2)[2]) #topic to send updated value to dashboard
    commandresponsetopic = str(message.topic.rsplit('/',2)[0]) + "/response" #topic to send response to dashboard
    try: #if there is an error let Cayenne know about it
        pfd.output_pins[int(message.topic.rsplit('/',2)[2])].value = int(message.payload.split(',')[1]) #set output to the value recieved
        updatevalue = message.payload.split(',')[1] #set value to send back to dashboard
        mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send back the value that was recieved to update the dashboard widget
        commandresponse = "ok," + str(message.payload.split(',')[0]) #set the response to send back to the dasboard
        mqttc.publish(commandresponsetopic, payload=commandresponse, retain=True) #send response to the dashboard
    except:
        commandresponse = "error," + str(message.payload.split(',')[0])
        mqttc.publish(topic, payload=commandresponse, retain=True)

#handle falling events
def updatedashboardfalling(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=1" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#handle rising events
def updatedashboardrising(event):
    updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(event.pin_num + 8) #topic to send updated value to dashboard
    updatevalue = "digital,d=0" #set value to send back to dashboard
    mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard

#Set up PiFace Digital
pifacedigitalio.init()
pfd = pifacedigitalio.PiFaceDigital()

#set up MQTT
mqttc = mqtt.Client(client_id=clientid)
mqttc.username_pw_set(username, password=password)
mqttc.connect("mqtt.mydevices.com", port=1883, keepalive=60)
mqttc.loop_start()
mqttc.subscribe("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#")
mqttc.message_callback_add("v1/" + str(username) + "/things/" + str(clientid) + "/cmd/#", on_message)

#set up interrupts
listener = pifacedigitalio.InputEventListener(chip=pfd)
for i in range(4):
    listener.register(i, pifacedigitalio.IODIR_FALLING_EDGE, updatedashboardfalling)
    listener.register(i, pifacedigitalio.IODIR_RISING_EDGE, updatedashboardrising)
listener.activate()

while True:
    try:
        for i in range(8): #since interrupts can be unreliable send the actual value to the dashboard every 1 second as well
            updatevaluetopic = "v1/" + str(username) + "/things/" + str(clientid) + "/data/" + str(i + 8) #topic to send updated value to dashboard
            updatevalue = "digital,d=" + str(pfd.input_pins[i].value) #set value to send back to dashboard
            mqttc.publish(updatevaluetopic, payload=updatevalue, retain=True) #send value to dashboard
        time.sleep(1)
    except (EOFError, SystemExit, KeyboardInterrupt): #handle ctrl+c and reboots cleanly
        mqttc.disconnect()
        listener.deactivate()
        sys.exit()

PIFace Digital 2 + Raspberry PI 3
#30

Thanks for the info. I have a PiFace Digital 2. I can access it with the emulator while it’s connected to the Pi. I just haven’t found a way to control it using Cayenne. What you posted is for the original PiFace Digital. I don’t have one of those. Do you think what you posted will work for the PiFace Digital 2? Thanks again. Have a good weekend.


#31

Yep, that code is for a 2. If you scroll up a bit I have instructions for setting up the dashboard. For reference, this is the PiFace I have https://www.amazon.com/gp/product/B00PL4LO50/ref=oh_aui_search_detailpage?ie=UTF8&psc=1


#32

Great! Thank you.