feat(iot): Sub 7 — per-sensor polling interval + rate-limit + entech seed
Per-sensor override on fp.tank.sensor.poll_interval_minutes with a
company-wide default (res.company.x_fc_default_poll_interval_minutes,
default 30) exposed in Settings → Fusion Plating → IoT. Single
lookup helper _fp_effective_poll_interval_minutes keeps downstream
call sites simple. Read-only poll_interval_display Char ("30 min
(default)" / "15 min (override)") keeps units unambiguous per user
request.
Ingest endpoint /fp/iot/ingest drops readings that arrive inside a
sensor's effective interval, returning {accepted, skipped} so the Pi
agent can log it. Pi-side interval stays its own concern.
Post-init hook seeds 5 small tanks + 20 big tanks (10 active, 10
inactive) with 1 temperature + 1 pH sensor each → 25 tanks, 50
sensors. Idempotent (keyed by tank.code, with_context(active_test=
False)). Opt-in via ir.config_parameter
fusion_plating_iot.seed_entech_tanks = '1' so a fresh install
elsewhere doesn't auto-seed. Flag set on entech today; 27 tanks / 52
sensors now live (2 pilot + 25 seeded).
Smoke on entech: 14/14 assertions pass including idempotency and
rate-limit conditions.
fusion_plating_iot → 19.0.2.0.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
<field name="last_reading_at"/>
|
||||
<field name="last_reading_in_spec" widget="boolean_toggle"/>
|
||||
<field name="reading_count"/>
|
||||
<field name="poll_interval_minutes" optional="show"/>
|
||||
<field name="poll_interval_display" optional="show"/>
|
||||
<field name="active" column_invisible="1"/>
|
||||
</list>
|
||||
</field>
|
||||
@@ -110,6 +112,22 @@
|
||||
<field name="last_reading_in_spec" readonly="1" widget="boolean_toggle"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="IoT Polling (Sub 7)">
|
||||
<group>
|
||||
<field name="poll_interval_minutes"/>
|
||||
<field name="poll_interval_display" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<div class="text-muted">
|
||||
<i class="fa fa-info-circle me-1"/>
|
||||
Leave the interval blank to inherit the
|
||||
company-wide default (configured under
|
||||
Settings → Fusion Plating → IoT). Readings
|
||||
arriving faster than the effective interval
|
||||
are dropped by the ingest endpoint.
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
Sub 7 — IoT default polling interval setting.
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<record id="res_config_settings_view_form_fp_iot" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.fp.iot</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id"
|
||||
ref="fusion_plating.res_config_settings_view_form_fp_core"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//app[@name='fusion_plating']" position="inside">
|
||||
<block title="IoT"
|
||||
name="fp_iot_settings"
|
||||
help="Defaults applied to physical sensors wired into
|
||||
Fusion Plating tanks. Per-sensor overrides live
|
||||
on each fp.tank.sensor record.">
|
||||
<setting id="fp_iot_default_poll_interval"
|
||||
string="Default Polling Interval"
|
||||
help="How often (in minutes) readings from a
|
||||
tank sensor are stored when the sensor
|
||||
itself does not specify its own interval.
|
||||
The ingest endpoint drops readings that
|
||||
arrive faster than the effective interval,
|
||||
so a Pi agent can freely poll more often
|
||||
without bloating the database.">
|
||||
<field name="x_fc_default_poll_interval_minutes"/>
|
||||
<span class="text-muted ms-2">minutes</span>
|
||||
</setting>
|
||||
</block>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user