kiwi
kiwi copied to clipboard
Application kiwi exited: exited in: Kiwi.Application.start(:normal, [])
First off this is awesome! I'm hoping to use Kiwi on my PIM420 in order to control some tasmota switches and other items in my home.
I'm not able to get any response using curl. I can ping and ssh into the Pi using the provided ssh key(took a bit for me to figure that part out since it's not mentioned that the key in the repo must be used).
I only thing that stands out in the RingLogger.next output is:
21:40:12.842 [debug] Restarted Erlang distribution as node :"[email protected]"
21:40:13.161 [debug] Mnesiahack: Schema initialized, at least if it wasn't there before.
21:40:14.620 [debug] Mnesiahack: Mnesia started.
21:40:15.622 [debug] Mnesiahack: All done.
21:40:15.762 [info] Application kiwi exited: exited in: Kiwi.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (FunctionClauseError) no function clause matching in Kiwi.Application.children/2
(kiwi 1.0.2) lib/kiwi/application.ex:54: Kiwi.Application.children(:rpi0, %{KEY_MGMT: "WPA-PSK", PSK: "PASSWORD HERE", SSID: "HOME_CONTROL"})
(kiwi 1.0.2) lib/kiwi/application.ex:14: Kiwi.Application.start/2
(kernel 7.3) application_master.erl:277: :application_master.start_it_old/4
21:40:15.827 [info] Application mojito exited: :stopped
21:40:15.828 [info] Application poolboy exited: :stopped
21:40:15.829 [info] Application castore exited: :stopped
21:40:15.840 [info] Application mint exited: :stopped
21:40:15.841 [info] Application corsica exited: :stopped
21:40:15.842 [info] Application jason exited: :stopped
21:40:15.853 [info] Application plug_cowboy exited: :stopped
21:40:15.854 [info] Application cowboy_telemetry exited: :stopped
21:40:15.856 [info] Application maru exited: :stopped
21:40:15.866 [info] Application plug exited: :stopped
21:40:15.877 [info] Application telemetry exited: :stopped
21:40:15.887 [info] Application plug_crypto exited: :stopped
21:40:15.898 [info] Application mime exited: :stopped
21:40:15.899 [info] Application eex exited: :stopped
21:40:15.909 [info] Application cowboy exited: :stopped
21:40:15.910 [info] Application cowlib exited: :stopped
21:40:15.921 [info] Application ranch exited: :stopped
21:40:15.922 [info] Application circuits_i2c exited: :stopped
21:40:15.923 [info] Application circuits_spi exited: :stopped
21:40:15.924 [info] Application circuits_gpio exited: :stopped
21:40:15.925 [info] Application toolshed exited: :stopped
21:40:15.936 [info] Application websockex exited: :stopped
21:40:15.983 [info] Application mnesia exited: :stopped
I've also attached a full copy of the output of RingLogger.next. I did remove my PSK and replace it with "PASSWORD HERE" but we know the issue is not wifi since I can ssh in so that shouldn't be an issue.
Any help would be greatly appreciated log.txt !
Did you enable the OBS endpoint?
//Edit: Maybe you can paste your configuration with blanked out password/ssid here?
I did not enable the OBS endpoint and removed the line as suggested in the Installation section.
Contents of kiwi.txt:
user@macbookair-wired-dock BOOT-A % cat kiwi.txt
NERVES_NETWORK_KEY_MGMT=WPA-PSK
NERVES_NETWORK_SSID=HOME_CONTROL
NERVES_NETWORK_PSK=PASSWORD HERE
user@macbookair-wired-dock BOOT-A %
Could you try enabling it and see if it works then?
So made some progress.
I added NERVES_NETWORK_OBS_SOCKET=ws://obs.lan:4444
to kiwi.txt:
user@macbookair-wired-dock BOOT-A % cat kiwi.txt
NERVES_NETWORK_KEY_MGMT=WPA-PSK
NERVES_NETWORK_SSID=HOME_CONTROL
NERVES_NETWORK_PSK=PASSWORD HERE
NERVES_NETWORK_OBS_SOCKET=ws://obs.lan:4444
user@macbookair-wired-dock BOOT-A %
I still get an error, but now the gpios are seen in the RingLogger.next output. Full output attached.
New error:
17:37:00.328 [info] Application kiwi exited: Kiwi.Application.start(:normal, []) returned an error: shutdown: failed to start child: Kiwi.OBS
** (EXIT) %WebSockex.ConnError{original: :nxdomain}
I was hoping to use this without OBS. Is that not possible?
Yes, it should be possible and I believe to have found the issue. Will work on a fix asap.
If you want to use it right now it's probably best to just set up any websocket on that address. As long as it can connect to it, it should be good.
So I added one of my internal web servers(port 81 is correct) to the kiwi.txt:
user@macbookair-wired-dock BOOT-A % cat kiwi.txt
NERVES_NETWORK_KEY_MGMT=WPA-PSK
NERVES_NETWORK_SSID=HOME_CONTROL
NERVES_NETWORK_PSK=PASSWORD HERE
NERVES_NETWORK_OBS_SOCKET=ws://192.168.0.147:81
user@macbookair-wired-dock BOOT-A %
I still get an error in the RingLogger.next output:
19:03:58.409 [info] Application kiwi exited: Kiwi.Application.start(:normal, []) returned an error: shutdown: failed to start child: Kiwi.OBS
** (EXIT) %WebSockex.RequestError{code: 200, message: "OK"}
Full log attached.
So I've got this working to the point it now responds in a web browser. But I'm not able to POST anything using curl.
Current kiwi.txt:
user@macbookair-wired-dock BOOT-A % cat kiwi.txt
NERVES_NETWORK_KEY_MGMT=WPA-PSK
NERVES_NETWORK_SSID=HOME_CONTROL
NERVES_NETWORK_PSK=PASSWORD HERE
NERVES_NETWORK_OBS_SOCKET=ws://192.168.0.147:8010
user@macbookair-wired-dock BOOT-A %
Fixed it to actually use a websocket by setting up a websocket test sever in docker.
GET /settings result:
user@macbookair-wired-dock ~ % curl "http://192.168.33.116:8080/settings" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{}'
{"content":{"param":"settings","reason":"required"},"timestamp":"2022-02-25 22:41:39.267703Z"}% >user@macbookair-wired-dock ~ %
HTTP Action:
user@macbookair-wired-dock ~ % curl -X POST "http://192.168.33.116:8080/settings/keys/key_1_in_row_1" \
-H "Content-Type: application/json; charset=utf-8" \
-d $'{
"object": {
"keydown": {
"http": [
{
"body": "{}",
"method": "post",
"headers": {
"content-type": "application/json"
},
"url": "http://192.168.33.133/cm?cmnd=Power%20TOGGLE"
}
]
}
}
}'
{"content":null,"timestamp":"2022-02-25 22:46:31.630382Z"}%
user@macbookair-wired-dock ~ %
Result seen in RingLogger.next:
iex([email protected])12> RingLogger.next
22:46:31.624 [info] POST /settings/keys/key_1_in_row_1
22:46:31.629 [error] {:aborted, {:no_exists, Kiwi.Collection.Setting}}
22:46:31.631 [info] Sent 500 in 6ms
3 out of 3 new messages shown.
:ok
iex([email protected])13>
I then press key_1_in_row_1 and the following is shown in RingerLogger.next:
iex([email protected])14> RingLogger.next
22:50:37.399 [debug] Handle Info
22:50:37.399 [debug] {:circuits_gpio, 20, 1228619885061, 0}
22:50:37.403 [debug] %{gpios: [#Reference<0.2322064396.268828676.223988>, #Reference<0.2322064396.268828676.223989>, #Reference<0.2322064396.268828676.223990>, #Reference<0.2322064396.268828676.223991>, #Reference<0.2322064396.268828676.223992>, #Reference<0.2322064396.268828676.223993>, #Reference<0.2322064396.268828676.223994>, #Reference<0.2322064396.268828676.223995>, #Reference<0.2322064396.268828676.223996>, #Reference<0.2322064396.268828676.223997>, #Reference<0.2322064396.268828676.223998>, #Reference<0.2322064396.268828676.223999>], key_1_in_row_1: 17, key_1_in_row_2: 15, key_1_in_row_3: 9, key_1_in_row_4: 9, key_2_in_row_1: 11, key_2_in_row_2: 5, key_2_in_row_3: 5, key_2_in_row_4: 7, key_3_in_row_1: 15, key_3_in_row_2: 7, key_3_in_row_3: 5, key_3_in_row_4: 7, ledarray: %Kiwi.LedArray{led_array: [0, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, ...], ref: #Reference<0.2322064396.268828676.224003>}}
22:50:37.403 [debug] Keydown for pin 20
22:50:37.405 [info] No key action defined for key_1_in_row_1!
22:50:37.510 [debug] Handle Info
22:50:37.510 [debug] {:circuits_gpio, 20, 1228730816300, 1}
22:50:37.515 [debug] %{gpios: [#Reference<0.2322064396.268828676.223988>, #Reference<0.2322064396.268828676.223989>, #Reference<0.2322064396.268828676.223990>, #Reference<0.2322064396.268828676.223991>, #Reference<0.2322064396.268828676.223992>, #Reference<0.2322064396.268828676.223993>, #Reference<0.2322064396.268828676.223994>, #Reference<0.2322064396.268828676.223995>, #Reference<0.2322064396.268828676.223996>, #Reference<0.2322064396.268828676.223997>, #Reference<0.2322064396.268828676.223998>, #Reference<0.2322064396.268828676.223999>], key_1_in_row_1: 18, key_1_in_row_2: 15, key_1_in_row_3: 9, key_1_in_row_4: 9, key_2_in_row_1: 11, key_2_in_row_2: 5, key_2_in_row_3: 5, key_2_in_row_4: 7, key_3_in_row_1: 15, key_3_in_row_2: 7, key_3_in_row_3: 5, key_3_in_row_4: 7, ledarray: %Kiwi.LedArray{led_array: [0, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, 0, 227, 0, 0, ...], ref: #Reference<0.2322064396.268828676.224003>}}
22:50:37.515 [debug] Keyup for pin 20
22:50:37.517 [info] No key action defined for key_1_in_row_1!
10 out of 10 new messages shown.
:ok
iex([email protected])15>
Can you give the bulk POST a try, as documented here? Your POST actually looks fine, but the response you retrieve doesn't look good.
Still getting errors.
POST:
curl -X "POST" "http://192.168.33.116:8080/settings" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"settings": [
{
"id": "key_1_in_row_1",
"object": {
"keydown": {
"http": [
{
"body": "{}",
"method": "post",
"headers": {
"content-type": "application/json"
},
"url": "http://192.168.33.129/cm?cmnd=Power%20TOGGLE"
}
]
}
}
}
}'
Output of RingLogger.next:
iex([email protected])4> RingLogger.next
21:34:06.863 [info] POST /settings
21:34:06.868 [error] %Plug.Parsers.ParseError{exception: %Jason.DecodeError{data: "{\n \"settings\": [\n {\n \"id\": \"key_1_in_row_1\",\n \"object\": {\n \"keydown\": {\n \"http\": [\n {\n \"body\": \"{}\",\n \"method\": \"post\",\n \"headers\": {\n \"content-type\": \"application/json\"\n },\n \"url\": \"http://192.168.33.129/cm?cmnd=Power%20TOGGLE\"\n }\n ]\n }\n }\n }\n }", position: 550, token: nil}, plug_status: 400}
21:34:06.871 [error] #PID<0.548.0> running Kiwi.Api (connection #PID<0.547.0>, stream id 1) terminated
Server: 192.168.33.116:8080 (http)
Request: POST /settings
** (exit) an exception was raised:
** (Protocol.UndefinedError) protocol Jason.Encoder not implemented for %Plug.Parsers.ParseError{exception: %Jason.DecodeError{data: "{\n \"settings\": [\n {\n \"id\": \"key_1_in_row_1\",\n \"object\": {\n \"keydown\": {\n \"http\": [\n {\n \"body\": \"{}\",\n \"method\": \"post\",\n \"headers\": {\n \"content-type\": \"application/json\"\n },\n \"url\": \"http://192.168.33.129/cm?cmnd=Power%20TOGGLE\"\n }\n ]\n }\n }\n }\n }", position: 550, token: nil}, plug_status: 400} of type Plug.Parsers.ParseError (a struct), Jason.Encoder protocol must always be explicitly implemented.
If you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:
@derive {Jason.Encoder, only: [....]}
defstruct ...
It is also possible to encode all fields, although this should be used carefully to avoid accidentally leaking private information when new fields are added:
@derive Jason.Encoder
defstruct ...
Finally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:
Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])
Protocol.derive(Jason.Encoder, NameOfTheStruct)
. This protocol is implemented for the following type(s): Kiwi.Collection.Setting, Kiwi.Collection.Led, NaiveDateTime, Atom, DateTime, BitString, Map, Decimal, Date, Any, Jason.Fragment, Integer, Float, List, Time
(jason 1.2.2) lib/jason.ex:199: Jason.encode_to_iodata!/2
(kiwi 1.0.2) lib/kiwi/helpers/response.ex:29: Kiwi.Helpers.Response.resp_json/2
(plug_cowboy 2.5.0) lib/plug/cowboy/handler.ex:12: Plug.Cowboy.Handler.init/2
(cowboy 2.9.0) /home/runner/work/kiwi/kiwi/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.9.0) /home/runner/work/kiwi/kiwi/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
(cowboy 2.9.0) /home/runner/work/kiwi/kiwi/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
(stdlib 3.14.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
3 out of 3 new messages shown.
:ok
iex([email protected])5>
Text file of output -> RingLogger.txt
Just a thought. Is there any way to make a config file and place it on the SD card instead of using curl?
I've validated the JSON you're posting here and found out you're missing a ]
at the end. This is valid json:
{
"settings": [{
"id": "key_1_in_row_1",
"object": {
"keydown": {
"http": [{
"body": "{}",
"method": "post",
"headers": {
"content-type": "application/json"
},
"url": "http://192.168.33.129/cm?cmnd=Power%20TOGGLE"
}]
}
}
}]
}
Please re-try with this.
I gave that a try on a linux machine this time and got the following:
root@ironhide:~# curl -X "POST" "http://192.168.33.116:8080/settings"
'{
"settings": [{
"id": "key_1_in_row_1",
"object": {
"keydown": {
"http": [{
"body": "{}",
"method": "post",
"headers": {
"content-type": "application/json"
},
"url": "http://192.168.33.129/cm?cmnd=Power%20TOGGLE"
}]
}
}
}]
}'
{"content":{"param":"settings","reason":"required"},"timestamp":"2022-03-01 21:09:51.673505Z"}-bash: {
"settings": [{
"id": "key_1_in_row_1",
"object": {
"keydown": {
"http": [{
"body": "{}",
"method": "post",
"headers": {
"content-type": "application/json"
},
"url": "http://192.168.33.129/cm?cmnd=Power%20TOGGLE"
}]
}
}
}]
}: File name too long
root@ironhide:~#
RingLogger.next:
iex([email protected])4> RingLogger.next
21:09:51.668 [info] POST /settings
21:09:51.673 [error] %Maru.Exceptions.InvalidFormat{param: :settings, plug_status: 400, reason: :required, value: nil}
21:09:51.674 [info] Sent 400 in 4ms
3 out of 3 new messages shown.
:ok
iex([email protected])5>
So I'm not sure what's happening.
Thanks for all the great feedback, I will investigate this!
Any update on this? Need anything further from me?
@SirMaple no info needed, sorry, I just haven't had time to dig into it.