TheThingsNetwork / lorawan-stack

The Things Stack, an Open Source LoRaWAN Network Server
https://www.thethingsindustries.com/stack/
Apache License 2.0
978 stars 307 forks source link

Build stand-alone Julia SDK for TTES APIs #3073

Open rvolosatovs opened 4 years ago

rvolosatovs commented 4 years ago

Summary

A stand-alone Julia SDK for TTES APIs, to integrate with existing Julia applications

Why do we need this?

Having SDK in a programming language helps the developer to integrate quickly than integrating the REST APIs

What is already there? What do you see now?

Only JS SDK is present as of now

What is missing? What do you want to see?

Julia SDK along with SDK integration documentation

How do you propose to implement this?

I have some useful functionality already implemented for personal use

Can you do this yourself and submit a Pull Request?

yes

Note: Interested developers can 👍 the issue for the core team to prioritize

rvolosatovs commented 3 years ago

Some ideas I had/used for NS testing:

import JSON

function get_device(app_id="test-app2", dev_id="test-dev-c")::Cmd
  if app_id == ""
    error("app_id must not be empty")
  end
  if dev_id == ""
    error("dev_id must not be empty")
  end
  `ttn-lw-cli devices get $app_id $dev_id --session --mac-state`
end

function send_uplink(app_id::String="test-app2", dev_id::String="test-dev-c"; f_cnt::UInt32, payload::AbstractArray{UInt8})::Cmd
  dev = JSON.parse(read(get_device(app_id, dev_id), String))
  `ttn-lw-cli simulate uplink --f-nwk-s-int-key $(dev["session"]["keys"]["f_nwk_s_int_key"]["key"]) --app-s-key $(dev["session"]["keys"]["app_s_key"]["key"]) --lorawan-version $(dev["mac_state"]["lorawan_version"]) --frm-payload 0x$(bytes2hex(payload)) --f-port 0x42 --dev-addr $(dev["session"]["dev_addr"]) --gateway-id test-gtw --f-cnt $f_cnt --band-id EU_863_870 --frequency $(dev["mac_state"]["current_parameters"]["channels"][1]["uplink_frequency"])`
end
function validate_uid(uid::String)
  if uid == ""
    error("uid must not be empty")
  end
end

function validate_app_id(app_id::String)
  if app_id == ""
    error("app ID must not be empty")
  end
end

function validate_dev_id(dev_id::String)
  if dev_id == ""
    error("dev ID must not be empty")
  end
end

function validate_tenant_id(tenant_id::String)
  if tenant_id == ""
    error("tenant ID must not be empty")
  end
end

function validate_proto(pb::String)
  if pb == ""
    error("proto must not be empty")
  end
end

function uid_to_app_id(uid::String)::String
  validate_uid(uid)
  replace(uid, r"(.+)\..*" => s"\1")
end

function uid_to_dev_id(uid::String)::String
  validate_uid(uid)
  replace(uid, r".+\.(.*)(@.*)" => s"\1")
end

function uid_to_tenant_id(uid::String)::String
  validate_uid(uid)
  replace(uid, r".+@*(.+)" => s"\1")
end

function set_device(uid::String)::Cmd
  validate_uid(uid)
  `redis-cli -x set ttn:v3:ns:devices:uid:$uid`
end

function set_device(uid::String, pb::String)::Cmd
  validate_uid(uid)
  validate_proto(pb)
  `redis-cli set ttn:v3:ns:devices:uid:$uid $pb`
end

function trigger_downlink(uid::String)::Cmd
  validate_uid(uid)
  `redis-cli xadd ttn:v3:ns:tasks:downlink:input '*' payload $uid replace 1 start_at 0`
end

function make_uid(app_id::String, dev_id::String, tenant_id::String="default")::String
  validate_app_id(app_id)
  validate_dev_id(dev_id)
  validate_tenant_id(tenant_id)
  "$app_id.$dev_id@$tenant_id"
end

function make_uid(app_id::String, dev_id::String)::String
  validate_app_id(app_id)
  validate_dev_id(dev_id)
  "$app_id.$dev_id"
end

function make_local_uid(tti_uid::String, tenant_id::String="default")::String
  validate_uid(tti_uid)
  validate_tenant_id(tenant_id)
  make_uid(uid_to_app_id(tti_uid), uid_to_dev_id(tti_uid), tenant_id)
end

function make_local_uid(tti_uid::String)::String
  validate_uid(tti_uid)
  make_uid(uid_to_app_id(tti_uid), uid_to_dev_id(tti_uid))
end