Added memory cache.
This commit is contained in:
parent
773e50f4d9
commit
2970c80b83
|
@ -1,5 +1,7 @@
|
|||
MOJI_APPCODE="YOUR_MOJI_APP_CODE"
|
||||
|
||||
CACHE_TTL="1800"
|
||||
|
||||
IOT_MQTT_HOST="YOUR_MQTT_HOST"
|
||||
IOT_MQTT_PORT="1883"
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
name: "Build and publish image"
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: "Checkout repository"
|
||||
uses: "actions/checkout@v2"
|
||||
- name: "Login with Github packages"
|
||||
uses: "docker/login-action@v1"
|
||||
with:
|
||||
registry: "ghcr.io"
|
||||
username: "${{ github.repository_owner }}"
|
||||
password: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: "Set up buildx"
|
||||
uses: "docker/setup-buildx-action@v1"
|
||||
- name: "Extract branch name"
|
||||
shell: "bash"
|
||||
run: "echo \"##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})\""
|
||||
id: "extract_branch"
|
||||
- name: "Build and push image"
|
||||
uses: "docker/build-push-action@v2"
|
||||
with:
|
||||
context: "./"
|
||||
file: "./Dockerfile"
|
||||
push: true
|
||||
tags: "ghcr.io/${{ github.repository_owner }}/iot-weather:${{ steps.extract_branch.outputs.branch }}"
|
1
Gemfile
1
Gemfile
|
@ -4,6 +4,7 @@ source 'https://rubygems.org'
|
|||
|
||||
gem 'cbor', '~> 0.5.9.6'
|
||||
gem 'dotenv', '~>2.7'
|
||||
gem 'lru_redux', '~>1.1'
|
||||
gem 'moji_weather', github: 'imi415/moji_weather', branch: 'master'
|
||||
gem 'mqtt', '~>0.5'
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ GEM
|
|||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
lru_redux (1.1.0)
|
||||
mqtt (0.5.0)
|
||||
multipart-post (2.2.3)
|
||||
nokogiri (1.13.8-x86_64-linux)
|
||||
|
@ -103,6 +104,7 @@ PLATFORMS
|
|||
DEPENDENCIES
|
||||
cbor (~> 0.5.9.6)
|
||||
dotenv (~> 2.7)
|
||||
lru_redux (~> 1.1)
|
||||
moji_weather!
|
||||
mqtt (~> 0.5)
|
||||
rubocop
|
||||
|
|
|
@ -5,9 +5,10 @@ require 'bundler'
|
|||
Bundler.require
|
||||
|
||||
Dotenv.load
|
||||
Dotenv.require_keys('MOJI_APPCODE', 'IOT_MQTT_HOST', 'IOT_MQTT_PORT', 'IOT_MQTT_SSL')
|
||||
Dotenv.require_keys('MOJI_APPCODE', 'CACHE_TTL', 'IOT_MQTT_HOST', 'IOT_MQTT_PORT', 'IOT_MQTT_SSL')
|
||||
|
||||
wxapi = MojiWeather::Api::RestClient.new(app_code: ENV['MOJI_APPCODE'])
|
||||
cache = LruRedux::TTL::Cache.new(100, ENV['CACHE_TTL'].to_i)
|
||||
|
||||
def extract_device_id(topic)
|
||||
devid = %r{iot/weather/(.*)/request}.match(topic)
|
||||
|
@ -19,6 +20,17 @@ def extract_device_id(topic)
|
|||
end
|
||||
end
|
||||
|
||||
def extract_req_type(type)
|
||||
case type
|
||||
when 'condition'
|
||||
MojiWeather::Api::ApiType::CONDITION
|
||||
when 'aqi'
|
||||
MojiWeather::Api::ApiType::AQI
|
||||
when 'forecast24'
|
||||
MojiWeather::Api::ApiType::FORECAST_24HRS
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
client = MQTT::Client.new
|
||||
|
||||
|
@ -34,49 +46,60 @@ begin
|
|||
|
||||
client.connect
|
||||
|
||||
puts "[#{Time.now}] client [#{client}] connected..."
|
||||
|
||||
client.subscribe('iot/weather/#')
|
||||
|
||||
client.get do |topic, payload|
|
||||
# this method also checks if this is from a request topic.
|
||||
dev_id = extract_device_id(topic)
|
||||
unless dev_id.nil?
|
||||
puts "[#{dev_id}] <- #{payload.length}B"
|
||||
puts "[#{Time.now}][#{dev_id}] <- #{payload.length}B"
|
||||
|
||||
# decode CBOR object, retrieve request.
|
||||
dev_req = CBOR.decode(payload)
|
||||
|
||||
wx_cond = case dev_req['type']
|
||||
when 'condition'
|
||||
MojiWeather::Api::ApiType::CONDITION
|
||||
when 'aqi'
|
||||
MojiWeather::Api::ApiType::AQI
|
||||
when 'forecast24'
|
||||
MojiWeather::Api::ApiType::FORECAST_24HRS
|
||||
end
|
||||
wx_cond = extract_req_type(dev_req['type'])
|
||||
|
||||
# Not a valid type
|
||||
next if wx_cond.nil?
|
||||
|
||||
req_params = if !dev_req['city_id'].nil?
|
||||
{ city_id: dev_req['city_id'] }
|
||||
elsif !dev_req['location'].nil?
|
||||
{ location: { lat: dev_req['location']['lat'], lon: dev_req['location']['lon'] } }
|
||||
else
|
||||
puts "[#{dev_id}] not a valid request"
|
||||
puts "[#{Time.now}][#{dev_id}] not a valid request"
|
||||
next
|
||||
end
|
||||
|
||||
# Request external service for weather information
|
||||
api_resp = wxapi.query(wx_cond, req_params)
|
||||
# Check cache
|
||||
api_resp = cache["cache_#{req_params}"]
|
||||
|
||||
# Cache missed..
|
||||
if api_resp.nil?
|
||||
puts "[#{Time.now}][#{dev_id}] cache missed"
|
||||
# Request external service for weather information
|
||||
api_resp = wxapi.query(wx_cond, req_params)
|
||||
|
||||
# Update cache entry
|
||||
cache["cache_#{req_params}"] = api_resp
|
||||
else
|
||||
puts "[#{Time.now}][#{dev_id}] cache hit"
|
||||
end
|
||||
|
||||
# Encode CBOR object
|
||||
resp = api_resp.to_cbor
|
||||
|
||||
# Publish to response topic.
|
||||
resp = api_resp.to_cbor
|
||||
puts "[#{dev_id}] -> #{resp.length}B"
|
||||
puts "[#{Time.now}][#{dev_id}] -> #{resp.length}B"
|
||||
|
||||
# Send response
|
||||
client.publish("iot/weather/#{dev_id}/response", resp)
|
||||
end
|
||||
end
|
||||
rescue SystemExit, Interrupt
|
||||
puts "Interrupt caught, client [#{client}] disconnect."
|
||||
puts "[#{Time.now}] Interrupt caught, client [#{client}] disconnect."
|
||||
client.disconnect
|
||||
rescue StandardError => e
|
||||
p e
|
||||
|
|
Loading…
Reference in New Issue