forked from blues/notecard-schema
-
Notifications
You must be signed in to change notification settings - Fork 0
Create comprehensive schema for card.triangulate API #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
1059b5d
Initial plan
Copilot 33e6462
Initial setup: Create basic schema templates for card.triangulate API
Copilot e214736
Implement complete card.triangulate API schema with comprehensive tests
Copilot 6da0837
Update card.triangulate schema descriptions with verbatim API documen…
Copilot f61ebce
chore: Manually update card.triangulate
zfields 0dd3dc5
fix: Update card.triangulate response tests to match manually updated…
Copilot df40eba
chore: Manually update card.triangulate response
zfields 8c544d3
Update card.triangulate.req.notecard.api.json
zakoverflow File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "$id": "https://raw.githubusercontent.com/blues/notecard-schema/master/card.triangulate.req.notecard.api.json", | ||
| "title": "card.triangulate Request Application Programming Interface (API) Schema", | ||
| "description": "Enables or disables a behavior by which the Notecard gathers information about surrounding cell towers and/or Wi-Fi access points with each new Notehub session.", | ||
| "type": "object", | ||
| "skus": [ | ||
| "CELL", | ||
| "CELL+WIFI", | ||
| "WIFI" | ||
| ], | ||
| "version": "0.2.1", | ||
| "apiVersion": "9.1.1", | ||
| "properties": { | ||
| "cmd": { | ||
| "description": "Command for the Notecard (no response)", | ||
| "const": "card.triangulate" | ||
| }, | ||
| "req": { | ||
| "description": "Request for the Notecard (expects response)", | ||
| "const": "card.triangulate" | ||
| }, | ||
| "mode": { | ||
| "description": "The triangulation approach to use for determining the Notecard location. The following keywords can be used separately or together in a comma-delimited list, in any order.", | ||
| "type": "string", | ||
| "pattern": "^(cell(,wifi)?|wifi(,cell)?|-)$", | ||
| "sub-descriptions": [ | ||
| { | ||
| "const": "cell", | ||
| "description": "Enables cell tower scanning to determine the position of the Device." | ||
| }, | ||
| { | ||
| "const": "wifi", | ||
| "description": "Enables the use of nearby Wi-Fi access points to determine the position of the Device. To leverage this feature, the host will need to provide access point information to the Notecard via the `text` argument in subsequent requests." | ||
| }, | ||
| { | ||
| "const": "-", | ||
| "description": "Clear the currently-set triangulation mode." | ||
| } | ||
| ] | ||
| }, | ||
| "on": { | ||
| "description": "`true` to instruct the Notecard to triangulate even if the module has not moved. Only takes effect when `set` is `true`.", | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "usb": { | ||
| "description": "`true` to perform triangulation only when the Notecard is connected to USB power. Only takes effect when `set` is `true`.", | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "set": { | ||
| "description": "`true` to instruct the module to use the state of the `on` and `usb` arguments.", | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "minutes": { | ||
| "description": "Minimum delay, in minutes, between triangulation attempts. Use `0` for no time-based suppression.", | ||
| "type": "integer", | ||
| "default": 0, | ||
| "minimum": -1 | ||
| }, | ||
| "text": { | ||
| "description": "When using Wi-Fi triangulation, a newline-terminated list of Wi-Fi access points obtained by the external module. Format should follow the ESP32's [AT+CWLAP command output](https://docs.espressif.com/projects/esp-at/en/latest/AT_Command_Set/Wi-Fi_AT_Commands.html#cmd-lap).", | ||
| "type": "string" | ||
| }, | ||
| "time": { | ||
| "description": "When passed with `text`, records the time that the Wi-Fi access point scan was performed. _If not provided, Notecard time is used._", | ||
| "type": "integer" | ||
| } | ||
| }, | ||
| "oneOf": [ | ||
| { | ||
| "required": [ | ||
| "req" | ||
| ], | ||
| "properties": { | ||
| "req": { | ||
| "const": "card.triangulate" | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "required": [ | ||
| "cmd" | ||
| ], | ||
| "properties": { | ||
| "cmd": { | ||
| "const": "card.triangulate" | ||
| } | ||
| } | ||
| } | ||
| ], | ||
| "additionalProperties": false, | ||
| "samples": [ | ||
| { | ||
| "title": "Single Mode", | ||
| "description": "Enable triangulation using cell towers only.", | ||
| "json": "{\"req\":\"card.triangulate\",\"mode\":\"cell\",\"on\":true,\"set\":true}" | ||
| }, | ||
| { | ||
| "title": "Dual Mode", | ||
| "description": "Enable triangulation using both Wi-Fi and cell towers when connected to USB power.", | ||
| "json": "{\"req\":\"card.triangulate\",\"mode\":\"wifi,cell\",\"on\":true,\"usb\":true,\"set\":true}" | ||
| }, | ||
| { | ||
| "title": "Send Wi-Fi AP Data", | ||
| "description": "Send a newline-terminated list of Wi-Fi access points to the Notecard for triangulation.", | ||
| "json": "{\"req\":\"card.triangulate\",\"text\":\"+CWLAP:(4,\\\"Blues\\\",-51,\\\"74:ac:b9:12:12:f8\\\",1)\\n+CWLAP:(3,\\\"AAAA-62DD\\\",-70,\\\"6c:55:e8:91:62:e1\\\",11)\\n+CWLAP:(4,\\\"Blues\\\",-81,\\\"74:ac:b9:11:12:23\\\",1)\\n+CWLAP:(4,\\\"Blues\\\",-82,\\\"74:ac:a9:12:19:48\\\",11)\\n+CWLAP:(4,\\\"Free Parking\\\",-83,\\\"02:18:4a:11:60:31\\\",6)\\n+CWLAP:(5,\\\"GO\\\",-84,\\\"01:13:6a:13:90:30\\\",6)\\n+CWLAP:(4,\\\"AAAA-5C62-2.4\\\",-85,\\\"d8:97:ba:7b:fd:60\\\",1)\\n+CWLAP:(3,\\\"DIRECT-a5-HP MLP50\\\",-86,\\\"fa:da:0c:1b:16:a5\\\",6)\\n+CWLAP:(3,\\\"DIRECT-c6-HP M182 LaserJet\\\",-88,\\\"da:12:65:44:31:c6\\\",6)\\n\\n\"}" | ||
| }, | ||
| { | ||
| "title": "Disable Triangulation", | ||
| "description": "Disable triangulation mode.", | ||
| "json": "{\"req\":\"card.triangulate\",\"mode\":\"-\"}" | ||
| } | ||
| ], | ||
| "annotations": [ | ||
| { | ||
| "title": "note", | ||
| "description": "See [Using Cell Tower & Wi-Fi Triangulation](https://dev.blues.io/guides-and-tutorials/collecting-sensor-data/notecard-guides/using-cell-tower-wi-fi-triangulation/) for more information." | ||
| } | ||
| ] | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "$id": "https://raw.githubusercontent.com/blues/notecard-schema/master/card.triangulate.rsp.notecard.api.json", | ||
| "title": "card.triangulate Response Application Programming Interface (API) Schema", | ||
| "description": "Response containing triangulated location information and triangulation settings.", | ||
| "type": "object", | ||
| "version": "0.1.2", | ||
| "apiVersion": "9.1.1", | ||
| "properties": { | ||
| "motion": { | ||
| "description": "UNIX Epoch time of last detected Notecard movement.", | ||
| "type": "integer", | ||
| "minimum": 0 | ||
| }, | ||
| "time": { | ||
| "description": "UNIX Epoch time of last triangulation scan.", | ||
| "type": "integer", | ||
| "minimum": 0 | ||
| }, | ||
| "mode": { | ||
| "description": "A comma-separated list indicating the active triangulation modes.", | ||
| "type": "string" | ||
| }, | ||
| "on": { | ||
| "description": "`true` if triangulation scans will be performed even if the device has not moved.", | ||
| "type": "boolean" | ||
| }, | ||
| "usb": { | ||
| "description": "`true` if triangulation scans will be performed only when the device is USB-powered.", | ||
| "type": "boolean" | ||
| }, | ||
| "length": { | ||
| "description": "The length of the `text` buffer provided in the current or a previous request.", | ||
|
||
| "type": "integer", | ||
| "minimum": 0 | ||
| } | ||
| }, | ||
| "samples": [ | ||
| { | ||
| "title": "Example Response", | ||
| "description": "Response showing triangulation configuration and status.", | ||
| "json": "{\"usb\":true,\"mode\":\"wifi,cell\",\"length\":443,\"on\":true,\"time\":1606755042,\"motion\":1606757487}" | ||
| } | ||
| ] | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| import pytest | ||
| import jsonschema | ||
| import json | ||
|
|
||
| SCHEMA_FILE = "card.triangulate.req.notecard.api.json" | ||
|
|
||
| def test_valid_req(schema): | ||
| """Tests a minimal valid request using 'req'.""" | ||
| instance = {"req": "card.triangulate"} | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
|
|
||
| def test_valid_cmd(schema): | ||
| """Tests a minimal valid request using 'cmd'.""" | ||
| instance = {"cmd": "card.triangulate"} | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
|
|
||
| def test_invalid_empty_object(schema): | ||
| """Tests invalid empty object (needs req or cmd).""" | ||
| instance = {} | ||
| with pytest.raises(jsonschema.ValidationError) as excinfo: | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
| assert "is not valid under any of the given schemas" in str(excinfo.value) | ||
|
|
||
| def test_invalid_both_req_and_cmd(schema): | ||
| """Tests invalid request having both req and cmd.""" | ||
| instance = {"req": "card.triangulate", "cmd": "card.triangulate"} | ||
| with pytest.raises(jsonschema.ValidationError) as excinfo: | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
| assert "is valid under each of" in str(excinfo.value) | ||
|
|
||
| def test_invalid_additional_property_with_req(schema): | ||
| """Tests invalid request with req and an additional property.""" | ||
| instance = {"req": "card.triangulate", "extra": "field"} | ||
| with pytest.raises(jsonschema.ValidationError) as excinfo: | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
| assert "Additional properties are not allowed ('extra' was unexpected)" in str(excinfo.value) | ||
|
|
||
| def test_invalid_additional_property_with_cmd(schema): | ||
| """Tests invalid request with cmd and an additional property.""" | ||
| instance = {"cmd": "card.triangulate", "extra": "field"} | ||
| with pytest.raises(jsonschema.ValidationError) as excinfo: | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
| assert "Additional properties are not allowed ('extra' was unexpected)" in str(excinfo.value) | ||
|
|
||
| def test_on_field_valid(schema): | ||
| """Tests valid 'on' field values.""" | ||
| # Valid boolean values | ||
| instance = {"req": "card.triangulate", "on": True} | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
|
|
||
| instance = {"req": "card.triangulate", "on": False} | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
|
|
||
| def test_on_field_invalid_type(schema): | ||
| """Tests invalid type for 'on' field.""" | ||
| instance = {"req": "card.triangulate", "on": "true"} | ||
| with pytest.raises(jsonschema.ValidationError) as excinfo: | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
| assert "'true' is not of type 'boolean'" in str(excinfo.value) | ||
|
|
||
| def test_on_field_invalid_number(schema): | ||
| """Tests invalid number type for 'on' field.""" | ||
| instance = {"req": "card.triangulate", "on": 1} | ||
| with pytest.raises(jsonschema.ValidationError) as excinfo: | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
| assert "1 is not of type 'boolean'" in str(excinfo.value) | ||
|
|
||
| def test_valid_request_with_cmd_and_on(schema): | ||
| """Tests valid request using 'cmd' with 'on' parameter.""" | ||
| instance = {"cmd": "card.triangulate", "on": True} | ||
| jsonschema.validate(instance=instance, schema=schema) | ||
|
|
||
| def test_validate_samples_from_schema(schema, schema_samples): | ||
| """Tests that samples in the schema definition are valid.""" | ||
| for sample in schema_samples: | ||
| sample_json_str = sample.get("json") | ||
| if not sample_json_str: | ||
| pytest.fail(f"Sample missing 'json' field: {sample.get('description', 'Unnamed sample')}") | ||
| try: | ||
| instance = json.loads(sample_json_str) | ||
| except json.JSONDecodeError as e: | ||
| pytest.fail(f"Failed to parse sample JSON: {sample_json_str}\nError: {e}") | ||
|
|
||
| jsonschema.validate(instance=instance, schema=schema) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description references a dependency on the 'set' parameter, but according to the PR description, the 'on' parameter should work independently to enable/disable triangulation mode. This creates confusion about the parameter's behavior.