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.
- odoo/addons/web_widget_remote_measure/README.rst +37 -32
- odoo/addons/web_widget_remote_measure/__manifest__.py +2 -4
- odoo/addons/web_widget_remote_measure/i18n/es.po +0 -19
- odoo/addons/web_widget_remote_measure/i18n/web_widget_remote_measure.pot +40 -28
- odoo/addons/web_widget_remote_measure/models/__init__.py +1 -0
- odoo/addons/web_widget_remote_measure/models/remote_measure_device.py +1 -1
- odoo/addons/web_widget_remote_measure/models/res_users.py +2 -0
- odoo/addons/web_widget_remote_measure/models/res_users_settings.py +10 -0
- odoo/addons/web_widget_remote_measure/readme/CONFIGURE.md +9 -0
- odoo/addons/web_widget_remote_measure/readme/CONTRIBUTORS.md +4 -0
- odoo/addons/web_widget_remote_measure/readme/{DESCRIPTION.rst → DESCRIPTION.md} +3 -3
- odoo/addons/web_widget_remote_measure/readme/USAGE.md +22 -0
- odoo/addons/web_widget_remote_measure/static/description/index.html +23 -18
- odoo/addons/web_widget_remote_measure/static/src/remote_measure_field/remote_measure_field.esm.js +428 -0
- odoo/addons/web_widget_remote_measure/static/src/{scss/remote_measure_widget.scss → remote_measure_field/remote_measure_field.scss} +3 -3
- odoo/addons/web_widget_remote_measure/static/src/remote_measure_field/remote_measure_field.xml +43 -0
- odoo/addons/web_widget_remote_measure/views/remote_measure_device_views.xml +9 -3
- {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
- odoo_addon_web_widget_remote_measure-17.0.1.0.0.4.dist-info/RECORD +31 -0
- {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
- odoo_addon_web_widget_remote_measure-17.0.1.0.0.4.dist-info/top_level.txt +1 -0
- odoo/addons/web_widget_remote_measure/readme/CONFIGURE.rst +0 -8
- odoo/addons/web_widget_remote_measure/readme/CONTRIBUTORS.rst +0 -5
- odoo/addons/web_widget_remote_measure/readme/USAGE.rst +0 -19
- odoo/addons/web_widget_remote_measure/static/src/js/remote_measure_device_kanban_widget.esm.js +0 -33
- odoo/addons/web_widget_remote_measure/static/src/js/remote_measure_widget.esm.js +0 -461
- odoo/addons/web_widget_remote_measure/static/src/xml/measure_device_status.xml +0 -15
- odoo_addon_web_widget_remote_measure-15.0.1.1.0.dist-info/RECORD +0 -31
- odoo_addon_web_widget_remote_measure-15.0.1.1.0.dist-info/top_level.txt +0 -1
- /odoo/addons/web_widget_remote_measure/readme/{ROADMAP.rst → ROADMAP.md} +0 -0
odoo/addons/web_widget_remote_measure/static/src/remote_measure_field/remote_measure_field.esm.js
ADDED
@@ -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
|
-
&.
|
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
|
-
&.
|
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
|
-
.
|
24
|
+
.o_field_remote_measure input {
|
25
25
|
width: 0;
|
26
26
|
margin: 0 4px;
|
27
27
|
}
|
odoo/addons/web_widget_remote_measure/static/src/remote_measure_field/remote_measure_field.xml
ADDED
@@ -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
|
-
|
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
|
-
|
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:
|
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 ::
|
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:
|
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/
|
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-
|
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=
|
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.
|
47
|
-
websockets devices are supported, but it can be extended
|
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
|
-
|
63
|
-
|
64
|
-
|
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
|
67
|
-
to have the "Show remote device button on navbar"
|
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
|
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
|
-
|
77
|
-
|
78
|
-
their card.
|
79
|
-
|
80
|
-
|
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
|
83
|
-
provide an uom field so records that aren't in that UoM
|
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
|
-
|
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
|
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:%
|
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
|
-
|
132
|
+
- `Tecnativa <https://www.tecnativa.com>`__:
|
128
133
|
|
129
|
-
|
130
|
-
|
131
|
-
|
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/
|
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.
|