Skip to Content
Menú
This question has been flagged
1 Respondre
627 Vistes

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>

Avatar
Descartar
Autor Best Answer

this is the JSON that should we accept and save the data to odoo and show then in our view :

{
    "deduplicationId": "d7ef9334-9455-4762-a8fe-6d67a21e81e0",
    "time": "2025-02-16T13:57:46.037091+00:00",
    "deviceInfo": {
        "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242",
        "tenantName": "ChirpStack",
        "applicationId": "6dcf61a7-e201-4128-b562-773eefbe40fc",
        "applicationName": "odoo-lora",
        "deviceProfileId": "d5152431-acb8-4de3-b4b3-784410f765ed",
        "deviceProfileName": "device-01",
        "deviceName": "flow-meter-001",
        "devEui": "04b6488910907499",
        "deviceClassEnabled": "CLASS_A",
        "tags": {}
    },
    "devAddr": "0014b276",
    "adr": false,
    "dr": 0,
    "fCnt": 262,
    "fPort": 1,
    "confirmed": false,
    "data": "ARsAAAAAAAAA0lIDABaREwA=",
    "object": {
        "bytes": 17,
        "tempInlet": 10.8,
        "heatingEnergy": 27,
        "coolingEnergy": 0,
        "tempOutlet": 27.5,
        "emptyTube": false,
        "type": 1,
        "subtype": 0,
        "deviceDefect": false,
        "packetType": "SP01",
        "diagnosticIntervalSetup": 0,
        "deviceStatusBits": 0,
        "volume": 217.81
    },
    "rxInfo": [
        {
            "gatewayId": "41374e4b83434a36",
            "uplinkId": 10241,
            "gwTime": "2025-02-16T13:57:46.037091+00:00",
            "rssi": -44,
            "snr": 11.25,
            "channel": 6,
            "location": {},
            "context": "EBzJLA==",
            "crcStatus": "CRC_OK"
        }
    ],
    "txInfo": {
        "frequency": 867700000,
        "modulation": {
            "lora": {
                "bandwidth": 125000,
                "spreadingFactor": 12,
                "codeRate": "CR_4_5"
            }
        }
    },
    "regionConfigId": "eu868"
}
Avatar
Descartar
Related Posts Respostes Vistes Activitat
0
d’ag. 25
1
3
d’ag. 25
800
1
d’ag. 25
557
3
d’ag. 25
843
1
d’ag. 25
475