-
-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Iota wallet #11398
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
Iota wallet #11398
Changes from 14 commits
e3ea17b
6ddaa34
8f07362
a1c0bf2
4845cb7
6cbdb9b
e06b875
9890675
667146e
32db13a
aa761ce
676b800
8b3d767
d7f1f10
1fae91a
03347dc
9290828
87224b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| """ | ||
| Support for IOTA wallets. | ||
|
|
||
| For more details about this component, please refer to the documentation at | ||
| https://home-assistant.io/components/iota/ | ||
| """ | ||
| import logging | ||
| from datetime import timedelta | ||
|
|
||
| import voluptuous as vol | ||
|
|
||
| import homeassistant.helpers.config_validation as cv | ||
| from homeassistant.helpers.discovery import load_platform | ||
| from homeassistant.helpers.entity import Entity | ||
|
|
||
| DOMAIN = 'iota' | ||
|
|
||
| REQUIREMENTS = ['pyota==2.0.3'] | ||
|
|
||
| IOTA_PLATFORMS = ['sensor'] | ||
|
|
||
| SCAN_INTERVAL = timedelta(minutes=10) | ||
|
|
||
| CONF_IRI = 'iri' | ||
| CONF_TESTNET = 'testnet' | ||
| CONF_WALLETS = 'wallets' | ||
| CONF_WALLET_NAME = 'name' | ||
| CONF_WALLET_SEED = 'seed' | ||
|
|
||
| WALLET_CONFIG = vol.Schema({ | ||
| vol.Required(CONF_WALLET_NAME): cv.string, | ||
| vol.Required(CONF_WALLET_SEED): cv.string, | ||
| }) | ||
|
|
||
| CONFIG_SCHEMA = vol.Schema({ | ||
| DOMAIN: vol.Schema({ | ||
| vol.Required(CONF_IRI): cv.string, | ||
| vol.Optional(CONF_TESTNET, default=False): cv.boolean, | ||
| vol.Required(CONF_WALLETS): vol.All(cv.ensure_list, [WALLET_CONFIG]) | ||
| }) | ||
| }, extra=vol.ALLOW_EXTRA) | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def setup(hass, config): | ||
| """Setup IOTA component.""" | ||
|
|
||
| # Load platforms | ||
| iota_config = config[DOMAIN] | ||
| for platform in IOTA_PLATFORMS: | ||
| load_platform(hass, platform, DOMAIN, iota_config, config) | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| class IotaDevice(Entity): | ||
| """Representation of a IOTA device.""" | ||
|
|
||
| def __init__(self, name, seed, iri, is_testnet=False): | ||
| """Initialisation of the IOTA device.""" | ||
| self._name = name | ||
| self._seed = seed | ||
| self.iri = iri | ||
| self.is_testnet = is_testnet | ||
|
|
||
| @property | ||
| def name(self): | ||
| """Return the default name of the device.""" | ||
| return self._name | ||
|
|
||
| @property | ||
| def device_state_attributes(self): | ||
| """Return the state attributes of the device.""" | ||
| attr = {CONF_WALLET_NAME: self._name} | ||
| return attr | ||
|
|
||
| @property | ||
| def api(self): | ||
| """Construct API object for interaction with the IRI node.""" | ||
| from iota import Iota | ||
| return Iota(adapter=self.iri, seed=self._seed) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| """ | ||
| Support for IOTA wallets. | ||
|
|
||
| For more details about this component, please refer to the documentation at | ||
| https://home-assistant.io/components/iota | ||
| """ | ||
| import logging | ||
| from datetime import timedelta | ||
|
|
||
| from homeassistant.components.iota import IotaDevice | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
| DEPENDENCIES = ['iota'] | ||
|
|
||
| SCAN_INTERVAL = timedelta(minutes=10) | ||
|
|
||
|
|
||
| def setup_platform(hass, config, add_devices, discovery_info=None): | ||
| """Set up the IOTA sensor.""" | ||
| # Add sensors for wallet balance | ||
| iota_config = discovery_info | ||
| sensors = [IotaBalanceSensor(wallet, iota_config) | ||
| for wallet in iota_config['wallets']] | ||
|
|
||
| # Add sensor for node information | ||
| sensors.append(IotaNodeSensor(iota_config=iota_config)) | ||
|
|
||
| add_devices(sensors) | ||
|
|
||
|
|
||
| class IotaBalanceSensor(IotaDevice): | ||
| """Implement an IOTA sensor for displaying wallets balance.""" | ||
|
|
||
| def __init__(self, wallet_config, iota_config): | ||
| """Initialize the sensor.""" | ||
| super().__init__(name=wallet_config['name'], | ||
| seed=wallet_config['seed'], | ||
| iri=iota_config['iri'], | ||
| is_testnet=iota_config['testnet']) | ||
| self._state = None | ||
|
|
||
| @property | ||
| def name(self): | ||
| """Return the name of the sensor.""" | ||
| return '{} Balance'.format(self._name) | ||
|
|
||
| @property | ||
| def state(self): | ||
| """Return the state of the sensor.""" | ||
| return self._state | ||
|
|
||
| @property | ||
| def unit_of_measurement(self): | ||
| """Return the unit of measurement.""" | ||
| return 'IOTA' | ||
|
|
||
| def update(self): | ||
| """Fetch new balance from IRI.""" | ||
| self._state = self.api.get_inputs()['totalBalance'] | ||
|
|
||
|
|
||
| class IotaNodeSensor(IotaDevice): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume that this should be a binary sensor. A node can be offline or online.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, a node can have multiple attributes, which are changing over time (https://iota.readme.io/v1.2.0/reference#getnodeinfo)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Attributes and state are not the same. A binary sensor can have attributes as well. If a node is always present then it's doesn't make sense. There are a dozen values available from getNodeInfo. Those details should be exposed as attributes.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Information about the node is part of the attributes of the node sensor and should be part of the wallet. |
||
| """Implement an IOTA sensor for displaying attributes of node.""" | ||
|
|
||
| def __init__(self, iota_config): | ||
| """Initialize the sensor.""" | ||
| super().__init__(name='Node Info', seed=None, iri=iota_config['iri'], | ||
| is_testnet=iota_config['testnet']) | ||
| self._state = None | ||
| self._attr = {} | ||
|
|
||
| @property | ||
| def name(self): | ||
| """Return the name of the sensor.""" | ||
| return 'IOTA Node' | ||
|
|
||
| @property | ||
| def state(self): | ||
| """Return the state of the sensor.""" | ||
| return self._state | ||
|
|
||
| @property | ||
| def device_state_attributes(self): | ||
| """Return the state attributes of the device.""" | ||
| return self._attr | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the moment this will stay empty.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed that line. |
||
|
|
||
| @property | ||
| def unit_of_measurement(self): | ||
| """Return the unit of measurement.""" | ||
| return '' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a valid unit of measurement.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed it |
||
|
|
||
| def update(self): | ||
| """Fetch new attribures IRI node.""" | ||
| node_info = self.api.get_node_info() | ||
| self._state = node_info.get('appVersion') | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is it useful to know the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The value of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would still require an additional part because it only shows the version and not if the node is up-to-date. |
||
|
|
||
| # convert values to raw string formats | ||
| self._attr = {k: str(v) for k, v in node_info.items()} | ||
|
|
||
| # add values of iri config | ||
| self._attr['url'] = self.iri | ||
| self._attr['testnet'] = self.is_testnet | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to update this as it will never change. Set it when you initialize the sensor.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
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.
There is only a sensor. This doesn't require to include a component.
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.
Hey, not yet. I am going to add more features to this component. Is it necessary to be a sensor only PR?
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.
No, it's the right way to create a component if there is coming a binary sensor or switch platform which can share the common stuff. Otherwise everything can be handled in the platform itself as no sharing is needed.