Skip to content

Commit 917f044

Browse files
authored
Merge pull request #886 from DaveNeudoerffer/MQTT_cleanup
More cleanup of debug and logging. Added ability to statically decla…
2 parents 4b25f57 + d926b57 commit 917f044

File tree

3 files changed

+85
-34
lines changed

3 files changed

+85
-34
lines changed

lib/mqtt.pm

+16-9
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ my $msg_id = 1;
195195
my $blocking_read_timeout = .5;
196196

197197
my %MQTT_Data;
198+
my $init_global_v_cmd = 0;
198199

199200
# $main::Debug{mqtt} = 0;
200201

@@ -1049,17 +1050,24 @@ sub get_voice_cmds {
10491050

10501051
#a bit of a kludge to pass along the voice command option, get the said value from the voice command.
10511052
my $object_name = $self->get_object_name();
1053+
my %global_voice_cmds = (
1054+
"<global> -- List all mqtt interfaces to the print log" => "&mqtt::print_interface_list()",
1055+
"<global> -- Publish current states of all local items" => "&mqtt_LocalItem::publish_current_states()",
1056+
"<global> -- Write all discovered items to <data_dir>/mqtt_discovered_items.mht.gen" => "&mqtt::write_discovered_items( '$::config_parms{data_dir}/mqtt_discovered_items.mht.gen' )",
1057+
);
10521058
my %voice_cmds = (
1053-
"List all mqtt interfaces to the print log" => "${object_name}->print_interface_list()",
1054-
"List retained topics for $command" => "${object_name}->list_retained_topics()",
1055-
"Publish discovery data for $command" => "${object_name}->publish_discovery_data()",
1056-
"Publish current states of all local items" => "mqtt_LocalItem::publish_current_states()",
1057-
"Cleanup discovery info on $command and republish" => "${object_name}->cleanup_discovery_topics()",
1058-
"Cleanup all retained topics on mqtt server $command and republish (BE CAREFUL)" => "${object_name}->cleanup_all_retained_topics()",
1059-
"Write all discovered items to <data_dir>/mqtt_discovered_items.mht.gen" => "&mqtt::write_discovered_items( '$::config_parms{data_dir}/mqtt_discovered_items.mht.gen' )",
1059+
"$command -- List retained topics" => "${object_name}->list_retained_topics()",
1060+
"$command -- Publish discovery data" => "${object_name}->publish_discovery_data()",
1061+
"$command -- Publish current states of local items" => "${object_name}->publish_current_states()",
1062+
"$command -- Cleanup discovery info and republish" => "${object_name}->cleanup_discovery_topics()",
1063+
"$command -- Cleanup all retained topics on mqtt server and republish (BE CAREFUL)" => "${object_name}->cleanup_all_retained_topics()",
10601064
# 'List [all,active,inactive] ' . $command . ' objects to the print log' => $self->get_object_name . '->print_object_list(SAID)',
10611065
# "Print $objects $command attributes to the print log" => "${object_name}->print_object_attrs(SAID)",
10621066
);
1067+
if( $init_global_v_cmd == 0 ) {
1068+
$init_global_v_cmd = 1;
1069+
%voice_cmds = (%global_voice_cmds, %voice_cmds);
1070+
}
10631071

10641072
return \%voice_cmds;
10651073
}
@@ -1070,13 +1078,12 @@ sub get_voice_cmds {
10701078
=cut
10711079

10721080
sub print_interface_list {
1073-
my ($self) = @_;
10741081
my @interfaces;
10751082

10761083
for my $inst (keys %MQTT_Data) {
10771084
push @interfaces, $MQTT_Data{$inst}{self}->{instance};
10781085
}
1079-
$self->log( "MQTT interface list: " . join( ',', @interfaces ) );
1086+
&mqtt::log( undef, "MQTT interface list: " . join( ',', @interfaces ) );
10801087
}
10811088

10821089
=item C<(get_interface_list())>

lib/mqtt_discovery.pm

+41-19
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,30 @@ sub new { #### mqtt_DiscoveredItem
7070
my $self;
7171
my $short_disc_topic;
7272
my $mqtt_type;
73+
my $disc_prefix;
74+
my $disc_type;
75+
my $node_id;
76+
my $device_id;
7377

7478

75-
my ($disc_prefix, $disc_type, $realm, $device_id) = $disc_topic =~ m|^(.*)/([^/]*)/([^/]+)/([^/]+)/config$|;
76-
if( $disc_prefix ) {
77-
$short_disc_topic = "$disc_type/$realm/$device_id/config";
78-
} else {
79-
($disc_prefix, $disc_type, $device_id) = $disc_topic =~ m|^(.*)/([^/]+)/([^/]+)/config$|;
80-
if( !$disc_prefix ) {
81-
$disc_obj->error( "UNRECOGNIZED DISCOVERY MESSAGE -- can't parse: $disc_topic" );
82-
return;
79+
if( $disc_topic =~ m|.*/.*| ) {
80+
($disc_prefix, $disc_type, $node_id, $device_id) = $disc_topic =~ m|^(.*)/([^/]*)/([^/]+)/([^/]+)/config$|;
81+
if( $disc_prefix ) {
82+
$short_disc_topic = "$disc_type/$node_id/$device_id/config";
83+
} else {
84+
($disc_prefix, $disc_type, $device_id) = $disc_topic =~ m|^(.*)/([^/]+)/([^/]+)/config$|;
85+
if( !$disc_prefix ) {
86+
$disc_obj->error( "UNRECOGNIZED DISCOVERY MESSAGE -- can't parse: $disc_topic" );
87+
return;
88+
}
89+
$short_disc_topic = "$disc_type/$device_id/config";
8390
}
84-
$short_disc_topic = "$disc_type/$device_id/config";
91+
} elsif( $disc_topic ) {
92+
$disc_type = $disc_topic;
93+
$short_disc_topic = '';
94+
} else {
95+
$disc_obj->error( "UNRECOGNIZED DISCOVERY MESSAGE -- discovery topic not valid: $disc_topic" );
96+
return;
8597
}
8698

8799
my $disc_info;
@@ -117,7 +129,7 @@ sub new { #### mqtt_DiscoveredItem
117129
}
118130
}
119131
if( $#listentopics < 0 ) {
120-
$disc_obj->error( "UNRECOGNIZED DISCOVERY MESSAGE -- no topic: $disc_topic -- M:'$disc_msg" );
132+
$disc_obj->error( "UNRECOGNIZED DISCOVERY MESSAGE -- no listen topic: M:'$disc_msg" );
121133
return;
122134
}
123135

@@ -129,12 +141,14 @@ sub new { #### mqtt_DiscoveredItem
129141
if( $obj->{is_local} ) {
130142
$disc_obj->debug( 1, "Ignoring discovery message received for local object: " . $obj->{local_item}->get_object_name );
131143
} else {
132-
if( $short_disc_topic eq $obj->{disc_topic} ) {
144+
if( !$obj->{disc_topic} ) {
145+
# object explicitly declared
146+
$disc_obj->debug( 1, "Discovery message received for unique_id:($unique_id) for object that was explicitly created: " . $obj->get_object_name );
147+
} else {
133148
$disc_obj->debug( 1, "Discovery message received for unique_id:($unique_id) for object that already exists: " . $obj->get_object_name );
134149
# Update the discover message so that if discovered items are written out, they get the new ones
135150
$obj->{disc_msg} = $disc_msg;
136-
} else {
137-
$disc_obj->error( "Discovery message received for unique_id:$unique_id, but topics don't match" );
151+
$obj->{disc_topic} = $short_disc_topic;
138152
}
139153
}
140154
$found = 1;
@@ -146,9 +160,13 @@ sub new { #### mqtt_DiscoveredItem
146160
$attr = 'object_id';
147161
}
148162
if( $obj->{disc_info}->{$attr} eq $disc_info->{$attr} ) {
149-
# Note that Home Assistant matches discovery objects up based on friendly name -- report error on duplicate friendly names
150-
$disc_obj->error( "Discovery message received for friendly_name ($disc_info->{$attr}) that already exists" );
151163
$found = 1;
164+
if( $obj->{discoverable} || $obj->{mqtt_dynamic} ) {
165+
# Note that Home Assistant matches discovery objects up based on friendly name -- report error on duplicate friendly names
166+
$disc_obj->error( "Discovery message received for friendly_name ($disc_info->{$attr}) that already exists" );
167+
} else {
168+
$disc_obj->debug( 1, "Discovery message received for friendly_name ($disc_info->{$attr}) that has already been locally declared -- ignoring" );
169+
}
152170
}
153171
}
154172
}
@@ -158,9 +176,9 @@ sub new { #### mqtt_DiscoveredItem
158176

159177
# create local MH object
160178
$obj_name = 'mqttd_';
161-
if( $realm ) {
162-
# $realm helps to identify the device
163-
$obj_name .= "${realm}_";
179+
if( $node_id ) {
180+
# $node_id helps to identify the device
181+
$obj_name .= "${node_id}_";
164182
}
165183
if( $disc_info->{name} ) {
166184
$obj_name .= $disc_info->{name};
@@ -188,7 +206,11 @@ sub new { #### mqtt_DiscoveredItem
188206
$self->{disc_prefix} = $disc_prefix;
189207
$self->{disc_msg} = $disc_msg;
190208
$self->{disc_obj} = $disc_obj;
191-
$self->{discovered} = 1;
209+
if( $short_disc_topic ) {
210+
$self->{discovered} = 1;
211+
} else {
212+
$self->{discovered} = 0;
213+
}
192214

193215
$self->debug( 1, "New mqtt_DiscoveredItem( \$$disc_obj->{mqtt_name}, '$name', '$disc_topic', '$disc_msg' )" );
194216

lib/mqtt_items.pm

+28-6
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ Description:
105105
106106
mqtt_InstMqttItem
107107
- implements a statically defined mh item for Insteon devices managed
108-
by insteon-mqtt
108+
by insteon-mqtt OR another instance of MisterHouse (since the MH published
109+
MQTT messages are based on insteon-mqtt). You could also use discovered items
110+
for this purpose.
109111
- see https://github.com/TD22057/insteon-mqtt
110112
- can publish HA discovery info, as insteon-mqtt does not implement discovery yet
111113
@@ -152,6 +154,12 @@ Description:
152154
- I have implemented these devices based on HomeAssistant documentation
153155
for discovery and information on blakaddr.com
154156
- In order to implement this properly, we would need a templating engine in perl
157+
158+
You can move one of the items from the file written out by write_discovered_items, or
159+
you could hand code an item of this type using a full discovery message. When you are
160+
hand declaring an mqtt item using this format, change the discovery_topic to just
161+
the discovery_type -- that will internally mark it so that it is not written out
162+
next time write_discovered_items is called.
155163
156164
mqtt_Discovery:
157165
This class has 2 functions. The discovery_action parameter defines which ones
@@ -196,6 +204,7 @@ Usage:
196204
# MQTT_DISCOVERY, obj name, discovery prefix, broker, publish|subscribe|both (default both)
197205
MQTT_DISCOVERY, mqtt_discovery1, homeassistant, mqtt_1, both
198206
207+
199208
###################################################
200209
# Different Item types for different types of MQTT functionality
201210
#
@@ -204,21 +213,26 @@ Usage:
204213
# - It helps identify your own discovery messages in a large mqtt system
205214
###################################################
206215
207-
# Used to define mqtt items as published by insteon-mqtt project
216+
# Used to define mqtt items as published by insteon-mqtt project or as published
217+
# by another instance of MisterHouse which has defined MQTT_LOCALITEMs.
218+
#
208219
# MQTT_INSTMQTT, name, groups, broker, type, topicpattern, discoverable Friendly Name
209220
MQTT_INSTMQTT, bootroom_switch, Lights, mqtt_1, switch, insteon/bootroom/+, 1, Bootroom Light
210221
211222
# Define a Tasmota item. Note that the topicpattern must be in the order that the device will
212223
# send. This is configured in the Tasmota MQTT configuration.
224+
#
213225
# MQTT_REMOTEITEM, name, groups, broker, type, topicpattern, discoverable Friendly Name
214226
MQTT_REMOTEITEM, tas_outdoor_plug, , mqtt_1, switch, tasmota_outdoor_plug/+/+, 0, Tasmota Outdoor Plug
215227
216228
217229
# Say you have a local INSTEON item (could be any kind of misterhouse item)
218230
INSTEON_SWITCHLINC, 52.9E.DD, shed_light, Lights|Outside
219231
#
220-
# Then you can create an mqtt item to publish its state and receive mqtt commands
232+
# Then you can create an mqtt item to publish its state and receive mqtt commands.
221233
# TopicPattern should be of the form "<node_id>/<mqtt name>/+".
234+
# *** This can be used to publish local MH items to Home Assistant.
235+
#
222236
# MQTT_LOCALITEM, name, local item, broker, type, topicpattern, discoverable Friendly Name
223237
MQTT_LOCALITEM, bootroom_switch, shed_light, mqtt_1, switch, insteon/bootroom/+, 1, Bootroom Light
224238
#
@@ -227,9 +241,17 @@ Usage:
227241
228242
.mht generated file:
229243
230-
# Discovery items are generated by the write_discovered_items function
231-
# You would not normally code these by hand
232-
# MQTT_DISCOVEREDITEM, name, discovery_obj, discovery_topic, discovery_message
244+
# Discovery items are generated by the write_discovered_items function.
245+
# You would not normally code these by hand.
246+
#
247+
# But if you want to move an item to your regular .mht file, change the discovery_topic to just
248+
# the discovery_type. That then will override any discovered item with the same unique_id,
249+
# and will not be written out with write_discovered_items.
250+
#
251+
# You could code one of these items by hand. This would also allow you to declare a remote
252+
# mqtt item using the full discovery message format.
253+
#
254+
# MQTT_DISCOVEREDITEM, name, discovery_obj, discovery_topic/discovery_type, discovery_message
233255
MQTT_DISCOVEREDITEM, mqtt_tasmota_outdoor_plug, mqtt_discovery, homeassistant/switch/877407_RL_1/config, {"name":"Tasmota Outside Plug","cmd_t":"~cmnd/POWER","stat_t":"~tele/STATE","val_tpl":"{{value_json.POWER}}","pl_off":"OFF","pl_on":"ON","avty_t":"~tele/LWT","pl_avail":"Online","pl_not_avail":"Offline","uniq_id":"877407_RL_1","device":{"identifiers":["877407"],"connections":[["mac","D8:F1:5B:87:74:07"]]},"~":"tasmota_outdoor_plug/"}
234256
235257

0 commit comments

Comments
 (0)