changes
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Dashboard Form ===== -->
|
||||
<record id="view_fp_sensor_dashboard_form" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.dashboard.form</field>
|
||||
<field name="model">fp.sensor.dashboard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sensor Dashboard">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" placeholder="e.g. % Nickel Activity"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="member_count" readonly="1"/>
|
||||
<field name="alert_count" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Sensors" name="sensors">
|
||||
<field name="sensor_ids" widget="many2many_tags"/>
|
||||
<field name="sensor_ids" mode="list">
|
||||
<list>
|
||||
<field name="name"/>
|
||||
<field name="unit"/>
|
||||
<field name="last_value" string="Last Value"/>
|
||||
<field name="last_measured"/>
|
||||
<field name="work_center_id" string="Station"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Alert Rules" name="alerts">
|
||||
<field name="alert_rule_ids">
|
||||
<list editable="bottom">
|
||||
<field name="sensor_id"/>
|
||||
<field name="threshold_low"/>
|
||||
<field name="threshold_high"/>
|
||||
<field name="active"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<chatter/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Dashboard List ===== -->
|
||||
<record id="view_fp_sensor_dashboard_list" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.dashboard.list</field>
|
||||
<field name="model">fp.sensor.dashboard</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Sensor Dashboards" default_order="name">
|
||||
<field name="name"/>
|
||||
<field name="alert_count" string="Alerts"
|
||||
decoration-danger="alert_count > 0"/>
|
||||
<field name="member_count" string="Members"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Window Action ===== -->
|
||||
<record id="action_fp_sensor_dashboard" model="ir.actions.act_window">
|
||||
<field name="name">Sensor Dashboards</field>
|
||||
<field name="res_model">fp.sensor.dashboard</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a sensor dashboard
|
||||
</p>
|
||||
<p>Group sensors into dashboards for monitoring and alerting.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Quick Measure Wizard Form ===== -->
|
||||
<record id="view_fp_sensor_measure_wizard_form" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.measure.wizard.form</field>
|
||||
<field name="model">fp.sensor.measure.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Record Measurement">
|
||||
<group>
|
||||
<field name="sensor_id"/>
|
||||
<field name="measurement_type" invisible="1"/>
|
||||
<field name="value"
|
||||
invisible="measurement_type != 'number'"/>
|
||||
<field name="value_text"
|
||||
invisible="measurement_type != 'text'"/>
|
||||
<field name="value_bool"
|
||||
invisible="measurement_type != 'boolean'"/>
|
||||
<field name="unit" invisible="not unit"/>
|
||||
<field name="effective_at"/>
|
||||
<field name="comment" placeholder="Write a comment..."/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_confirm" string="Save" type="object"
|
||||
class="btn-primary"/>
|
||||
<button string="Cancel" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Wizard Action (called from sensor form) ===== -->
|
||||
<record id="action_fp_sensor_measure_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Record Measurement</field>
|
||||
<field name="res_model">fp.sensor.measure.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Measurement Form ===== -->
|
||||
<record id="view_fp_sensor_measurement_form" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.measurement.form</field>
|
||||
<field name="model">fp.sensor.measurement</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sensor Measurement">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="sensor_id"/>
|
||||
<field name="measurement_type" invisible="1"/>
|
||||
<field name="value" invisible="measurement_type != 'number'"/>
|
||||
<field name="value_text" invisible="measurement_type != 'text'"/>
|
||||
<field name="value_bool" invisible="measurement_type != 'boolean'"/>
|
||||
<field name="unit"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="effective_at"/>
|
||||
<field name="source"/>
|
||||
<field name="creator_id" widget="many2one_avatar_user"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="comment" placeholder="Write a comment..."/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Measurement List ===== -->
|
||||
<record id="view_fp_sensor_measurement_list" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.measurement.list</field>
|
||||
<field name="model">fp.sensor.measurement</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Sensor Measurements" default_order="effective_at desc"
|
||||
decoration-muted="source == 'api'">
|
||||
<field name="value" string="Measurement"/>
|
||||
<field name="value_text" optional="hide"/>
|
||||
<field name="comment"/>
|
||||
<field name="sensor_id"/>
|
||||
<field name="measurement_type" column_invisible="1"/>
|
||||
<field name="creator_id" widget="many2one_avatar_user" string="Creator"/>
|
||||
<field name="effective_at" string="Created At"/>
|
||||
<field name="source" widget="badge" optional="show"
|
||||
decoration-info="source == 'manual'"
|
||||
decoration-success="source == 'api'"
|
||||
decoration-warning="source == 'iot'"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Measurement Search ===== -->
|
||||
<record id="view_fp_sensor_measurement_search" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.measurement.search</field>
|
||||
<field name="model">fp.sensor.measurement</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="sensor_id"/>
|
||||
<field name="creator_id"/>
|
||||
<separator/>
|
||||
<filter string="Manual" name="filter_manual"
|
||||
domain="[('source', '=', 'manual')]"/>
|
||||
<filter string="API" name="filter_api"
|
||||
domain="[('source', '=', 'api')]"/>
|
||||
<filter string="IoT" name="filter_iot"
|
||||
domain="[('source', '=', 'iot')]"/>
|
||||
<separator/>
|
||||
<filter string="Today" name="filter_today"
|
||||
domain="[('effective_at', '>=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="This Week" name="filter_week"
|
||||
domain="[('effective_at', '>=', (context_today() - datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]"/>
|
||||
<group>
|
||||
<filter string="Sensor" name="group_sensor"
|
||||
context="{'group_by': 'sensor_id'}"/>
|
||||
<filter string="Creator" name="group_creator"
|
||||
context="{'group_by': 'creator_id'}"/>
|
||||
<filter string="Source" name="group_source"
|
||||
context="{'group_by': 'source'}"/>
|
||||
<filter string="Date" name="group_date"
|
||||
context="{'group_by': 'effective_at:day'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Window Action ===== -->
|
||||
<record id="action_fp_sensor_measurement" model="ir.actions.act_window">
|
||||
<field name="name">Sensor Measurements</field>
|
||||
<field name="res_model">fp.sensor.measurement</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="search_view_id" ref="view_fp_sensor_measurement_search"/>
|
||||
<field name="context">{'search_default_filter_today': 0}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No measurements recorded yet
|
||||
</p>
|
||||
<p>Measurements are recorded manually via the sensor form or automatically via the IoT API.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Sensors parent menu under Operations ===== -->
|
||||
<menuitem id="menu_fp_sensors"
|
||||
name="Sensors"
|
||||
parent="fusion_plating.menu_fp_operations"
|
||||
sequence="20"/>
|
||||
|
||||
<menuitem id="menu_fp_sensor_dashboards"
|
||||
name="Dashboards"
|
||||
parent="menu_fp_sensors"
|
||||
action="action_fp_sensor_dashboard"
|
||||
sequence="10"/>
|
||||
|
||||
<menuitem id="menu_fp_sensors_all"
|
||||
name="All Sensors"
|
||||
parent="menu_fp_sensors"
|
||||
action="action_fp_sensor"
|
||||
sequence="20"/>
|
||||
|
||||
<menuitem id="menu_fp_sensor_measurements"
|
||||
name="Measurements"
|
||||
parent="menu_fp_sensors"
|
||||
action="action_fp_sensor_measurement"
|
||||
sequence="30"/>
|
||||
|
||||
<menuitem id="menu_fp_sensor_types"
|
||||
name="Sensor Types"
|
||||
parent="menu_fp_sensors"
|
||||
action="action_fp_sensor_type"
|
||||
sequence="40"/>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Sensor Type Form ===== -->
|
||||
<record id="view_fp_sensor_type_form" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.type.form</field>
|
||||
<field name="model">fp.sensor.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sensor Type">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" icon="fa-microchip"
|
||||
type="object" name="action_view_sensors"
|
||||
invisible="sensor_count == 0">
|
||||
<field name="sensor_count" widget="statinfo" string="Sensors"/>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="measurement_type"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Sensor Type List ===== -->
|
||||
<record id="view_fp_sensor_type_list" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.type.list</field>
|
||||
<field name="model">fp.sensor.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Sensor Types" default_order="name">
|
||||
<field name="name"/>
|
||||
<field name="measurement_type"/>
|
||||
<field name="sensor_count" string="Sensors"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Sensor Type Search ===== -->
|
||||
<record id="view_fp_sensor_type_search" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.type.search</field>
|
||||
<field name="model">fp.sensor.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<separator/>
|
||||
<filter string="Number" name="filter_number" domain="[('measurement_type', '=', 'number')]"/>
|
||||
<filter string="Text" name="filter_text" domain="[('measurement_type', '=', 'text')]"/>
|
||||
<filter string="Boolean" name="filter_boolean" domain="[('measurement_type', '=', 'boolean')]"/>
|
||||
<group>
|
||||
<filter string="Type" name="group_type" context="{'group_by': 'measurement_type'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Window Action ===== -->
|
||||
<record id="action_fp_sensor_type" model="ir.actions.act_window">
|
||||
<field name="name">Sensor Types</field>
|
||||
<field name="res_model">fp.sensor.type</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="search_view_id" ref="view_fp_sensor_type_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a sensor type
|
||||
</p>
|
||||
<p>Sensor types define what a sensor measures (Number, Text, or Boolean).</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
148
fusion-plating/fusion_plating_sensors/views/fp_sensor_views.xml
Normal file
148
fusion-plating/fusion_plating_sensors/views/fp_sensor_views.xml
Normal file
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Sensor Form ===== -->
|
||||
<record id="view_fp_sensor_form" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.form</field>
|
||||
<field name="model">fp.sensor</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sensor">
|
||||
<header>
|
||||
<button name="action_quick_measure"
|
||||
string="+ Measure"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-plus"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" icon="fa-bar-chart"
|
||||
type="object" name="action_view_measurements">
|
||||
<field name="measurement_count" widget="statinfo"
|
||||
string="Measurements"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" placeholder="e.g. Waste Water Treatment pH"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group string="Sensor Configuration">
|
||||
<field name="sensor_type_id"/>
|
||||
<field name="measurement_type" invisible="1"/>
|
||||
<field name="unit" placeholder="e.g. ph, %, g/L, PPM"/>
|
||||
<field name="uuid" placeholder="Hardware UUID for IoT"/>
|
||||
<field name="use_location"/>
|
||||
</group>
|
||||
<group string="Location">
|
||||
<field name="work_center_id" string="Station"/>
|
||||
<field name="tank_id"/>
|
||||
<field name="facility_id"/>
|
||||
<field name="location_name"
|
||||
invisible="not use_location"
|
||||
placeholder="e.g. WaterTreatmentArea"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Last Reading">
|
||||
<group>
|
||||
<field name="last_value" readonly="1"
|
||||
invisible="measurement_type != 'number'"/>
|
||||
<field name="last_value_text" readonly="1"
|
||||
invisible="measurement_type != 'text'"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="last_measured" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Recent Measurements" name="measurements">
|
||||
<field name="measurement_ids" mode="list" limit="5">
|
||||
<list editable="bottom" default_order="effective_at desc"
|
||||
decoration-muted="source == 'api'">
|
||||
<field name="effective_at" string="Date"/>
|
||||
<field name="value"
|
||||
invisible="parent.measurement_type != 'number'"/>
|
||||
<field name="value_text"
|
||||
invisible="parent.measurement_type != 'text'"/>
|
||||
<field name="value_bool"
|
||||
invisible="parent.measurement_type != 'boolean'"/>
|
||||
<field name="comment"/>
|
||||
<field name="creator_id" widget="many2one_avatar_user"/>
|
||||
<field name="source" widget="badge"
|
||||
decoration-info="source == 'manual'"
|
||||
decoration-success="source == 'api'"
|
||||
decoration-warning="source == 'iot'"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<chatter/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Sensor List ===== -->
|
||||
<record id="view_fp_sensor_list" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.list</field>
|
||||
<field name="model">fp.sensor</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Sensors" default_order="name">
|
||||
<field name="name"/>
|
||||
<field name="sensor_type_id"/>
|
||||
<field name="last_value" string="Last Measurement"/>
|
||||
<field name="unit"/>
|
||||
<field name="measurement_type" column_invisible="1"/>
|
||||
<field name="last_measured" string="Last Measured"/>
|
||||
<field name="work_center_id" string="Station" optional="show"/>
|
||||
<field name="location_name" string="Location" optional="show"/>
|
||||
<field name="uuid" optional="hide"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Sensor Search ===== -->
|
||||
<record id="view_fp_sensor_search" model="ir.ui.view">
|
||||
<field name="name">fp.sensor.search</field>
|
||||
<field name="model">fp.sensor</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="uuid"/>
|
||||
<field name="sensor_type_id"/>
|
||||
<field name="work_center_id" string="Station"/>
|
||||
<field name="tank_id"/>
|
||||
<field name="facility_id"/>
|
||||
<separator/>
|
||||
<filter string="Number Sensors" name="filter_number"
|
||||
domain="[('measurement_type', '=', 'number')]"/>
|
||||
<filter string="Has UUID" name="filter_has_uuid"
|
||||
domain="[('uuid', '!=', False)]"/>
|
||||
<group>
|
||||
<filter string="Station" name="group_station"
|
||||
context="{'group_by': 'work_center_id'}"/>
|
||||
<filter string="Type" name="group_type"
|
||||
context="{'group_by': 'sensor_type_id'}"/>
|
||||
<filter string="Facility" name="group_facility"
|
||||
context="{'group_by': 'facility_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Window Action ===== -->
|
||||
<record id="action_fp_sensor" model="ir.actions.act_window">
|
||||
<field name="name">Sensors</field>
|
||||
<field name="res_model">fp.sensor</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="search_view_id" ref="view_fp_sensor_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create your first sensor
|
||||
</p>
|
||||
<p>Sensors track chemistry readings at tanks, work centres, and other locations.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user