odoo-addon-web-widget-remote-measure 15.0.1.1.0__py3-none-any.whl → 17.0.1.0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. odoo/addons/web_widget_remote_measure/README.rst +37 -32
  2. odoo/addons/web_widget_remote_measure/__manifest__.py +2 -4
  3. odoo/addons/web_widget_remote_measure/i18n/es.po +0 -19
  4. odoo/addons/web_widget_remote_measure/i18n/web_widget_remote_measure.pot +40 -28
  5. odoo/addons/web_widget_remote_measure/models/__init__.py +1 -0
  6. odoo/addons/web_widget_remote_measure/models/remote_measure_device.py +1 -1
  7. odoo/addons/web_widget_remote_measure/models/res_users.py +2 -0
  8. odoo/addons/web_widget_remote_measure/models/res_users_settings.py +10 -0
  9. odoo/addons/web_widget_remote_measure/readme/CONFIGURE.md +9 -0
  10. odoo/addons/web_widget_remote_measure/readme/CONTRIBUTORS.md +4 -0
  11. odoo/addons/web_widget_remote_measure/readme/{DESCRIPTION.rst → DESCRIPTION.md} +3 -3
  12. odoo/addons/web_widget_remote_measure/readme/USAGE.md +22 -0
  13. odoo/addons/web_widget_remote_measure/static/description/index.html +23 -18
  14. odoo/addons/web_widget_remote_measure/static/src/remote_measure_field/remote_measure_field.esm.js +428 -0
  15. odoo/addons/web_widget_remote_measure/static/src/{scss/remote_measure_widget.scss → remote_measure_field/remote_measure_field.scss} +3 -3
  16. odoo/addons/web_widget_remote_measure/static/src/remote_measure_field/remote_measure_field.xml +43 -0
  17. odoo/addons/web_widget_remote_measure/views/remote_measure_device_views.xml +9 -3
  18. {odoo_addon_web_widget_remote_measure-15.0.1.1.0.dist-info → odoo_addon_web_widget_remote_measure-17.0.1.0.0.4.dist-info}/METADATA +42 -37
  19. odoo_addon_web_widget_remote_measure-17.0.1.0.0.4.dist-info/RECORD +31 -0
  20. {odoo_addon_web_widget_remote_measure-15.0.1.1.0.dist-info → odoo_addon_web_widget_remote_measure-17.0.1.0.0.4.dist-info}/WHEEL +1 -1
  21. odoo_addon_web_widget_remote_measure-17.0.1.0.0.4.dist-info/top_level.txt +1 -0
  22. odoo/addons/web_widget_remote_measure/readme/CONFIGURE.rst +0 -8
  23. odoo/addons/web_widget_remote_measure/readme/CONTRIBUTORS.rst +0 -5
  24. odoo/addons/web_widget_remote_measure/readme/USAGE.rst +0 -19
  25. odoo/addons/web_widget_remote_measure/static/src/js/remote_measure_device_kanban_widget.esm.js +0 -33
  26. odoo/addons/web_widget_remote_measure/static/src/js/remote_measure_widget.esm.js +0 -461
  27. odoo/addons/web_widget_remote_measure/static/src/xml/measure_device_status.xml +0 -15
  28. odoo_addon_web_widget_remote_measure-15.0.1.1.0.dist-info/RECORD +0 -31
  29. odoo_addon_web_widget_remote_measure-15.0.1.1.0.dist-info/top_level.txt +0 -1
  30. /odoo/addons/web_widget_remote_measure/readme/{ROADMAP.rst → ROADMAP.md} +0 -0
@@ -0,0 +1,428 @@
1
+ /** @odoo-module **/
2
+ import {FloatField, floatField} from "@web/views/fields/float/float_field";
3
+ import {
4
+ onWillDestroy,
5
+ onWillStart,
6
+ onWillUnmount,
7
+ useEffect,
8
+ useState,
9
+ } from "@odoo/owl";
10
+ import {_t} from "@web/core/l10n/translation";
11
+ import {registry} from "@web/core/registry";
12
+ import {useService} from "@web/core/utils/hooks";
13
+
14
+ // Animate the measure steps for each measure received.
15
+ export const nextState = {
16
+ "fa-thermometer-empty": "fa-thermometer-quarter",
17
+ "fa-thermometer-quarter": "fa-thermometer-half",
18
+ "fa-thermometer-half": "fa-thermometer-three-quarters",
19
+ "fa-thermometer-three-quarters": "fa-thermometer-full",
20
+ "fa-thermometer-full": "fa-thermometer-empty",
21
+ };
22
+
23
+ export class RemoteMeasureField extends FloatField {
24
+ static props = {
25
+ ...FloatField.props,
26
+ remote_device_field: {type: String, optional: true},
27
+ uom_field: {type: String, optional: true},
28
+ default_user_device: {type: Boolean, optional: true},
29
+ allow_additive_measure: {type: Boolean, optional: true},
30
+ };
31
+ static template = "web_widget_remote_measure.RemoteMeasureField";
32
+
33
+ setup() {
34
+ super.setup();
35
+ this.rpc = useService("rpc");
36
+ this.orm = useService("orm");
37
+ this.user = useService("user");
38
+ this.remote_device_data = {};
39
+ [this.default_user_device] =
40
+ (this.props.default_user_device &&
41
+ this.user.settings.remote_measure_device_id) ||
42
+ [];
43
+ // When we're in the own device, we already have the data
44
+ if (
45
+ this.props.record.resModel === "remote.measure.device" &&
46
+ this.props.record.resId
47
+ ) {
48
+ this.remote_device_data.id = this.props.record.resId;
49
+ [this.uom] = this.props.record.data.uom_id;
50
+ } else if (this.props.remote_device_field) {
51
+ [this.remote_device_data.id] =
52
+ this.props.record.data[this.props.remote_device_field];
53
+ } else if (this.default_user_device) {
54
+ [this.remote_device_data.id] = this.default_user_device;
55
+ }
56
+ if (!this.uom && this.props.uom_field) {
57
+ [this.uom] = this.props.record.data[this.props.uom_field];
58
+ }
59
+ onWillStart(async () => {
60
+ if (!this.remote_device_data || !this.uom) {
61
+ return;
62
+ }
63
+ [this.uom] = await this.orm.call("uom.uom", "read", [this.uom]);
64
+ [this.remote_device_data] = await this.orm.call(
65
+ "remote.measure.device",
66
+ "read",
67
+ [this.remote_device_data.id]
68
+ );
69
+ this._assigDeviceData();
70
+ });
71
+ this.default_ui_state = {
72
+ stop: true,
73
+ measuring: false,
74
+ icon: "fa-thermometer-half",
75
+ // Additional class for colors and others
76
+ class: "btn-secondary",
77
+ input_val: this.value,
78
+ start_add: false,
79
+ };
80
+ this.state = useState({
81
+ ...this.state,
82
+ ...this.default_ui_state,
83
+ additive_measure: false,
84
+ });
85
+ // Reset states when we leave the button
86
+ // TODO: Also halt any reading!
87
+ useEffect(
88
+ (readonly) => {
89
+ if (readonly) {
90
+ this.state.stop = true;
91
+ this.state.measuring = false;
92
+ }
93
+ },
94
+ () => [this.props.readonly]
95
+ );
96
+ useEffect(
97
+ (value) => {
98
+ if (value > 0 && this.props.allow_additive_measure) {
99
+ this.state.additive_measure = true;
100
+ }
101
+ },
102
+ () => [this.value]
103
+ );
104
+ onWillDestroy(() => this._closeSocket());
105
+ onWillUnmount(() => this._closeSocket());
106
+ }
107
+
108
+ // Private methods
109
+
110
+ /**
111
+ * @private
112
+ */
113
+ _assigDeviceData() {
114
+ if (!this.remote_device_data) {
115
+ return;
116
+ }
117
+ Object.assign(this, {
118
+ host: this.remote_device_data.host,
119
+ protocol: this.remote_device_data.protocol,
120
+ connection_mode: this.remote_device_data.connection_mode,
121
+ uom_category: this.uom.category_id[0],
122
+ device_uom: this.remote_device_data.uom_id[0],
123
+ device_uom_category: this.remote_device_data.uom_category_id[0],
124
+ });
125
+ }
126
+
127
+ /**
128
+ * @override
129
+ * @param {Event} ev
130
+ * Auto select all the content
131
+ */
132
+ onFocusIn(ev) {
133
+ super.onFocusIn(...arguments);
134
+ ev.target.select();
135
+ }
136
+ /**
137
+ * @override
138
+ * Ensure that the socket is close
139
+ */
140
+ onFocusOut() {
141
+ super.onFocusOut(...arguments);
142
+ this._closeSocket();
143
+ }
144
+
145
+ // UX Methods
146
+
147
+ async measure() {
148
+ this.state.stop = false;
149
+ this.state.measuring = true;
150
+ await this[`_connect_to_${this.connection_mode}`]();
151
+ }
152
+ /**
153
+ * Stop requesting measures from device
154
+ */
155
+ measure_stop() {
156
+ this._closeSocket();
157
+ this.state.stop = true;
158
+ this.state.measuring = false;
159
+ this._awaitingMeasure();
160
+ this._recordMeasure();
161
+ }
162
+ /**
163
+ * Start requesting measures from the remote device
164
+ */
165
+ onMeasure() {
166
+ this.state.icon = "fa-thermometer-empty";
167
+ this.measure();
168
+ }
169
+ onMeasureAdd() {
170
+ this.state.start_add = true;
171
+ this.measure();
172
+ }
173
+ /**
174
+ * Validate the requested measure
175
+ */
176
+ onValidateMeasure() {
177
+ this.measure_stop();
178
+ }
179
+
180
+ /**
181
+ * Once we consider the measure is stable render the button as green
182
+ */
183
+ _stableMeasure() {
184
+ this.state.class = "btn-success";
185
+ }
186
+ /**
187
+ * While a measure is not stable the button will be red
188
+ */
189
+ _unstableMeasure() {
190
+ this.state.class = "btn-danger";
191
+ }
192
+ /**
193
+ * While the widget isn't querying it will be purple as a signal that we can start
194
+ */
195
+ _awaitingMeasure() {
196
+ Object.assign(this.state, this.default_ui_state);
197
+ }
198
+ /**
199
+ * Set the field measure in the field
200
+ */
201
+ _recordMeasure() {
202
+ this.state.start_add = false;
203
+ this.state.input_val = this.amount;
204
+ }
205
+ /**
206
+ * Convert the measured units to the units expecte by the record if different
207
+ * @param {Number} amount
208
+ * @returns {Number} converted amount
209
+ */
210
+ _compute_quantity(amount) {
211
+ if (this.uom.id === this.device_uom.id) {
212
+ return amount;
213
+ }
214
+ let converted_amount = amount / this.remote_device_data.uom_factor;
215
+ converted_amount *= this.uom.factor;
216
+ return converted_amount;
217
+ }
218
+ /**
219
+ * Set value
220
+ */
221
+ async _setMeasure() {
222
+ if (isNaN(this.amount)) {
223
+ return;
224
+ }
225
+ this.amount = this._compute_quantity(this.amount);
226
+ if (this.state.start_add) {
227
+ this.amount += this.state.input_val;
228
+ }
229
+ this.props.record.update({[this.props.name]: this.amount});
230
+ }
231
+ nextStateIcon() {
232
+ this.state.icon = nextState[this.state.icon];
233
+ }
234
+
235
+ // Connection methods
236
+ // TODO: It'd be nice to extract al this logic to services although right now
237
+ // is quite intricate with te UI logic, so some refactor would be needed.
238
+
239
+ /**
240
+ * F501 Protocol response:
241
+ * [STX][status1][status2][data][ETX]
242
+ * - status1 beign weight status: \x20 (space) for stable weight and ? for unstable
243
+ * - status2 beign weight sign: + for positive and - for negative.
244
+ * - data being the weight itself with 6 characters for weight and one . for the
245
+ * decimal dot
246
+ *
247
+ * @param {String} msg ASCII string
248
+ * @returns {Object} with the value and the stable flag
249
+ */
250
+ _proccess_msg_f501(msg) {
251
+ return {
252
+ stable: msg[1] === "\x20",
253
+ value: parseFloat(msg.slice(2, 10)),
254
+ };
255
+ }
256
+
257
+ /**
258
+ * Implemented for a continous remote stream
259
+ * TODO: Abstract more the possible device scenarios
260
+ */
261
+ async _connect_to_websockets() {
262
+ try {
263
+ this.socket = new WebSocket(this.host);
264
+ } catch (error) {
265
+ // Avoid websockets security error. Local devices won't have wss normally
266
+ if (error.code === 18) {
267
+ return;
268
+ }
269
+ throw error;
270
+ }
271
+ var stream_success_counter = 10;
272
+ this.socket.onmessage = async (msg) => {
273
+ const data = await msg.data.text();
274
+ const processed_data = this[`_proccess_msg_${this.protocol}`](data);
275
+ if (processed_data.stable) {
276
+ this._stableMeasure();
277
+ if (!stream_success_counter) {
278
+ this._closeSocket();
279
+ this._awaitingMeasure();
280
+ this._recordMeasure();
281
+ return;
282
+ }
283
+ } else {
284
+ stream_success_counter = 5;
285
+ this._unstableMeasure();
286
+ }
287
+ if (stream_success_counter) {
288
+ --stream_success_counter;
289
+ }
290
+ this.nextStateIcon();
291
+ this.amount = processed_data.value;
292
+ this._setMeasure();
293
+ };
294
+ this.socket.onerror = () => {
295
+ this._awaitingMeasure();
296
+ };
297
+ }
298
+ /**
299
+ * Send read params to the remote device
300
+ * @returns {Object}
301
+ */
302
+ _read_from_device_tcp_params() {
303
+ return {command: false};
304
+ }
305
+ /**
306
+ * Process call
307
+ * @returns {Number}
308
+ */
309
+ async _read_from_device_tcp() {
310
+ const data = await this.rpc(
311
+ `/remote_measure_device/${this.remote_device_data.id}`,
312
+ this._read_from_device_tcp_params()
313
+ );
314
+ if (!data) {
315
+ return null;
316
+ }
317
+ const processed_data = this[`_proccess_msg_${this.protocol}`](data);
318
+ if (isNaN(processed_data.value)) {
319
+ processed_data.value = 0;
320
+ }
321
+ return processed_data;
322
+ }
323
+ /**
324
+ * Connect to the local controller, which makes the direct connection to the
325
+ * scale.
326
+ */
327
+ async _connect_to_tcp() {
328
+ var stream_success_counter = 20;
329
+ this._unstableMeasure();
330
+ // Used to set the read interval if any
331
+ const timer = (ms) => new Promise((res) => setTimeout(res, ms));
332
+ // Don't keep going forever unless non stop reading
333
+ for (
334
+ let attemps_left = this.remote_device_data.non_stop_read ? Infinity : 1000;
335
+ attemps_left > 0;
336
+ attemps_left--
337
+ ) {
338
+ // Allow to break the loop manually
339
+ if (this.state.stop) {
340
+ break;
341
+ }
342
+ const processed_data = await this._read_from_device_tcp();
343
+ if (!processed_data) {
344
+ continue;
345
+ }
346
+ if (processed_data.stable) {
347
+ this._stableMeasure();
348
+ } else {
349
+ this._unstableMeasure();
350
+ stream_success_counter = 20;
351
+ }
352
+ if (processed_data.stable && stream_success_counter <= 0) {
353
+ this._stableMeasure();
354
+ this._awaitingMeasure();
355
+ this._recordMeasure();
356
+ break;
357
+ } else if (this.remote_device_data.non_stop_read) {
358
+ stream_success_counter = 20;
359
+ this._recordMeasure();
360
+ }
361
+ if (stream_success_counter) {
362
+ --stream_success_counter;
363
+ }
364
+ this.nextStateIcon();
365
+ this.amount = processed_data.value;
366
+ this._setMeasure();
367
+ // Set sleep interval
368
+ if (this.remote_device_data.read_interval) {
369
+ await timer(this.remote_device_data.read_interval);
370
+ }
371
+ }
372
+ }
373
+ /**
374
+ * Implement for your device protocol service
375
+ */
376
+ _connect_to_webservices() {
377
+ return;
378
+ }
379
+ /**
380
+ * Procure to close the socket whenever the widget stops being used
381
+ */
382
+ _closeSocket() {
383
+ if (this.socket) {
384
+ this.socket.close();
385
+ this.socket = undefined;
386
+ }
387
+ }
388
+ }
389
+
390
+ export const remoteMeasureField = {
391
+ ...floatField,
392
+ component: RemoteMeasureField,
393
+ supportedOptions: [
394
+ ...floatField.supportedOptions,
395
+ {
396
+ label: _t("UoM"),
397
+ name: "uom_field",
398
+ type: "field",
399
+ availableTypes: ["many2one"],
400
+ },
401
+ {
402
+ label: _t("Remote device"),
403
+ name: "remote_device_field",
404
+ type: "field",
405
+ availableTypes: ["many2one"],
406
+ },
407
+ {
408
+ label: _t("Use default device"),
409
+ name: "default_user_device",
410
+ type: "boolean",
411
+ },
412
+ {
413
+ label: _t("Additive Measure"),
414
+ name: "allow_additive_measure",
415
+ type: "boolean",
416
+ },
417
+ ],
418
+ extractProps({options}) {
419
+ const props = floatField.extractProps(...arguments);
420
+ props.remote_device_field = options.remote_device_field;
421
+ props.uom_field = options.uom_field;
422
+ props.default_user_device = options.default_user_device;
423
+ props.allow_additive_measure = options.allow_additive_measure;
424
+ return props;
425
+ },
426
+ };
427
+
428
+ registry.category("fields").add("remote_measure", remoteMeasureField);
@@ -1,12 +1,12 @@
1
1
  .o_field_widget {
2
- &.o_field_remote_device {
2
+ &.o_field_remote_measure {
3
3
  display: inline-flex;
4
4
  > span,
5
5
  > button {
6
6
  flex: 0 0 auto;
7
7
  }
8
8
  }
9
- &.o_field_remote_device {
9
+ &.o_field_remote_measure {
10
10
  &.o_input {
11
11
  align-items: baseline;
12
12
 
@@ -21,7 +21,7 @@
21
21
  .o_list_table {
22
22
  .o_data_row.o_selected_row
23
23
  > .o_data_cell:not(.o_readonly_modifier):not(.o_invisible_modifier) {
24
- .o_field_remote_device input {
24
+ .o_field_remote_measure input {
25
25
  width: 0;
26
26
  margin: 0 4px;
27
27
  }
@@ -0,0 +1,43 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <templates id="template" xml:space="preserve">
3
+ <t t-name="web_widget_remote_measure.RemoteMeasureField">
4
+ <span t-if="props.readonly" t-esc="formattedValue" />
5
+ <t t-else="">
6
+ <t t-if="this.remote_device_data">
7
+ <span
8
+ t-if="this.state.stop"
9
+ class="o_field_remote_device_start btn btn-primary btn-sm"
10
+ t-on-click.prevent="onMeasure"
11
+ >
12
+ <i t-attf-class="fa {{this.state.icon}}" role="img" />
13
+ </span>
14
+ <span
15
+ t-elif="!this.state.stop"
16
+ t-attf-class="o_field_remote_device_stop btn btn-sm {{ this.state.class }}"
17
+ t-on-click.prevent="onValidateMeasure"
18
+ >
19
+ <i t-attf-class="fa {{this.state.icon}}" role="img" />
20
+ </span>
21
+ <span
22
+ t-if="this.state.additive_measure"
23
+ class="o_field_remote_device_start btn btn-link btn-sm"
24
+ t-on-click.prevent="onMeasureAdd"
25
+ >
26
+ <i t-attf-class="fa fa-plus" role="img" />
27
+ </span>
28
+ </t>
29
+ <input
30
+ t-on-focusin="onFocusIn"
31
+ t-on-focusout="onFocusOut"
32
+ t-att-id="props.id"
33
+ t-ref="numpadDecimal"
34
+ t-att-placeholder="props.placeholder"
35
+ t-att-type="props.inputType"
36
+ inputmode="decimal"
37
+ class="o_input"
38
+ autocomplete="off"
39
+ t-att-step="props.step"
40
+ />
41
+ </t>
42
+ </t>
43
+ </templates>
@@ -11,7 +11,7 @@
11
11
  name="test_tcp_connection"
12
12
  class="oe_highlight"
13
13
  groups="base.group_no_one"
14
- attrs="{'invisible': [('connection_mode', '!=', 'tcp')]}"
14
+ invisible="connection_mode != 'tcp'"
15
15
  />
16
16
  </header>
17
17
  <sheet>
@@ -20,7 +20,7 @@
20
20
  name="web_ribbon"
21
21
  title="Archived"
22
22
  bg_color="bg-danger"
23
- attrs="{'invisible': [('active', '=', True)]}"
23
+ invisible="active"
24
24
  />
25
25
  <div class="oe_title">
26
26
  <h1><field name="name" placeholder="e.g. Dock 1 Scale" /></h1>
@@ -49,12 +49,18 @@
49
49
  <record id="measure_device_tree" model="ir.ui.view">
50
50
  <field name="model">remote.measure.device</field>
51
51
  <field name="arch" type="xml">
52
- <tree>
52
+ <tree editable="top">
53
53
  <field name="name" />
54
54
  <field name="host" />
55
55
  <field name="protocol" optional="show" />
56
56
  <field name="uom_id" optional="show" />
57
57
  <field name="connection_mode" optional="show" />
58
+ <field
59
+ name="test_measure"
60
+ optional="hide"
61
+ widget="remote_measure"
62
+ options="{'allow_additive_measure': True}"
63
+ />
58
64
  </tree>
59
65
  </field>
60
66
  </record>
@@ -1,17 +1,17 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: odoo-addon-web_widget_remote_measure
3
- Version: 15.0.1.1.0
3
+ Version: 17.0.1.0.0.4
4
+ Requires-Python: >=3.10
5
+ Requires-Dist: odoo>=17.0a,<17.1dev
4
6
  Summary: Allows to connect to remote devices to record measures
5
7
  Home-page: https://github.com/OCA/stock-weighing
8
+ License: AGPL-3
6
9
  Author: Tecnativa, Odoo Community Association (OCA)
7
10
  Author-email: support@odoo-community.org
8
- License: AGPL-3
9
11
  Classifier: Programming Language :: Python
10
12
  Classifier: Framework :: Odoo
11
- Classifier: Framework :: Odoo :: 15.0
13
+ Classifier: Framework :: Odoo :: 17.0
12
14
  Classifier: License :: OSI Approved :: GNU Affero General Public License v3
13
- Requires-Python: >=3.8
14
- Requires-Dist: odoo<15.1dev,>=15.0a
15
15
 
16
16
  ============================
17
17
  Remote Measure Devices Input
@@ -22,7 +22,7 @@ Remote Measure Devices Input
22
22
  !! This file is generated by oca-gen-addon-readme !!
23
23
  !! changes will be overwritten. !!
24
24
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
25
- !! source digest: sha256:e90b90010e6a00f6e63bc471ba0342f0ed21608944d223276fffcf69e5e102d6
25
+ !! source digest: sha256:da3f687629ae8a2ddd5133d846c7ea58650065bd0de8a5c9f78430ab5f336940
26
26
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27
27
 
28
28
  .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -32,20 +32,20 @@ Remote Measure Devices Input
32
32
  :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
33
33
  :alt: License: AGPL-3
34
34
  .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--weighing-lightgray.png?logo=github
35
- :target: https://github.com/OCA/stock-weighing/tree/15.0/web_widget_remote_measure
35
+ :target: https://github.com/OCA/stock-weighing/tree/17.0/web_widget_remote_measure
36
36
  :alt: OCA/stock-weighing
37
37
  .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
38
- :target: https://translation.odoo-community.org/projects/stock-weighing-15-0/stock-weighing-15-0-web_widget_remote_measure
38
+ :target: https://translation.odoo-community.org/projects/stock-weighing-17-0/stock-weighing-17-0-web_widget_remote_measure
39
39
  :alt: Translate me on Weblate
40
40
  .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
41
- :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-weighing&target_branch=15.0
41
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-weighing&target_branch=17.0
42
42
  :alt: Try me on Runboat
43
43
 
44
44
  |badge1| |badge2| |badge3| |badge4| |badge5|
45
45
 
46
- This module allows to input data from remote devices in your network. Currently, only
47
- websockets devices are supported, but it can be extended for any protocol like
48
- Webservices.
46
+ This module allows to input data from remote devices in your network.
47
+ Currently, only websockets devices are supported, but it can be extended
48
+ for any protocol like Webservices.
49
49
 
50
50
  Other modules can extend this one in order to use the widget.
51
51
 
@@ -59,35 +59,40 @@ Configuration
59
59
 
60
60
  To configure your remote devices:
61
61
 
62
- #. Go to *Settings > Technical > Devices > Remote devices*
63
- #. Create a new one configuring the required info.
64
- #. If the devices has an special port, set it up in the host data: e.g.: 10.1.1.2:3210
62
+ 1. Go to *Settings > Technical > Devices > Remote devices*
63
+ 2. Create a new one configuring the required info.
64
+ 3. If the devices has an special port, set it up in the host data: e.g.:
65
+ 10.1.1.2:3210
65
66
 
66
- If you want to see the button in the top bar to set the user's remote device, you need
67
- to have the "Show remote device button on navbar" group.
67
+ If you want to see the button in the top bar to set the user's remote
68
+ device, you need to have the "Show remote device button on navbar"
69
+ group.
68
70
 
69
71
  Usage
70
72
  =====
71
73
 
72
- The remote device has to be in the users network so their web clients can reach them.
74
+ The remote device has to be in the users network so their web clients
75
+ can reach them.
73
76
 
74
77
  In order to test a device you can:
75
78
 
76
- #. Go to *Settings > Technical > Devices > Remote devices*
77
- #. In the Kanban view you'll wich devices can be reached as they'll have a green dot in
78
- their card.
79
- #. Go to one of those and click *Edit*.
80
- #. You can start measuring from the remote device in the *Test measure* field.
79
+ 1. Go to *Settings > Technical > Devices > Remote devices*
80
+ 2. In the Kanban view you'll wich devices can be reached as they'll have
81
+ a green dot in their card.
82
+ 3. Go to one of those and click *Edit*.
83
+ 4. You can start measuring from the remote device in the *Test measure*
84
+ field.
81
85
 
82
- On the technical side, you can use the widget in your own `Float``. You'll need to
83
- provide an uom field so records that aren't in that UoM don't measure from the device.
86
+ On the technical side, you can use the widget in your own Float\`.
87
+ You'll need to provide an uom field so records that aren't in that UoM
88
+ don't measure from the device.
84
89
 
85
90
  .. code:: xml
86
91
 
87
- <field name="float_field" widget="remote_measure" options="{'remote_device_field': 'measure_device_id', 'uom_field': 'uom_id'}" />
92
+ <field name="float_field" widget="remote_measure" options="{'remote_device_field': 'measure_device_id', 'uom_field': 'uom_id'}" />
88
93
 
89
- The users are able to change their default remote device by using the button with the
90
- balance icon set on the navbar.
94
+ The users are able to change their default remote device by using the
95
+ button with the balance icon set on the navbar.
91
96
 
92
97
  Known issues / Roadmap
93
98
  ======================
@@ -109,7 +114,7 @@ Bug Tracker
109
114
  Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-weighing/issues>`_.
110
115
  In case of trouble, please check there if your issue has already been reported.
111
116
  If you spotted it first, help us to smash it by providing a detailed and welcomed
112
- `feedback <https://github.com/OCA/stock-weighing/issues/new?body=module:%20web_widget_remote_measure%0Aversion:%2015.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
117
+ `feedback <https://github.com/OCA/stock-weighing/issues/new?body=module:%20web_widget_remote_measure%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
113
118
 
114
119
  Do not contact contributors directly about support or help with technical issues.
115
120
 
@@ -117,21 +122,21 @@ Credits
117
122
  =======
118
123
 
119
124
  Authors
120
- ~~~~~~~
125
+ -------
121
126
 
122
127
  * Tecnativa
123
128
 
124
129
  Contributors
125
- ~~~~~~~~~~~~
130
+ ------------
126
131
 
127
- * `Tecnativa <https://www.tecnativa.com>`_:
132
+ - `Tecnativa <https://www.tecnativa.com>`__:
128
133
 
129
- * David Vidal
130
- * Sergio Teruel
131
- * Carlos Roca
134
+ - David Vidal
135
+ - Sergio Teruel
136
+ - Carlos Roca
132
137
 
133
138
  Maintainers
134
- ~~~~~~~~~~~
139
+ -----------
135
140
 
136
141
  This module is maintained by the OCA.
137
142
 
@@ -151,6 +156,6 @@ Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
151
156
 
152
157
  |maintainer-chienandalu|
153
158
 
154
- This module is part of the `OCA/stock-weighing <https://github.com/OCA/stock-weighing/tree/15.0/web_widget_remote_measure>`_ project on GitHub.
159
+ This module is part of the `OCA/stock-weighing <https://github.com/OCA/stock-weighing/tree/17.0/web_widget_remote_measure>`_ project on GitHub.
155
160
 
156
161
  You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.