Skip to content
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

Allow downloading miot spec files by model for miottemplate #904

Merged
merged 2 commits into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions devtools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ This directory contains tooling useful for developers

This tool generates some boilerplate code for adding support for MIoT devices

1. Obtain device type from http://miot-spec.org/miot-spec-v2/instances?status=all
2. Execute `python miottemplate.py download <type>` to download the description file.
3. Execute `python miottemplate.py generate <file>` to generate pseudo-python for the device.
1. If you know the model, use `python miottemplate.py download <model>` to download the description file.
* This will download the model<->urn mapping file from http://miot-spec.org/miot-spec-v2/instances?status=all and store it locally
* If you know the urn, you can use `--urn` to avoid downloading the mapping file (should not be necessary)

2. `python miottemplate.py print <description file>.json` prints out the siid/piid/aiid information from the spec file
22 changes: 22 additions & 0 deletions devtools/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ def indent(data, level=4):
return indented


@dataclass
class InstanceInfo:
model: str
status: str
type: str
version: int


@dataclass
class ModelMapping(DataClassJsonMixin):
instances: List[InstanceInfo]

def urn_for_model(self, model: str):
matches = [inst.type for inst in self.instances if inst.model == model]
if len(matches) > 1:
print(
"WARNING more than a single match for model %s: %s" % (model, matches)
)

return matches[0]


@dataclass
class Property(DataClassJsonMixin):
iid: int
Expand Down
59 changes: 53 additions & 6 deletions devtools/miottemplate.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import logging
from pathlib import Path

import click

from containers import Device
import requests
from containers import Device, ModelMapping

MIOTSPEC_MAPPING = Path("model_miotspec_mapping.json")

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -89,14 +93,57 @@ def print(file):


@cli.command()
@click.argument("type")
def download(type):
def download_mapping():
"""Download model<->urn mapping."""
click.echo(
"Downloading and saving model<->urn mapping to %s" % MIOTSPEC_MAPPING.name
)
url = "http://miot-spec.org/miot-spec-v2/instances?status=all"
res = requests.get(url)

with MIOTSPEC_MAPPING.open("w") as f:
f.write(res.text)


def get_mapping() -> ModelMapping:
with MIOTSPEC_MAPPING.open("r") as f:
return ModelMapping.from_json(f.read())


@cli.command()
def list():
"""List all entries in the model<->urn mapping file."""
mapping = get_mapping()

for inst in mapping.instances:
click.echo(f"* {repr(inst)}")


@cli.command()
@click.option("--urn", default=None)
@click.argument("model", required=False)
@click.pass_context
def download(ctx, urn, model):
"""Download description file for model."""
import requests

url = f"https://miot-spec.org/miot-spec-v2/instance?type={type}"
if urn is None:
if model is None:
click.echo("You need to specify either the model or --urn")
return

if not MIOTSPEC_MAPPING.exists():
click.echo(
"miotspec mapping doesn't exist, downloading to %s"
% MIOTSPEC_MAPPING.name
)
ctx.invoke(download_mapping)

mapping = get_mapping()
urn = mapping.urn_for_model(model)

url = f"https://miot-spec.org/miot-spec-v2/instance?type={urn}"
content = requests.get(url)
save_to = f"{type}.json"
save_to = f"{urn}.json"
click.echo(f"Saving data to {save_to}")
with open(save_to, "w") as f:
f.write(content.text)
Expand Down