Move 7 IoT modules to oca-ocb-hw and 9 product modules to oca-product

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ernad Husremovic 2025-08-30 17:53:59 +02:00
parent 233861d40c
commit e47fde0e04
705 changed files with 0 additions and 57244 deletions

View file

@ -1,44 +0,0 @@
# IoT AMQP
Odoo addon: iot_amqp_oca
## Installation
```bash
pip install odoo-bringout-oca-iot-iot_amqp_oca
```
## Dependencies
This addon depends on:
- iot_output_oca
## Manifest Information
- **Name**: IoT AMQP
- **Version**: 16.0.1.0.0
- **Category**: IoT
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/iot](https://github.com/OCA/iot) branch 16.0, addon `iot_amqp_oca`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -1,32 +0,0 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Iot_amqp_oca Module - iot_amqp_oca
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -1,3 +0,0 @@
# Configuration
Refer to Odoo settings for iot_amqp_oca. Configure related models, access rights, and options as needed.

View file

@ -1,3 +0,0 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -1,5 +0,0 @@
# Dependencies
This addon depends on:
- [iot_output_oca](https://github.com/bringout/oca-technical)

View file

@ -1,4 +0,0 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon iot_amqp_oca or install in UI.

View file

@ -1,7 +0,0 @@
# Install
```bash
pip install odoo-bringout-oca-iot-iot_amqp_oca"
# or
uv pip install odoo-bringout-oca-iot-iot_amqp_oca"
```

View file

@ -1,15 +0,0 @@
# Models
Detected core models and extensions in iot_amqp_oca.
```mermaid
classDiagram
class iot_amqp_host
class iot_communication_system_action
class iot_device_output
class iot_device_output_action
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -1,6 +0,0 @@
# Overview
Packaged Odoo addon: iot_amqp_oca. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon iot_amqp_oca
- License: LGPL-3

View file

@ -1,3 +0,0 @@
# Reports
This module does not define custom reports.

View file

@ -1,34 +0,0 @@
# Security
Access control and security definitions in iot_amqp_oca.
## Access Control Lists (ACLs)
Model access permissions defined in:
- **[ir.model.access.csv](../iot_amqp_oca/security/ir.model.access.csv)**
- 2 model access rules
## Record Rules
Row-level security rules defined in:
```mermaid
graph TB
subgraph "Security Layers"
A[Users] --> B[Groups]
B --> C[Access Control Lists]
C --> D[Models]
B --> E[Record Rules]
E --> F[Individual Records]
end
```
Security files overview:
- **[ir.model.access.csv](../iot_amqp_oca/security/ir.model.access.csv)**
- Model access permissions (CRUD rights)
Notes
- Access Control Lists define which groups can access which models
- Record Rules provide row-level security (filter records by user/group)
- Security groups organize users and define permission sets
- All security is enforced at the ORM level by Odoo

View file

@ -1,5 +0,0 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -1,7 +0,0 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon iot_amqp_oca
```

View file

@ -1,3 +0,0 @@
# Wizards
This module does not include UI wizards.

View file

@ -1,80 +0,0 @@
========
IoT AMQP
========
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:906fa0b02813f40ecaaf8f4b48261919b2f1ee30a29ac68ad2f4ea6d0165a24d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fiot-lightgray.png?logo=github
:target: https://github.com/OCA/iot/tree/16.0/iot_amqp_oca
:alt: OCA/iot
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/iot-16-0/iot-16-0-iot_amqp_oca
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/iot&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This addon defines AMQP as an integration option with a device.
With AMQP, we will send and AMQP message to a broker that will send it to the
device.
Then, the device will do the expected action.
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/iot/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/iot/issues/new?body=module:%20iot_amqp_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Creu Blanca
Contributors
~~~~~~~~~~~~
* Enric Tobella <etobella@creublanca.es>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/iot <https://github.com/OCA/iot/tree/16.0/iot_amqp_oca>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -1 +0,0 @@
from . import models

View file

@ -1,20 +0,0 @@
# Copyright (C) 2018 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "IoT AMQP",
"version": "16.0.1.0.0",
"category": "IoT",
"author": "Creu Blanca, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"summary": "Integrate Iot Outputs with AMQP",
"depends": ["iot_output_oca"],
"external_dependencies": {"python": ["pika"]},
"website": "https://github.com/OCA/iot",
"data": [
"security/ir.model.access.csv",
"views/iot_amqp_host.xml",
"data/system_data.xml",
"views/iot_device_output_views.xml",
],
}

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="amqp_system" model="iot.communication.system">
<field name="name">AMQP</field>
<field name="applies_to">output</field>
</record>
<record id="amqp_action" model="iot.communication.system.action">
<field name="communication_system_id" ref="amqp_system" />
<field name="name">amqp</field>
</record>
</odoo>

View file

@ -1,140 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_amqp
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_amqp
#: model:ir.ui.menu,name:iot_amqp.iot_amqp_host_menu
msgid "AMQP Hosts"
msgstr "AMQP hostovi"
#. module: iot_amqp
#: model_terms:ir.ui.view,arch_db:iot_amqp.iot_device_output_form
msgid "AMQP configuration"
msgstr "AMQP konfiguracija"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__active
msgid "Active"
msgstr "Aktivan"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_exchange
msgid "Amqp Exchange"
msgstr "Amqp exchange"
#. module: iot_amqp
#: model:ir.actions.act_window,name:iot_amqp.iot_amqp_host_act_window
#: model:ir.model,name:iot_amqp.model_iot_amqp_host
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_host_id
msgid "Amqp Host"
msgstr "Amqp host"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_payload
msgid "Amqp Payload"
msgstr "Amqp payload"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_routing_key
msgid "Amqp Routing Key"
msgstr "Amqp routing ključ"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__connection
msgid "Connection"
msgstr "Konekcija"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__display_name
msgid "Display Name"
msgstr "Prikazani naziv"
#. module: iot_amqp
#: code:addons/iot_amqp/models/iot_device_output.py:23
#, python-format
msgid "Exchange is required"
msgstr "Exchange je potreban"
#. module: iot_amqp
#: code:addons/iot_amqp/models/iot_device_output.py:31
#, python-format
msgid "Host is required"
msgstr "Host je potreban"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__id
msgid "ID"
msgstr "ID"
#. module: iot_amqp
#: model:ir.model,name:iot_amqp.model_iot_device_output_action
msgid "IoT Action"
msgstr "IoT akcija"
#. module: iot_amqp
#: model:ir.model,name:iot_amqp.model_iot_device_output
msgid "IoT Device"
msgstr "IoT uređaj"
#. module: iot_amqp
#: model:ir.model,name:iot_amqp.model_iot_system_action
msgid "IoT System.action"
msgstr "IoT sistem.akcija"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host____last_update
msgid "Last Modified on"
msgstr "Zadnje mijenjano"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__name
msgid "Name"
msgstr "Naziv:"
#. module: iot_amqp
#: code:addons/iot_amqp/models/iot_device_output.py:27
#, python-format
msgid "Routing Key is required"
msgstr "Routing ključ je potreban"
#. module: iot_amqp
#: model_terms:ir.ui.view,arch_db:iot_amqp.iot_device_output_form
msgid "Run"
msgstr "Pokrenut"
#. module: iot_amqp
#: model_terms:ir.ui.view,arch_db:iot_amqp.iot_amqp_host_form_view
msgid "amqp://USER:PASS@HOST"
msgstr "amqp://KORISNIK:LOZINKA@HOST"

View file

@ -1,140 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_amqp
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_amqp
#: model:ir.ui.menu,name:iot_amqp.iot_amqp_host_menu
msgid "AMQP Hosts"
msgstr ""
#. module: iot_amqp
#: model_terms:ir.ui.view,arch_db:iot_amqp.iot_device_output_form
msgid "AMQP configuration"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__active
msgid "Active"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_exchange
msgid "Amqp Exchange"
msgstr ""
#. module: iot_amqp
#: model:ir.actions.act_window,name:iot_amqp.iot_amqp_host_act_window
#: model:ir.model,name:iot_amqp.model_iot_amqp_host
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_host_id
msgid "Amqp Host"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_payload
msgid "Amqp Payload"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_device_output__amqp_routing_key
msgid "Amqp Routing Key"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__connection
msgid "Connection"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__create_uid
msgid "Created by"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__create_date
msgid "Created on"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__display_name
msgid "Display Name"
msgstr ""
#. module: iot_amqp
#: code:addons/iot_amqp/models/iot_device_output.py:23
#, python-format
msgid "Exchange is required"
msgstr ""
#. module: iot_amqp
#: code:addons/iot_amqp/models/iot_device_output.py:31
#, python-format
msgid "Host is required"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__id
msgid "ID"
msgstr ""
#. module: iot_amqp
#: model:ir.model,name:iot_amqp.model_iot_device_output_action
msgid "IoT Action"
msgstr ""
#. module: iot_amqp
#: model:ir.model,name:iot_amqp.model_iot_device_output
msgid "IoT Device"
msgstr ""
#. module: iot_amqp
#: model:ir.model,name:iot_amqp.model_iot_system_action
msgid "IoT System.action"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host____last_update
msgid "Last Modified on"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__write_uid
msgid "Last Updated by"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__write_date
msgid "Last Updated on"
msgstr ""
#. module: iot_amqp
#: model:ir.model.fields,field_description:iot_amqp.field_iot_amqp_host__name
msgid "Name"
msgstr ""
#. module: iot_amqp
#: code:addons/iot_amqp/models/iot_device_output.py:27
#, python-format
msgid "Routing Key is required"
msgstr ""
#. module: iot_amqp
#: model_terms:ir.ui.view,arch_db:iot_amqp.iot_device_output_form
msgid "Run"
msgstr ""
#. module: iot_amqp
#: model_terms:ir.ui.view,arch_db:iot_amqp.iot_amqp_host_form_view
msgid "amqp://USER:PASS@HOST"
msgstr ""

View file

@ -1,142 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_amqp_oca
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_amqp_oca
#: model:ir.ui.menu,name:iot_amqp_oca.iot_amqp_host_menu
msgid "AMQP Hosts"
msgstr ""
#. module: iot_amqp_oca
#: model_terms:ir.ui.view,arch_db:iot_amqp_oca.iot_device_output_form
msgid "AMQP configuration"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__active
msgid "Active"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_exchange
msgid "Amqp Exchange"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.actions.act_window,name:iot_amqp_oca.iot_amqp_host_act_window
#: model:ir.model,name:iot_amqp_oca.model_iot_amqp_host
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_host_id
msgid "Amqp Host"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_payload
msgid "Amqp Payload"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_routing_key
msgid "Amqp Routing Key"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__connection
msgid "Connection"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__create_uid
msgid "Created by"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__create_date
msgid "Created on"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__display_name
msgid "Display Name"
msgstr ""
#. module: iot_amqp_oca
#. odoo-python
#: code:addons/iot_amqp_oca/models/iot_device_output.py:0
#, python-format
msgid "Exchange is required"
msgstr ""
#. module: iot_amqp_oca
#. odoo-python
#: code:addons/iot_amqp_oca/models/iot_device_output.py:0
#, python-format
msgid "Host is required"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__id
msgid "ID"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model,name:iot_amqp_oca.model_iot_device_output_action
msgid "IoT Action"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model,name:iot_amqp_oca.model_iot_communication_system_action
msgid "IoT Communication System action"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model,name:iot_amqp_oca.model_iot_device_output
msgid "IoT Device"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host____last_update
msgid "Last Modified on"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__write_uid
msgid "Last Updated by"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__write_date
msgid "Last Updated on"
msgstr ""
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__name
msgid "Name"
msgstr ""
#. module: iot_amqp_oca
#. odoo-python
#: code:addons/iot_amqp_oca/models/iot_device_output.py:0
#, python-format
msgid "Routing Key is required"
msgstr ""
#. module: iot_amqp_oca
#: model_terms:ir.ui.view,arch_db:iot_amqp_oca.iot_device_output_form
msgid "Run"
msgstr ""
#. module: iot_amqp_oca
#: model_terms:ir.ui.view,arch_db:iot_amqp_oca.iot_amqp_host_form_view
msgid "amqp://USER:PASS@HOST"
msgstr ""

View file

@ -1,145 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_amqp_oca
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-07-12 12:09+0000\n"
"Last-Translator: Francesco Foresti <francesco.foresti@ooops404.com>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: iot_amqp_oca
#: model:ir.ui.menu,name:iot_amqp_oca.iot_amqp_host_menu
msgid "AMQP Hosts"
msgstr "Host AMQP"
#. module: iot_amqp_oca
#: model_terms:ir.ui.view,arch_db:iot_amqp_oca.iot_device_output_form
msgid "AMQP configuration"
msgstr "Configurazione AMQP"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__active
msgid "Active"
msgstr "Attivo"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_exchange
msgid "Amqp Exchange"
msgstr "Comunicazione AMQP"
#. module: iot_amqp_oca
#: model:ir.actions.act_window,name:iot_amqp_oca.iot_amqp_host_act_window
#: model:ir.model,name:iot_amqp_oca.model_iot_amqp_host
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_host_id
msgid "Amqp Host"
msgstr "Host AMQP"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_payload
msgid "Amqp Payload"
msgstr "Contenuto AMQP"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_device_output__amqp_routing_key
msgid "Amqp Routing Key"
msgstr "Chiave instradamento AMQP"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__connection
msgid "Connection"
msgstr "Connessione"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__create_date
msgid "Created on"
msgstr "Creato il"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: iot_amqp_oca
#. odoo-python
#: code:addons/iot_amqp_oca/models/iot_device_output.py:0
#, python-format
msgid "Exchange is required"
msgstr "Richiesta comunicazione"
#. module: iot_amqp_oca
#. odoo-python
#: code:addons/iot_amqp_oca/models/iot_device_output.py:0
#, python-format
msgid "Host is required"
msgstr "Richiesto host"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__id
msgid "ID"
msgstr "ID"
#. module: iot_amqp_oca
#: model:ir.model,name:iot_amqp_oca.model_iot_device_output_action
msgid "IoT Action"
msgstr "Azione IoT"
#. module: iot_amqp_oca
#: model:ir.model,name:iot_amqp_oca.model_iot_communication_system_action
msgid "IoT Communication System action"
msgstr "Azione sisterma comunicazione IoT"
#. module: iot_amqp_oca
#: model:ir.model,name:iot_amqp_oca.model_iot_device_output
msgid "IoT Device"
msgstr "Dispositivo IoT"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host____last_update
msgid "Last Modified on"
msgstr "Ultima modifica il"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: iot_amqp_oca
#: model:ir.model.fields,field_description:iot_amqp_oca.field_iot_amqp_host__name
msgid "Name"
msgstr "Nome"
#. module: iot_amqp_oca
#. odoo-python
#: code:addons/iot_amqp_oca/models/iot_device_output.py:0
#, python-format
msgid "Routing Key is required"
msgstr "Richiesta chiave instradamento"
#. module: iot_amqp_oca
#: model_terms:ir.ui.view,arch_db:iot_amqp_oca.iot_device_output_form
msgid "Run"
msgstr "Esegui"
#. module: iot_amqp_oca
#: model_terms:ir.ui.view,arch_db:iot_amqp_oca.iot_amqp_host_form_view
msgid "amqp://USER:PASS@HOST"
msgstr "amqp://USER:PASS@HOST"

View file

@ -1,4 +0,0 @@
from . import iot_amqp_host
from . import iot_device_output
from . import iot_communication_system_action
from . import iot_device_output_action

View file

@ -1,13 +0,0 @@
# Copyright 2020 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class IotAmqpHost(models.Model):
_name = "iot.amqp.host"
_description = "Amqp Host"
name = fields.Char(required=True)
connection = fields.Char()
active = fields.Boolean(default=True)

View file

@ -1,10 +0,0 @@
from odoo import models
class IoTCommunicationSystemAction(models.Model):
_inherit = "iot.communication.system.action"
def _run(self, device_action):
if self != self.env.ref("iot_amqp_oca.amqp_action"):
return super()._run(device_action)
device_action._run_amqp()

View file

@ -1,27 +0,0 @@
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class IotDeviceOutput(models.Model):
_inherit = "iot.device.output"
amqp_exchange = fields.Char()
amqp_routing_key = fields.Char()
amqp_payload = fields.Char()
amqp_host_id = fields.Many2one(
"iot.amqp.host",
)
@api.constrains(
"amqp_exchange", "amqp_routing_key", "amqp_host_id", "communication_system_id"
)
def _check_amqp(self):
amqp_system = self.env.ref("iot_amqp_oca.amqp_system")
for rec in self:
if rec.communication_system_id == amqp_system:
if not rec.amqp_exchange:
raise ValidationError(_("Exchange is required"))
if not rec.amqp_routing_key:
raise ValidationError(_("Routing Key is required"))
if not rec.amqp_host_id:
raise ValidationError(_("Host is required"))

View file

@ -1,33 +0,0 @@
# Copyright 2020 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import models
_logger = logging.getLogger(__name__)
try:
from pika import BlockingConnection, URLParameters, spec
except (ImportError, IOError) as err:
_logger.debug(err)
class IotDeviceOutputAction(models.Model):
_inherit = "iot.device.output.action"
def _run_amqp(self):
url = self.output_id.amqp_host_id.connection
connection = BlockingConnection(URLParameters(url))
channel = connection.channel()
result = channel.basic_publish(**self._generate_amqp_data())
_logger.debug(result)
connection.close()
def _generate_amqp_data(self):
return {
"exchange": self.output_id.amqp_exchange,
"routing_key": self.output_id.amqp_routing_key,
"body": self.output_id.amqp_payload,
"properties": spec.BasicProperties(),
"mandatory": False,
}

View file

@ -1 +0,0 @@
* Enric Tobella <etobella@creublanca.es>

View file

@ -1,5 +0,0 @@
This addon defines AMQP as an integration option with a device.
With AMQP, we will send and AMQP message to a broker that will send it to the
device.
Then, the device will do the expected action.

View file

@ -1,3 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_iot_amqp_host,access_iot_amqp_host,model_iot_amqp_host,iot_oca.group_iot_user,1,0,0,0
manage_iot_amqp_host,manage_iot_amqp_host,model_iot_amqp_host,iot_oca.group_iot_manager,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_iot_amqp_host access_iot_amqp_host model_iot_amqp_host iot_oca.group_iot_user 1 0 0 0
3 manage_iot_amqp_host manage_iot_amqp_host model_iot_amqp_host iot_oca.group_iot_manager 1 1 1 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -1,426 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>IoT AMQP</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="iot-amqp">
<h1 class="title">IoT AMQP</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:906fa0b02813f40ecaaf8f4b48261919b2f1ee30a29ac68ad2f4ea6d0165a24d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/iot/tree/16.0/iot_amqp_oca"><img alt="OCA/iot" src="https://img.shields.io/badge/github-OCA%2Fiot-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/iot-16-0/iot-16-0-iot_amqp_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/iot&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This addon defines AMQP as an integration option with a device.</p>
<p>With AMQP, we will send and AMQP message to a broker that will send it to the
device.
Then, the device will do the expected action.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/iot/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/iot/issues/new?body=module:%20iot_amqp_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>Creu Blanca</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/iot/tree/16.0/iot_amqp_oca">OCA/iot</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View file

@ -1,4 +0,0 @@
from . import test_amqp
from odoo.addons.iot_output_oca.tests import test_iot
# We want to test original tests in order to ensure that all works as expected

View file

@ -1,84 +0,0 @@
# Copyright 2020 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from unittest.mock import patch
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
class TestChannel:
def __init__(self, test, output, *args, **kwargs):
self.test = test
self.output = output
self.kwargs = kwargs
self.args = args
def basic_publish(
self, exchange, routing_key, body, properties=None, mandatory=False
):
self.test.assertEqual(exchange, self.output.amqp_exchange)
self.test.assertEqual(routing_key, self.output.amqp_routing_key)
self.test.assertEqual(body, self.output.amqp_payload)
class TestBlockingConnection:
def __init__(self, test, output, *args, **kwargs):
self.test = test
self.output = output
self.kwargs = kwargs
self.args = args
def connect(self, hostname, port, username, password):
return
def channel(self):
return TestChannel(self.test, self.output, *self.args, **self.kwargs)
def close(self):
pass
class TestAmqp(TransactionCase):
def setUp(self):
super().setUp()
self.host = self.env["iot.amqp.host"].create(
{"name": "Host", "connection": "amqp://demo_connection"}
)
self.device = self.env["iot.device"].create({"name": "Device"})
self.system = self.env.ref("iot_amqp_oca.amqp_system")
self.action = self.env.ref("iot_amqp_oca.amqp_action")
self.output = self.env["iot.device.output"].create(
{
"communication_system_id": self.system.id,
"device_id": self.device.id,
"name": "Output",
"amqp_exchange": "EXCHANGE",
"amqp_routing_key": "ROUTING_KEY",
"amqp_host_id": self.host.id,
"amqp_payload": "PAYLOAD",
}
)
def test_constrain_01(self):
with self.assertRaises(ValidationError):
self.output.amqp_exchange = False
def test_constrain_02(self):
with self.assertRaises(ValidationError):
self.output.amqp_routing_key = False
def test_constrain_03(self):
with self.assertRaises(ValidationError):
self.output.amqp_host_id = False
def test_amqp(self):
with patch(
"odoo.addons.iot_amqp_oca.models."
"iot_device_output_action.BlockingConnection"
) as mock:
mock.return_value = TestBlockingConnection(self, self.output)
self.output.with_context(
iot_communication_system_action_id=self.action.id
).device_run_action()
mock.assert_called()

View file

@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2020 Creu Blanca
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="iot_amqp_host_form_view">
<field name="name">iot.amqp.host.form (in iot_amqp)</field>
<field name="model">iot.amqp.host</field>
<field name="arch" type="xml">
<form>
<header />
<sheet>
<group>
<field name="name" />
<field name="connection" placeholder="amqp://USER:PASS@HOST" />
</group>
</sheet>
<div class="oe_chatter" />
</form>
</field>
</record>
<record model="ir.ui.view" id="iot_amqp_host_search_view">
<field name="name">iot.amqp.host.search (in iot_amqp)</field>
<field name="model">iot.amqp.host</field>
<field name="arch" type="xml">
<search>
<field name="name" />
</search>
</field>
</record>
<record model="ir.ui.view" id="iot_amqp_host_tree_view">
<field name="name">iot.amqp.host.tree (in iot_amqp)</field>
<field name="model">iot.amqp.host</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="iot_amqp_host_act_window">
<field name="name">Amqp Host</field>
<field name="res_model">iot.amqp.host</field>
<field name="view_mode">tree,form</field>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<menuitem
name="AMQP Hosts"
sequence="80"
id="iot_amqp_host_menu"
action="iot_amqp_host_act_window"
parent="iot_oca.iot_configuration_menu"
/>
</odoo>

View file

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="iot_device_output_form" model="ir.ui.view">
<field name="name">iot.device.output.form</field>
<field name="model">iot.device.output</field>
<field name="inherit_id" ref="iot_output_oca.iot_device_output_form" />
<field name="arch" type="xml">
<xpath
expr="//field[@name='communication_system_id']/../.."
position="after"
>
<group
string="AMQP configuration"
name="amqp_config"
attrs="{'invisible': [('communication_system_id', '!=', %(iot_amqp_oca.amqp_system)s)]}"
>
<field
name="amqp_host_id"
attrs="{'required': [('communication_system_id', '=', %(iot_amqp_oca.amqp_system)s)]}"
/>
<field
name="amqp_exchange"
attrs="{'required': [('communication_system_id', '=', %(iot_amqp_oca.amqp_system)s)]}"
/>
<field
name="amqp_routing_key"
attrs="{'required': [('communication_system_id', '=', %(iot_amqp_oca.amqp_system)s)]}"
/>
<field name="amqp_payload" />
</group>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button
name="device_run_action"
type="object"
context="{'iot_system_action_id': %(iot_amqp_oca.amqp_action)s}"
icon="fa-cogs"
string="Run"
attrs="{'invisible': [('communication_system_id', '!=', %(iot_amqp_oca.amqp_system)s)]}"
/>
</xpath>
</field>
</record>
</odoo>

View file

@ -1,42 +0,0 @@
[project]
name = "odoo-bringout-oca-iot-iot_amqp_oca"
version = "16.0.0"
description = "IoT AMQP - Integrate Iot Outputs with AMQP"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-iot-iot_output_oca>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["iot_amqp_oca"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]

View file

@ -1,44 +0,0 @@
# IoT Input
Odoo addon: iot_input_oca
## Installation
```bash
pip install odoo-bringout-oca-iot-iot_input_oca
```
## Dependencies
This addon depends on:
- iot_oca
## Manifest Information
- **Name**: IoT Input
- **Version**: 16.0.1.0.1
- **Category**: IoT
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/iot](https://github.com/OCA/iot) branch 16.0, addon `iot_input_oca`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -1,32 +0,0 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Iot_input_oca Module - iot_input_oca
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -1,3 +0,0 @@
# Configuration
Refer to Odoo settings for iot_input_oca. Configure related models, access rights, and options as needed.

View file

@ -1,3 +0,0 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -1,5 +0,0 @@
# Dependencies
This addon depends on:
- [iot_oca](https://github.com/bringout/oca-technical)

View file

@ -1,4 +0,0 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon iot_input_oca or install in UI.

View file

@ -1,7 +0,0 @@
# Install
```bash
pip install odoo-bringout-oca-iot-iot_input_oca"
# or
uv pip install odoo-bringout-oca-iot-iot_input_oca"
```

View file

@ -1,14 +0,0 @@
# Models
Detected core models and extensions in iot_input_oca.
```mermaid
classDiagram
class iot_device_input
class iot_device_input_action
class iot_device
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -1,6 +0,0 @@
# Overview
Packaged Odoo addon: iot_input_oca. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon iot_input_oca
- License: LGPL-3

View file

@ -1,3 +0,0 @@
# Reports
This module does not define custom reports.

View file

@ -1,34 +0,0 @@
# Security
Access control and security definitions in iot_input_oca.
## Access Control Lists (ACLs)
Model access permissions defined in:
- **[ir.model.access.csv](../iot_input_oca/security/ir.model.access.csv)**
- 4 model access rules
## Record Rules
Row-level security rules defined in:
```mermaid
graph TB
subgraph "Security Layers"
A[Users] --> B[Groups]
B --> C[Access Control Lists]
C --> D[Models]
B --> E[Record Rules]
E --> F[Individual Records]
end
```
Security files overview:
- **[ir.model.access.csv](../iot_input_oca/security/ir.model.access.csv)**
- Model access permissions (CRUD rights)
Notes
- Access Control Lists define which groups can access which models
- Record Rules provide row-level security (filter records by user/group)
- Security groups organize users and define permission sets
- All security is enforced at the ORM level by Odoo

View file

@ -1,5 +0,0 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -1,7 +0,0 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon iot_input_oca
```

View file

@ -1,3 +0,0 @@
# Wizards
This module does not include UI wizards.

View file

@ -1,157 +0,0 @@
=========
IoT Input
=========
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4027dfc83e42e31e5a186fd4a2fd0d7e1bb0829ed30f9395c9053177d9b13140
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fiot-lightgray.png?logo=github
:target: https://github.com/OCA/iot/tree/16.0/iot_input_oca
:alt: OCA/iot
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/iot-16-0/iot-16-0-iot_input_oca
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/iot&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This addon allows to use a device in order to input data to odoo automatically.
It opens a URL that a device can use to connect (with a password) that can only
execute an specific action.
Inputs are useful when a device wants to communicate to odoo for a single
and simple action.
This way, the device does not need to be configured with a odoo user and
password, it is handled by odoo devices.
Examples:
* Sending the temperature every three minutes.
* Sending the RFID that the device has received in order to perform some action
**Table of contents**
.. contents::
:local:
Usage
=====
There are two endpoints you can use:
Endpoint 1: /iot/<serial>/action
Takes `application/x-www-form-urlencoded` parameters:
passphase, value (where value is a JSON object)
1. Create a Device on `IoT > Config Devices`
2. Access the Inputs section of the device
3. Create an input. You must define a serial, passphrase, function and model
The function that the system will call must be of the following kind::
@api.model
def call_function(self, key):
return {}
Where `key` is the input string send by the device and the result must be a dictionary
that will be responded to the device as a JSON.
Endpoint 2: /iot/<device_identification>/multi_input
It can be used to send values with multiple data in one POST request such as:
- Values for inputs of the same device with different address (multi input)
- Values for inputs of the same device with same address, different values (multi event)
- Mix of the above (multi input, multi event)
Takes `application/x-www-form-urlencoded` parameters:
passphase, values (a JSON array of JSON objects)
It is called using device_identification and passing two POST parameters: device passphrase and
a JSON string containing an array of values for input
- The value for the `address` key can be a string or a numeric (to conserve bytes in memory
restricted devices when creating the JSON object) and is converted to string when parsing.
- The value for the `value` key can either be string, number or boolean according to
JSON specs.
You can see an example of a valid JSON input object in the examples folder, using a few
combinations.
It requires the function that the system will call must be of the following kind::
@api.model
def call_function(self, key):
'do something
if err:
return {'status': 'error', 'message': 'The error message you want to send to the device'}
return {'status': 'ok', 'message': 'Optional success message'}
Where `key` is a dict send by the device having at least value for keys: 'address', 'value'
The function must always return a JSON with status and message. If value contains a value
with 'uuid' as key, it is returned along with the object for the IoT device to identify
success/failure per record.
It has full error reporting and the return value is a JSON array of dicts containing at
least status and message. Error message respose is at some points generic, though
extended logging is done in Odoo server logs.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/iot/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/iot/issues/new?body=module:%20iot_input_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Creu Blanca
Contributors
~~~~~~~~~~~~
* Enric Tobella <etobella@creublanca.es>
* Dimitrios Tanis <dtanis@tanisfood.gr>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-etobella| image:: https://github.com/etobella.png?size=40px
:target: https://github.com/etobella
:alt: etobella
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-etobella|
This module is part of the `OCA/iot <https://github.com/OCA/iot/tree/16.0/iot_input_oca>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -1,2 +0,0 @@
from . import models
from . import controller

View file

@ -1,19 +0,0 @@
# Copyright (C) 2018 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "IoT Input",
"version": "16.0.1.0.1",
"author": "Creu Blanca, Odoo Community Association (OCA)",
"category": "IoT",
"license": "AGPL-3",
"installable": True,
"summary": "IoT Input module",
"depends": ["iot_oca"],
"website": "https://github.com/OCA/iot",
"maintainers": ["etobella"],
"data": [
"security/ir.model.access.csv",
"views/iot_device_views.xml",
"views/iot_device_input_views.xml",
],
}

View file

@ -1 +0,0 @@
from . import iot_input_controller

View file

@ -1,105 +0,0 @@
# Copyright 2018 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import json
import logging
from odoo import _, http
_logger = logging.getLogger(__name__)
class CallIot(http.Controller):
@http.route(
["/iot/<serial>/action"],
type="http",
auth="none",
methods=["POST"],
csrf=False,
)
def call_unauthorized_iot(self, serial, passphrase=False, *args, **kwargs):
request = http.request
if not request.env:
return json.dumps(False)
return json.dumps(
request.env["iot.device.input"]
.sudo()
.get_device(serial, passphrase)
.call_device(**kwargs)
)
@http.route(
["/iot/<serial>/multi_input"],
type="http",
auth="none",
methods=["POST"],
csrf=False,
)
def call_unauthorized_iot_multi_input(
self, serial, passphrase=False, values=False, *args, **kwargs
):
"""Controller to write multiple input data to device inputs
:param string passphrase:
Device passphrase in POST data.
:param string values:
JSON formatted string containing a JSON an array of JSON objects.
"""
request = http.request
if not request.env:
_logger.warning("env not set")
return json.dumps({"status": "error", "message": _("Server Error")})
if not passphrase:
_logger.warning("Passphrase is required")
return json.dumps(
{"status": "error", "message": _("Passphrase is required")}
)
if not values:
_logger.warning("Values is required")
return json.dumps({"status": "error", "message": _("Values is required")})
# Decode JSON object here and use pure python objects in further calls
try:
if isinstance(values, str):
values = json.loads(values)
if not isinstance(values, list):
raise SyntaxError
except json.decoder.JSONDecodeError:
_logger.warning("Values is not a valid JSON")
return json.dumps(
{"status": "error", "message": _("Values is not a valid JSON")}
)
except SyntaxError:
_logger.warning("Values should be a JSON array of JSON objects")
return json.dumps(
{
"status": "error",
"message": _("Values should be a JSON array of JSON objects"),
}
)
# Encode response to JSON and return
result = (
request.env["iot.device.input"]
.sudo()
.get_device(serial, passphrase)
.call_device(values=values)
)
if result["status"] != "ok":
return json.dumps({"status": result["status"]})
return json.dumps(result["result"])
@http.route(
["/iot/<serial>/check"], type="http", auth="none", methods=["POST"], csrf=False
)
def check_unauthorized_iot(self, serial, *args, **kwargs):
request = http.request
if not request.env:
return json.dumps(False)
device = (
request.env["iot.device.input"]
.sudo()
.get_device(serial, kwargs["passphrase"])
)
if device:
return json.dumps({"state": True})
return json.dumps({"state": False})

View file

@ -1,19 +0,0 @@
[
{
"address": "ZMPT101B_1",
"value": 230
},
{
"address": 1,
"value": true
},
{
"address": 2,
"value": "Door opened",
"uuid": "abcde"
},
{
"address": 10,
"value": -18.5
}
]

View file

@ -1,250 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_input
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__action_ids
msgid "Action"
msgstr "Akcija"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__action_count
msgid "Action Count"
msgstr "Broj akcija"
#. module: iot_input
#: model:ir.model,name:iot_input.model_iot_device_input_action
msgid "Action of device inputs"
msgstr "Akcija unosa uređaja"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__active
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_input_search
msgid "Active"
msgstr "Aktivan"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__address
msgid "Address"
msgstr "Adresa"
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:54
#, python-format
msgid "Address for Input is required"
msgstr "Adresa za unos je potrebna"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__args
msgid "Args"
msgstr "Argumenti"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__call_function
msgid "Call Function"
msgstr "Pozovi funkciju"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__call_model_id
msgid "Call Model"
msgstr "Pozovi model"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__create_uid
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__create_date
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: iot_input
#: code:addons/iot_input/models/mail_message.py:15
#, python-format
msgid "Detected automatically by %s"
msgstr "Automatski otkriveno od %s"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__device_id
msgid "Device"
msgstr "Uređaj"
#. module: iot_input
#: code:addons/iot_input/models/iot_device_input.py:61
#, python-format
msgid "Device cannot be found"
msgstr "Uređaj se ne može pronaći"
#. module: iot_input
#: model:ir.model,name:iot_input.model_iot_device_input
msgid "Device input"
msgstr "Unos uređaja"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__display_name
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__display_name
msgid "Display Name"
msgstr "Prikazani naziv"
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:136
#, python-format
msgid "Empty values array"
msgstr "Prazan niz vrijednosti"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__id
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__id
msgid "ID"
msgstr "ID"
#. module: iot_input
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_input_search
msgid "Inactive"
msgstr "Neaktivan"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device__input_ids
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__input_id
msgid "Input"
msgstr "Ulaz"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device__input_count
msgid "Input Count"
msgstr "Broj unosa"
#. module: iot_input
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_form
msgid "Inputs"
msgstr "Ulazi"
#. module: iot_input
#: model:ir.model,name:iot_input.model_iot_device
msgid "IoT Device"
msgstr "IoT uređaj"
#. module: iot_input
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_input_search
msgid "IoT Device Input Search"
msgstr "Pretraga unosa IoT uređaja"
#. module: iot_input
#: model:ir.actions.act_window,name:iot_input.iot_device_input_action
msgid "IoT Inputs"
msgstr "IoT unosi"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__lang
msgid "Language"
msgstr "Jezik"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input____last_update
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action____last_update
msgid "Last Modified on"
msgstr "Zadnje mijenjano"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__write_uid
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__write_date
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: iot_input
#: model:ir.model,name:iot_input.model_mail_message
msgid "Message"
msgstr "Poruka"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__name
msgid "Name"
msgstr "Naziv:"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__passphrase
msgid "Passphrase"
msgstr "Parolska fraza"
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:43
#, python-format
msgid "Passphrase is required"
msgstr "Parolska fraza je potrebna"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__res
msgid "Res"
msgstr "Res"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__serial
msgid "Serial"
msgstr "Serijski broj"
#. module: iot_input
#: code:addons/iot_input/models/iot_device_input.py:47
#, python-format
msgid "Serial and passphrase are required"
msgstr "Serijski broj i parolska fraza su potrebni"
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:39
#, python-format
msgid "Server Error"
msgstr "Greška poslužitelja"
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:74
#: code:addons/iot_input/models/iot_device.py:87
#: code:addons/iot_input/models/iot_device.py:117
#: code:addons/iot_input/models/iot_device.py:123
#: code:addons/iot_input/models/iot_device.py:129
#, python-format
msgid "Server Error. Check server logs"
msgstr "Greška servera. Provjerite zapisnike servera"
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:61
#, python-format
msgid "Value for Input is required"
msgstr "Vrijednost za unos je potrebna"
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:56
#, python-format
msgid "Values is not a valid JSON"
msgstr "Vrijednosti nisu važeći JSON"
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:47
#, python-format
msgid "Values is required"
msgstr "Vrijednosti su potrebne"
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:61
#, python-format
msgid "Values should be a JSON array of JSON objects"
msgstr "Vrijednosti trebaju biti JSON niz JSON objekata"

View file

@ -1,246 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_input_oca
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2022-06-03 11:05+0000\n"
"Last-Translator: jabelchi <jabelchi@gmail.com>\n"
"Language-Team: none\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3.2\n"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_kanban
msgid ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" Inputs"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_ids
msgid "Action"
msgstr "Acció"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_count
msgid "Action Count"
msgstr "Nombre d'accions"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input_action
msgid "Action of device inputs"
msgstr "Acció d'entrades de dispositiu"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__active
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Active"
msgstr "Actiu"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__address
msgid "Address"
msgstr "Adreça"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Address for Input is required"
msgstr "L'adreça d'entrada és necessària"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__args
msgid "Args"
msgstr "Args"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_function
msgid "Call Function"
msgstr "Crida a la funció"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_model_id
msgid "Call Model"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_uid
msgid "Created by"
msgstr "Creat per"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_date
msgid "Created on"
msgstr "Creat el"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__device_id
msgid "Device"
msgstr "Dispositiu"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Device cannot be found"
msgstr "No es troba el dispositiu"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input
msgid "Device input"
msgstr "Entrada de dispositiu"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__display_name
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__display_name
msgid "Display Name"
msgstr "Nom a mostrar"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__id
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__id
msgid "ID"
msgstr "ID"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Inactive"
msgstr "Inactiu"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_ids
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__input_id
msgid "Input"
msgstr "Entrada"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_count
msgid "Input Count"
msgstr "Nombre d'entrades"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_form
msgid "Inputs"
msgstr "Entrades"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device
msgid "IoT Device"
msgstr "Dispositiu IoT"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "IoT Device Input Search"
msgstr "Cerca de dispositius IoT"
#. module: iot_input_oca
#: model:ir.actions.act_window,name:iot_input_oca.iot_device_input_action
msgid "IoT Inputs"
msgstr "Entrades IoT"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__kwargs
msgid "Kwargs"
msgstr "Kwargs"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__lang
msgid "Language"
msgstr "Idioma"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input____last_update
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action____last_update
msgid "Last Modified on"
msgstr "Darrera modificació el"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_uid
msgid "Last Updated by"
msgstr "Darrera actualització per"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_date
msgid "Last Updated on"
msgstr "Darrera actualització el"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__name
msgid "Name"
msgstr "Nom"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__passphrase
msgid "Passphrase"
msgstr "Contrasenya"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Passphrase is required"
msgstr "Es requereix contrasenya"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__res
msgid "Res"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__serial
msgid "Serial"
msgstr "Número de sèrie"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Serial and passphrase are required"
msgstr "Es requereix número de sèrie i contrasenya"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Server Error"
msgstr "Error de servidor"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Server Error. Check server logs"
msgstr "Error de servidor. Comproveu els registres del servidor"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is not a valid JSON"
msgstr "El valor no és un JSON vàlid"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is required"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values should be a JSON array of JSON objects"
msgstr ""

View file

@ -1,248 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_input_oca
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-09-03 13:40+0000\n"
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
"Language-Team: none\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_kanban
msgid ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" Inputs"
msgstr ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" Entradas"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_ids
msgid "Action"
msgstr "Acción"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_count
msgid "Action Count"
msgstr "Conteo de acciones"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input_action
msgid "Action of device inputs"
msgstr "Acción de las entradas del dispositivo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__active
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Active"
msgstr "Activo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__address
msgid "Address"
msgstr "Dirección"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Address for Input is required"
msgstr "Se requiere la dirección para la entrada"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__args
msgid "Args"
msgstr "Argumentos"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_function
msgid "Call Function"
msgstr "Función de llamada"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_model_id
msgid "Call Model"
msgstr "Modelo de llamada"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_date
msgid "Created on"
msgstr "Creado el"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__device_id
msgid "Device"
msgstr "Dispositivo"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Device cannot be found"
msgstr "No se puede encontrar el dispositivo"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input
msgid "Device input"
msgstr "Entrada del dispositivo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__display_name
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__display_name
msgid "Display Name"
msgstr "Mostrar Nombre"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__id
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__id
msgid "ID"
msgstr "ID (identificación)"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Inactive"
msgstr "Inactivo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_ids
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__input_id
msgid "Input"
msgstr "Entrada"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_count
msgid "Input Count"
msgstr "Conteo de entradas"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_form
msgid "Inputs"
msgstr "Entradas"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device
msgid "IoT Device"
msgstr "Dispositivo IoT"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "IoT Device Input Search"
msgstr "Búsqueda de entrada de dispositivos IoT"
#. module: iot_input_oca
#: model:ir.actions.act_window,name:iot_input_oca.iot_device_input_action
msgid "IoT Inputs"
msgstr "Entradas IoT"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__kwargs
msgid "Kwargs"
msgstr "Kwargs"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__lang
msgid "Language"
msgstr "Lenguaje"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input____last_update
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action____last_update
msgid "Last Modified on"
msgstr "Última Modificación el"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_uid
msgid "Last Updated by"
msgstr "Actualizado por Última vez por"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_date
msgid "Last Updated on"
msgstr "Última actualización el"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__name
msgid "Name"
msgstr "Nombre"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__passphrase
msgid "Passphrase"
msgstr "Frase de acceso"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Passphrase is required"
msgstr "Se requiere una frase de acceso"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__res
msgid "Res"
msgstr "Resultado"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__serial
msgid "Serial"
msgstr "Serie"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Serial and passphrase are required"
msgstr "Se requiere serie y frase de contraseña"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Server Error"
msgstr "Error del servidor"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Server Error. Check server logs"
msgstr "Error del servidor. Compruebe los registros del servidor"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is not a valid JSON"
msgstr "Los valores no son un JSON válido"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is required"
msgstr "Se requieren valores"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values should be a JSON array of JSON objects"
msgstr "Los valores deben ser una matriz de objetos JSON"

View file

@ -1,248 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_input_oca
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-10-09 08:13+0000\n"
"Last-Translator: Mostafa Barmshory <mostafa.barmshory@gmail.com>\n"
"Language-Team: none\n"
"Language: fa\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_kanban
msgid ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" Inputs"
msgstr ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" ورودی‌ها"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_ids
msgid "Action"
msgstr "فعالیت"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_count
msgid "Action Count"
msgstr "تعداد فعالیت"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input_action
msgid "Action of device inputs"
msgstr "فعالیت از دستگاه‌های ورودی"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__active
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Active"
msgstr "فعال"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__address
msgid "Address"
msgstr "آدرس"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Address for Input is required"
msgstr "آدرس برای ورودی اجباری است"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__args
msgid "Args"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_function
msgid "Call Function"
msgstr "فراخوانی عملکرد"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_model_id
msgid "Call Model"
msgstr "فراخوانی مدل"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_uid
msgid "Created by"
msgstr "ایجاد شده توسط"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_date
msgid "Created on"
msgstr "ایجاد شده توسط"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__device_id
msgid "Device"
msgstr "دستگاه"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Device cannot be found"
msgstr "دستگاه یافت نشد"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input
msgid "Device input"
msgstr "دستگاه ورودی"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__display_name
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__display_name
msgid "Display Name"
msgstr "نام نمایشی"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__id
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__id
msgid "ID"
msgstr "شناسه"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Inactive"
msgstr "غیر فعال"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_ids
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__input_id
msgid "Input"
msgstr "ورودی"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_count
msgid "Input Count"
msgstr "تعداد ورودی"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_form
msgid "Inputs"
msgstr "ورودی‌ها"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device
msgid "IoT Device"
msgstr "دستگاه اینترنت اشیا"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "IoT Device Input Search"
msgstr "جستجوی دستگاه ورودی اینترنت اشیا"
#. module: iot_input_oca
#: model:ir.actions.act_window,name:iot_input_oca.iot_device_input_action
msgid "IoT Inputs"
msgstr "ورودی‌های اینترنت اشیا"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__kwargs
msgid "Kwargs"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__lang
msgid "Language"
msgstr "زبان‌ها"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input____last_update
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action____last_update
msgid "Last Modified on"
msgstr "آخرین نگارش در"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_uid
msgid "Last Updated by"
msgstr "آخرین به روز رسانی با"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_date
msgid "Last Updated on"
msgstr "آخرین به روز رسانی در"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__name
msgid "Name"
msgstr "نام"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__passphrase
msgid "Passphrase"
msgstr "گذرواژه"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Passphrase is required"
msgstr "گذرواژه اجباری است"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__res
msgid "Res"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__serial
msgid "Serial"
msgstr "سریال"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Serial and passphrase are required"
msgstr "سریال و گذرواژه اجباری است"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Server Error"
msgstr "خطای سرور"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Server Error. Check server logs"
msgstr "خطای سرور. لاگ‌های سرور را چک کنید"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is not a valid JSON"
msgstr "مقدار یک JSON معتبر نیست"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is required"
msgstr "مقدار اجباری است"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values should be a JSON array of JSON objects"
msgstr "مقدارها باید یک ارايه JSON از اشیا JSON باشد"

View file

@ -1,250 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_input
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__action_ids
msgid "Action"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__action_count
msgid "Action Count"
msgstr ""
#. module: iot_input
#: model:ir.model,name:iot_input.model_iot_device_input_action
msgid "Action of device inputs"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__active
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_input_search
msgid "Active"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__address
msgid "Address"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:54
#, python-format
msgid "Address for Input is required"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__args
msgid "Args"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__call_function
msgid "Call Function"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__call_model_id
msgid "Call Model"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__create_uid
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__create_uid
msgid "Created by"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__create_date
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__create_date
msgid "Created on"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/models/mail_message.py:15
#, python-format
msgid "Detected automatically by %s"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__device_id
msgid "Device"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/models/iot_device_input.py:61
#, python-format
msgid "Device cannot be found"
msgstr ""
#. module: iot_input
#: model:ir.model,name:iot_input.model_iot_device_input
msgid "Device input"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__display_name
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__display_name
msgid "Display Name"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:136
#, python-format
msgid "Empty values array"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__id
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__id
msgid "ID"
msgstr ""
#. module: iot_input
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_input_search
msgid "Inactive"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device__input_ids
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__input_id
msgid "Input"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device__input_count
msgid "Input Count"
msgstr ""
#. module: iot_input
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_form
msgid "Inputs"
msgstr ""
#. module: iot_input
#: model:ir.model,name:iot_input.model_iot_device
msgid "IoT Device"
msgstr ""
#. module: iot_input
#: model_terms:ir.ui.view,arch_db:iot_input.iot_device_input_search
msgid "IoT Device Input Search"
msgstr ""
#. module: iot_input
#: model:ir.actions.act_window,name:iot_input.iot_device_input_action
msgid "IoT Inputs"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__lang
msgid "Language"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input____last_update
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action____last_update
msgid "Last Modified on"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__write_uid
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__write_uid
msgid "Last Updated by"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__write_date
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__write_date
msgid "Last Updated on"
msgstr ""
#. module: iot_input
#: model:ir.model,name:iot_input.model_mail_message
msgid "Message"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__name
msgid "Name"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__passphrase
msgid "Passphrase"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:43
#, python-format
msgid "Passphrase is required"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input_action__res
msgid "Res"
msgstr ""
#. module: iot_input
#: model:ir.model.fields,field_description:iot_input.field_iot_device_input__serial
msgid "Serial"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/models/iot_device_input.py:47
#, python-format
msgid "Serial and passphrase are required"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:39
#, python-format
msgid "Server Error"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:74
#: code:addons/iot_input/models/iot_device.py:87
#: code:addons/iot_input/models/iot_device.py:117
#: code:addons/iot_input/models/iot_device.py:123
#: code:addons/iot_input/models/iot_device.py:129
#, python-format
msgid "Server Error. Check server logs"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/models/iot_device.py:61
#, python-format
msgid "Value for Input is required"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:56
#, python-format
msgid "Values is not a valid JSON"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:47
#, python-format
msgid "Values is required"
msgstr ""
#. module: iot_input
#: code:addons/iot_input/controller/iot_input_controller.py:61
#, python-format
msgid "Values should be a JSON array of JSON objects"
msgstr ""

View file

@ -1,244 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_input_oca
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_kanban
msgid ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" Inputs"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_ids
msgid "Action"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_count
msgid "Action Count"
msgstr ""
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input_action
msgid "Action of device inputs"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__active
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Active"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__address
msgid "Address"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Address for Input is required"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__args
msgid "Args"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_function
msgid "Call Function"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_model_id
msgid "Call Model"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_uid
msgid "Created by"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_date
msgid "Created on"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__device_id
msgid "Device"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Device cannot be found"
msgstr ""
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input
msgid "Device input"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__display_name
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__display_name
msgid "Display Name"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__id
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__id
msgid "ID"
msgstr ""
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Inactive"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_ids
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__input_id
msgid "Input"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_count
msgid "Input Count"
msgstr ""
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_form
msgid "Inputs"
msgstr ""
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device
msgid "IoT Device"
msgstr ""
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "IoT Device Input Search"
msgstr ""
#. module: iot_input_oca
#: model:ir.actions.act_window,name:iot_input_oca.iot_device_input_action
msgid "IoT Inputs"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__kwargs
msgid "Kwargs"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__lang
msgid "Language"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input____last_update
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action____last_update
msgid "Last Modified on"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_uid
msgid "Last Updated by"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_date
msgid "Last Updated on"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__name
msgid "Name"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__passphrase
msgid "Passphrase"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Passphrase is required"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__res
msgid "Res"
msgstr ""
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__serial
msgid "Serial"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Serial and passphrase are required"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Server Error"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Server Error. Check server logs"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is not a valid JSON"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is required"
msgstr ""
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values should be a JSON array of JSON objects"
msgstr ""

View file

@ -1,248 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_input_oca
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-08-30 10:06+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.6.2\n"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_kanban
msgid ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" Inputs"
msgstr ""
"<i class=\"fa fa-keyboard-o\"/>\n"
" Input"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_ids
msgid "Action"
msgstr "Azione"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__action_count
msgid "Action Count"
msgstr "Conteggio azione"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input_action
msgid "Action of device inputs"
msgstr "Azione degli input dispositivo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__active
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Active"
msgstr "Attivo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__address
msgid "Address"
msgstr "Indirizzo"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Address for Input is required"
msgstr "È richiesto un indirizzo per l'input"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__args
msgid "Args"
msgstr "Argomenti"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_function
msgid "Call Function"
msgstr "Richiama funzione"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__call_model_id
msgid "Call Model"
msgstr "Richiama modello"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__create_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__create_date
msgid "Created on"
msgstr "Creato il"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__device_id
msgid "Device"
msgstr "Dispositivo"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Device cannot be found"
msgstr "Dispositivo non trovato"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device_input
msgid "Device input"
msgstr "Input dispositivo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__display_name
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__id
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__id
msgid "ID"
msgstr "ID"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "Inactive"
msgstr "Inattivo"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_ids
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__input_id
msgid "Input"
msgstr "Input"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device__input_count
msgid "Input Count"
msgstr "Conteggio input"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_form
msgid "Inputs"
msgstr "Input"
#. module: iot_input_oca
#: model:ir.model,name:iot_input_oca.model_iot_device
msgid "IoT Device"
msgstr "Dispositivo IoT"
#. module: iot_input_oca
#: model_terms:ir.ui.view,arch_db:iot_input_oca.iot_device_input_search
msgid "IoT Device Input Search"
msgstr "Ricerca input dispositivo IoT"
#. module: iot_input_oca
#: model:ir.actions.act_window,name:iot_input_oca.iot_device_input_action
msgid "IoT Inputs"
msgstr "Input IoT"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__kwargs
msgid "Kwargs"
msgstr "Kwargs"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__lang
msgid "Language"
msgstr "Lingua"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input____last_update
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action____last_update
msgid "Last Modified on"
msgstr "Ultima modifica il"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_uid
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__write_date
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__name
msgid "Name"
msgstr "Nome"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__passphrase
msgid "Passphrase"
msgstr "Passphrase"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Passphrase is required"
msgstr "Richiesta passphrase"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input_action__res
msgid "Res"
msgstr "Res"
#. module: iot_input_oca
#: model:ir.model.fields,field_description:iot_input_oca.field_iot_device_input__serial
msgid "Serial"
msgstr "Seriale"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device_input.py:0
#, python-format
msgid "Serial and passphrase are required"
msgstr "Richiesti seriale e passphrase"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Server Error"
msgstr "Errore server"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/models/iot_device.py:0
#, python-format
msgid "Server Error. Check server logs"
msgstr "Errore server: controllare i log del server"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is not a valid JSON"
msgstr "I valori non sono in formato JSON"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values is required"
msgstr "Richiesti valori"
#. module: iot_input_oca
#. odoo-python
#: code:addons/iot_input_oca/controller/iot_input_controller.py:0
#, python-format
msgid "Values should be a JSON array of JSON objects"
msgstr "I valori devono essere una matrice o un oggetto JSON"

View file

@ -1,2 +0,0 @@
from . import iot_device
from . import iot_device_input

View file

@ -1,77 +0,0 @@
import logging
from odoo import _, api, fields, models
_logger = logging.getLogger(__name__)
class IotDevice(models.Model):
_inherit = "iot.device"
input_ids = fields.One2many("iot.device.input", inverse_name="device_id")
input_count = fields.Integer(compute="_compute_input_count")
@api.depends("input_ids")
def _compute_input_count(self):
for r in self:
r.input_count = len(r.input_ids)
def action_show_input(self):
self.ensure_one()
action = self.env.ref("iot_input_oca.iot_device_input_action")
result = action.read()[0]
result["context"] = {
"default_device_id": self.id,
}
result["domain"] = [("device_id", "=", self.id)]
if len(self.input_ids) == 1:
result["views"] = [(False, "form")]
result["res_id"] = self.input_ids.id
return result
def parse_single_input(self, uuid=False, address=False, **kwargs):
"""Handle single input for device
:param dict value:
Dict containing at least keys 'address', 'value'
:returns: dict with keys 'status', 'message' where:
- status='ok' when value is parsed without errors
- status='error' and message='error message' when error occurs
If value contains a value with key 'uuid', it is passed in the return dict
to identify result for each entry at the iot end
:rtype: dict
"""
msg = {}
if uuid:
msg["uuid"] = uuid
if not address:
_logger.warning("Address for Input is required")
msg.update(
{"status": "error", "message": _("Address for Input is required")}
)
return msg
device_input = self.input_ids.filtered(lambda i: i.address == str(address))
if len(device_input) == 1:
if not device_input.active:
_logger.warning(
"Input with address %s is inactive, no data will be logged",
device_input.address,
)
msg.update(
{
"status": "error",
"message": _("Server Error. Check server logs"),
}
)
return msg
res = device_input.call_device(**kwargs)
if uuid:
res["uuid"] = uuid
return res
else:
_logger.warning("Input with address %s not found", address)
msg.update(
{"status": "error", "message": _("Server Error. Check server logs")}
)
return msg

View file

@ -1,146 +0,0 @@
import logging
import traceback
from io import StringIO
from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
_logger = logging.getLogger(__name__)
class IotDeviceInput(models.Model):
_name = "iot.device.input"
_description = "Device input"
_order = "name"
name = fields.Char(required=True)
device_id = fields.Many2one(
"iot.device", required=True, readonly=True, auto_join=True
)
call_model_id = fields.Many2one("ir.model")
call_function = fields.Char(required=True)
active = fields.Boolean(default=True)
serial = fields.Char()
address = fields.Char()
passphrase = fields.Char()
action_ids = fields.One2many(
"iot.device.input.action",
inverse_name="input_id",
readonly=True,
)
action_count = fields.Integer(compute="_compute_action_count")
lang = fields.Selection(
selection=lambda self: self.env["res.lang"].get_installed(),
string="Language",
)
@api.depends("action_ids")
def _compute_action_count(self):
for r in self:
r.action_count = len(r.action_ids)
def _call_device(self, *args, **kwargs):
self.ensure_one()
obj = self
if self.call_model_id:
obj = self.env[self.call_model_id.model].with_context(
iot_device_input_id=self.id,
iot_device_name=self.device_id.name,
iot_device_id=self.device_id.id,
)
if self.lang:
obj = obj.with_context(lang=self.lang)
return getattr(obj, self.call_function)(*args, **kwargs)
def parse_args(self, serial, passphrase):
if not serial or not passphrase:
raise ValidationError(_("Serial and passphrase are required"))
return [
("serial", "=", serial),
("passphrase", "=", passphrase),
("device_id.active", "=", True),
]
@api.model
def get_device(self, serial, passphrase):
return self.search(self.parse_args(serial, passphrase), limit=1)
def call_device(self, **kwargs):
if not self:
return {"status": "error", "message": _("Device cannot be found")}
new_kwargs = kwargs.copy()
args = []
if "value" in new_kwargs and len(new_kwargs) == 1:
args.append(new_kwargs.pop("value"))
try:
# We want to control that if an error happens,
# everything will return to normal but we can process it properly
with self.env.cr.savepoint():
res = self._call_device(*args, **new_kwargs)
if not res.get("status"):
res["status"] = "ok"
error = False
except self._swallable_exceptions():
buff = StringIO()
traceback.print_exc(file=buff)
error = buff.getvalue()
_logger.error(error)
res = {"status": "ko"}
self.device_id.last_contact_date = fields.Datetime.now()
self.env["iot.device.input.action"].create(
self._add_action_vals(res, error, args, new_kwargs)
)
return res
def _swallable_exceptions(self):
# TODO: improve this list
return (UserError, ValidationError, AttributeError, TypeError)
def _add_action_vals(self, res, error, args, kwargs):
new_res = res.copy()
if error:
new_res["error"] = error
return {
"input_id": self.id,
"args": str(args or kwargs),
"res": str(res),
}
def test_input_device(self, value):
return {"value": value}
def test_model_function(self, value):
return {"status": "ok", "message": value}
def parse_multi_input(self, values):
"""Handle multiple inputs for device
:param list values:
Values is a list of dicts with at least values for keys 'address', 'value'
Each dict in the list can have:
- Different address (multi input)
- Same address, different values (multi event)
- Mix of the above (multi input, multi event)
:returns: JSON encodable list of dicts
:rtype: list
"""
device = self.device_id
if not values:
_logger.warning(
"Empty values array for input with identification %s",
self.serial,
)
return {"status": "ko"}
res = []
for d in values:
res.append(device.parse_single_input(**d))
return {"result": res}
class IoTDeviceAction(models.Model):
_name = "iot.device.input.action"
_description = "Action of device inputs"
input_id = fields.Many2one("iot.device.input")
args = fields.Char()
kwargs = fields.Char()
res = fields.Char()

View file

@ -1,2 +0,0 @@
* Enric Tobella <etobella@creublanca.es>
* Dimitrios Tanis <dtanis@tanisfood.gr>

View file

@ -1,14 +0,0 @@
This addon allows to use a device in order to input data to odoo automatically.
It opens a URL that a device can use to connect (with a password) that can only
execute an specific action.
Inputs are useful when a device wants to communicate to odoo for a single
and simple action.
This way, the device does not need to be configured with a odoo user and
password, it is handled by odoo devices.
Examples:
* Sending the temperature every three minutes.
* Sending the RFID that the device has received in order to perform some action

View file

@ -1,55 +0,0 @@
There are two endpoints you can use:
Endpoint 1: /iot/<serial>/action
Takes `application/x-www-form-urlencoded` parameters:
passphase, value (where value is a JSON object)
1. Create a Device on `IoT > Config Devices`
2. Access the Inputs section of the device
3. Create an input. You must define a serial, passphrase, function and model
The function that the system will call must be of the following kind::
@api.model
def call_function(self, key):
return {}
Where `key` is the input string send by the device and the result must be a dictionary
that will be responded to the device as a JSON.
Endpoint 2: /iot/<device_identification>/multi_input
It can be used to send values with multiple data in one POST request such as:
- Values for inputs of the same device with different address (multi input)
- Values for inputs of the same device with same address, different values (multi event)
- Mix of the above (multi input, multi event)
Takes `application/x-www-form-urlencoded` parameters:
passphase, values (a JSON array of JSON objects)
It is called using device_identification and passing two POST parameters: device passphrase and
a JSON string containing an array of values for input
- The value for the `address` key can be a string or a numeric (to conserve bytes in memory
restricted devices when creating the JSON object) and is converted to string when parsing.
- The value for the `value` key can either be string, number or boolean according to
JSON specs.
You can see an example of a valid JSON input object in the examples folder, using a few
combinations.
It requires the function that the system will call must be of the following kind::
@api.model
def call_function(self, key):
'do something
if err:
return {'status': 'error', 'message': 'The error message you want to send to the device'}
return {'status': 'ok', 'message': 'Optional success message'}
Where `key` is a dict send by the device having at least value for keys: 'address', 'value'
The function must always return a JSON with status and message. If value contains a value
with 'uuid' as key, it is returned along with the object for the IoT device to identify
success/failure per record.
It has full error reporting and the return value is a JSON array of dicts containing at
least status and message. Error message respose is at some points generic, though
extended logging is done in Odoo server logs.

View file

@ -1,5 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_iot_device_input,access_iot_device_input,model_iot_device_input,iot_oca.group_iot_user,1,1,1,0
manage_iot_device_input,access_iot_device_input,model_iot_device_input,iot_oca.group_iot_manager,1,1,1,1
access_iot_device_input_action,access_iot_device_input_action,model_iot_device_input_action,iot_oca.group_iot_user,1,1,1,0
manage_iot_device_input_action,access_iot_device_input_action,model_iot_device_input_action,iot_oca.group_iot_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_iot_device_input access_iot_device_input model_iot_device_input iot_oca.group_iot_user 1 1 1 0
3 manage_iot_device_input access_iot_device_input model_iot_device_input iot_oca.group_iot_manager 1 1 1 1
4 access_iot_device_input_action access_iot_device_input_action model_iot_device_input_action iot_oca.group_iot_user 1 1 1 0
5 manage_iot_device_input_action access_iot_device_input_action model_iot_device_input_action iot_oca.group_iot_manager 1 1 1 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -1,489 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>IoT Input</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="iot-input">
<h1 class="title">IoT Input</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4027dfc83e42e31e5a186fd4a2fd0d7e1bb0829ed30f9395c9053177d9b13140
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/iot/tree/16.0/iot_input_oca"><img alt="OCA/iot" src="https://img.shields.io/badge/github-OCA%2Fiot-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/iot-16-0/iot-16-0-iot_input_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/iot&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This addon allows to use a device in order to input data to odoo automatically.</p>
<p>It opens a URL that a device can use to connect (with a password) that can only
execute an specific action.</p>
<p>Inputs are useful when a device wants to communicate to odoo for a single
and simple action.
This way, the device does not need to be configured with a odoo user and
password, it is handled by odoo devices.</p>
<p>Examples:</p>
<ul class="simple">
<li>Sending the temperature every three minutes.</li>
<li>Sending the RFID that the device has received in order to perform some action</li>
</ul>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>There are two endpoints you can use:
Endpoint 1: /iot/&lt;serial&gt;/action</p>
<p>Takes <cite>application/x-www-form-urlencoded</cite> parameters:
passphase, value (where value is a JSON object)</p>
<ol class="arabic simple">
<li>Create a Device on <cite>IoT &gt; Config Devices</cite></li>
<li>Access the Inputs section of the device</li>
<li>Create an input. You must define a serial, passphrase, function and model</li>
</ol>
<p>The function that the system will call must be of the following kind:</p>
<pre class="literal-block">
&#64;api.model
def call_function(self, key):
return {}
</pre>
<p>Where <cite>key</cite> is the input string send by the device and the result must be a dictionary
that will be responded to the device as a JSON.</p>
<p>Endpoint 2: /iot/&lt;device_identification&gt;/multi_input
It can be used to send values with multiple data in one POST request such as:
- Values for inputs of the same device with different address (multi input)
- Values for inputs of the same device with same address, different values (multi event)
- Mix of the above (multi input, multi event)</p>
<p>Takes <cite>application/x-www-form-urlencoded</cite> parameters:
passphase, values (a JSON array of JSON objects)</p>
<p>It is called using device_identification and passing two POST parameters: device passphrase and
a JSON string containing an array of values for input
- The value for the <cite>address</cite> key can be a string or a numeric (to conserve bytes in memory
restricted devices when creating the JSON object) and is converted to string when parsing.
- The value for the <cite>value</cite> key can either be string, number or boolean according to
JSON specs.
You can see an example of a valid JSON input object in the examples folder, using a few
combinations.</p>
<p>It requires the function that the system will call must be of the following kind:</p>
<pre class="literal-block">
&#64;api.model
def call_function(self, key):
'do something
if err:
return {'status': 'error', 'message': 'The error message you want to send to the device'}
return {'status': 'ok', 'message': 'Optional success message'}
</pre>
<p>Where <cite>key</cite> is a dict send by the device having at least value for keys: address, value</p>
<p>The function must always return a JSON with status and message. If value contains a value
with uuid as key, it is returned along with the object for the IoT device to identify
success/failure per record.</p>
<p>It has full error reporting and the return value is a JSON array of dicts containing at
least status and message. Error message respose is at some points generic, though
extended logging is done in Odoo server logs.</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/iot/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/iot/issues/new?body=module:%20iot_input_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
<ul class="simple">
<li>Creu Blanca</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li>
<li>Dimitrios Tanis &lt;<a class="reference external" href="mailto:dtanis&#64;tanisfood.gr">dtanis&#64;tanisfood.gr</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/etobella"><img alt="etobella" src="https://github.com/etobella.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/iot/tree/16.0/iot_input_oca">OCA/iot</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View file

@ -1,3 +0,0 @@
from . import test_iot_in
from . import test_iot_multi_input
from . import test_iot_controller

View file

@ -1,10 +0,0 @@
from odoo import models
class ResPartner(models.Model):
_inherit = "res.partner"
def test_fake_iot_input(self, value):
partner = self.browse(value)
partner.message_post(body=str(value))
return {}

View file

@ -1,141 +0,0 @@
import json
from odoo.tests.common import HttpCase, tagged
@tagged("post_install", "-at_install")
class TestIotController(HttpCase):
def setUp(self):
super().setUp()
self.device_identification = "test_device_name"
self.passphrase = "password"
self.system = self.env["iot.communication.system"].create(
{"name": "Demo system"}
)
self.device = self.env["iot.device"].create(
{
"name": "Device",
"communication_system_id": self.system.id,
}
)
self.address_1 = "I0"
self.serial = "testingdeviceserial"
self.input_passphrase = "password"
self.device_input_1 = self.env["iot.device.input"].create(
{
"name": "Input 1",
"device_id": self.device.id,
"address": self.address_1,
"serial": self.serial,
"passphrase": self.input_passphrase,
"call_model_id": self.env.ref(
"iot_input_oca.model_iot_device_input"
).id,
"call_function": "test_model_function",
}
)
self.address_2 = "I1"
self.env["iot.device.input"].create(
{
"name": "Input 2",
"device_id": self.device.id,
"address": self.address_2,
"call_model_id": self.env.ref(
"iot_input_oca.model_iot_device_input"
).id,
"call_function": "test_model_function",
}
)
self.env["iot.device.input"].create(
{
"name": "Multi Input",
"device_id": self.device.id,
"serial": self.device_identification,
"passphrase": self.passphrase,
"call_function": "parse_multi_input",
}
)
self.single_input_values = [{"input": self.address_1, "value": "test"}]
self.values = json.dumps(
[
{"address": self.address_1, "value": "test value 1"},
{
"address": self.address_1,
"value": 2.3,
}, # Checking that nothing wrong happens with a non string
{"address": self.address_2, "value": "test value 3"},
]
)
def test_single_controller(self):
res = self.url_open(
"/iot/%s/action" % self.serial,
data={"passphrase": self.input_passphrase, "value": "123"},
)
self.assertEqual(res.json()["status"], "ok")
def test_single_controller_archived_device(self):
self.device.write({"active": False})
res = self.url_open(
"/iot/%s/action" % self.serial,
data={"passphrase": self.input_passphrase, "value": "123"},
)
self.assertEqual(res.json()["status"], "error")
def test_multi_controller_archived_device(self):
self.device.write({"active": False})
res = self.url_open(
"/iot/%s/multi_input" % self.serial,
data={"passphrase": self.input_passphrase, "values": self.values},
)
self.assertEqual(res.json()["status"], "error")
def test_multi_input_controller_error_passphrase(self):
res = self.url_open(
"/iot/%s/multi_input" % self.device_identification,
data={"values": self.values},
).json()
self.assertEqual(res["status"], "error")
def test_multi_input_controller_error_values(self):
res = self.url_open(
"/iot/%s/multi_input" % self.device_identification,
data={"passphrase": self.passphrase},
).json()
self.assertEqual(res["status"], "error")
def test_multi_input_controller_syntax_error(self):
res = self.url_open(
"/iot/%s/multi_input" % self.device_identification,
data={"passphrase": self.passphrase, "values": "{}"},
).json()
self.assertEqual(res["status"], "error")
def test_multi_input_controller_malformed_error(self):
res = self.url_open(
"/iot/%s/multi_input" % self.device_identification,
data={"passphrase": self.passphrase, "values": "{1234}"},
).json()
self.assertEqual(res["status"], "error")
def test_multi_input_controller(self):
res = self.url_open(
"/iot/%s/multi_input" % self.device_identification,
data={"passphrase": self.passphrase, "values": self.values},
)
result = res.json()
for response in result:
self.assertEqual(response["status"], "ok")
def test_multi_input_controller_unauthorized_iot_exists(self):
res = self.url_open(
"/iot/%s/check" % self.serial, data={"passphrase": self.input_passphrase}
).json()
self.assertEqual(res["state"], True)
def test_multi_input_controller_unauthorized_iot_no_exists(self):
res = self.url_open(
"/iot/%s/check" % self.passphrase,
data={"passphrase": self.input_passphrase},
).json()
self.assertEqual(res["state"], False)

View file

@ -1,122 +0,0 @@
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
class TestIotIn(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.serial = "testingdeviceserial"
cls.passphrase = "password"
cls.system = cls.env["iot.communication.system"].create({"name": "Demo system"})
cls.device = cls.env["iot.device"].create(
{"name": "Device", "communication_system_id": cls.system.id}
)
cls.device_input = cls.env["iot.device.input"].create(
{
"name": "Input",
"device_id": cls.device.id,
"active": True,
"serial": cls.serial,
"passphrase": cls.passphrase,
"call_model_id": cls.env.ref("iot_input_oca.model_iot_device_input").id,
"call_function": "test_input_device",
}
)
cls.iot = cls.env["iot.device.input"]
def test_device_action_count_ids(self):
self.assertEqual(self.device.input_count, 1)
def _get_devices(self):
action = self.device.action_show_input()
devices = self.env[action["res_model"]]
if action["res_id"]:
devices = devices.browse(action["res_id"])
else:
devices = devices.search(action["domain"])
return devices
def test_device_action(self):
devices = self._get_devices()
self.assertEqual(devices, self.device_input)
device_input_02 = self.env["iot.device.input"].create(
{
"name": "Input",
"device_id": self.device.id,
"active": True,
"serial": self.serial + self.serial,
"passphrase": self.passphrase,
"call_model_id": self.env.ref(
"iot_input_oca.model_iot_device_input"
).id,
"call_function": "test_input_device",
}
)
devices = self._get_devices()
self.assertIn(self.device_input, devices)
self.assertIn(device_input_02, devices)
def test_device_error_wrong_serial(self):
self.assertFalse(
self.iot.get_device(
serial=self.serial + self.serial, passphrase=self.passphrase
)
)
def test_device_error_wrong_passphrase(self):
self.assertFalse(
self.iot.get_device(
serial=self.serial, passphrase=self.passphrase + self.passphrase
)
)
def test_device_error_archived(self):
self.device_input.active = False
self.assertFalse(
self.iot.get_device(serial=self.serial, passphrase=self.passphrase)
)
def test_device_error_missing_data(self):
with self.assertRaises(ValidationError):
self.iot.get_device(serial=False, passphrase=self.passphrase)
def test_error_execution_without_device(self):
res = self.iot.call_device(value="hello")
self.assertEqual(res["status"], "error")
def test_device_input_calling(self):
iot = self.iot.get_device(serial=self.serial, passphrase=self.passphrase)
self.assertEqual(iot, self.device_input)
self.assertEqual(0, self.device_input.action_count)
args = "hello"
res = iot.call_device(value=args)
self.assertEqual(res, {"status": "ok", "value": args})
self.assertTrue(self.device_input.action_ids)
self.assertEqual(self.device_input.action_ids.args, str([args]))
self.assertEqual(self.device_input.action_ids.res, str(res))
self.assertEqual(1, self.device_input.action_count)
def test_device_input_calling_with_lang(self):
devices = self._get_devices()
self.assertEqual(devices, self.device_input)
device_input_lang = self.env["iot.device.input"].create(
{
"name": "Input",
"lang": "en_US",
"device_id": self.device.id,
"active": True,
"serial": self.serial + self.serial,
"passphrase": self.passphrase,
"call_model_id": self.env.ref(
"iot_input_oca.model_iot_device_input"
).id,
"call_function": "test_input_device",
}
)
devices = self._get_devices()
self.assertIn(self.device_input, devices)
self.assertIn(device_input_lang, devices)
args = "hello"
res = device_input_lang.call_device(value=args)
self.assertEqual(res, {"status": "ok", "value": args})

View file

@ -1,196 +0,0 @@
from odoo.tests.common import TransactionCase
from odoo.tools import mute_logger
class TestIotIn(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.device_identification = "test_device_name"
cls.passphrase = "password"
cls.system = cls.env["iot.communication.system"].create({"name": "Demo system"})
cls.device = cls.env["iot.device"].create(
{
"name": "Device",
"communication_system_id": cls.system.id,
}
)
cls.address_1 = "I0"
cls.device_input_1 = cls.env["iot.device.input"].create(
{
"name": "Input 1",
"device_id": cls.device.id,
"address": cls.address_1,
"call_model_id": cls.env.ref("iot_input_oca.model_iot_device_input").id,
"call_function": "test_model_function",
}
)
cls.address_2 = "I1"
cls.env["iot.device.input"].create(
{
"name": "Input 2",
"device_id": cls.device.id,
"address": cls.address_2,
"call_model_id": cls.env.ref("iot_input_oca.model_iot_device_input").id,
"call_function": "test_model_function",
}
)
cls.env["iot.device.input"].create(
{
"name": "Multi Input",
"device_id": cls.device.id,
"serial": cls.device_identification,
"passphrase": cls.passphrase,
"call_function": "parse_multi_input",
}
)
cls.single_input_values = [{"input": cls.address_1, "value": "test"}]
cls.iot = cls.env["iot.device.input"]
def test_multi_input_error_wrong_identification(self):
iot = self.iot.get_device(
serial=self.device_identification + self.device_identification,
passphrase=self.passphrase,
)
# device not found -> result is error
self.assertEqual(
iot.call_device(values=self.single_input_values)["status"],
"error",
)
def test_multi_input_error_no_inputs(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
self.assertEqual(
iot.call_device(values=[])["status"],
"ko",
)
def test_multi_input_non_existing_address(self):
non_existing_address = "I3"
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for response in iot.call_device(
values=[{"address": non_existing_address, "value": "test value 1"}],
)["result"]:
self.assertEqual(response["status"], "error")
@mute_logger("odoo.addons.iot_input_oca.models.iot_device_input")
def test_error_missing_parameter(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for response in iot.call_device(values=[{"address": self.address_1}])["result"]:
self.assertEqual(response["status"], "ko")
@mute_logger("odoo.addons.iot_input_oca.models.iot_device_input")
def test_error_with_extra_args(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for response in iot.call_device(
values=[{"address": self.address_1, "uuid": "abc"}],
)["result"]:
self.assertEqual(response["status"], "ko")
self.assertTrue("uuid" in response)
def test_error_no_address_with_extra_args(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for response in iot.call_device(values=[{"uuid": "abc"}])["result"]:
self.assertEqual(response["status"], "error")
self.assertTrue("uuid" in response)
def test_error_no_address(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for response in iot.call_device(values=[{"value": "test value"}])["result"]:
self.assertEqual(response["status"], "error")
def test_correct_one_input(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for response in iot.call_device(
values=[{"address": self.address_1, "value": "test"}],
)["result"]:
self.assertEqual(response["status"], "ok")
def test_correct_two_inputs(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for response in iot.call_device(
values=[
{"address": self.address_1, "value": "test value 1"},
{
"address": self.address_1,
"value": 2.3,
}, # Checking that nothing wrong happens with a non string
{"address": self.address_2, "value": "test value 3"},
],
)["result"]:
self.assertEqual(response["status"], "ok")
def test_correct_with_extra_args(self):
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
response_with_uuid = [
{"address": self.address_1, "value": "test value 1", "uuid": "abc"},
{"address": self.address_1, "value": "test value 2", "uuid": "def"},
{"address": self.address_2, "value": "test value 3", "uuid": "ghi"},
]
for response in iot.call_device(values=response_with_uuid)["result"]:
self.assertTrue(response["uuid"])
self.assertEqual(
response["message"],
[x for x in response_with_uuid if x["uuid"] == response["uuid"]][0][
"value"
],
)
def test_error_archived_device(self):
self.device.active = False
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
self.assertEqual(
iot.call_device(
values=[{"address": self.address_1, "value": "test"}],
)["status"],
"error",
)
def test_error_archived_device_input(self):
self.device_input_1.active = False
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for result in iot.call_device(
values=[{"address": self.address_1, "value": "test"}],
)["result"]:
self.assertEqual(
result["status"],
"error",
)
def test_error_archived_device_input_extra_args(self):
self.device_input_1.active = False
iot = self.iot.get_device(
serial=self.device_identification, passphrase=self.passphrase
)
for result in iot.call_device(
values=[{"address": self.address_1, "value": "test", "uuid": "ghi"}],
)["result"]:
self.assertEqual(
result["status"],
"error",
)
self.assertEqual(result["uuid"], "ghi")

View file

@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="iot_device_input_tree" model="ir.ui.view">
<field name="name">iot.device.input.tree</field>
<field name="model">iot.device.input</field>
<field name="arch" type="xml">
<tree delete="0">
<field name="name" />
<field name="address" />
<field name="serial" />
</tree>
</field>
</record>
<record id="iot_device_input_form" model="ir.ui.view">
<field name="name">iot.device.input.form</field>
<field name="model">iot.device.input</field>
<field name="arch" type="xml">
<form>
<header />
<sheet>
<widget
name="web_ribbon"
text="Archived"
bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<field name="active" invisible="1" />
<div class="oe_button_box" name="button_box" />
<div class="oe_title">
<h1>
<field name="name" />
</h1>
</div>
<group>
<group>
<field name="address" />
<field name="serial" />
<field name="passphrase" widget="password" />
</group>
<group>
<field name="call_model_id" options="{'no_create':True}" />
<field name="call_function" />
<field name="lang" />
</group>
</group>
<notebook invisible="1" />
</sheet>
</form>
</field>
</record>
<record id="iot_device_input_search" model="ir.ui.view">
<field name="name">iot.device.input.search</field>
<field name="model">iot.device.input</field>
<field name="arch" type="xml">
<search string="IoT Device Input Search">
<field name="name" />
<filter
name="active"
string="Active"
domain="[('active','=',True)]"
help="Active"
/>
<filter
name="inactive"
string="Inactive"
domain="[('active','=',False)]"
help="Inactive"
/>
<separator />
</search>
</field>
</record>
<record model="ir.actions.act_window" id="iot_device_input_action">
<field name="name">IoT Inputs</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">iot.device.input</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>

View file

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="iot_device_form" model="ir.ui.view">
<field name="name">iot.device.form</field>
<field name="model">iot.device</field>
<field name="inherit_id" ref="iot_oca.iot_device_form" />
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button
name="action_show_input"
type="object"
class="oe_stat_button"
icon="fa-keyboard-o"
>
<field string="Inputs" name="input_count" widget="statinfo" />
</button>
</xpath>
</field>
</record>
<record id="iot_device_kanban" model="ir.ui.view">
<field name="name">iot.device.kanban</field>
<field name="model">iot.device</field>
<field name="inherit_id" ref="iot_oca.iot_device_kanban" />
<field name="arch" type="xml">
<xpath expr="//div[@role='menu']/*[1]" position="before">
<a
type="object"
name="action_show_input"
role="menuitem"
class="dropdown-item"
>
<i class="fa fa-keyboard-o" />
Inputs
</a>
</xpath>
</field>
</record>
</odoo>

View file

@ -1,42 +0,0 @@
[project]
name = "odoo-bringout-oca-iot-iot_input_oca"
version = "16.0.0"
description = "IoT Input - IoT Input module"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-iot-iot_oca>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["iot_input_oca"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]

View file

@ -1,45 +0,0 @@
# IoT Key Employee RFID
Odoo addon: iot_key_employee_rfid
## Installation
```bash
pip install odoo-bringout-oca-iot-iot_key_employee_rfid
```
## Dependencies
This addon depends on:
- hr_attendance_rfid
- iot_rule
## Manifest Information
- **Name**: IoT Key Employee RFID
- **Version**: 16.0.1.0.0
- **Category**: N/A
- **License**: AGPL-3
- **Installable**: False
## Source
Based on [OCA/iot](https://github.com/OCA/iot) branch 16.0, addon `iot_key_employee_rfid`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -1,32 +0,0 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Iot_key_employee_rfid Module - iot_key_employee_rfid
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -1,3 +0,0 @@
# Configuration
Refer to Odoo settings for iot_key_employee_rfid. Configure related models, access rights, and options as needed.

View file

@ -1,3 +0,0 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -1,6 +0,0 @@
# Dependencies
This addon depends on:
- [hr_attendance_rfid](https://github.com/bringout/oca-technical)
- [iot_rule](https://github.com/bringout/oca-technical)

View file

@ -1,4 +0,0 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon iot_key_employee_rfid or install in UI.

View file

@ -1,7 +0,0 @@
# Install
```bash
pip install odoo-bringout-oca-iot-iot_key_employee_rfid"
# or
uv pip install odoo-bringout-oca-iot-iot_key_employee_rfid"
```

View file

@ -1,13 +0,0 @@
# Models
Detected core models and extensions in iot_key_employee_rfid.
```mermaid
classDiagram
class hr_employee
class iot_key
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -1,6 +0,0 @@
# Overview
Packaged Odoo addon: iot_key_employee_rfid. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon iot_key_employee_rfid
- License: LGPL-3

View file

@ -1,3 +0,0 @@
# Reports
This module does not define custom reports.

View file

@ -1,8 +0,0 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -1,5 +0,0 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -1,7 +0,0 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon iot_key_employee_rfid
```

View file

@ -1,3 +0,0 @@
# Wizards
This module does not include UI wizards.

View file

@ -1,78 +0,0 @@
=====================
IoT Key Employee RFID
=====================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f050534fb0fe825ed9eb152a71240158b02f1d0c75d760526df54bfeccbb1c22
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fiot-lightgray.png?logo=github
:target: https://github.com/OCA/iot/tree/16.0/iot_key_employee_rfid
:alt: OCA/iot
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/iot-16-0/iot-16-0-iot_key_employee_rfid
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/iot&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This addon allows the use of an RFID Card as an IoT Key.
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/iot/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/iot/issues/new?body=module:%20iot_key_employee_rfid%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* CreuBlanca
Contributors
~~~~~~~~~~~~
* Enric Tobella <etobella@creublanca.es>
* Luis Burrel <lu.bu.sax@gmail.com>
* Aaron Henriquez <ahforgeflow@forgeflow.com>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/iot <https://github.com/OCA/iot/tree/16.0/iot_key_employee_rfid>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -1,14 +0,0 @@
# Copyright 2019 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "IoT Key Employee RFID",
"summary": """
Use an Employee RFID Card as an IoT Key""",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "CreuBlanca,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/iot",
"depends": ["hr_attendance_rfid", "iot_rule"],
"data": ["views/hr_employee.xml"],
}

View file

@ -1,66 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_key_employee_rfid
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_key_employee_rfid
#. odoo-python
#: code:addons/iot_key_employee_rfid/models/hr_employee.py:0
#, python-format
msgid "%s / RFID"
msgstr "%s / RFID"
#. module: iot_key_employee_rfid
#: model:ir.model,name:iot_key_employee_rfid.model_hr_employee
msgid "Employee"
msgstr "Zaposleni"
#. module: iot_key_employee_rfid
#: model_terms:ir.ui.view,arch_db:iot_key_employee_rfid.hr_employee_form_view
msgid "Generate IoT Key for this RFID Card"
msgstr "Generiraj IoT ključ za ovu RFID karticu"
#. module: iot_key_employee_rfid
#: model:ir.model,name:iot_key_employee_rfid.model_iot_key
msgid "IoT Key"
msgstr "IoT ključ"
#. module: iot_key_employee_rfid
#: model_terms:ir.ui.view,arch_db:iot_key_employee_rfid.hr_employee_form_view
msgid "IoT Key for the RFID Card"
msgstr "IoT ključ za RFID karticu"
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__iot_key_ids
msgid "IoT Keys"
msgstr "IoT ključevi"
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__rule_ids
msgid "IoT Rules"
msgstr "IoT pravila"
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__iot_key_id
msgid "Iot Key"
msgstr "IoT ključ"
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__iot_key_count
msgid "Iot Key Count"
msgstr "Broj IoT ključeva"
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__rfid_card_code
msgid "RFID Card Code"
msgstr "Kod RFID kartice"

View file

@ -1,66 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * iot_key_employee_rfid
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: iot_key_employee_rfid
#. odoo-python
#: code:addons/iot_key_employee_rfid/models/hr_employee.py:0
#, python-format
msgid "%s / RFID"
msgstr ""
#. module: iot_key_employee_rfid
#: model:ir.model,name:iot_key_employee_rfid.model_hr_employee
msgid "Employee"
msgstr ""
#. module: iot_key_employee_rfid
#: model_terms:ir.ui.view,arch_db:iot_key_employee_rfid.hr_employee_form_view
msgid "Generate IoT Key for this RFID Card"
msgstr ""
#. module: iot_key_employee_rfid
#: model:ir.model,name:iot_key_employee_rfid.model_iot_key
msgid "IoT Key"
msgstr ""
#. module: iot_key_employee_rfid
#: model_terms:ir.ui.view,arch_db:iot_key_employee_rfid.hr_employee_form_view
msgid "IoT Key for the RFID Card"
msgstr ""
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__iot_key_ids
msgid "IoT Keys"
msgstr ""
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__rule_ids
msgid "IoT Rules"
msgstr ""
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__iot_key_id
msgid "Iot Key"
msgstr ""
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__iot_key_count
msgid "Iot Key Count"
msgstr ""
#. module: iot_key_employee_rfid
#: model:ir.model.fields,field_description:iot_key_employee_rfid.field_hr_employee__rfid_card_code
msgid "RFID Card Code"
msgstr ""

Some files were not shown because too many files have changed in this diff Show more