ectomobile/app/controllers/readings_controller.rb
f d147a8ad9e
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
guardar todo
cuando el arduino ya está creado no se guardan los sensores
2022-09-06 16:17:00 -03:00

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