Этот клиент позволяет вам подключиться к API MyJohnDeere без необходимости кодировать собственный процесс oAuth, запросы API и нумерацию страниц.
get
, create
, put
и delete
для простых, аутентифицированных и прямых вызовов API.each
, map
и т. д. будут извлекать новые страницы данных по мере необходимости. Мы предоставляем документацию RDoc, но вот полезное руководство для начала работы. Поскольку имя драгоценного камня длинное, во всех примерах будет использоваться такое сокращение:
JD = MyJohnDeereApi
Итак, когда вы видите:
JD :: Authorize
На самом деле это означает:
MyJohnDeereApi :: Authorize
Эта библиотека доступна как драгоценный камень. Чтобы использовать его, просто установите драгоценный камень:
gem install my_john_deere_api
Если вы используете Bundler (а почему бы и нет?), добавьте драгоценный камень в свой драгоценный файл:
gem 'my_john_deere_api'
и запустите:
bundle install
Это самый простой путь авторизации, хотя вашему пользователю придется пройти через дополнительную процедуру, предоставив вам код подтверждения:
# Create an authorize object, using your app's API key and secret. You can
# pass an environment (`:live` or `:sandbox`), which default to `:live`.
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Retrieve a valid authorization url from John Deere, where you can send
# your user for authorizing your app to the JD platform.
url = authorize . authorize_url
# Verify the code given to the user during the authorization process, and
# turn this into access credentials for your user.
authorize . verify ( code )
На самом деле вам, скорее всего, потребуется повторно создать экземпляр объекта авторизации, когда пользователь вернется, и это работает без проблем:
# Create an authorize object, using your app's API key and secret.
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Retrieve a valid authorization url from John Deere.
url = authorize . authorize_url
# Queue elevator music while your app serves other users...
# Re-create the authorize instance in a different process
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Proceed as normal
authorize . verify ( code )
В веб-приложении вы предпочитаете, чтобы пользователю не приходилось копировать/вставлять коды подтверждения. Таким образом, вы можете передать URL-адрес :oauth_callback. Когда пользователь авторизует ваше приложение с помощью John Deere, он перенаправляется на предоставленный вами URL-адрес с параметром oauth_verifier, который содержит код подтверждения, поэтому пользователю не нужно его предоставлять.
# Create an authorize object, using your app's API key and secret.
authorize = JD :: Authorize . new (
API_KEY ,
API_SECRET ,
environment : :sandbox ,
oauth_callback : 'https://example.com'
)
# Retrieve a valid authorization url from John Deere.
# This will contain the callback url encoded into the
# query string for you.
url = authorize . authorize_url
# Queue elevator music while your app serves other users...
# Re-create the authorize instance in a different process.
# It's not necessary to re-initialize with the callback url.
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Inside a Rails controller, you might do this:
authorize . verify ( params [ :oauth_verifier ] )
После завершения авторизации объект Client
предоставит большую часть интерфейса для этой библиотеки. Клиент можно использовать с учетными данными пользователя или без них, поскольку некоторые вызовы API относятся к взаимодействию вашего приложения с John Deere, а не вашего пользователя. Но большинство взаимодействий будет связано с пользовательскими данными. Вот как создать экземпляр клиента:
client = JD :: Client . new (
# the application's API key
API_KEY ,
# the application's API secret
API_SECRET ,
# the chosen environment (:sandbox or :live)
environment : :sandbox ,
# optional contribution_definition_id. This is needed for some requests,
# but the client can be created without it, in order to find it.
contribution_definition_id : CONTRIBUTION_DEFINITION_ID ,
# the user's access credentials
access : [ ACCESS_TOKEN , ACCESS_SECRET ]
)
После подключения клиент работает как упрощенная версия ActiveRecord. Хэши JSON из API преобразуются в объекты, чтобы с ними было проще работать. Коллекции объектов, например организации, обрабатывают нумерацию страниц за вас. Просто выполните итерацию с использованием each
, map
и т. д., и новые страницы будут загружены по мере необходимости.
Этот клиент находится в стадии разработки. В настоящее время вы можете делать следующие вещи, не прибегая к вызовам API:
client
├── contribution_products
| ├── count
| ├── all
| ├── first
| └── find(contribution_product_id)
| └── contribution_definitions
| ├── count
| ├── all
| ├── first
| └── find(contribution_definition_id)
└── organizations
├── count
├── all
├── first
└── find(organization_id)
├── assets(attributes)
| ├── create(attributes)
| ├── count
| ├── all
| ├── first
| └── find(asset_id)
| ├── save
| ├── update(attributes)
| └── locations
| ├── create(attributes)
| ├── count
| ├── all
| └── first
└── fields
├── count
├── all
├── first
└── find(field_id)
└── flags
├── count
├── all
└── first
Коллекции продуктов Contribution действуют как список. В дополнение ко всем методам, включенным в перечислимый модуль Ruby, коллекции продуктов поддерживают следующие методы:
Продукт индивидуального вклада поддерживает следующие методы и ассоциации:
client . contribution_products
# => collection of contribution products under this client
client . contribution_products . count
# => 1
client . contribution_products . first
# => an individual contribution product
contribution_product = client . contribution_products . find ( 1234 )
# => an individual contribution product, fetched by ID
contribution_product . market_place_name
# => 'Market Place Name'
contribution_product . contribution_definitions
# => collection of contribution definitions belonging to this contribution product
Обрабатывает определения вклада продукта вклада. Коллекции определений вклада поддерживают следующие методы:
Определение индивидуального вклада поддерживает следующие методы и ассоциации:
contribution_product . contribution_definitions
# => collection of contribution definitions under this contribution product
client . contribution_definitions . count
# => 1
client . contribution_definitions . first
# => an individual contribution definition
contribution_definition = contribution_product . contribution_definitions . find ( 1234 )
# => an individual contribution definition, fetched by ID
contribution_definition . name
# => 'Contribution Definition Name'
Управляет организациями аккаунта. Коллекции организаций поддерживают следующие методы:
Отдельная организация поддерживает следующие методы и ассоциации:
Метод count
требует загрузки только первой страницы результатов, поэтому его вызов относительно дешев. С другой стороны, all
принудительно загружает всю коллекцию из API John Deere, поэтому используйте его с осторожностью. Организации нельзя создавать через API, поэтому в этой коллекции нет метода create
.
client . organizations
# => collection of organizations under this client
client . organizations . count
# => 15
client . organizations . first
# => an individual organization object
organization = client . organizations . find ( 1234 )
# => an individual organization object, fetched by ID
organization . name
# => 'Smith Farms'
organization . type
# => 'customer'
organization . member?
# => true
organization . links
# => {
# 'self' => 'https://sandboxapi.deere.com/platform/organizations/1234',
# 'machines' => 'https://sandboxapi.deere.com/platform/organizations/1234/machines',
# 'wdtCapableMachines' => 'https://sandboxapi.deere.com/platform/organizations/1234/machines?capability=wdt'
# }
organization . assets
# => collection of assets belonging to this organization
organization . fields
# => collection of fields belonging to this organization
Управляет активами организации. Коллекции активов поддерживают следующие методы:
Отдельный актив поддерживает следующие методы и ассоциации:
organization = client . organizations . first
# => the first organization returned by the client
organization . assets
# => collection of assets belonging to this organization
asset = organization . assets . find ( 123 )
# => an individual asset object, fetched by ID
asset . title
# => 'AgThing Water Device'
asset . category
# => 'DEVICE'
asset . type
# => 'SENSOR'
asset . sub_type
# => 'OTHER'
asset . links
# => a hash of API urls related to this asset
Метод create
создает актив на платформе John Deere и возвращает вновь созданную запись.
asset = organization . assets . create (
title : 'Asset Title' ,
asset_category : 'DEVICE' ,
asset_type : 'SENSOR' ,
asset_sub_type : 'ENVIRONMENTAL'
)
asset . title
# => 'Asset Title'
Метод update
обновляет локальный объект, а также актив на платформе John Deere. Обновить можно только название актива.
asset . update ( title : 'New Title' )
asset . title
# => 'New Title', also John Deere record is updated
Метод save
обновляет John Deere с учетом всех внесенных локальных изменений.
asset . title = 'New Title'
asset . save
# => Successful Net::HTTPNoContent object
Управляет местоположениями активов. Коллекции местоположений активов поддерживают следующие методы:
Отдельное местоположение поддерживает следующие методы:
asset = organizations . assets . first
# => the first asset returned by the organization
asset . locations
# => collection of locations belonging to this asset
location = asset . locations . first
# => the first location returned by the asset. Note that locations do not have their own id's
# in the JD platform, and therefore cannot be requested individually via a "find" method.
location . timestamp
# => "2019-11-11T23:00:00.000Z"
# John Deere includes 3 decimal places in the format, but does not actually
# store fractions of a second, so it will always end in ".000". This is
# important, because timestamps must be unique.
location . geometry
# => a GeoJSON formatted hash, for example:
# {
# "type"=>"Feature",
# "geometry"=>{
# "geometries"=>[
# {
# "coordinates"=>[-95.123456, 40.123456],
# "type"=>"Point"
# }
# ],
# "type"=>"GeometryCollection"
# }
# }
location . measurement_data
# => the status details of this location, for example:
# [
# {
# "@type"=>"BasicMeasurement",
# "name"=>"[Soil Temperature](http://example.com/current_temperature)",
# "value"=>"21.0",
# "unit"=>"°C"
# }
# ]
Метод create
создает местоположение на платформе John Deere и возвращает вновь созданный объект из John Deere. Однако новой информации не будет, поскольку уникальный идентификатор не генерируется. Отправленная временная метка (по умолчанию «сейчас») будет округлена до ближайшей секунды.
locaton = asset . locatons . create (
# You can pass fractional seconds, but they will be truncated by JD.
timestamp : "2019-11-11T23:00:00.123Z" ,
# JD requires more complicated JSON geometry, but this client will convert a simple
# set of lat/long coordinates into the larger format automatically.
geometry : [ - 95.123456 , 40.123456 ] ,
# This is a list of "measurements"
measurement_data : [
{
name : 'Temperature' ,
value : '68.0' ,
unit : 'F'
}
]
)
location . timestamp
# => "2019-11-11T23:00:00.000Z"
# Note that the timestamp's fractional second is truncated by John Deere, though they
# still return the record with three digits of precision.
location . geometry
# => a GeoJSON formatted hash in its larger format
# {
# "type"=>"Feature",
# "geometry"=>{
# "geometries"=>[
# {
# "coordinates"=>[-95.123456, 40.123456],
# "type"=>"Point"
# }
# ],
# "type"=>"GeometryCollection"
# }
# }
location . measurement_data
# [
# {
# "@type"=>"BasicMeasurement",
# "name"=>"Temperature",
# "value"=>"68.0",
# "unit"=>"F"
# }
# ]
Местоположение не обновляется и не удаляется. Самая новая запись о местоположении всегда действует как статус данного актива и отображается на карте.
Обратите внимание, что в John Deere местоположения называются «Местоположениями активов», но для краткости мы называем ассоциацию «Местоположениями», как в asset.locations
.
Обрабатывает поля организации. Коллекции полей поддерживают следующие методы:
Отдельное поле поддерживает следующие методы и ассоциации:
Метод count
требует загрузки только первой страницы результатов, поэтому его вызов относительно дешев. С другой стороны, all
принудительно загружает всю коллекцию из API John Deere, поэтому используйте его с осторожностью. Поля можно создавать через API, но для этой коллекции пока нет метода create
.
organization . fields
# => collection of fields under this organization
organization . fields . count
# => 15
organization . fields . first
# => an individual field object
field = organization . fields . find ( 1234 )
# => an individual field object, fetched by ID
field . name
# => 'Smith Field'
field . archived?
# => false
field . links
# => a hash of API urls related to this field
field . flags
# => collection of flags belonging to this field
Обрабатывает флаги поля. Коллекции флагов поддерживают следующие методы. Обратите внимание: John Deere не предоставляет конечную точку для получения определенного флага по идентификатору:
Отдельный флаг поддерживает следующие методы и ассоциации:
Метод count
требует загрузки только первой страницы результатов, поэтому его вызов относительно дешев. С другой стороны, all
принудительно загружает всю коллекцию из API John Deere, поэтому используйте его с осторожностью. Флаги можно создавать через API, но для этой коллекции пока нет метода create
.
field . flags
# => collection of flags under this field
field . flags . count
# => 15
flag = field . flags . first
# => an individual flag object
flag . notes
# => 'A big rock on the left after entering the field'
flag . geometry
# => a GeoJSON formatted hash, for example:
# {
# "type"=>"Feature",
# "geometry"=>{
# "geometries"=>[
# {
# "coordinates"=>[-95.123456, 40.123456],
# "type"=>"Point"
# }
# ],
# "type"=>"GeometryCollection"
# }
# }
field . archived?
# => false
field . proximity_alert_enabled?
# => true
field . links
# => a hash of API urls related to this flag
Хотя целью клиента является устранение необходимости совершать/интерпретировать вызовы API John Deere, важно иметь возможность выполнять вызовы, которые еще не полностью поддерживаются клиентом. Или иногда вам нужно устранить неполадки.
Для запросов GET требуется только путь к ресурсу.
client . get ( '/organizations' )
Сокращенный образец ответа:
{
"links" : [ " ... " ],
"total" : 1 ,
"values" : [
{
"@type" : " Organization " ,
"name" : " ABC Farms " ,
"type" : " customer " ,
"member" : true ,
"id" : " 123123 " ,
"links" : [ " ... " ]
}
]
}
Это не предоставит никаких клиентских преимуществ, таких как разбивка на страницы или проверка, но он анализирует возвращенный JSON.
Для запросов POST требуется путь к ресурсу и хэш тела запроса. Клиент преобразует ключи в формат JSON.
client . post (
'/organizations/123123/assets' ,
{
"title" => "i like turtles" ,
"assetCategory" => "DEVICE" ,
"assetType" => "SENSOR" ,
"assetSubType" => "ENVIRONMENTAL" ,
"links" => [
{
"@type" => "Link" ,
"rel" => "contributionDefinition" ,
"uri" => "https://sandboxapi.deere.com/platform/contributionDefinitions/CONTRIBUTION_DEFINITION_ID"
}
]
}
)
Стандартный ответ John Deere — это код состояния HTTP 201 с сообщением «Создано». Этот метод возвращает полный ответ Net::HTTP.
Для запросов PUT требуется путь к ресурсу и хэш тела запроса. Клиент преобразует ключи в формат JSON.
client . put (
'/assets/123123' ,
{
"title" => "i REALLY like turtles" ,
"assetCategory" => "DEVICE" ,
"assetType" => "SENSOR" ,
"assetSubType" => "ENVIRONMENTAL" ,
"links" => [
{
"@type" => "Link" ,
"rel" => "contributionDefinition" ,
"uri" => "https://sandboxapi.deere.com/platform/contributionDefinitions/CONTRIBUTION_DEFINITION_ID"
}
]
}
)
Стандартный ответ John Deere — это код состояния HTTP 204 с сообщением «Нет контента». Этот метод возвращает полный ответ Net::HTTP.
Для запросов DELETE требуется только путь к ресурсу.
client . delete ( '/assets/123123' )
Стандартный ответ John Deere — это код состояния HTTP 204 с сообщением «Нет контента». Этот метод возвращает полный ответ Net::HTTP.
Пользовательские ошибки помогают четко выявить проблемы при использовании клиента:
:sandbox
или :production
.Отметьте этот драгоценный камень на GitHub. Это помогает разработчикам находить и выбирать этот драгоценный камень среди других, которые могут быть там. Насколько нам известно, других драгоценных камней John Deere, которые активно обслуживаются, не существует.
Самый простой способ внести свой вклад:
vcr_setup
vcr_setup
.