d147a8ad9e
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
cuando el arduino ya está creado no se guardan los sensores
100 lines
3.1 KiB
Ruby
100 lines
3.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ReadingsController < ActionController::API
|
|
# rescue_from ActiveRecord::RecordNotFound, with: :bad_request_error
|
|
# rescue_from ActionController::ParameterMissing, with: :bad_request_error
|
|
|
|
# @see {https://docutopia.tupale.co/sutty:nodemecu:api}
|
|
def create
|
|
if reading_params.empty?
|
|
head :ok
|
|
return
|
|
end
|
|
|
|
Reading.transaction do
|
|
reading.id = params[:transaction_uuid]
|
|
reading.signature = request.headers[:'X-Signature']
|
|
reading.raw_transaction = request.raw_post
|
|
reading.raw_transaction << "\n"
|
|
reading.verified = reading.verify(public_key)
|
|
|
|
params[:arduinos]&.reject do |a|
|
|
a[:id].blank? || a[:sensores].empty?
|
|
end&.each do |a|
|
|
arduino = raspberry.arduinos.find_or_create_by(local_id: a[:id])
|
|
|
|
a[:sensores].each do |s|
|
|
arduino.sensors.create(reading: reading, **sensor_params(s))
|
|
end
|
|
end
|
|
|
|
if raspberry.save!
|
|
render plain: reading.id, status: :ok
|
|
else
|
|
head :bad_request
|
|
end
|
|
end
|
|
rescue ActiveRecord::RecordNotUnique
|
|
render plain: params[:transaction_uuid], status: :ok
|
|
rescue ActiveRecord::RecordInvalid
|
|
head :bad_request
|
|
end
|
|
|
|
private
|
|
|
|
def bad_request_error
|
|
head :bad_request
|
|
end
|
|
|
|
# Registra una Raspberry junto con su llave pública.
|
|
#
|
|
# Como el número de serie se agregó después, queremos migrar ad-hoc
|
|
# las Raspberries que fueron registradas por su nombre y asociarles el
|
|
# número de serie apenas empiecen a actualizarse los nodemecu.
|
|
def raspberry
|
|
@raspberry ||= begin
|
|
r = Raspberry.find_or_create_by(serial_number: params[:serial_number])
|
|
r ||= Raspberry.find_or_create_by(name: params[:controller_id])
|
|
r.tap do |r|
|
|
r.name = params[:controller_id]
|
|
r.serial_number = params[:serial_number]
|
|
r.save
|
|
end
|
|
end
|
|
end
|
|
|
|
def public_key
|
|
@public_key ||= SSHData::PublicKey.parse_openssh(raspberry.public_keys.find_or_create_by(content: params[:public_key]).content)
|
|
end
|
|
|
|
# Procesa la transacción
|
|
def reading_params
|
|
@reading_params ||= params.permit(:timestamp,
|
|
:error_code,
|
|
:battery_status,
|
|
:sample,
|
|
:signature,
|
|
coordinates: %i[lat lng]).tap do |p|
|
|
p[:timestamp] = Time.at p[:timestamp].to_i
|
|
rescue TypeError
|
|
end
|
|
end
|
|
|
|
def reading
|
|
@reading ||= raspberry.readings.build reading_params
|
|
end
|
|
|
|
# Procesa los parámetros de un sensor
|
|
def sensor_params(sensor)
|
|
sensor.permit(:timestamp, :type, :value, :unit, :error).tap do |p|
|
|
p[:local_type] = p.delete :type
|
|
end
|
|
end
|
|
|
|
def append_info_to_payload(payload)
|
|
super
|
|
|
|
payload[:errors] = reading.try(:errors).try(:full_messages)
|
|
end
|
|
end
|