BrewBlox service for GPIO on Raspberry Pi

The docker ps entry for eventbus should include:

0.0.0.0:1883->1883/tcp

If it doesn’t, you may need to run docker-compose up -d to apply changes.

1 Like

Hello Bob,all,

I managed to subscribe to the Eventbus state messages as written some messages below. I am lost however on extracting the specific PID output setting for my Induction cooker. I am still a Python noob.

Here’s what I’ve been trying so far:

import paho.mqtt.client as mqtt
import json

The callback for when the client receives a CONNACK response from the server.

def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))

# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("brewcast/state/#")

The callback for when a PUBLISH message is received from the server.

Petty prints the Eventbus messages

def on_message(client, userdata, msg):
data = json.loads(msg.payload)
print(json.dumps(data, indent=6, separators=(". ", " = ")))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect(“192.168.188.45”, 1883, 60)

Blocking call that processes network traffic, dispatches callbacks and

handles reconnecting.

Other loop*() functions are available that give a threaded interface and a

manual interface.

client.loop_forever()

The output

many nested nids

The particular one I am looking for is mid :115

{
“nid” = 115.
“groups” = [
0
].
“type” = “Pid”.
“data” = {
“outputValue” = 100.0.
“outputSetting” = 100.0.
“enabled” = true.
“active” = true.
“p” = 118.2939453125.
“i” = 0.19677734375.
“d” = -0.1416015625.
“derivativeFilter” = “FILT_45s”.
“integralReset” = 0.0.
“boilMinOutput” = 0.0.
“boilModeActive” = false.
“derivative[delta_degC / minute]” = 0.005028252628567342.
“drivenOutputId<ActuatorAnalogInterface,driven>” = “PWMMockInduktion”.
“inputSetting[degC]” = 28.0.
“integral[delta_degC * hour]” = 0.0.
“inputId” = “SetpointInduktion”.
“boilPointAdjust[delta_degC]” = 0.0.
“td[second]” = 30.
“inputValue[degC]” = 25.96142578125.
“kp[1 / degC]” = 58.0.
“outputId” = “PWMMockInduktion”.
“error[delta_degC]” = 2.03955078125.
“ti[second]” = 600
}.
“id” = “PIDInduktion”
}.

So I’d like to obtain the outputValue value only, store it in a variable and push that into a separate MQTT topic for the MQTT device to subscribe to.

I am failing miserably on parsing the JSON file for that particular value. Any hint is highly appreciated.

Many thanks and best regards,
Steffen

SERVICE_ID = 'spark-one' # replace with the name of your spark service
PID_ID = 'PIDInduktion' # replace with string ID of desired PID
BLOCK_EVT = 'Spark.blocks' # const value

if not msg.payload:
    print('Discarding empty message')
    return

state = json.loads(msg.payload)
state_key = state['key']
state_type = state['type']

if state_key != SERVICE_ID or state_type != BLOCK_EVT:
    print(f'discarding state message: key={state_key} type={state_type}')
    return

# Find first block in list with correct ID
# Returns default value arg (None) if not found
blocks = state['data'] # list
pid = next((block for block in blocks if block['id'] == PID_ID), None)

if pid is None:
    print('PID not found in blocks')
    return

outputValue = pid['data']['outputValue']

For reference:

block[‘id’] is guaranteed to be unique. id and nid (numeric ID) exist because the Spark has very little persistent memory. We use 16 bit numbers as ID there, and the Spark service links those with user-defined string IDs.

Edit: forum posts allow code blocks by using triple backticks:

```
code goes here
```

This prevents ‘#’ comments being rendered as header.

1 Like

Hey Bob,

that worked ! :slight_smile:

Many Many thanks. I guess the rest is not difficult anymore.

I’ll report back soon.

Best regsrds,
Steffen

Best regards,
Steffen