# Home IOT tricks

## Push notifications

At home, I use MQTT and Gotify to send alerts for things that require attention. Consuming messages from a topic is quite straightforward using a short Ruby script.

Personally, I'm using this script in conjunction with a pair of ESP8266s which tell me when my laundry's done.

### Requirements

* Ruby (I am using version 3.2.2, but earlier and later versions will probably be fine)
* A Gotify server
* IOT devices pushing messages to an MQTT server

The following Ruby gems are used:

* json
* mqtt
* faraday (although net/http would be work if you tweaked the script)

### The code

The below is a straightforward example. You could add to it to send specific push notifications depending on the topic or a key in the JSON in the message. Perhaps JSON's not required for your use case and you can do string comparisons. Perhaps this is a solved problem and I'm overengineering things - e-mail me at netsplit@sdf.org.

It connects to your MQTT server (you can also pass a username and password to the "connect" instance method) and keeps an eye on every topic. When a message is received, it parses the JSON and sends a push notification with the title "Started" and message "It started".

Switch the configurable values (the "token" and "url" in the Faraday constructor and the MQTT server) for your own.

```ruby
#!/usr/bin/env ruby

# frozen_string_literal: true

require 'json'
require 'mqtt'
require 'faraday'

http = Faraday.new(
  url: 'https://gotify-server-here',
  params: { token: 'gotify-token-here' }
)

MQTT::Client.connect('mqtt.example.org') do |client|
  # A more specific topic can be used here (# is a wildcard)
  client.get('#') do |topic, message|
    puts "#{topic}: #{message}" # Debugging, not required

    begin
      content = JSON.parse(message, symbolize_names: true)
    rescue JSON::ParserError
      # If invalid JSON is provided, default to using the original message
      content = message
    end

    if content.is_a?(Hash) && content[:started]
      http.post('message', title: 'Started', message: 'It started', priority: 10)
    end

    # ...
  end
end
```