Class: MQTT::Persistence

Inherits:
Object
  • Object
show all
Defined in:
lib/mqtt/persistence.rb

Instance Method Summary collapse

Constructor Details

#initialize(mqtt, dir = "Persistence") ⇒ Persistence

Initialize the Persistence instance.

This will immediately connect and subscribe to the wildcard of `dir + "/#"`

Parameters:

  • mqtt (MQTT::SubHandler)

    The MQTT instance to use for storing/communication

  • dir (String) (defaults to: "Persistence")

    A valid MQTT topic string under which to nest the persistence.

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/mqtt/persistence.rb', line 17

def initialize(mqtt, dir = "Persistence")
	raise ArgumentError, "Not a mqtt class!" unless mqtt.is_a? MQTT::SubHandler

	@mqtt = mqtt;
	@dir  = dir;

	@rawData   = Hash.new();
	@paramList = Hash.new();

	@mqtt.subscribe_to "#{@dir}/+" do |data, key|
		_process_data(data, key[0].to_sym);
	end
end

Instance Method Details

#[](key) {|newData, oldData| ... } ⇒ Object Also known as: on_set

Read out a given, set-up key, returning ‘nil` if nothing has been read yet (or the value is nil right now), returning the data otherwise. If a block is given (using the on_set alias), this block will be added as a callback.

Parameters:

  • key (Symbol)

    The key to fetch. Must have been set up first!

Yield Parameters:

  • newData

    The newly parsed data (depending on the key’s type.)

  • oldData

    The former data that was present.

Raises:

  • (ArgumentError)


118
119
120
121
122
123
124
125
126
127
128
# File 'lib/mqtt/persistence.rb', line 118

def [](key, &callback)
	raise ArgumentError, "Key needs to be a symbol!" unless key.is_a? Symbol
	raise ArgumentError, "Key has not been set up!" unless @paramList.key? key;

	if(callback)
		@paramList[key][:cbList] << callback
		yield(@paramList[key][:current], nil) if @paramList[key][:current]
	end

	return @paramList[key][:current];
end

#[]=(key, data) ⇒ Object

Set a given key to a new value, provided the key has been set up. Will run the ‘on_change` and `on_set` callbacks immediately, then publish to MQTT.

Parameters:

  • key (Symbol)

    The key to write. Must have been set up first!

  • data (#to_json, #to_mqtt_string)

    The data to write.

Raises:

  • (ArgumentError)


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/mqtt/persistence.rb', line 135

def []=(key, data)
	raise ArgumentError, "Key needs to be a symbol!" unless key.is_a? Symbol
	raise ArgumentError, "Key has not been set up!" unless param = @paramList[key];

	newString = _prepare_send(data, key);
	return if @rawData[key] == newString;
	@rawData[key] = newString;

	if(param[:first])
		param.delete :first
		param[:cbList] = [param[:cbList], param[:change_cb]].flatten;
	end

	oldData = param[:current];
	param[:current] = data;
	param[:cbList].each do |cb|
		cb.call(param[:current], oldData);
	end

	@mqtt.publish_to "#{@dir}/#{key}", newString, retain: true;
end

#on_change(key) {|| ... } ⇒ Object

Add a callback to be triggered whenever the key’s value changes. The slight difference to ‘on_set` is that this callback is not executed on the very first value received from MQTT, making it easier to not trigger some code on restart, only on actual changes.

Parameters:

  • (See #[])

Yield Parameters:

  • (See #[])

Raises:

  • (ArgumentError)


162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/mqtt/persistence.rb', line 162

def on_change(key, &callback)
	raise ArgumentError, "Key needs to be a symbol!" unless key.is_a? Symbol
	raise ArgumentError, "Key has not been set up!" unless @paramList.key? key;

	raise ArgumentError, "A callback needs to be given!" unless callback;

	if(@paramList[key][:first])
		@paramList[key][:change_cb] << callback;
	else
		@paramList[key][:cbList] << callback;
	end
end

#setup(key, type_class = nil) ⇒ Object

Set up a key, unless it has already been configured.

Parameters:



107
108
109
110
# File 'lib/mqtt/persistence.rb', line 107

def setup(key, type_class = nil)
	return if @paramList.key? key;
	setup!(key, type_class);
end

#setup!(key, type_class = nil) ⇒ Object

Force setting up a key, overwriting what was already configured. You usually don’t need this!

Parameters:

  • key (Symbol)

    The key that should be set up.

  • type_class (#from_mqtt_string) (defaults to: nil)

    The class to use to parse the data. A JSON-conversion is used if the class doesn’t respond to ‘from_mqtt_string`

Raises:

  • (ArgumentError)


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/mqtt/persistence.rb', line 88

def setup!(key, type_class = nil)
	raise ArgumentError, "Key needs to be a symbol!" unless key.is_a? Symbol

	@paramList[key] = {
		type: 	type_class,
		current: nil,
		cbList:	Array.new(),

		first:		true,
		change_cb:	Array.new(),
	}

	if(data = @rawData[key])
		@rawData[key] = nil;
		_process_data(data, key);
	end
end