Module: SDN::CLI::MQTT::Subscriptions
- Defined in:
- lib/sdn/cli/mqtt/subscriptions.rb
Overview
MQTT subscription handlers that translate inbound command messages into SDN commands.
Instance Method Summary collapse
-
#handle_message(topic, value) ⇒ void
Converts an MQTT command message into one or more queued SDN messages.
Instance Method Details
#handle_message(topic, value) ⇒ void
This method returns an undefined value.
Converts an MQTT command message into one or more queued SDN messages.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/sdn/cli/mqtt/subscriptions.rb', line 14 def (topic, value) SDN.logger.info "Got #{value.inspect} at #{topic}" unless (match = topic.match(%r{^#{Regexp.escape(@base_topic)}/ (?<addr>\h{6})/ (?<property>discover| label| control| jog-(?<jog_type>pulses|ms)| position-pulses| position-percent| ip| reset| (?<speed_type>up-speed|down-speed|slow-speed)| up-limit| down-limit| direction|i p(?<ip>\d+)-(?<ip_type>pulses|percent)| groups)/ set$}x)) return end addr = Message.parse_address(match[:addr]) property = match[:property] # not homie compliant; allows linking the position-percent property # directly to an OpenHAB rollershutter channel if property == "position-percent" && value =~ /^(?:UP|DOWN|STOP)$/i property = "control" value = value.downcase end mqtt_addr = Message.print_address(addr).delete(".") motor = @motors[mqtt_addr] is_group = Message.group_address?(addr) follow_up = if motor&.node_type == :st50ilt2 Message::ILT2::GetMotorPosition.new(addr) else Message::GetMotorStatus.new(addr) end ns = (motor&.node_type == :st50ilt2) ? Message::ILT2 : Message = case property when "discover" follow_up = nil if value == "discover" # discovery is low priority, and longer timeout enqueue(MessageAndRetries.new(Message::GetNodeAddr.new(addr), 1, 50)) end nil when "label" follow_up = Message::GetNodeLabel.new(addr) ns::SetNodeLabel.new(addr, value) unless is_group when "control" case value when "up", "down" ((motor&.node_type == :st50ilt2) ? ns::SetMotorPosition : Message::MoveTo) .new(addr, :"#{value}_limit") when "stop" if motor&.node_type == :st50ilt2 ns::SetMotorPosition.new(addr, :stop) else Message::Stop.new(addr) end when "next_ip" if motor&.node_type == :st50ilt2 ns::SetMotorPosition.new(addr, :next_ip_down) else Message::MoveOf.new(addr, :next_ip) end when "previous_ip" if motor&.node_type == :st50ilt2 ns::SetMotorPosition.new(addr, :next_ip_up) else Message::MoveOf.new(addr, :previous_ip) end when "wink" Message::Wink.new(addr) when "refresh" follow_up = nil ((motor&.node_type == :st50ilt2) ? ns::GetMotorPosition : Message::GetMotorStatus) .new(addr) end when /jog-(?:pulses|ms)/ value = value.to_i ((motor&.node_type == :st50ilt2) ? ns::SetMotorPosition : Message::MoveOf) .new(addr, :"jog_#{value.negative? ? :up : :down}_#{match[:jog_type]}", value.abs) when "reset" return unless Message::SetFactoryDefault::RESET.key?(value.to_sym) Message::SetFactoryDefault.new(addr, value.to_sym) when "position-pulses", "position-percent", "ip" if value == "REFRESH" follow_up = nil ((motor&.node_type == :st50ilt2) ? ns::GetMotorPosition : Message::GetMotorStatus) .new(addr) else ((motor&.node_type == :st50ilt2) ? ns::SetMotorPosition : Message::MoveTo) .new(addr, property.sub("position-", "position_").to_sym, value.to_i) end when "direction" return if is_group follow_up = Message::GetMotorDirection.new(addr) return unless %w[standard reversed].include?(value) Message::SetMotorDirection.new(addr, value.to_sym) when "up-limit", "down-limit" return if is_group if %w[delete current_position jog_ms jog_pulses].include?(value) type = value.to_sym value = 10 else type = :specified_position end target = (property == "up-limit") ? :up : :down follow_up = Message::GetMotorLimits.new(addr) Message::SetMotorLimits.new(addr, type, target, value.to_i) when /^ip\d-(?:pulses|percent)$/ return if is_group ip = match[:ip].to_i return unless (1..16).cover?(ip) follow_up = ns::GetMotorIP.new(addr, ip) if motor&.node_type == :st50ilt2 value = if value == "delete" nil elsif value == "current_position" motor.position_pulses elsif match[:ip_type] == "pulses" value.to_i else value.to_f / motor.down_limit * 100 end ns::SetMotorIP.new(addr, ip, value) else type = if value == "delete" :delete elsif value == "current_position" :current_position elsif match[:ip_type] == "pulses" :position_pulses else :position_percent end Message::SetMotorIP.new(addr, type, ip, value.to_i) end when "up-speed", "down-speed", "slow-speed" return if is_group return unless motor follow_up = Message::GetMotorRollingSpeed.new(addr) = Message::SetMotorRollingSpeed.new(addr, up_speed: motor.up_speed, down_speed: motor.down_speed, slow_speed: motor.slow_speed) .send(:"#{property.sub("-", "_")}=", value.to_i) when "groups" return if is_group return unless motor = motor.set_groups(value) @mutex.synchronize do .each { |m| @queue.push(MessageAndRetries.new(m, 5, 0)) } @cond.signal end nil end if motor && [Message::MoveTo, Message::Move, Message::Wink, Message::Stop].include?(.class) motor.last_action = .class motor.last_action_retries = 3 end return unless .ack_requested = true unless /^SDN::Message::Get/.match?(.class.name) @mutex.synchronize do @queue.push(MessageAndRetries.new(, 5, 0)) if follow_up && @queue.none? do |mr| mr. == follow_up end @queue.push(MessageAndRetries.new(follow_up, 5, 1)) end @cond.signal end end |