Skip to content

Latest commit

 

History

History
139 lines (112 loc) · 6.96 KB

FB_OUTPUT_BINARY_MQTT.md

File metadata and controls

139 lines (112 loc) · 6.96 KB

FB_OUTPUT_BINARY_MQTT

MQTT Discovery

General

Can be switched using pulses that are high for one clock cycle (for example from FB_INPUT_PUSHBUTTON_MQTT), maintains output state through powercycles.

Block diagram

INPUT(S)

  • TOGGLE: when high the output OUT gets toggled. input should one be high for one clockcycle.
  • PRIO_HIGH: when high the output OUT is set to high, has priority over the TOGGLE and PRIO_LOW input.
  • PRIO_LOW: when high the output OUT is set to low, has priority over the TOGGLE input.

OUTPUT(S)

  • OUT: output to switch digital output on and off. Can be connected to a relay for example.

METHOD(S)

  • InitMQTT: enables MQTT events on the FB, an overview of the parameters:

    • MQTTPublishPrefix: datatype POINTER TO STRING, pointer to the MQTT publish prefix that should be used for publishing any messages/events for this FB. Suffix is automatically set to FB name.
    • MQTTSubscribePrefix: datatype POINTER TO STRING, pointer to the MQTT subscribe prefix that should be used for publishing any messages/events to this FB. Suffix is automatically set to FB name.
    • pMqttPublishQueue: datatype POINTER TO FB_MqttPublishQueue, pointer to the MQTT queue to publish messages.
    • pMqttCallbackCollector: datatype SD_MQTT.CallbackCollector, pointer to the MQTT callback collector, required to register FB for subscriptions on a certain topic.
  • PublishReceived: callback method called by the callbackcollector when a message is received on the subscribed topic by the callbackcollector.

MQTT Event Behaviour

Requires method call InitMQTT to enable MQTT capabilities.

Event Description MQTT payload QoS Retain flag Published on startup
Output changes: OUT A change is detected on output OUT. TRUE/FALSE 2 TRUE yes

MQTT publish topic is a concatination of the publish prefix and the function block name.

MQTT Subscription Behaviour

Requires method call InitMQTT to enable MQTT capabilities. Commands are executed by the FB if the topic MQTTSubscribeTopic matches the MQTT topic and the payload exists in the table below.

Command Description expected payload Additional notes
Change output to high Request to change output to high. TRUE Command executed when PRIO_HIGH and PRIO_LOW inputs are low.
Change output to low Request to change output to low. FALSE Command executed when PRIO_HIGH and PRIO_LOW inputs are low.

MQTT subscription topic is a concatenation of the subscribe prefix variable and the function block name.

Code example

  • variables initiation:
MQTTPubSwitchPrefix     :STRING(100) := 'Devices/PLC/House/Out/DigitalOutputs/';
MQTTSubSwitchPrefix     :STRING(100) := 'Devices/PLC/House/In/DigitalOutputs/';
FB_DO_SW_001            :FB_OUTPUT_BINARY_MQTT;
  • Init MQTT method call (called once during startup):
FB_DO_SW_001.InitMQTT(MQTTPublishPrefix:= ADR(MQTTPubSwitchPrefix),                 (* pointer to string prefix for the MQTT publish topic *)
    MQTTSubscribePrefix:= ADR(MQTTSubSwitchPrefix),                                 (* pointer to string prefix for the MQTT subscribe topic *)
    pMQTTPublishQueue := ADR(MQTTVariables.fbMQTTPublishQueue),                     (* pointer to MQTTPublishQueue to send a new MQTT event *)
    pMQTTCallbackCollector := ADR(MQTTVariables.collector_FB_OUTPUT_BINARY_MQTT)    (* pointer to CallbackCollector to receive MQTT subscription events *)
);

The MQTT publish topic in this code example will be Devices/PLC/House/Out/DigitalOutputs/FB_DO_SW_001 (MQTTPubSwitchPrefix variable + function block name). The subscription topic will be Devices/PLC/House/In/DigitalOutputs/FB_DO_SW_001 (MQTTSubSwitchPrefix variable + function block name).

  • checking for events to switch the digital output (cyclic):
FB_DO_SW_001(OUT=>  DO_001,                 (* couple the function block to the physical output *)
    PRIO_HIGH:=     FALSE,                  (* brings the output high regardless of other input values *)
    PRIO_LOW:=      FALSE                   (* brings the output low regardless of other input values. NOTE: Priohigh overrules Priolow input *)
    TOGGLE:=        FB_DI_PB_009.SINGLE     (* for toggling the output *)	
);
  • integration with FB_INPUT_PUSHBUTTON_MQTT:
FB_DO_SW_001(OUT=>  DO_001,                 (* couple the function block to the physical output *)
    PRIO_HIGH:=     FALSE,                  (* brings the output high regardless of other input values *)
    PRIO_LOW:=      FALSE,                  (* brings the output low regardless of other input values. NOTE: Priohigh overrules Priolow input *)
    TOGGLE:=        FB_DI_PB_001.SINGLE     (* for toggling the output *)	
);
  • MQTT discovery (choose one):
(* switch entity *)
FB_DO_SW_001.InitMqttDiscoveryAsSwitch(
	Name := 'switch 001',			        (* The name show in Home Assistant frond-end*)
	Device := ADR(PLC_DEVICE),				(* The device show in Home Assistant *)
);

(* light entity *)
FB_DO_SW_001.InitMqttDiscoveryAsLight(
	Name := 'light 001',			        (* The name show in Home Assistant frond-end*)
	Device := ADR(PLC_DEVICE),				(* The device show in Home Assistant *)
);

(* siren entity *)
FB_DO_SW_001.InitMqttDiscoveryAsSiren(
	Name := 'siren 001',			        (* The name show in Home Assistant frond-end*)
	Device := ADR(PLC_DEVICE),				(* The device show in Home Assistant *)
);

(* lock entity *)
FB_DO_SW_001.InitMqttDiscoveryAsLock(
	Name := 'lock 001',			            (* The name show in Home Assistant frond-end*)
	Device := ADR(PLC_DEVICE),				(* The device show in Home Assistant *)
);

By default a 'NO' (Normally Open) contact is asumed for MQTT discovery yet this can be inverted to a 'NC' (Normally Closed) contact by leveraging the 'Invert' parameter:

FB_DO_SW_001.InitMqttDiscoveryAsLock(
	Name := 'lock 001',			            (* The name show in Home Assistant frond-end*)
	Device := ADR(PLC_DEVICE),				(* The device show in Home Assistant *)
    Invert := TRUE                          (* FALSE by default = NO, TRUE = NC *)
);

Home Assistant YAML

If MQTT discovery is not working for you, you can use the YAML code below in your MQTT lights config:

mqtt:
  light:
  - name: "FB_DO_SW_001"
    state_topic: "Devices/PLC/House/Out/DigitalOutputs/FB_DO_SW_001"
    command_topic: "Devices/PLC/House/In/DigitalOutputs/FB_DO_SW_001"
    payload_on: "TRUE"
    payload_off: "FALSE"
    qos: 2
    optimistic: false
    availability_topic: "Devices/PLC/House/availability"
    payload_available: "online"
    payload_not_available: "offline"