# frozen_string_literal: true require "dry-transformer" require "json" module DjiMqttConnect module Thing::Product class OsdMarshal < MessageMarshal include Utils::MessageParsing # Make a copy of the raw data class AttributeTransformer < Dry::Transformer::Pipe import Dry::Transformer::Conditional import Dry::Transformer::HashTransformations define! do # Ensure there is a data element map_value "data", ->(data) { data || {} } # Create a backup for unsupported attributes copy_keys "data" => "_data" map_value "data" do # Rename the invalid (for Ruby) wireless link attributes guard ->(data) { data.key?("wireless_link") } do # Translate wireless_link 4g keys (from remote payload) map_value "wireless_link" do rename_keys "4g_freq_band" => "_4g_freq_band", "4g_gnd_quality" => "_4g_gnd_quality", "4g_link_state" => "_4g_link_state", "4g_quality" => "_4g_quality", "4g_uav_quality" => "_4g_uav_quality" end end end end end # Parse message from Device > Cloud Server def load(raw_message) parsed_message = parse_json(raw_message) message_data = parsed_message.fetch("data", {}) message_class = if drone_osd_data_attributes.all? { |attribute| message_data.key?(attribute.to_s) } DroneOsdMessage elsif required_remote_osd_data_attributes.all? { |attribute| message_data.key?(attribute.to_s) } && optional_remote_osd_data_attributes.any? { |attribute| message_data.key?(attribute.to_s) } RemoteOsdMessage elsif dock_osd_data_attributes.any? { |attribute| message_data.key?(attribute.to_s) } DockOsdMessage else OsdMessage end transformed_message = attribute_transformer.call(parsed_message) build_message(message_class, transformed_message) end private def attribute_transformer @attribute_transformer ||= AttributeTransformer.new end def dock_osd_data_attributes @dock_osd_data_attributes ||= DockOsdMessage::STABLE_DATA_ATTRIBUTES.map(&:to_s) end def drone_osd_data_attributes @drone_osd_data_attributes ||= DroneOsdMessage::STABLE_DATA_ATTRIBUTES.map(&:to_s) end def required_remote_osd_data_attributes @required_remote_osd_data_attributes ||= begin data_keys = DjiMqttConnect::Thing::Product::RemoteOsdMessage::Data.schema.keys data_keys.select(&:required?).map(&:name) end end def optional_remote_osd_data_attributes @optional_remote_osd_data_attributes ||= begin data_keys = DjiMqttConnect::Thing::Product::RemoteOsdMessage::Data.schema.keys data_keys.reject(&:required?).map(&:name) end end end end end