Files
JIMRI/jython/MQTT/SetMqttParser.py
T
2026-06-17 14:00:51 +02:00

116 lines
4.1 KiB
Python

# Example of how to install a new parser for the MQTT Turnouts
#
# This is also a sample JSON coder/decoder, just ensure PUBLISHJSON = True
#
# The script before should be run before loading the panels
# (use RUNAFTERPANELS = False to gain some time)
# or after the panel(s) are loaded and then use RUNAFTERPANELS = True
#
# Author: Bob Jacobsen, copyright 2019
# Author: Gert Jim Muller, copyright 2019
# Author: Dave McMorran, copyright 2019
#
import jmri
import java
import json
PUBLISHJSON = False # True:publish JSON, False:just the state
RUNAFTERPANELS = True # False to speed up (ms), but need script before panels
# True needed if Tunrouts are already loadedin the table
# First, create the parser class
class ParserReplacement( jmri.jmrix.mqtt.MqttContentParser ):
# Parse the payload as published by MQTT
def beanFromPayload( self, bean, payload, topic ):
# this needs code
print "from Broker. Bean", bean
print "with topic", topic
# Try JSON first
try:
json_payload = json.loads( payload )
except:
print "and text payload", payload
payload_state = payload
else:
print "and json payload", payload
try:
payload_state = json_payload["state"]
except:
payload_state = payload
# THROWN/CLOSED is the default behavior, here so you can modify it as desired
if ( payload_state == "THROWN" ) or ( payload_state == "1" ) or ( payload_state == 1 ):
bean.newKnownState( CLOSED if bean.getInverted( ) else THROWN )
elif ( payload_state == "CLOSED" ) or ( payload_state == "0" ) or ( payload_state == 0 ):
bean.newKnownState( THROWN if bean.getInverted( ) else CLOSED )
else:
bean.newKnownState( INCONSISTENT )
return
# Parse a change in the bean
def payloadFromBean( self, bean, newState ) :
# sort out states
print "from Bean", bean
print "with state", newState
# JSON, if set to True
if PUBLISHJSON :
data = {}
if ( not bean.getInverted( ) ) :
if ( newState & jmri.Turnout.CLOSED ) :
data['state'] = "CLOSED"
else:
data['state'] = "THROWN"
else :
if ( newState & jmri.Turnout.CLOSED ) :
data['state'] = "THROWN"
else:
data['state'] = "CLOSED"
json_data = json.dumps( data )
return json_data
# Without JSON - this is the same as the default behavior, here so you can modify it as desired
else:
if ( not bean.getInverted( ) ) :
if ( newState & jmri.Turnout.CLOSED ) :
return "CLOSED"
else :
return "THROWN"
else :
if ( newState & jmri.Turnout.CLOSED ) :
return "THROWN"
else :
return "CLOSED"
# Find the MqttTurnoutManager
m = jmri.InstanceManager.getNullableDefault( jmri.jmrix.mqtt.MqttTurnoutManager )
print "From InstanceManager as MqttTurnoutManager: ", m
if ( m is None ) :
# Might only have one connection,
mList = jmri.InstanceManager.getDefault( jmri.TurnoutManager ).getManagerList( )
#print mList
for m in mList:
if( isinstance( m, jmri.jmrix.mqtt.MqttTurnoutManager ) ):
break
m = None
#m = mList[1] # 1 is only appropriate if the MQTT connection is first configured in JMRI
print "From InstanceManager as TurnoutManager: ", m
# Install the Parser
if ( m is not None ) :
p = ParserReplacement( )
# install in Manager for all future-defined turnouts
m.setParser( p )
print( "ParserReplacement installed" )
# install in any turnouts that have already been created
if RUNAFTERPANELS :
for turnout in m.getNamedBeanSet( ) :
turnout.setParser( p )
else:
print( "ParserReplacement not installed" )