152 lines
5.4 KiB
Python
152 lines
5.4 KiB
Python
import json
|
|
import logging
|
|
|
|
from odoo import api, fields, models, tools
|
|
from odoo.exceptions import ValidationError
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
class AttendanceIot(models.Model):
|
|
_name = 'attendance.iot'
|
|
_description = '考勤机设备'
|
|
_rec_name = 'display_name'
|
|
|
|
name = fields.Char(string="设备号")
|
|
display_name = fields.Char(string="名称", compute='_compute_display_name', store=True)
|
|
attendance_address = fields.Char(string="设备地址")
|
|
broker = fields.Char(string='服务器地址/ip')
|
|
port = fields.Char(string='端口号')
|
|
number = fields.Integer(string="数量", compute="compute_iot_num")
|
|
id_valid = fields.Datetime(string="设备有效期")
|
|
company_id = fields.Many2one('res.company', string="公司")
|
|
remake = fields.Text(string='备注')
|
|
employee_ids = fields.Many2many('hr.employee', string="员工")
|
|
is_connected = fields.Boolean(string="连接状态", default=False)
|
|
last_update_time = fields.Datetime(string="最后更新时间")
|
|
|
|
@api.depends('company_id', 'attendance_address', 'name')
|
|
def _compute_display_name(self):
|
|
for r in self:
|
|
parts = []
|
|
if r.company_id:
|
|
parts.append(r.company_id.name)
|
|
if r.attendance_address:
|
|
parts.append(r.attendance_address)
|
|
if r.name:
|
|
parts.append(r.name)
|
|
r.display_name = ' - '.join(parts) if parts else r.name or ''
|
|
|
|
def action_init_device(self):
|
|
'''
|
|
初始化设备数据
|
|
'''
|
|
# 查找 员工
|
|
values = []
|
|
upload_records = self.env['attendance.iot.user']
|
|
for record in self:
|
|
employees = self.env['hr.employee'].search([('company_id', '=', record.company_id.id)])
|
|
# employee_list = [emp.name for emp in employees]
|
|
# _logger.info(f"{employee_list}")
|
|
for employee in employees:
|
|
iot_user = self.env['attendance.iot.user'].search([('attendance_iot_id', '=', record.id),
|
|
('employee_id', '=', employee.id)])
|
|
|
|
if iot_user:
|
|
upload_records += iot_user
|
|
continue
|
|
values.append({
|
|
'employee_id': employee.id,
|
|
'attendance_iot_id': record.id
|
|
})
|
|
_logger.info(f"{employee.name}")
|
|
# 没有的创建
|
|
self.env['attendance.iot.user'].create(values)
|
|
# 有记录的更新
|
|
upload_records.action_update_iot_info()
|
|
|
|
def open_record(self):
|
|
self.ensure_one()
|
|
return {
|
|
'name': '设备关联用户',
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'attendance.iot.user',
|
|
'view_mode': 'tree',
|
|
'domain': [('attendance_iot_id', '=', self.id)],
|
|
'context': {'default_attendance_iot_id': self.id}
|
|
}
|
|
|
|
def compute_iot_num(self):
|
|
for num in self:
|
|
num.number = len(self.env['attendance.iot.user'].search([('attendance_iot_id', '=', num.id)]))
|
|
|
|
def action_send_sync_sigle(self):
|
|
'''
|
|
向设备发送数据同步信号
|
|
'''
|
|
for record in self:
|
|
self.env['iot.message'].create([{
|
|
'name': '增加用户',
|
|
'topic': f'iot/device/{record.name}',
|
|
'device_sn': record.name,
|
|
'message_data': json.dumps({
|
|
'cmd': 'uploadFaceInfo'
|
|
}, ensure_ascii=False)
|
|
}])
|
|
|
|
# 发送开门信号
|
|
def action_send_open_door_sigle(self):
|
|
for record in self:
|
|
msg = {
|
|
'cmd': 'setDoor',
|
|
'value': 'on'
|
|
}
|
|
msg.pop('face_template', None)
|
|
self.env['iot.message'].create([{
|
|
'name': '开门',
|
|
'topic': f'iot/device/{record.name}',
|
|
'device_sn': record.name,
|
|
'message_data': json.dumps(msg, ensure_ascii=False)
|
|
}])
|
|
|
|
def action_send_close_door_sigle(self):
|
|
for record in self:
|
|
msg = {
|
|
'cmd': 'setDoor',
|
|
'value': 'off'
|
|
}
|
|
msg.pop('face_template', None)
|
|
self.env['iot.message'].create([{
|
|
'name': '开门',
|
|
'topic': f'iot/device/{record.name}',
|
|
'device_sn': record.name,
|
|
'message_data': json.dumps(msg, ensure_ascii=False)
|
|
}])
|
|
|
|
def action_view_logs(self):
|
|
"""查看该设备的 MQTT 操作日志(开门/关门/下发/同步)"""
|
|
self.ensure_one()
|
|
return {
|
|
'name': '考勤机日志',
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'iot.message',
|
|
'view_mode': 'tree,form',
|
|
'domain': [('device_sn', '=', self.name)],
|
|
}
|
|
|
|
def touch_last_update(self):
|
|
"""更新最后触发时间(MQTT/API 每次触发时调用)"""
|
|
self.write({'last_update_time': fields.Datetime.now()})
|
|
|
|
def _log(self, event_type, content):
|
|
"""写入设备操作日志到 iot.message"""
|
|
self.ensure_one()
|
|
self.env['iot.message'].create({
|
|
'name': event_type,
|
|
'device_sn': self.name,
|
|
'topic': f'iot/device/{self.name}',
|
|
'message_data': content,
|
|
'state': 'done',
|
|
})
|
|
|
|
|