-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
mqtt_messages_handler.rb
82 lines (69 loc) · 2.27 KB
/
mqtt_messages_handler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
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
class MqttMessagesHandler
def self.handle_topic(topic, message)
return if topic.nil?
# The following do NOT need a device
if topic.to_s.include?('inventory')
DeviceInventory.create({ report: (message rescue nil) })
elsif topic.to_s.include?('hello')
orphan_device = OrphanDevice.find_by(device_token: device_token(topic))
return if orphan_device.nil?
handle_hello(orphan_device)
end
device = Device.find_by(device_token: device_token(topic))
return if device.nil?
if topic.to_s.include?('raw')
handle_readings(device, parse_raw_readings(message))
elsif topic.to_s.include?('readings')
handle_readings(device, message)
elsif topic.to_s.include?('info')
device.update hardware_info: JSON.parse(message)
end
end
# takes a packet and stores data
def self.handle_readings(device, message)
data = self.data(message)
return if data.nil? or data&.empty?
data.each do |reading|
Storer.new(device, reading)
end
rescue Exception => e
Sentry.capture_exception(e)
#puts e.inspect
#puts message
end
# takes a raw packet and converts into JSON
def self.parse_raw_readings(message)
clean_tm = message[1..-2].split(",")[0].gsub("t:", "").strip
raw_readings = message[1..-2].split(",")[1..]
reading = { 'data' => ['recorded_at' => clean_tm, 'sensors' => []] }
raw_readings.each do |raw_read|
raw_id = raw_read.split(":")[0].strip
raw_value = raw_read.split(":")[1]&.strip
reading['data'].first['sensors'] << { 'id' => raw_id, 'value' => raw_value }
end
JSON[reading]
end
def self.handle_hello(orphan_device)
payload = {}
orphan_device.update(device_handshake: true)
payload[:onboarding_session] = orphan_device.onboarding_session
Redis.current.publish('token-received', payload.to_json)
end
# takes a packet and returns 'device token' from topic
def self.device_token(topic)
topic[/device\/sck\/(.*?)\//m, 1].to_s
end
# takes a packet and returns 'data' from payload
def self.data(message)
# TODO: what if message is empty?
if message
begin
JSON.parse(message)['data']
rescue JSON::ParserError
# Handle error
end
else
raise "No data(message)"
end
end
end