Skip to content

Commit

Permalink
Allow downloading miot spec files by model for miottemplate (rytilaht…
Browse files Browse the repository at this point in the history
…i#904)

* Allow downloading miot spec files by model for miottemplate

* Modify 'download' to use model instead of urn, urn can still be passed with --urn
* Downloads and caches 'model_miotspec_mapping.json', if not available
* Add 'list' to list all entries in the mapping file

* Update readme
  • Loading branch information
rytilahti authored and xvlady committed May 9, 2021
1 parent d79ef51 commit fd641d0
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 9 deletions.
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

0 comments on commit fd641d0

Please sign in to comment.