import time
import json
import logging
from odoo import http
from odoo.http import request
from chirpstack_api import integration
from google.protobuf.json_format import Parse, MessageToDict
_logger = logging.getLogger(__name__)
class ChirpStackWebhook(http.Controller):
def _log(self, msg):
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
_logger.info(f"[{timestamp}] {msg}")
@http.route('/chirpstack/webhook', type='http', auth='public', methods=['POST'], csrf=False)
def webhook_handler(self, **kwargs):
try:
self._log("\n" + "=" * 50)
self._log(f"Incoming request to: {request.httprequest.path}")
# Log request details
event = request.httprequest.args.get('event', '')
content_type = request.httprequest.content_type.lower()
raw_body = request.httprequest.get_data()
self._log(f"Event type: {event}")
self._log(f"Content-Type: {content_type}")
self._log(f"Body size: {len(raw_body)} bytes")
# Log body content based on content type
if 'application/json' in content_type:
self._log("Payload format: JSON")
self._log(f"Body (truncated): {raw_body[:200].decode('utf-8')}...")
else:
self._log("Payload format: Protobuf (binary)")
self._log(f"Hex preview: {raw_body[:20].hex()}...")
# Dispatch to event-specific handler
if event == "up":
return self.process_uplink(raw_body, content_type)
elif event == "join":
return self.process_join(raw_body, content_type)
else:
self._log(f"Unknown event type: {event}")
return request.make_response(json.dumps({
'status': 'ignored',
'event': event
}), headers=[('Content-Type', 'application/json')])
except Exception as e:
# Log errors in the general handler
self._log(f"ERROR in webhook_handler: {str(e)}")
return request.make_response(json.dumps({
'status': 'error',
'message': str(e)
}), headers=[('Content-Type', 'application/json')], status=500)
def process_uplink(self, body, content_type):
try:
self._log("\nProcessing uplink event...")
self._log(f"Body content: {body[:100]}...")
if 'application/json' in content_type:
body_str = body.decode('utf-8')
uplink = Parse(body_str, integration.UplinkEvent())
data = json.loads(body_str)
else:
uplink = integration.UplinkEvent()
uplink.ParseFromString(body)
data = MessageToDict(uplink)
self._log("\nUPLINK EVENT")
self._log(f"Device EUI: {uplink.device_info.dev_eui}")
self._log(f"Payload (hex): {uplink.data.hex()}")
self._log("Full data:")
_logger.info(json.dumps(data, indent=2))
# Log additional information for debugging
if 'txInfo' in data:
self._log(f"Frequency: {data['txInfo'].get('frequency')} Hz")
self._log(f"DR: {data['txInfo'].get('dr')}")
if 'rxInfo' in data and len(data['rxInfo']) > 0:
rx = data['rxInfo'][0]
self._log(f"Gateway ID: {rx.get('gatewayId')}")
self._log(f"RSSI: {rx.get('rssi')}")
self._log(f"SNR: {rx.get('snr')}")
# Optional: Save to Odoo model
self._log("Saving device data to Odoo...")
device = request.env['lora.device'].sudo().create_or_update_device(data)
self._log(f"Device ID: {device.id if device else 'N/A'}")
return request.make_response(json.dumps({
'status': 'success',
'device_id': device.id if device else None
}), headers=[('Content-Type', 'application/json')])
except Exception as e:
# Log errors specific to uplink processing
self._log(f"Uplink processing error: {str(e)}")
return request.make_response(json.dumps({
'status': 'error',
'message': str(e)
}), headers=[('Content-Type', 'application/json')], status=500)
def process_join(self, body, content_type):
try:
self._log("\nProcessing join event...")
self._log(f"Body content: {body[:100]}...")
if 'application/json' in content_type:
join = Parse(body.decode('utf-8'), integration.JoinEvent())
else:
join = integration.JoinEvent()
join.ParseFromString(body)
self._log("\nJOIN EVENT")
self._log(f"Device EUI: {join.device_info.dev_eui}")
self._log(f"DevAddr: {join.dev_addr}")
self._log(f"Application ID: {join.device_info.application_id}")
return request.make_response(json.dumps({
'status': 'success',
'device_eui': join.device_info.dev_eui
}), headers=[('Content-Type', 'application/json')])
except Exception as e:
# Log errors specific to join processing
self._log(f"Join processing error: {str(e)}")
return request.make_response(json.dumps({
'status': 'error',
'message': str(e)
}), headers=[('Content-Type', 'application/json')], status=500)
im trying to get data in odoo module and updeate them but its not working
curl -X POST http://192.168.20.45:8069/chirpstack/webhook -H "Content-Type: application/json" -d '{
"event": "up",
"deviceInfo": {"deviceName": "Temperature Sensor 1", "devEui": "0004A30B001C0537"},
"rxInfo": [{"gatewayId": "gateway1", "rssi": -75, "snr": 10}],
"txInfo": {"frequency": 868100000, "dr": 5},
"data": "AQIDBA==",
"object": {"volume": 100.5, "tempInlet": 22.5, "tempOutlet": 19.0, "heatingEnergy": 150.0, "coolingEnergy": 120.0},
"time": "2025-04-17T12:00:00Z"
}'
<!doctype html>
<html lang=en>
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>